🔔欢迎

HaloLight 多框架管理后台文档已上线!

支持 12+ 框架版本,欢迎体验。

Skip to content

NestJS 后端 API

HaloLight NestJS 后端 API,基于 NestJS 11 框架构建的企业级后端服务,提供完整的 RBAC 权限系统和 Swagger 文档。

特性

  • 🏗️ NestJS 11 - 企业级 Node.js 框架,模块化架构
  • 🔷 Prisma ORM 5 - 类型安全的数据库访问,支持 PostgreSQL 16
  • 🔐 JWT 双令牌 - AccessToken + RefreshToken 认证机制
  • 🛡️ RBAC 权限 - 基于角色的访问控制,支持通配符权限
  • 📚 Swagger 文档 - 自动生成交互式 API 文档
  • 类型验证 - class-validator 实现 DTO 自动验证
  • 🐳 Docker 部署 - 多阶段构建优化,Docker Compose 一键部署
  • 🧪 完整测试 - Jest 单元测试 + E2E 测试

技术栈

类别技术
框架NestJS 11
语言TypeScript 5.7
数据库PostgreSQL 16 + Prisma ORM 5
认证JWT + Passport.js
验证class-validator + class-transformer
文档Swagger/OpenAPI
测试Jest + Supertest
容器化Docker + Docker Compose
包管理pnpm 10.23.0

快速开始

bash
# 克隆仓库
git clone https://github.com/halolight/halolight-api-nestjs.git
cd halolight-api-nestjs

# 安装依赖
pnpm install

# 生成 Prisma Client
pnpm prisma:generate

# 运行数据库迁移
pnpm prisma:migrate

# 运行开发服务器
pnpm dev

# 构建生产版本
pnpm build
pnpm start:prod

项目结构

halolight-api-nestjs/
├── src/
│   ├── common/                  # 共享模块
│   │   ├── decorators/          # 自定义装饰器(@Public, @CurrentUser, @RequirePermissions)
│   │   ├── filters/             # 全局异常过滤器
│   │   ├── guards/              # 守卫(JWT 认证、权限校验)
│   │   └── interceptors/        # 拦截器(日志、转换)
│   ├── configs/                 # 配置模块
│   │   ├── config.module.ts     # 环境变量配置
│   │   ├── env.validation.ts    # 环境变量验证(class-validator)
│   │   └── swagger.config.ts    # Swagger 文档配置
│   ├── infrastructure/          # 基础设施层
│   │   └── prisma/              # Prisma ORM 配置与服务
│   ├── modules/                 # 业务模块(12 个)
│   │   ├── auth/                # 认证模块(登录、注册、刷新令牌)
│   │   ├── users/               # 用户管理(CRUD、分页、搜索)
│   │   ├── roles/               # 角色管理(CRUD + 权限分配)
│   │   ├── permissions/         # 权限管理(通配符支持)
│   │   ├── teams/               # 团队管理
│   │   ├── documents/           # 文档管理(标签、文件夹)
│   │   ├── files/               # 文件管理
│   │   ├── folders/             # 文件夹管理(树形结构)
│   │   ├── calendar/            # 日历事件管理
│   │   ├── notifications/       # 通知管理
│   │   ├── messages/            # 消息会话管理
│   │   └── dashboard/           # 仪表盘统计
│   ├── app.controller.ts        # 根控制器(首页、健康检查)
│   ├── app.service.ts           # 根服务
│   ├── app.module.ts            # 根模块
│   └── main.ts                  # 应用入口(Bootstrap)
├── prisma/
│   ├── schema.prisma            # 数据库模型定义(17 个实体)
│   └── migrations/              # 数据库迁移历史
├── test/
│   ├── app.e2e-spec.ts          # E2E 测试
│   └── jest-e2e.json            # E2E Jest 配置
├── Dockerfile                   # Docker 多阶段构建
├── docker-compose.yml           # Docker Compose 配置(API + PostgreSQL + Redis)
└── package.json

API 模块

项目包含 12 个核心业务模块,提供 60+ RESTful API 端点

模块端点数描述
Auth5用户认证(登录、注册、刷新 Token、获取当前用户、登出)
Users5用户管理(CRUD、分页、搜索、过滤)
Roles6角色管理(CRUD + 权限分配)
Permissions4权限管理(支持通配符权限:users:*, *
Teams5团队管理
Documents5文档管理(支持标签、文件夹)
Files5文件管理
Folders5文件夹管理(树形结构)
Calendar5日历事件管理
Notifications5通知管理
Messages5消息会话
Dashboard5仪表盘统计

认证相关端点

方法路径描述权限
POST/api/auth/login用户登录Public
POST/api/auth/register用户注册Public
POST/api/auth/refresh刷新令牌Public
GET/api/auth/me获取当前用户JWT Required
POST/api/auth/logout用户登出JWT Required

用户管理端点

方法路径描述权限
GET/api/users获取用户列表(分页、搜索)JWT Required
GET/api/users/:id获取用户详情JWT Required
POST/api/users创建用户JWT Required
PATCH/api/users/:id更新用户JWT Required
DELETE/api/users/:id删除用户JWT Required

完整 API 参考

1。认证模块 (Auth)

1.1 用户登录

端点POST /api/auth/login权限:Public (无需认证) 描述:使用邮箱和密码登录,返回 JWT 令牌

请求体

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

字段说明

  • email (string,必填):用户邮箱,需符合邮箱格式
  • password (string,必填):用户密码,最少 8 个字符

成功响应 (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"
  }
}

错误响应

  • 400 Bad Request:请求参数验证失败
  • 401 Unauthorized:邮箱或密码错误

curl 示例

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 用户注册

端点POST /api/auth/register权限:Public (无需认证) 描述:注册新用户账号

请求体

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

字段说明

  • email (string,必填):用户邮箱,需符合邮箱格式且唯一
  • name (string,必填):用户姓名
  • password (string,必填):密码,最少 8 个字符
  • phone (string,可选):手机号码

成功响应 (201):

json
{
  "accessToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
  "refreshToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
  "user": {
    "id": "clx9876543210",
    "email": "newuser@example.com",
    "name": "New User",
    "avatar": null,
    "phone": "+86 138****8888",
    "status": "ACTIVE"
  }
}

错误响应

  • 400 Bad Request:请求参数验证失败
  • 409 Conflict:邮箱已被注册

curl 示例

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 刷新令牌

端点POST /api/auth/refresh权限:Public (无需认证) 描述:使用 RefreshToken 获取新的 AccessToken

请求体

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

成功响应 (200):

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

错误响应

  • 401 Unauthorized:RefreshToken 无效或已过期

curl 示例

bash
curl -X POST http://localhost:3000/api/auth/refresh \
  -H "Content-Type: application/json" \
  -d '{
    "refreshToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
  }'

1.4 获取当前用户

端点GET /api/auth/me权限:JWT Required (需要认证) 描述:获取当前登录用户的详细信息

请求头

Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...

成功响应 (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"
}

错误响应

  • 401 Unauthorized:Token 无效或已过期

curl 示例

bash
curl -X GET http://localhost:3000/api/auth/me \
  -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."

1.5 用户登出

端点POST /api/auth/logout权限:JWT Required (需要认证) 描述:登出当前用户,使令牌失效

请求头

Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...

成功响应 (200):

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

curl 示例

bash
curl -X POST http://localhost:3000/api/auth/logout \
  -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."

2。用户管理模块 (Users)

2.1 获取用户列表

端点GET /api/users权限:JWT Required 描述:获取用户列表,支持分页、搜索和过滤

查询参数

  • page (number,可选):页码,默认 1
  • limit (number,可选):每页数量,默认 10
  • search (string,可选):搜索关键词 (搜索姓名或邮箱)
  • status (string,可选):用户状态过滤 (ACTIVE | INACTIVE | SUSPENDED)

成功响应 (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 示例

bash
# 基本查询
curl -X GET "http://localhost:3000/api/users?page=1&limit=10" \
  -H "Authorization: Bearer YOUR_TOKEN"

# 搜索用户
curl -X GET "http://localhost:3000/api/users?search=admin&status=ACTIVE" \
  -H "Authorization: Bearer YOUR_TOKEN"

2.2 获取用户详情

端点GET /api/users/:id权限:JWT Required 描述:根据用户 ID 获取用户详细信息

路径参数

  • id (string,必填):用户 ID

成功响应 (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"
}

错误响应

  • 404 Not Found:用户不存在

curl 示例

bash
curl -X GET http://localhost:3000/api/users/clx1234567890 \
  -H "Authorization: Bearer YOUR_TOKEN"

2.3 创建用户

端点POST /api/users权限:JWT Required 描述:创建新用户 (管理员功能)

请求体

json
{
  "email": "newuser@example.com",
  "name": "New User",
  "password": "securePass123",
  "phone": "+86 138****8888",
  "status": "ACTIVE",
  "avatar": "https://avatar.example.com/newuser.jpg"
}

字段说明

  • email (string,必填):用户邮箱
  • name (string,必填):用户姓名
  • password (string,必填):密码,最少 8 个字符
  • phone (string,可选):手机号码
  • status (string,可选):用户状态,默认 ACTIVE
  • avatar (string,可选):头像 URL

成功响应 (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 示例

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 更新用户

端点PATCH /api/users/:id权限:JWT Required 描述:更新用户信息

路径参数

  • id (string,必填):用户 ID

请求体

json
{
  "name": "Updated Name",
  "phone": "+86 139****9999",
  "avatar": "https://avatar.example.com/updated.jpg",
  "status": "ACTIVE"
}

字段说明:所有字段均为可选,只需传递需要更新的字段

成功响应 (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 示例

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 /api/users/:id权限:JWT Required 描述:删除用户 (软删除或硬删除)

路径参数

  • id (string,必填):用户 ID

成功响应 (200):

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

错误响应

  • 404 Not Found:用户不存在
  • 403 Forbidden:无权限删除该用户

curl 示例

bash
curl -X DELETE http://localhost:3000/api/users/clx1234567890 \
  -H "Authorization: Bearer YOUR_TOKEN"

3。角色管理模块 (Roles)

3.1 获取角色列表

端点GET /api/roles权限:JWT Required 描述:获取所有角色列表

成功响应 (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 示例

bash
curl -X GET http://localhost:3000/api/roles \
  -H "Authorization: Bearer YOUR_TOKEN"

3.2 创建角色

端点POST /api/roles权限:JWT Required 描述:创建新角色

请求体

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

成功响应 (201):

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

curl 示例

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 分配权限给角色

端点POST /api/roles/:id/permissions权限:JWT Required 描述:为角色分配权限

路径参数

  • id (string,必填):角色 ID

请求体

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

成功响应 (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 示例

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。权限管理模块 (Permissions)

4.1 获取权限列表

端点GET /api/permissions权限:JWT Required 描述:获取所有权限列表,支持通配符权限

成功响应 (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 示例

bash
curl -X GET http://localhost:3000/api/permissions \
  -H "Authorization: Bearer YOUR_TOKEN"

4.2 创建权限

端点POST /api/permissions权限:JWT Required 描述:创建新权限

请求体

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

字段说明

  • name (string,必填):权限名称,格式为 resource:action 或使用通配符 *
  • description (string,可选):权限描述

成功响应 (201):

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

curl 示例

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。团队管理模块 (Teams)

5.1 获取团队列表

端点GET /api/teams权限:JWT Required 描述:获取当前用户所属的所有团队

成功响应 (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 示例

bash
curl -X GET http://localhost:3000/api/teams \
  -H "Authorization: Bearer YOUR_TOKEN"

5.2 创建团队

端点POST /api/teams权限:JWT Required 描述:创建新团队

请求体

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

成功响应 (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 示例

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。文档管理模块 (Documents)

6.1 获取文档列表

端点GET /api/documents权限:JWT Required 描述:获取文档列表,支持分页和过滤

查询参数

  • page (number,可选):页码,默认 1
  • limit (number,可选):每页数量,默认 10
  • folderId (string,可选):文件夹 ID 过滤
  • tags (string,可选):标签过滤,逗号分隔

成功响应 (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 示例

bash
curl -X GET "http://localhost:3000/api/documents?page=1&limit=10&tags=api" \
  -H "Authorization: Bearer YOUR_TOKEN"

6.2 创建文档

端点POST /api/documents权限:JWT Required 描述:创建新文档

请求体

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

成功响应 (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 示例

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。文件管理模块 (Files)

7.1 上传文件

端点POST /api/files/upload权限:JWT Required 描述:上传文件

请求头

Content-Type: multipart/form-data

表单数据

  • file (File,必填):要上传的文件
  • folderId (string,可选):文件夹 ID

成功响应 (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 示例

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 /api/files权限:JWT Required 描述:获取文件列表

查询参数

  • folderId (string,可选):文件夹 ID 过滤

成功响应 (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 示例

bash
curl -X GET "http://localhost:3000/api/files?folderId=folder_001" \
  -H "Authorization: Bearer YOUR_TOKEN"

8。文件夹管理模块 (Folders)

8.1 获取文件夹树

端点GET /api/folders/tree权限:JWT Required 描述:获取文件夹树形结构

成功响应 (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 示例

bash
curl -X GET http://localhost:3000/api/folders/tree \
  -H "Authorization: Bearer YOUR_TOKEN"

8.2 创建文件夹

端点POST /api/folders权限:JWT Required 描述:创建新文件夹

请求体

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

成功响应 (201):

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

curl 示例

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)

9.1 获取日历事件

端点GET /api/calendar/events权限:JWT Required 描述:获取日历事件列表

查询参数

  • startDate (string,可选):开始日期 (ISO 8601)
  • endDate (string,可选):结束日期 (ISO 8601)

成功响应 (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 示例

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 创建日历事件

端点POST /api/calendar/events权限:JWT Required 描述:创建新的日历事件

请求体

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"]
}

成功响应 (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 示例

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。通知模块 (Notifications)

10.1 获取通知列表

端点GET /api/notifications权限:JWT Required 描述:获取当前用户的通知列表

查询参数

  • unreadOnly (boolean,可选):仅显示未读通知

成功响应 (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 示例

bash
curl -X GET "http://localhost:3000/api/notifications?unreadOnly=true" \
  -H "Authorization: Bearer YOUR_TOKEN"

10.2 标记通知为已读

端点PATCH /api/notifications/:id/read权限:JWT Required 描述:标记指定通知为已读

路径参数

  • id (string,必填):通知 ID

成功响应 (200):

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

curl 示例

bash
curl -X PATCH http://localhost:3000/api/notifications/notif_001/read \
  -H "Authorization: Bearer YOUR_TOKEN"

11。消息模块 (Messages)

11.1 获取会话列表

端点GET /api/messages/conversations权限:JWT Required 描述:获取当前用户的所有消息会话

成功响应 (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 示例

bash
curl -X GET http://localhost:3000/api/messages/conversations \
  -H "Authorization: Bearer YOUR_TOKEN"

11.2 发送消息

端点POST /api/messages权限:JWT Required 描述:发送新消息

请求体

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

成功响应 (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 示例

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)

12.1 获取统计数据

端点GET /api/dashboard/stats权限:JWT Required 描述:获取仪表盘统计数据

成功响应 (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 示例

bash
curl -X GET http://localhost:3000/api/dashboard/stats \
  -H "Authorization: Bearer YOUR_TOKEN"

认证流程

JWT 令牌使用

所有需要认证的接口都需要在请求头中携带 JWT Token:

Authorization: Bearer <access_token>

令牌刷新流程

  1. 使用登录接口获取 accessTokenrefreshToken
  2. 使用 accessToken 访问受保护的接口
  3. accessToken 过期 (7 天),使用 refreshToken 调用刷新接口
  4. 获取新的 accessTokenrefreshToken

认证示例 (完整流程)

bash
# 1. 登录获取令牌
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. 提取 AccessToken
ACCESS_TOKEN=$(echo $LOGIN_RESPONSE | jq -r '.accessToken')

# 3. 使用 Token 访问受保护接口
curl -X GET http://localhost:3000/api/users \
  -H "Authorization: Bearer $ACCESS_TOKEN"

# 4. Token 过期后,使用 RefreshToken 刷新
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\"}"

错误处理

标准错误响应格式

所有错误响应遵循统一格式:

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"
    }
  ]
}

常见错误码

状态码含义常见场景
400Bad Request请求参数验证失败
401UnauthorizedToken 无效或已过期
403Forbidden无权限访问资源
404Not Found资源不存在
409Conflict资源冲突(如邮箱已存在)
422Unprocessable Entity业务逻辑验证失败
429Too Many Requests请求频率超限
500Internal Server Error服务器内部错误

错误处理示例

bash
# 捕获错误响应
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

数据库模型

Prisma Schema 包含 17 个实体模型,支持完整的 RBAC 权限系统:

prisma
// 核心用户模型
model User {
  id            String   @id @default(cuid())
  email         String   @unique
  name          String
  password      String
  avatar        String?
  phone         String?
  status        UserStatus @default(ACTIVE)

  // 关系
  roles         UserRole[]
  teams         TeamMember[]
  ownedTeams    Team[]
  documents     Document[]
  // ... 更多关系
}

// RBAC 模型
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  // 格式: "users:create", "users:*", "*"
  description String?
  roles       RolePermission[]
}

完整的模型关系:

  • User ↔ Role (多对多,通过 UserRole)
  • Role ↔ Permission (多对多,通过 RolePermission)
  • User ↔ Team (用户可以拥有团队或作为成员加入)
  • Document ↔ User (文档所有者和共享关系)
  • Folder (自引用,支持树形结构)
  • ActivityLog (审计日志,记录所有操作)

环境变量

bash
# 应用配置
NODE_ENV=production
PORT=3000

# 数据库(PostgreSQL)
DATABASE_URL="postgresql://user:password@localhost:5432/halolight_db"

# JWT 认证
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 配置
CORS_ORIGIN=http://localhost:3000,https://halolight.h7ml.cn

# 可选:Redis 缓存
REDIS_HOST=localhost
REDIS_PORT=6379

# 可选:文件上传
MAX_FILE_SIZE=10485760  # 10MB
UPLOAD_PATH=./uploads

# 可选:限流配置
THROTTLE_TTL=60        # 秒
THROTTLE_LIMIT=10      # 请求数

Docker 部署

使用 Docker Compose (推荐)

bash
# 克隆项目
git clone https://github.com/halolight/halolight-api-nestjs.git
cd halolight-api-nestjs

# 配置环境变量
cp .env.production .env
# 编辑 .env 文件,设置数据库密码、JWT 密钥等

# 启动所有服务(API + PostgreSQL + Redis)
docker-compose up -d

# 查看日志
docker-compose logs -f app

# 停止服务
docker-compose down

仅构建 API 容器

bash
# 构建镜像
docker build -t halolight-api-nestjs .

# 运行容器
docker run -d \
  --name halolight-api \
  -p 3000:3000 \
  -e DATABASE_URL="your-database-url" \
  -e JWT_SECRET="your-jwt-secret" \
  halolight-api-nestjs

常用命令

bash
# 开发
pnpm dev              # 启动开发服务器(热重载)
pnpm start:debug      # 调试模式启动

# 构建
pnpm build            # 构建生产版本
pnpm start:prod       # 运行生产构建

# 代码质量
pnpm lint             # ESLint 检查
pnpm lint:fix         # 自动修复 ESLint 问题
pnpm format           # Prettier 格式化
pnpm type-check       # TypeScript 类型检查

# 测试
pnpm test             # 运行单元测试
pnpm test:watch       # 监听模式运行测试
pnpm test:cov         # 生成测试覆盖率报告
pnpm test:e2e         # 运行 E2E 测试

# 数据库
pnpm prisma:generate  # 生成 Prisma Client
pnpm prisma:migrate   # 运行数据库迁移(开发环境)
pnpm prisma:studio    # 打开 Prisma Studio(数据库 GUI)
pnpm prisma:seed      # 运行数据库种子
pnpm db:reset         # 重置数据库

架构特点

1。模块化设计

每个业务模块独立封装,遵循 NestJS 模块化架构:

typescript
@Module({
  imports: [PrismaModule],      // 依赖注入
  controllers: [UsersController], // 路由控制器
  providers: [UsersService],      // 业务逻辑
  exports: [UsersService],        // 导出供其他模块使用
})
export class UsersModule {}

2。DTO 验证

使用 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。守卫和装饰器

使用自定义装饰器和守卫实现认证授权:

typescript
// 公开路由(跳过 JWT 验证)
@Public()
@Post('login')
async login(@Body() loginDto: LoginDto) { ... }

// 受保护路由(需要 JWT)
@Get('me')
async getCurrentUser(@CurrentUser() user: User) { ... }

// 权限控制(未来扩展)
@RequirePermissions('users:create')
@Post()
async create(@Body() dto: CreateUserDto) { ... }

4。全局异常处理

统一的错误响应格式:

json
{
  "statusCode": 400,
  "timestamp": "2025-12-04T12:00:00.000Z",
  "path": "/api/users",
  "method": "POST",
  "message": "Validation failed",
  "error": "Bad Request"
}

5。Swagger 文档

自动生成交互式 API 文档,访问 /docs

  • 完整的 API 端点列表
  • 请求/响应 Schema
  • 在线测试功能
  • JWT 认证支持

开发工作流

1。创建新模块

bash
# 使用 NestJS CLI 生成模块
nest g module modules/my-module
nest g controller modules/my-module
nest g service modules/my-module

2。定义 Prisma 模型

编辑 prisma/schema.prisma

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

运行迁移:

bash
pnpm prisma:migrate

3。创建 DTO

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

4。实现服务

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。实现控制器

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

相关链接

下一步