๐Ÿ””Welcome

HaloLight multi-framework admin dashboard docs is now live!

Supports 12+ framework versions. Welcome to try.

Skip to content

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 โ€‹

CategoryTechnology
FrameworkNestJS 11
LanguageTypeScript 5.7
DatabasePostgreSQL 16 + Prisma ORM 5
AuthenticationJWT + Passport.js
Validationclass-validator + class-transformer
DocumentationSwagger/OpenAPI
TestingJest + Supertest
ContainerizationDocker + Docker Compose
Package Managerpnpm 10.23.0

Quick Start โ€‹

bash
# 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:prod

Project 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.json

API Modules โ€‹

The project includes 12 core business modules providing 60+ RESTful API endpoints:

ModuleEndpointsDescription
Auth5User authentication (login, register, refresh token, current user, logout)
Users5User management (CRUD, pagination, search, filtering)
Roles6Role management (CRUD + permission assignment)
Permissions4Permission management (wildcard support: users:*, *)
Teams5Team management
Documents5Document management (tags, folders support)
Files5File management
Folders5Folder management (tree structure)
Calendar5Calendar event management
Notifications5Notification management
Messages5Message conversations
Dashboard5Dashboard statistics

Authentication Endpoints โ€‹

MethodPathDescriptionPermission
POST/api/auth/loginUser loginPublic
POST/api/auth/registerUser registrationPublic
POST/api/auth/refreshRefresh tokenPublic
GET/api/auth/meGet current userJWT Required
POST/api/auth/logoutUser logoutJWT Required

User Management Endpoints โ€‹

MethodPathDescriptionPermission
GET/api/usersGet user list (pagination, search)JWT Required
GET/api/users/:idGet user detailsJWT Required
POST/api/usersCreate userJWT Required
PATCH/api/users/:idUpdate userJWT Required
DELETE/api/users/:idDelete userJWT 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:

json
{
  "email": "admin@halolight.h7ml.cn",
  "password": "password123"
}

Field Descriptions:

  • email (string, required): User email address, must be valid email format
  • password (string, required): User password, minimum 8 characters

Success Response (200):

json
{
  "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 failed
  • 401 Unauthorized: Invalid email or password

curl Example:

bash
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:

json
{
  "email": "newuser@example.com",
  "name": "New User",
  "password": "securePass123",
  "phone": "+86 138****8888"
}

Field Descriptions:

  • email (string, required): User email, must be valid and unique
  • name (string, required): User name
  • password (string, required): Password, minimum 8 characters
  • phone (string, optional): Phone number

Success Response (201):

json
{
  "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 failed
  • 409 Conflict: Email already registered

curl Example:

bash
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:

json
{
  "refreshToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}

Success Response (200):

json
{
  "accessToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
  "refreshToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}

Error Responses:

  • 401 Unauthorized: RefreshToken is invalid or expired

curl Example:

bash
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):

json
{
  "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:

bash
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):

json
{
  "message": "Successfully logged out"
}

curl Example:

bash
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 1
  • limit (number, optional): Items per page, default 10
  • search (string, optional): Search keyword (searches name or email)
  • status (string, optional): User status filter (ACTIVE | INACTIVE | SUSPENDED)

Success Response (200):

json
{
  "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:

bash
# 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):

json
{
  "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:

bash
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:

json
{
  "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 email
  • name (string, required): User name
  • password (string, required): Password, minimum 8 characters
  • phone (string, optional): Phone number
  • status (string, optional): User status, default ACTIVE
  • avatar (string, optional): Avatar URL

Success Response (201):

json
{
  "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:

bash
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:

json
{
  "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):

json
{
  "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:

bash
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):

json
{
  "message": "User successfully deleted",
  "id": "clx1234567890"
}

Error Responses:

  • 404 Not Found: User does not exist
  • 403 Forbidden: No permission to delete this user

curl Example:

bash
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):

json
{
  "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:

bash
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:

json
{
  "name": "Editor",
  "description": "Can edit content"
}

Success Response (201):

json
{
  "id": "role_editor",
  "name": "Editor",
  "description": "Can edit content",
  "createdAt": "2024-12-04T12:00:00.000Z"
}

curl Example:

bash
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:

json
{
  "permissionIds": ["perm_001", "perm_002", "perm_003"]
}

Success Response (200):

json
{
  "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:

bash
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):

json
{
  "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:

bash
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:

json
{
  "name": "documents:publish",
  "description": "Publish documents"
}

Field Descriptions:

  • name (string, required): Permission name, format resource:action or wildcard *
  • description (string, optional): Permission description

Success Response (201):

json
{
  "id": "perm_doc_publish",
  "name": "documents:publish",
  "description": "Publish documents",
  "createdAt": "2024-12-04T12:00:00.000Z"
}

curl Example:

bash
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):

json
{
  "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:

bash
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:

json
{
  "name": "Marketing Team",
  "description": "Marketing and promotion team"
}

Success Response (201):

json
{
  "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:

bash
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 1
  • limit (number, optional): Items per page, default 10
  • folderId (string, optional): Filter by folder ID
  • tags (string, optional): Filter by tags, comma separated

Success Response (200):

json
{
  "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:

bash
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:

json
{
  "title": "New Document",
  "content": "Document content in markdown format...",
  "folderId": "folder_001",
  "tags": ["guide", "tutorial"]
}

Success Response (201):

json
{
  "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:

bash
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-data

Form Data:

  • file (File, required): File to upload
  • folderId (string, optional): Folder ID

Success Response (201):

json
{
  "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:

bash
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):

json
{
  "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:

bash
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):

json
{
  "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:

bash
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:

json
{
  "name": "New Folder",
  "parentId": "folder_root"
}

Success Response (201):

json
{
  "id": "folder_003",
  "name": "New Folder",
  "parentId": "folder_root",
  "createdAt": "2024-12-04T12:00:00.000Z"
}

curl Example:

bash
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):

json
{
  "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:

bash
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:

json
{
  "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):

json
{
  "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:

bash
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):

json
{
  "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:

bash
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):

json
{
  "id": "notif_001",
  "isRead": true,
  "readAt": "2024-12-04T12:30:00.000Z"
}

curl Example:

bash
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):

json
{
  "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:

bash
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:

json
{
  "conversationId": "conv_001",
  "content": "Hello, how are you?",
  "attachments": []
}

Success Response (201):

json
{
  "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:

bash
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):

json
{
  "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:

bash
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 โ€‹

  1. Login to get accessToken and refreshToken
  2. Use accessToken to access protected endpoints
  3. When accessToken expires (7 days), use refreshToken to call refresh endpoint
  4. Get new accessToken and refreshToken

Authentication Example (Complete Flow) โ€‹

bash
# 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:

json
{
  "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 CodeMeaningCommon Scenarios
400Bad RequestRequest validation failed
401UnauthorizedToken invalid or expired
403ForbiddenNo permission to access resource
404Not FoundResource does not exist
409ConflictResource conflict (e.g. email already exists)
422Unprocessable EntityBusiness logic validation failed
429Too Many RequestsRequest rate limit exceeded
500Internal Server ErrorServer internal error

Error Handling Example โ€‹

bash
# 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'
fi

Database Models โ€‹

Prisma Schema includes 17 entity models, supporting complete RBAC permission system:

prisma
// 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 โ€‹

bash
# 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      # requests

Docker Deployment โ€‹

bash
# 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 down

Build API Container Only โ€‹

bash
# 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-nestjs

Common Commands โ€‹

bash
# 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 database

Architecture Highlights โ€‹

1. Modular Design โ€‹

Each business module is independently encapsulated, following NestJS modular architecture:

typescript
@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:

typescript
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:

typescript
// 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:

json
{
  "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 โ€‹

bash
# Use NestJS CLI to generate module
nest g module modules/my-module
nest g controller modules/my-module
nest g service modules/my-module

2. Define Prisma Model โ€‹

Edit prisma/schema.prisma:

prisma
model MyModel {
  id        String   @id @default(cuid())
  name      String
  createdAt DateTime @default(now())
  updatedAt DateTime @updatedAt
}

Run migration:

bash
pnpm prisma:migrate

3. Create DTO โ€‹

typescript
// dto/create-my-model.dto.ts
export class CreateMyModelDto {
  @ApiProperty()
  @IsString()
  name: string;
}

4. Implement Service โ€‹

typescript
@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 โ€‹

typescript
@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);
  }
}

Next Steps โ€‹