Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions .github/scripts/detect-branch-name.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#!/bin/bash

# Exit immediately if any command fails
set -e

echo "Detecting Branch Name..."

if [[ "$BRANCH_NAME" == *"note"* ]]; then
echo "test_tag=note" >> $GITHUB_OUTPUT
fi
34 changes: 34 additions & 0 deletions .github/workflows/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# CI/CD workflows

## Convention and Standard
### Naming
- Each workflow should have a unique name and filename.
- Name the **main** workflows as `workflow-filename.yml`
- Name the **reusable** workflows as `_reusable-workflow.yml` (with `_` prefix)
- A workflow’s name should **not** be changed once it has been committed to the repository, as this may cause history mismatches and unexpected errors.
Therefore, it is recommended to consider changes carefully before modifying existing workflows.

### Directory structure
- `.github/workflows`: All **runnable workflows** must be placed in this directory, as required by the official GitHub Actions documentation. Otherwise, they may not execute correctly.
- `.github/scripts`: Place **reusable or lengthy bash scripts** in this directory so they can be referenced and reused in workflows.

### Workflows (Planned)
- Changes on `feature` branch: Run unit tests, linting, security check, etc
- PR on `develop` branch (for integration/staging):
- Unit + Integration tests (API, DB, UI, etc)
- Build and push staging images
- Deploy to staging environment and test (optional)
- PR on `main` branch (for production): Final build verification
- Completed merge on `main` branch (for production):
- Build and push production-ready images with version tags
- Deploy to production environment

## Reference
### GitHub Actions Workflows
- Official documentation: [GitHub Actions Docs - How To](https://docs.github.com/en/actions/how-tos)
- Advanced customization: [Mert Mengü - Guide to GitHub Actions for Advanced CI/CD Workflows](https://medium.com/@mertmengu/guide-to-github-actions-for-advanced-ci-cd-workflows-1e494271ac22)
- GitHub Actions with Spring Boot: [Pudding Entertainment - GitHub Actions: Spring Boot Application Build and Deployment](https://pudding-entertainment.medium.com/github-actions-spring-boot-application-build-and-deployment-c52a2a233cb9)

### Branching Strategy
- Different branching strategies, including using develop and main branch: [Devtron - Branching Strategy for CI/CD](https://devtron.ai/blog/best-branching-strategy-for-ci-cd/)
- Run tests on feature and master branch: [TeamCity - Branching Strategy for CI/CD](https://www.jetbrains.com/teamcity/ci-cd-guide/concepts/branching-strategy/)
47 changes: 47 additions & 0 deletions .github/workflows/_reusable-test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
name: Reusable Test Workflow

on:
# Workflow only runs when being called by others
workflow_call:
inputs:
test-level: # select between [unit, integration, all]
required: true
type: string
test-tag: # not required, but will automatically run all tests if left empty
required: false
type: string

jobs:
build-and-test:
name: Build and Run Tests
runs-on: ubuntu-latest

steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Setup Java JDK 17
uses: actions/setup-java@v3
with:
distribution: 'corretto'
java-version: 17

- name: Build with Maven
run: mvn clean install

- name: Run All Unit Tests
run: |
if [ -n "${{ inputs.test-tag }}" ]; then
mvn test -Punit-test -Dgroups="${{ inputs.test-tag }}"
else
mvn test -Punit-test
fi

- name: Run All Integration Tests
if: inputs.test-level != 'unit'
run: |
if [ -n "${{ inputs.test-tag }}" ]; then
mvn verify -Pintegration-test -Dgroups="${{ inputs.test-tag }}"
else
mvn verify -Pintegration-test
fi
30 changes: 30 additions & 0 deletions .github/workflows/ci-cd-develop.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
name: CI/CD on Develop Branch

on:
# Workflow runs whenever a new PR to develop is created
pull_request:
branches:
- develop

jobs:
# Build and run test based on the branch detection result
build-and-test:
name: Build and Run All Tests
uses: ./.github/workflows/_reusable-test.yml
secrets: inherit
with:
test-level: 'all'

# Build and push image (placeholder only since the app is not completed yet)
build-images:
name: Build Images and Deploy to Docker Hub
needs: build-and-test
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Build and push
run: |
echo "Building images..."
echo "Published to Docker Hub!"
39 changes: 39 additions & 0 deletions .github/workflows/feature-test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
name: Feature Branch Test

on:
# Workflow runs whenever the source code changes on the target feature branch
push:
branches:
- "feature/**"
- "fix/**"
paths:
- "src/**"

jobs:
# Detect feature changes based on branch name
detect-changes:
name: Detect Feature Changes
runs-on: ubuntu-latest
outputs:
test_tag: ${{ steps.detect.outputs.test_tag }}
steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Detect Changes
id: detect
env:
BRANCH_NAME: ${{ github.ref_name }}
run: |
chmod +x .github/scripts/detect-branch-name.sh
./.github/scripts/detect-branch-name.sh

# Build and run test based on the branch detection result
build-and-test:
name: Build and Run Tests
needs: detect-changes
uses: ./.github/workflows/_reusable-test.yml
secrets: inherit
with:
test-level: 'unit'
test-tag: ${{ needs.detect-changes.outputs.test_tag }}
173 changes: 155 additions & 18 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,25 +1,88 @@
# SmartNotes Backend
> **Active development** happens on [develop](https://github.com/TUT888/SmartNotes/tree/develop) branch.
> The [main](https://github.com/TUT888/SmartNotes/tree/main) branch contains **stable release code**.

Personal project for smart note taking application
Backend service for **SmartNotes**, a personal project that enables smart note-taking with AI integration to
help individuals have a better experience in note-taking, organizing, and revising knowledge.

**SmartNotes Frontend Repository:** [https://github.com/pvdev1805/SmartNotes](https://github.com/pvdev1805/SmartNotes)

## Table of Contents

- [Project Info](#project-info)
- [Tech Stack](#tech-stack)
- [Branching Strategy with CI/CD](#branching-strategy-with-cicd)
- [Supported Features](#supported-features)
- [User Authentication](#1-user-authentication)
- [AI-Powered Quiz Generation](#2-ai-powered-quiz-generation)
- [CRUD Management Features](#3-crud-management-features)
- [Project Setup](#project-setup)
- [Prerequisites](#prerequisites)
- [HuggingFace API](#huggingface-api)
- [Environment Variables](#environment-variables)
- [How to Test](#how-to-test)
- [Test Commands](#test-commands-windows)
- [Test Structure](#test-structure)
- [Test Notes](#test-notes)
- [Contributors](#contributors)

## Project Info
### Tech Stack
- **Java 17** + **Spring Boot 3.5.5** for backend services
- **Maven** for build and dependency management
- **HuggingFace API** for AI quiz generation
- **MySQL** for database and persistence
- **Redis** for caching and session management
- **Docker** for containerization
- **Cloud and Deployment**: AWS (planned)
- **CI/CD**: GitHub Actions

### Branching Strategy with CI/CD
> For detail documentation about CI/CD process, please refer to another [dedicated README](./.github/workflows/README.md)

- **main**: stable, production‑ready code
- **develop**: integration branch with the latest completed features
- **feature/***: branches for individual features or fixes, merged into `develop` via pull requests

[Back to top](#smartnotes-backend)

## Supported Features
| Module | Method | API | Description |
| -------- | -------- | -------- | ------- |
| Authentication | POST | `/api/auth/register` | Register new user |
| | POST | `/api/auth/login` | Login with your account |
| | POST | `/api/auth/logout` | Logout of current session |
| | POST | `/api/auth/refresh` | Refresh your authentication token |
| | GET | `/api/users/me` | Get your information (logged in) |
| Document | GET | `/api/documents` | List all available documents |
| | DELETE | `/api/documents/{id}` | Delete document using its id |
| Note | POST | `/api/documents/notes` | Create new note |
| | GET | `/api/documents/notes/{id}` | Get note content using its id |
| | PUT | `/api/documents/notes/{id}` | Update note content using its id |
| | DELETE | `/api/documents/notes/{id}` | Delete note content using its id |
| AI | GET | `/api/ai/generateQuiz/sample` | Get a sample quiz from sample response, this API does not require API TOKEN |
| | GET | `/api/ai/generateQuiz/{noteId}` | Generate relevant quizzes based on 1 note, this feature **requires HuggingFace API TOKEN** to run |
### 1. User Authentication
- Register, login, logout, and refresh tokens
- JWT-based secure authentication
- Secure access to user profile information

### 2. AI-Powered Quiz Generation
- Generate quizzes from notes using HuggingFace models
- Sample endpoint for testing without authentication

### 3. CRUD Management Features
**Document Management (CRUD)**: All types of documents including notes, flashcards, and quizzes:
- List all documents by user, or delete specific document

**Note Management**:
- Create, update, retrieve, and delete notes

**Flashcard & Flashcard Sets Management**:
- Create, update, retrieve, and delete flashcards
- Organize flashcards into sets

**Quiz & Quiz Sets Management**:
- Create, update, retrieve, and delete quizzes
- Organize quizzes into sets
- Track quiz attempts and scores

[Back to top](#smartnotes-backend)

## Project Setup
### Prerequisites
- **Java 17** or higher
- **MySQL**
- **Docker**
- For integration tests with Testcontainers
- For Redis (optional for local development on Windows)
- **HuggingFace Account** (for AI features)

### HuggingFace API
- Create a HuggingFace account
- Create Access Token:
Expand All @@ -33,6 +96,7 @@ Personal project for smart note taking application
### Environment variables
In project root directory, create `.env` file and paste your **ACCESS TOKEN** here
```
# AI INFERENCE
API_TOKEN=<YOUR-TOKEN-HERE>
API_URL=<YOUR-INFERENCE-PROVIDER>
MODEL=<YOUR-SELECTED-MODEL>
Expand All @@ -41,10 +105,83 @@ AI_API_USER_ROLE=user
AI_API_SYSTEM_ROLE=system
AI_API_TEMPERATURE=<YOUR-CUSTOM-VALUE>
AI_API_TOP_P=<YOUR-CUSTOM-VALUE>

# Database
DB_PORT=<YOUR-DATABASE-PORT>
DB_NAME=<YOUR-DATABASE-NAME>
DB_USERNAME=<YOUR-DATABASE-DB_USERNAME>
DB_PASSWORD=<YOUR-DATABASE-DB_PASSWORD>
```

# JWT Config
JWT_KEYSTORE_PASSWORD=<YOUR-KEYSTORE>
JWT_KEY_PASSWORD=<YOUR-PASSWORD>

# Redis Config
REDIS_HOST=<YOUR-HOST>
REDIS_PORT=<YOUR-PORT>
```

[Back to top](#smartnotes-backend)

## How to test
### Test commands (Windows)
Run all tests
```bash
# Run all tests (unit + integration)
./mvnw.cmd verify
```

Run specific type of test
```bash
# Run specific test file
./mvnw.cmd test -Dtest=NoteServiceTest

# Run all unit tests (service tests with mocks)
./mvnw.cmd test -Punit-test

# Run all integration tests (repository + controller with containers)
./mvnw.cmd verify -Pintegration-test
```

Run specific test group with tag, use **boolean expression** for tags combination
```bash
# Run test with "note" tag
./mvnw.cmd test -Dgroups="note"

# Run tests with "note" or "document" tags
./mvnw.cmd test -Dgroups="note | document"

# Combine with test type: run all unit tests with "note" tag
./mvnw.cmd test -Punit-test -Dgroups="note | document"
```

### Test Structure
```
src/test/java/
├── unit/ # Fast tests (Surefire)
│ └── service/ # Service unit tests with mocked dependencies
└── integration/ # Slower tests (Failsafe)
├── repository/ # Repository tests with H2
└── controller/ # Full-stack tests with MySQL + Redis containers
```

### Test Notes
- **Unit tests** run with Surefire and use mocked dependencies
- **Integration tests** run with Failsafe and use Testcontainers
- Docker must be running for integration tests (uses MySQL and Redis containers)
- First integration test run may take longer (downloads container images)

[Back to top](#smartnotes-backend)

## Contributors
**Project Maintainers:** This project (both frontend and backend) is developed and maintained by:

- **Alice Tat** ([@TUT888](https://github.com/TUT888))
- **Phu Vo** ([@pvdev1805](https://github.com/pvdev1805))

**Project Repositories:**
- Backend: [SmartNotes Backend](https://github.com/TUT888/SmartNotes)
- Frontend: [SmartNotes Frontend](https://github.com/pvdev1805/SmartNotes)

[Back to top](#smartnotes-backend)
Loading