NestJS Backend API โ
HaloLight NestJS Backend API, an enterprise-grade backend service built with NestJS 11 framework, providing complete RBAC permission system and Swagger documentation.
Features โ
- ๐๏ธ NestJS 11 - Enterprise Node.js framework with modular architecture
- ๐ท Prisma ORM 5 - Type-safe database access with PostgreSQL 16 support
- ๐ JWT Dual Tokens - AccessToken + RefreshToken authentication mechanism
- ๐ก๏ธ RBAC Permissions - Role-Based Access Control with wildcard permission support
- ๐ Swagger Docs - Auto-generated interactive API documentation
- โ Type Validation - Automatic DTO validation with class-validator
- ๐ณ Docker Deploy - Multi-stage build optimization, one-click Docker Compose deployment
- ๐งช Complete Testing - Jest unit tests + E2E tests
Tech Stack โ
| Category | Technology |
|---|---|
| Framework | NestJS 11 |
| Language | TypeScript 5.7 |
| Database | PostgreSQL 16 + Prisma ORM 5 |
| Authentication | JWT + Passport.js |
| Validation | class-validator + class-transformer |
| Documentation | Swagger/OpenAPI |
| Testing | Jest + Supertest |
| Containerization | Docker + Docker Compose |
| Package Manager | pnpm 10.23.0 |
Quick Start โ
# Clone repository
git clone https://github.com/halolight/halolight-api-nestjs.git
cd halolight-api-nestjs
# Install dependencies
pnpm install
# Generate Prisma Client
pnpm prisma:generate
# Run database migrations
pnpm prisma:migrate
# Run development server
pnpm dev
# Build for production
pnpm build
pnpm start:prodProject Structure โ
halolight-api-nestjs/
โโโ src/
โ โโโ common/ # Shared modules
โ โ โโโ decorators/ # Custom decorators (@Public, @CurrentUser, @RequirePermissions)
โ โ โโโ filters/ # Global exception filters
โ โ โโโ guards/ # Guards (JWT auth, permission checks)
โ โ โโโ interceptors/ # Interceptors (logging, transformation)
โ โโโ configs/ # Configuration modules
โ โ โโโ config.module.ts # Environment variable configuration
โ โ โโโ env.validation.ts # Environment validation (class-validator)
โ โ โโโ swagger.config.ts # Swagger documentation configuration
โ โโโ infrastructure/ # Infrastructure layer
โ โ โโโ prisma/ # Prisma ORM configuration and service
โ โโโ modules/ # Business modules (12 modules)
โ โ โโโ auth/ # Authentication (login, register, refresh tokens)
โ โ โโโ users/ # User management (CRUD, pagination, search)
โ โ โโโ roles/ # Role management (CRUD + permission assignment)
โ โ โโโ permissions/ # Permission management (wildcard support)
โ โ โโโ teams/ # Team management
โ โ โโโ documents/ # Document management (tags, folders)
โ โ โโโ files/ # File management
โ โ โโโ folders/ # Folder management (tree structure)
โ โ โโโ calendar/ # Calendar event management
โ โ โโโ notifications/ # Notification management
โ โ โโโ messages/ # Message conversation management
โ โ โโโ dashboard/ # Dashboard statistics
โ โโโ app.controller.ts # Root controller (homepage, health check)
โ โโโ app.service.ts # Root service
โ โโโ app.module.ts # Root module
โ โโโ main.ts # Application entry (Bootstrap)
โโโ prisma/
โ โโโ schema.prisma # Database model definitions (17 entities)
โ โโโ migrations/ # Database migration history
โโโ test/
โ โโโ app.e2e-spec.ts # E2E tests
โ โโโ jest-e2e.json # E2E Jest configuration
โโโ Dockerfile # Docker multi-stage build
โโโ docker-compose.yml # Docker Compose config (API + PostgreSQL + Redis)
โโโ package.jsonAPI Modules โ
The project includes 12 core business modules providing 60+ RESTful API endpoints:
| Module | Endpoints | Description |
|---|---|---|
| Auth | 5 | User authentication (login, register, refresh token, current user, logout) |
| Users | 5 | User management (CRUD, pagination, search, filtering) |
| Roles | 6 | Role management (CRUD + permission assignment) |
| Permissions | 4 | Permission management (wildcard support: users:*, *) |
| Teams | 5 | Team management |
| Documents | 5 | Document management (tags, folders support) |
| Files | 5 | File management |
| Folders | 5 | Folder management (tree structure) |
| Calendar | 5 | Calendar event management |
| Notifications | 5 | Notification management |
| Messages | 5 | Message conversations |
| Dashboard | 5 | Dashboard statistics |
Authentication Endpoints โ
| Method | Path | Description | Permission |
|---|---|---|---|
| POST | /api/auth/login | User login | Public |
| POST | /api/auth/register | User registration | Public |
| POST | /api/auth/refresh | Refresh token | Public |
| GET | /api/auth/me | Get current user | JWT Required |
| POST | /api/auth/logout | User logout | JWT Required |
User Management Endpoints โ
| Method | Path | Description | Permission |
|---|---|---|---|
| GET | /api/users | Get user list (pagination, search) | JWT Required |
| GET | /api/users/:id | Get user details | JWT Required |
| POST | /api/users | Create user | JWT Required |
| PATCH | /api/users/:id | Update user | JWT Required |
| DELETE | /api/users/:id | Delete user | JWT Required |
Complete API Reference โ
1. Authentication Module (Auth) โ
1.1 User Login โ
Endpoint: POST /api/auth/loginPermission: Public (no authentication required) Description: Login with email and password, returns JWT tokens
Request Body:
{
"email": "admin@halolight.h7ml.cn",
"password": "password123"
}Field Descriptions:
email(string, required): User email address, must be valid email formatpassword(string, required): User password, minimum 8 characters
Success Response (200):
{
"accessToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"refreshToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"user": {
"id": "clx1234567890",
"email": "admin@halolight.h7ml.cn",
"name": "Admin User",
"avatar": "https://avatar.example.com/admin.jpg",
"phone": "+86 138****8888",
"status": "ACTIVE"
}
}Error Responses:
400 Bad Request: Request validation failed401 Unauthorized: Invalid email or password
curl Example:
curl -X POST http://localhost:3000/api/auth/login \
-H "Content-Type: application/json" \
-d '{
"email": "admin@halolight.h7ml.cn",
"password": "password123"
}'1.2 User Registration โ
Endpoint: POST /api/auth/registerPermission: Public (no authentication required) Description: Register new user account
Request Body:
{
"email": "newuser@example.com",
"name": "New User",
"password": "securePass123",
"phone": "+86 138****8888"
}Field Descriptions:
email(string, required): User email, must be valid and uniquename(string, required): User namepassword(string, required): Password, minimum 8 charactersphone(string, optional): Phone number
Success Response (201):
{
"accessToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"refreshToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"user": {
"id": "clx9876543210",
"email": "newuser@example.com",
"name": "New User",
"avatar": null,
"phone": "+86 138****8888",
"status": "ACTIVE"
}
}Error Responses:
400 Bad Request: Request validation failed409 Conflict: Email already registered
curl Example:
curl -X POST http://localhost:3000/api/auth/register \
-H "Content-Type: application/json" \
-d '{
"email": "newuser@example.com",
"name": "New User",
"password": "securePass123",
"phone": "+86 138****8888"
}'1.3 Refresh Token โ
Endpoint: POST /api/auth/refreshPermission: Public (no authentication required) Description: Get new AccessToken using RefreshToken
Request Body:
{
"refreshToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}Success Response (200):
{
"accessToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"refreshToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}Error Responses:
401 Unauthorized: RefreshToken is invalid or expired
curl Example:
curl -X POST http://localhost:3000/api/auth/refresh \
-H "Content-Type: application/json" \
-d '{
"refreshToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}'1.4 Get Current User โ
Endpoint: GET /api/auth/mePermission: JWT Required (authentication required) Description: Get current logged-in user details
Request Headers:
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...Success Response (200):
{
"id": "clx1234567890",
"email": "admin@halolight.h7ml.cn",
"name": "Admin User",
"avatar": "https://avatar.example.com/admin.jpg",
"phone": "+86 138****8888",
"status": "ACTIVE",
"roles": [
{
"id": "role_admin",
"name": "Administrator",
"permissions": ["*"]
}
],
"createdAt": "2024-01-01T00:00:00.000Z",
"updatedAt": "2024-12-04T12:00:00.000Z"
}Error Responses:
401 Unauthorized: Token is invalid or expired
curl Example:
curl -X GET http://localhost:3000/api/auth/me \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."1.5 User Logout โ
Endpoint: POST /api/auth/logoutPermission: JWT Required (authentication required) Description: Logout current user and invalidate token
Request Headers:
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...Success Response (200):
{
"message": "Successfully logged out"
}curl Example:
curl -X POST http://localhost:3000/api/auth/logout \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."2. User Management Module (Users) โ
2.1 Get User List โ
Endpoint: GET /api/usersPermission: JWT Required Description: Get user list with pagination, search and filtering
Query Parameters:
page(number, optional): Page number, default 1limit(number, optional): Items per page, default 10search(string, optional): Search keyword (searches name or email)status(string, optional): User status filter (ACTIVE | INACTIVE | SUSPENDED)
Success Response (200):
{
"data": [
{
"id": "clx1234567890",
"email": "admin@halolight.h7ml.cn",
"name": "Admin User",
"avatar": "https://avatar.example.com/admin.jpg",
"phone": "+86 138****8888",
"status": "ACTIVE",
"createdAt": "2024-01-01T00:00:00.000Z"
}
],
"meta": {
"total": 100,
"page": 1,
"limit": 10,
"totalPages": 10
}
}curl Examples:
# Basic query
curl -X GET "http://localhost:3000/api/users?page=1&limit=10" \
-H "Authorization: Bearer YOUR_TOKEN"
# Search users
curl -X GET "http://localhost:3000/api/users?search=admin&status=ACTIVE" \
-H "Authorization: Bearer YOUR_TOKEN"2.2 Get User Details โ
Endpoint: GET /api/users/:idPermission: JWT Required Description: Get user details by ID
Path Parameters:
id(string, required): User ID
Success Response (200):
{
"id": "clx1234567890",
"email": "admin@halolight.h7ml.cn",
"name": "Admin User",
"avatar": "https://avatar.example.com/admin.jpg",
"phone": "+86 138****8888",
"status": "ACTIVE",
"roles": [
{
"id": "role_admin",
"name": "Administrator"
}
],
"teams": [
{
"id": "team_001",
"name": "Development Team",
"role": "OWNER"
}
],
"createdAt": "2024-01-01T00:00:00.000Z",
"updatedAt": "2024-12-04T12:00:00.000Z"
}Error Responses:
404 Not Found: User does not exist
curl Example:
curl -X GET http://localhost:3000/api/users/clx1234567890 \
-H "Authorization: Bearer YOUR_TOKEN"2.3 Create User โ
Endpoint: POST /api/usersPermission: JWT Required Description: Create new user (admin functionality)
Request Body:
{
"email": "newuser@example.com",
"name": "New User",
"password": "securePass123",
"phone": "+86 138****8888",
"status": "ACTIVE",
"avatar": "https://avatar.example.com/newuser.jpg"
}Field Descriptions:
email(string, required): User emailname(string, required): User namepassword(string, required): Password, minimum 8 charactersphone(string, optional): Phone numberstatus(string, optional): User status, default ACTIVEavatar(string, optional): Avatar URL
Success Response (201):
{
"id": "clx9876543210",
"email": "newuser@example.com",
"name": "New User",
"avatar": "https://avatar.example.com/newuser.jpg",
"phone": "+86 138****8888",
"status": "ACTIVE",
"createdAt": "2024-12-04T12:00:00.000Z"
}curl Example:
curl -X POST http://localhost:3000/api/users \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"email": "newuser@example.com",
"name": "New User",
"password": "securePass123"
}'2.4 Update User โ
Endpoint: PATCH /api/users/:idPermission: JWT Required Description: Update user information
Path Parameters:
id(string, required): User ID
Request Body:
{
"name": "Updated Name",
"phone": "+86 139****9999",
"avatar": "https://avatar.example.com/updated.jpg",
"status": "ACTIVE"
}Field Descriptions: All fields are optional, only send fields that need to be updated
Success Response (200):
{
"id": "clx1234567890",
"email": "admin@halolight.h7ml.cn",
"name": "Updated Name",
"avatar": "https://avatar.example.com/updated.jpg",
"phone": "+86 139****9999",
"status": "ACTIVE",
"updatedAt": "2024-12-04T12:30:00.000Z"
}curl Example:
curl -X PATCH http://localhost:3000/api/users/clx1234567890 \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "Updated Name",
"phone": "+86 139****9999"
}'2.5 Delete User โ
Endpoint: DELETE /api/users/:idPermission: JWT Required Description: Delete user (soft delete or hard delete)
Path Parameters:
id(string, required): User ID
Success Response (200):
{
"message": "User successfully deleted",
"id": "clx1234567890"
}Error Responses:
404 Not Found: User does not exist403 Forbidden: No permission to delete this user
curl Example:
curl -X DELETE http://localhost:3000/api/users/clx1234567890 \
-H "Authorization: Bearer YOUR_TOKEN"3. Role Management Module (Roles) โ
3.1 Get Role List โ
Endpoint: GET /api/rolesPermission: JWT Required Description: Get all roles list
Success Response (200):
{
"data": [
{
"id": "role_admin",
"name": "Administrator",
"description": "Full system access",
"permissions": [
{
"id": "perm_all",
"name": "*",
"description": "All permissions"
}
],
"userCount": 5,
"createdAt": "2024-01-01T00:00:00.000Z"
},
{
"id": "role_user",
"name": "Regular User",
"description": "Basic user access",
"permissions": [
{
"id": "perm_read",
"name": "users:read",
"description": "Read user data"
}
],
"userCount": 50,
"createdAt": "2024-01-01T00:00:00.000Z"
}
]
}curl Example:
curl -X GET http://localhost:3000/api/roles \
-H "Authorization: Bearer YOUR_TOKEN"3.2 Create Role โ
Endpoint: POST /api/rolesPermission: JWT Required Description: Create new role
Request Body:
{
"name": "Editor",
"description": "Can edit content"
}Success Response (201):
{
"id": "role_editor",
"name": "Editor",
"description": "Can edit content",
"createdAt": "2024-12-04T12:00:00.000Z"
}curl Example:
curl -X POST http://localhost:3000/api/roles \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "Editor",
"description": "Can edit content"
}'3.3 Assign Permissions to Role โ
Endpoint: POST /api/roles/:id/permissionsPermission: JWT Required Description: Assign permissions to role
Path Parameters:
id(string, required): Role ID
Request Body:
{
"permissionIds": ["perm_001", "perm_002", "perm_003"]
}Success Response (200):
{
"id": "role_editor",
"name": "Editor",
"permissions": [
{
"id": "perm_001",
"name": "documents:create"
},
{
"id": "perm_002",
"name": "documents:update"
},
{
"id": "perm_003",
"name": "documents:delete"
}
]
}curl Example:
curl -X POST http://localhost:3000/api/roles/role_editor/permissions \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"permissionIds": ["perm_001", "perm_002", "perm_003"]
}'4. Permission Management Module (Permissions) โ
4.1 Get Permission List โ
Endpoint: GET /api/permissionsPermission: JWT Required Description: Get all permissions list, supports wildcard permissions
Success Response (200):
{
"data": [
{
"id": "perm_all",
"name": "*",
"description": "All permissions"
},
{
"id": "perm_users_all",
"name": "users:*",
"description": "All user operations"
},
{
"id": "perm_users_create",
"name": "users:create",
"description": "Create users"
},
{
"id": "perm_users_read",
"name": "users:read",
"description": "Read user data"
},
{
"id": "perm_users_update",
"name": "users:update",
"description": "Update users"
},
{
"id": "perm_users_delete",
"name": "users:delete",
"description": "Delete users"
}
]
}curl Example:
curl -X GET http://localhost:3000/api/permissions \
-H "Authorization: Bearer YOUR_TOKEN"4.2 Create Permission โ
Endpoint: POST /api/permissionsPermission: JWT Required Description: Create new permission
Request Body:
{
"name": "documents:publish",
"description": "Publish documents"
}Field Descriptions:
name(string, required): Permission name, formatresource:actionor wildcard*description(string, optional): Permission description
Success Response (201):
{
"id": "perm_doc_publish",
"name": "documents:publish",
"description": "Publish documents",
"createdAt": "2024-12-04T12:00:00.000Z"
}curl Example:
curl -X POST http://localhost:3000/api/permissions \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "documents:publish",
"description": "Publish documents"
}'5. Team Management Module (Teams) โ
5.1 Get Team List โ
Endpoint: GET /api/teamsPermission: JWT Required Description: Get all teams current user belongs to
Success Response (200):
{
"data": [
{
"id": "team_001",
"name": "Development Team",
"description": "Core development team",
"owner": {
"id": "user_001",
"name": "Admin User"
},
"memberCount": 10,
"createdAt": "2024-01-01T00:00:00.000Z"
}
]
}curl Example:
curl -X GET http://localhost:3000/api/teams \
-H "Authorization: Bearer YOUR_TOKEN"5.2 Create Team โ
Endpoint: POST /api/teamsPermission: JWT Required Description: Create new team
Request Body:
{
"name": "Marketing Team",
"description": "Marketing and promotion team"
}Success Response (201):
{
"id": "team_002",
"name": "Marketing Team",
"description": "Marketing and promotion team",
"owner": {
"id": "user_001",
"name": "Admin User"
},
"createdAt": "2024-12-04T12:00:00.000Z"
}curl Example:
curl -X POST http://localhost:3000/api/teams \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "Marketing Team",
"description": "Marketing and promotion team"
}'6. Document Management Module (Documents) โ
6.1 Get Document List โ
Endpoint: GET /api/documentsPermission: JWT Required Description: Get document list with pagination and filtering
Query Parameters:
page(number, optional): Page number, default 1limit(number, optional): Items per page, default 10folderId(string, optional): Filter by folder IDtags(string, optional): Filter by tags, comma separated
Success Response (200):
{
"data": [
{
"id": "doc_001",
"title": "API Documentation",
"content": "Complete API documentation...",
"folderId": "folder_001",
"tags": ["api", "documentation"],
"author": {
"id": "user_001",
"name": "Admin User"
},
"createdAt": "2024-01-01T00:00:00.000Z",
"updatedAt": "2024-12-04T12:00:00.000Z"
}
],
"meta": {
"total": 50,
"page": 1,
"limit": 10,
"totalPages": 5
}
}curl Example:
curl -X GET "http://localhost:3000/api/documents?page=1&limit=10&tags=api" \
-H "Authorization: Bearer YOUR_TOKEN"6.2 Create Document โ
Endpoint: POST /api/documentsPermission: JWT Required Description: Create new document
Request Body:
{
"title": "New Document",
"content": "Document content in markdown format...",
"folderId": "folder_001",
"tags": ["guide", "tutorial"]
}Success Response (201):
{
"id": "doc_002",
"title": "New Document",
"content": "Document content in markdown format...",
"folderId": "folder_001",
"tags": ["guide", "tutorial"],
"author": {
"id": "user_001",
"name": "Admin User"
},
"createdAt": "2024-12-04T12:00:00.000Z"
}curl Example:
curl -X POST http://localhost:3000/api/documents \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"title": "New Document",
"content": "Document content...",
"folderId": "folder_001",
"tags": ["guide", "tutorial"]
}'7. File Management Module (Files) โ
7.1 Upload File โ
Endpoint: POST /api/files/uploadPermission: JWT Required Description: Upload file
Request Headers:
Content-Type: multipart/form-dataForm Data:
file(File, required): File to uploadfolderId(string, optional): Folder ID
Success Response (201):
{
"id": "file_001",
"name": "document.pdf",
"size": 1024000,
"mimeType": "application/pdf",
"url": "https://storage.example.com/files/document.pdf",
"folderId": "folder_001",
"uploadedBy": {
"id": "user_001",
"name": "Admin User"
},
"createdAt": "2024-12-04T12:00:00.000Z"
}curl Example:
curl -X POST http://localhost:3000/api/files/upload \
-H "Authorization: Bearer YOUR_TOKEN" \
-F "file=@/path/to/document.pdf" \
-F "folderId=folder_001"7.2 Get File List โ
Endpoint: GET /api/filesPermission: JWT Required Description: Get file list
Query Parameters:
folderId(string, optional): Filter by folder ID
Success Response (200):
{
"data": [
{
"id": "file_001",
"name": "document.pdf",
"size": 1024000,
"mimeType": "application/pdf",
"url": "https://storage.example.com/files/document.pdf",
"createdAt": "2024-12-04T12:00:00.000Z"
}
]
}curl Example:
curl -X GET "http://localhost:3000/api/files?folderId=folder_001" \
-H "Authorization: Bearer YOUR_TOKEN"8. Folder Management Module (Folders) โ
8.1 Get Folder Tree โ
Endpoint: GET /api/folders/treePermission: JWT Required Description: Get folder tree structure
Success Response (200):
{
"data": [
{
"id": "folder_root",
"name": "Root Folder",
"parentId": null,
"children": [
{
"id": "folder_001",
"name": "Documents",
"parentId": "folder_root",
"children": []
},
{
"id": "folder_002",
"name": "Images",
"parentId": "folder_root",
"children": []
}
]
}
]
}curl Example:
curl -X GET http://localhost:3000/api/folders/tree \
-H "Authorization: Bearer YOUR_TOKEN"8.2 Create Folder โ
Endpoint: POST /api/foldersPermission: JWT Required Description: Create new folder
Request Body:
{
"name": "New Folder",
"parentId": "folder_root"
}Success Response (201):
{
"id": "folder_003",
"name": "New Folder",
"parentId": "folder_root",
"createdAt": "2024-12-04T12:00:00.000Z"
}curl Example:
curl -X POST http://localhost:3000/api/folders \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "New Folder",
"parentId": "folder_root"
}'9. Calendar Module (Calendar) โ
9.1 Get Calendar Events โ
Endpoint: GET /api/calendar/eventsPermission: JWT Required Description: Get calendar events list
Query Parameters:
startDate(string, optional): Start date (ISO 8601)endDate(string, optional): End date (ISO 8601)
Success Response (200):
{
"data": [
{
"id": "event_001",
"title": "Team Meeting",
"description": "Weekly team sync",
"startTime": "2024-12-05T10:00:00.000Z",
"endTime": "2024-12-05T11:00:00.000Z",
"location": "Conference Room A",
"attendees": [
{
"id": "user_001",
"name": "Admin User"
}
],
"createdAt": "2024-12-04T12:00:00.000Z"
}
]
}curl Example:
curl -X GET "http://localhost:3000/api/calendar/events?startDate=2024-12-01&endDate=2024-12-31" \
-H "Authorization: Bearer YOUR_TOKEN"9.2 Create Calendar Event โ
Endpoint: POST /api/calendar/eventsPermission: JWT Required Description: Create new calendar event
Request Body:
{
"title": "Project Review",
"description": "Q4 project review meeting",
"startTime": "2024-12-10T14:00:00.000Z",
"endTime": "2024-12-10T16:00:00.000Z",
"location": "Conference Room B",
"attendeeIds": ["user_001", "user_002"]
}Success Response (201):
{
"id": "event_002",
"title": "Project Review",
"description": "Q4 project review meeting",
"startTime": "2024-12-10T14:00:00.000Z",
"endTime": "2024-12-10T16:00:00.000Z",
"location": "Conference Room B",
"attendees": [
{
"id": "user_001",
"name": "Admin User"
},
{
"id": "user_002",
"name": "Developer User"
}
],
"createdAt": "2024-12-04T12:00:00.000Z"
}curl Example:
curl -X POST http://localhost:3000/api/calendar/events \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"title": "Project Review",
"startTime": "2024-12-10T14:00:00.000Z",
"endTime": "2024-12-10T16:00:00.000Z",
"attendeeIds": ["user_001", "user_002"]
}'10. Notification Module (Notifications) โ
10.1 Get Notification List โ
Endpoint: GET /api/notificationsPermission: JWT Required Description: Get current user's notification list
Query Parameters:
unreadOnly(boolean, optional): Show only unread notifications
Success Response (200):
{
"data": [
{
"id": "notif_001",
"type": "SYSTEM",
"title": "System Update",
"message": "The system will be updated tonight",
"isRead": false,
"createdAt": "2024-12-04T12:00:00.000Z"
}
],
"unreadCount": 5
}curl Example:
curl -X GET "http://localhost:3000/api/notifications?unreadOnly=true" \
-H "Authorization: Bearer YOUR_TOKEN"10.2 Mark Notification as Read โ
Endpoint: PATCH /api/notifications/:id/readPermission: JWT Required Description: Mark notification as read
Path Parameters:
id(string, required): Notification ID
Success Response (200):
{
"id": "notif_001",
"isRead": true,
"readAt": "2024-12-04T12:30:00.000Z"
}curl Example:
curl -X PATCH http://localhost:3000/api/notifications/notif_001/read \
-H "Authorization: Bearer YOUR_TOKEN"11. Message Module (Messages) โ
11.1 Get Conversation List โ
Endpoint: GET /api/messages/conversationsPermission: JWT Required Description: Get all message conversations for current user
Success Response (200):
{
"data": [
{
"id": "conv_001",
"participants": [
{
"id": "user_001",
"name": "Admin User"
},
{
"id": "user_002",
"name": "Developer User"
}
],
"lastMessage": {
"id": "msg_001",
"content": "Hello!",
"senderId": "user_002",
"createdAt": "2024-12-04T12:00:00.000Z"
},
"unreadCount": 2,
"updatedAt": "2024-12-04T12:00:00.000Z"
}
]
}curl Example:
curl -X GET http://localhost:3000/api/messages/conversations \
-H "Authorization: Bearer YOUR_TOKEN"11.2 Send Message โ
Endpoint: POST /api/messagesPermission: JWT Required Description: Send new message
Request Body:
{
"conversationId": "conv_001",
"content": "Hello, how are you?",
"attachments": []
}Success Response (201):
{
"id": "msg_002",
"conversationId": "conv_001",
"content": "Hello, how are you?",
"sender": {
"id": "user_001",
"name": "Admin User"
},
"createdAt": "2024-12-04T12:30:00.000Z"
}curl Example:
curl -X POST http://localhost:3000/api/messages \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"conversationId": "conv_001",
"content": "Hello, how are you?"
}'12. Dashboard Module (Dashboard) โ
12.1 Get Statistics โ
Endpoint: GET /api/dashboard/statsPermission: JWT Required Description: Get dashboard statistics
Success Response (200):
{
"users": {
"total": 1000,
"active": 850,
"newThisMonth": 50
},
"documents": {
"total": 5000,
"createdThisWeek": 120
},
"teams": {
"total": 50,
"activeProjects": 35
},
"activities": [
{
"id": "act_001",
"type": "USER_LOGIN",
"user": "Admin User",
"timestamp": "2024-12-04T12:00:00.000Z"
}
]
}curl Example:
curl -X GET http://localhost:3000/api/dashboard/stats \
-H "Authorization: Bearer YOUR_TOKEN"Authentication Flow โ
JWT Token Usage โ
All authenticated endpoints require JWT Token in request headers:
Authorization: Bearer <access_token>Token Refresh Flow โ
- Login to get
accessTokenandrefreshToken - Use
accessTokento access protected endpoints - When
accessTokenexpires (7 days), userefreshTokento call refresh endpoint - Get new
accessTokenandrefreshToken
Authentication Example (Complete Flow) โ
# 1. Login to get tokens
LOGIN_RESPONSE=$(curl -X POST http://localhost:3000/api/auth/login \
-H "Content-Type: application/json" \
-d '{
"email": "admin@halolight.h7ml.cn",
"password": "password123"
}')
# 2. Extract AccessToken
ACCESS_TOKEN=$(echo $LOGIN_RESPONSE | jq -r '.accessToken')
# 3. Use Token to access protected endpoints
curl -X GET http://localhost:3000/api/users \
-H "Authorization: Bearer $ACCESS_TOKEN"
# 4. When token expires, use RefreshToken to refresh
REFRESH_TOKEN=$(echo $LOGIN_RESPONSE | jq -r '.refreshToken')
curl -X POST http://localhost:3000/api/auth/refresh \
-H "Content-Type: application/json" \
-d "{\"refreshToken\": \"$REFRESH_TOKEN\"}"Error Handling โ
Standard Error Response Format โ
All error responses follow unified format:
{
"statusCode": 400,
"timestamp": "2025-12-04T12:00:00.000Z",
"path": "/api/users",
"method": "POST",
"message": "Validation failed",
"error": "Bad Request",
"details": [
{
"field": "email",
"message": "email must be a valid email address"
}
]
}Common Error Codes โ
| Status Code | Meaning | Common Scenarios |
|---|---|---|
| 400 | Bad Request | Request validation failed |
| 401 | Unauthorized | Token invalid or expired |
| 403 | Forbidden | No permission to access resource |
| 404 | Not Found | Resource does not exist |
| 409 | Conflict | Resource conflict (e.g. email already exists) |
| 422 | Unprocessable Entity | Business logic validation failed |
| 429 | Too Many Requests | Request rate limit exceeded |
| 500 | Internal Server Error | Server internal error |
Error Handling Example โ
# Capture error response
RESPONSE=$(curl -s -w "\n%{http_code}" -X POST http://localhost:3000/api/users \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{"email": "invalid-email"}')
HTTP_CODE=$(echo "$RESPONSE" | tail -n1)
BODY=$(echo "$RESPONSE" | sed '$d')
if [ $HTTP_CODE -ne 201 ]; then
echo "Error: HTTP $HTTP_CODE"
echo "$BODY" | jq '.message'
fiDatabase Models โ
Prisma Schema includes 17 entity models, supporting complete RBAC permission system:
// Core user model
model User {
id String @id @default(cuid())
email String @unique
name String
password String
avatar String?
phone String?
status UserStatus @default(ACTIVE)
// Relations
roles UserRole[]
teams TeamMember[]
ownedTeams Team[]
documents Document[]
// ... more relations
}
// RBAC models
model Role {
id String @id @default(cuid())
name String @unique
description String?
permissions RolePermission[]
users UserRole[]
}
model Permission {
id String @id @default(cuid())
name String @unique // Format: "users:create", "users:*", "*"
description String?
roles RolePermission[]
}Complete model relationships:
- User โ Role (many-to-many via UserRole)
- Role โ Permission (many-to-many via RolePermission)
- User โ Team (users can own teams or join as members)
- Document โ User (document owner and sharing)
- Folder (self-referencing for tree structure)
- ActivityLog (audit log for all operations)
Environment Variables โ
# Application configuration
NODE_ENV=production
PORT=3000
# Database (PostgreSQL)
DATABASE_URL="postgresql://user:password@localhost:5432/halolight_db"
# JWT authentication
JWT_SECRET=your-super-secret-jwt-key-change-in-production-min-32-chars
JWT_EXPIRES_IN=7d
JWT_REFRESH_SECRET=your-super-secret-refresh-key-change-in-production-min-32-chars
JWT_REFRESH_EXPIRES_IN=30d
# CORS configuration
CORS_ORIGIN=http://localhost:3000,https://halolight.h7ml.cn
# Optional: Redis cache
REDIS_HOST=localhost
REDIS_PORT=6379
# Optional: File upload
MAX_FILE_SIZE=10485760 # 10MB
UPLOAD_PATH=./uploads
# Optional: Rate limiting
THROTTLE_TTL=60 # seconds
THROTTLE_LIMIT=10 # requestsDocker Deployment โ
Using Docker Compose (Recommended) โ
# Clone project
git clone https://github.com/halolight/halolight-api-nestjs.git
cd halolight-api-nestjs
# Configure environment variables
cp .env.production .env
# Edit .env file, set database password, JWT secret, etc.
# Start all services (API + PostgreSQL + Redis)
docker-compose up -d
# View logs
docker-compose logs -f app
# Stop services
docker-compose downBuild API Container Only โ
# Build image
docker build -t halolight-api-nestjs .
# Run container
docker run -d \
--name halolight-api \
-p 3000:3000 \
-e DATABASE_URL="your-database-url" \
-e JWT_SECRET="your-jwt-secret" \
halolight-api-nestjsCommon Commands โ
# Development
pnpm dev # Start development server (hot reload)
pnpm start:debug # Start in debug mode
# Build
pnpm build # Build for production
pnpm start:prod # Run production build
# Code Quality
pnpm lint # ESLint check
pnpm lint:fix # Auto-fix ESLint issues
pnpm format # Prettier formatting
pnpm type-check # TypeScript type checking
# Testing
pnpm test # Run unit tests
pnpm test:watch # Run tests in watch mode
pnpm test:cov # Generate test coverage report
pnpm test:e2e # Run E2E tests
# Database
pnpm prisma:generate # Generate Prisma Client
pnpm prisma:migrate # Run database migrations (development)
pnpm prisma:studio # Open Prisma Studio (database GUI)
pnpm prisma:seed # Run database seeding
pnpm db:reset # Reset databaseArchitecture Highlights โ
1. Modular Design โ
Each business module is independently encapsulated, following NestJS modular architecture:
@Module({
imports: [PrismaModule], // Dependency injection
controllers: [UsersController], // Route controllers
providers: [UsersService], // Business logic
exports: [UsersService], // Export for use by other modules
})
export class UsersModule {}2. DTO Validation โ
Automatic validation using class-validator:
export class CreateUserDto {
@ApiProperty({ example: 'user@example.com' })
@IsEmail()
email: string;
@ApiProperty({ minLength: 8 })
@IsString()
@MinLength(8)
password: string;
@ApiProperty()
@IsString()
name: string;
}3. Guards and Decorators โ
Custom decorators and guards for authentication and authorization:
// Public route (skip JWT verification)
@Public()
@Post('login')
async login(@Body() loginDto: LoginDto) { ... }
// Protected route (JWT required)
@Get('me')
async getCurrentUser(@CurrentUser() user: User) { ... }
// Permission control (future extension)
@RequirePermissions('users:create')
@Post()
async create(@Body() dto: CreateUserDto) { ... }4. Global Exception Handling โ
Unified error response format:
{
"statusCode": 400,
"timestamp": "2025-12-04T12:00:00.000Z",
"path": "/api/users",
"method": "POST",
"message": "Validation failed",
"error": "Bad Request"
}5. Swagger Documentation โ
Auto-generated interactive API documentation, accessible at /docs:
- Complete API endpoint list
- Request/Response schemas
- Online testing functionality
- JWT authentication support
Development Workflow โ
1. Create New Module โ
# Use NestJS CLI to generate module
nest g module modules/my-module
nest g controller modules/my-module
nest g service modules/my-module2. Define Prisma Model โ
Edit prisma/schema.prisma:
model MyModel {
id String @id @default(cuid())
name String
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}Run migration:
pnpm prisma:migrate3. Create DTO โ
// dto/create-my-model.dto.ts
export class CreateMyModelDto {
@ApiProperty()
@IsString()
name: string;
}4. Implement Service โ
@Injectable()
export class MyModuleService {
constructor(private prisma: PrismaService) {}
async findAll() {
return this.prisma.myModel.findMany();
}
async create(dto: CreateMyModelDto) {
return this.prisma.myModel.create({ data: dto });
}
}5. Implement Controller โ
@Controller('my-models')
@ApiTags('MyModels')
export class MyModuleController {
constructor(private service: MyModuleService) {}
@Get()
@ApiOperation({ summary: 'Get all models' })
findAll() {
return this.service.findAll();
}
@Post()
@ApiOperation({ summary: 'Create model' })
create(@Body() dto: CreateMyModelDto) {
return this.service.create(dto);
}
}Related Links โ
Next Steps โ
- Check API Patterns to learn how to call from frontend
- Check Authentication System to understand permission control
- Check Overall Architecture to explore HaloLight ecosystem