# NestJS **Repository Path**: mzzhref/nest-js ## Basic Information - **Project Name**: NestJS - **Description**: 搭一个 NestJS 后端服务架子 - **Primary Language**: NodeJS - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 1 - **Forks**: 1 - **Created**: 2026-06-08 - **Last Updated**: 2026-06-29 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # nextjs-server 基于 **NestJS + TypeScript** 的 Node.js 后端服务。项目已接入多环境配置、MySQL + TypeORM、Redis + ioredis、结构化日志、请求日志、本地日志查询和 API 自动验证能力,适合作为后续业务模块扩展的服务端基础工程。 ## 目录 - [技术栈](#技术栈) - [功能概览](#功能概览) - [项目结构](#项目结构) - [模块说明](#模块说明) - [环境配置](#环境配置) - [启动与构建命令](#启动与构建命令) - [接口列表](#接口列表) - [日志说明](#日志说明) - [API 自动验证](#api-自动验证) - [开发约定](#开发约定) - [注意事项](#注意事项) ## 技术栈 - **运行时**:Node.js - **开发语言**:TypeScript - **后端框架**:NestJS - **配置管理**:`@nestjs/config` - **环境变量校验**:Joi - **数据库**:MySQL - **ORM / 数据源**:TypeORM DataSource - **Redis 客户端**:ioredis - **参数校验 / 转换**:class-validator、class-transformer - **开发热重启**:nodemon + ts-node - **工程化**:ESLint、Prettier、Nest CLI - **工具函数依赖**:cross-env-plugins ## 功能概览 当前项目已实现以下能力: - NestJS 应用基础结构 - TypeScript 严格模式基础配置 - `@/*` 路径别名,指向 `src/*` - 多环境配置加载:`.env.${NODE_ENV}` + `.env` - Joi 环境变量校验 - 全局 API 前缀,默认 `/api` - 全局 ValidationPipe:自动转换参数并剔除白名单外字段 - MySQL DataSource 全局模块 - Redis 全局服务封装 - MySQL / Redis 连接状态监控 - 健康检查接口 - 结构化日志服务 - 控制台日志输出 - 本地 JSONL 日志文件输出 - HTTP 请求日志中间件 - 日志文件按年月日小时分目录与分片 - 日志保留天数自动清理 - 本地日志查询接口 - API 自动验证 CLI - API 验证 Markdown 报告生成 - 统一工具函数出口 `src/utils/utils.ts` ## 项目结构 ```text src/ ├─ api-verifier/ # API 自动验证 CLI、注册中心、执行器、HTTP 客户端、报告生成 │ ├─ cli/ # API 验证命令参数解析和 CLI 入口 │ ├─ http/ # API 验证 HTTP 请求客户端 │ └─ report/ # Markdown 验证报告生成 ├─ config/ # 配置读取、MySQL / Redis 配置、环境变量校验 ├─ database/ # MySQL DataSource 全局模块 ├─ logging/ # 日志模块、请求日志、依赖监控、日志查询 API │ ├─ dto/ # 日志查询参数 DTO │ ├─ interfaces/ # 日志与依赖状态类型定义 │ └─ sinks/ # 控制台 / 文件日志输出实现 ├─ modules/ # 业务模块目录 │ ├─ health/ # 健康检查模块 │ ├─ role/ # 角色模块、角色表维护和默认角色初始化 │ └─ user/ # 用户模块、默认管理员和用户角色关系 ├─ redis/ # Redis 模块、RedisService、Redis 注入 token ├─ utils/ # 项目统一工具函数出口 ├─ app.module.ts # 应用根模块 └─ main.ts # HTTP 服务启动入口 ``` 根目录关键文件: ```text .env.example # 环境变量模板,可提交 Git .env # 公共默认配置,不应放真实敏感信息 .env.development # 开发环境真实配置,不提交 Git .env.production # 生产环境真实配置,不提交 Git nodemon.json # 开发热重启配置 nest-cli.json # Nest CLI 配置 package.json # npm 脚本与依赖 README.md # 项目说明文档 tsconfig.json # TypeScript 编译配置 ``` ## 模块说明 ### 1. AppModule 位置:`src/app.module.ts` 应用根模块,负责统一引入: - `ConfigModule` - `DatabaseModule` - `RedisModule` - `LoggingModule` - `HealthModule` - `RoleModule` - `UserModule` - `ApiVerifierModule` 配置加载顺序: ```text .env.${NODE_ENV} .env ``` > 业务模块需要显式加入 `AppModule.imports` 后才会生效,项目不会自动扫描 `src/modules/` 目录注册模块。 ### 2. Bootstrap 启动入口 位置:`src/main.ts` 启动时会完成: - 创建 Nest 应用 - 读取应用名、端口、环境和 API 前缀 - 设置全局 API 前缀:`app.setGlobalPrefix(apiPrefix)` - 开启 shutdown hooks - 注册全局 `ValidationPipe` - 启动 HTTP 服务 - 输出服务启动成功 / 失败日志 默认启动地址格式: ```text http://localhost:${APP_PORT}/${APP_API_PREFIX} ``` ### 3. Config 配置模块 位置:`src/config/` | 文件 | 说明 | | --- | --- | | `configuration.ts` | 将环境变量映射为应用配置对象 | | `env.validation.ts` | 使用 Joi 校验环境变量 | | `database.config.ts` | 创建 TypeORM MySQL 配置 | | `redis.config.ts` | 创建 ioredis 配置 | 已支持的配置分组: - `app`:应用名、环境、端口、API 前缀 - `database`:MySQL 连接、同步、SQL 日志 - `redis`:Redis 连接、密码、DB 编号 - `log`:日志级别、日志目录、日志输出开关、依赖检查间隔、文件大小、保留天数 ### 4. DatabaseModule 位置:`src/database/database.module.ts` 功能: - 全局提供 TypeORM `DataSource` - 读取 `src/config/database.config.ts` 生成 MySQL 连接配置 - 当前注册实体:`User` - 生产环境强制关闭 `synchronize` 当前实体: | 实体 | 表名 | 说明 | | --- | --- | --- | | `User` | `users` | 用户表实体,包含用户名、密码哈希、启用状态、软删除时间和审计时间 | | `Role` | `roles` | 角色表实体,默认包含管理员和普通用户 | | `UserRole` | `user_roles` | 用户角色关系表,支持一个用户绑定多个角色 | ### 5. RedisModule / RedisService 位置:`src/redis/` 功能: - 基于 ioredis 创建 Redis 客户端 - Redis 采用 `lazyConnect: true` - Redis 连接失败不会阻断服务启动 - 统一通过 `RedisService` 操作 Redis - 模块销毁时调用 `quit()` 释放连接 `RedisService` 已提供方法: | 方法 | 说明 | | --- | --- | | `getClient()` | 获取 ioredis 原始客户端 | | `ping()` | Redis PING 检查 | | `get(key)` | 读取字符串值 | | `set(key, value, ttlSeconds?)` | 写入字符串值,可选 TTL | | `del(...keys)` | 删除一个或多个 key | ### 6. LoggingModule 位置:`src/logging/` 功能: - 全局日志服务 `AppLoggerService` - 控制台日志输出 `ConsoleLogSink` - 文件日志输出 `FileLogSink` - HTTP 请求日志中间件 `RequestLoggingMiddleware` - MySQL / Redis 依赖状态监控 `DependencyMonitorService` - 本地日志查询服务 `LogQueryService` - 日志查询接口 `LogsController` - 日志查询 API 验证用例 `LoggingApiVerifier` 日志级别: ```text fatal < error < warn < info < debug ``` 请求日志会自动生成并返回: ```http X-Request-Id: ``` 健康检查成功请求默认不写入访问日志,可通过以下配置开启: ```env LOG_HEALTH_LOG_ENABLED=true ``` ### 7. HealthModule 位置:`src/modules/health/` 功能: - 提供健康检查接口 `GET /api/health` - 返回应用名称、运行环境、MySQL 状态、Redis 状态和时间戳 - 注册健康检查 API 自动验证用例 ### 8. RoleModule 位置:`src/modules/role/` 功能: - 提供角色表 `roles` 维护能力 - 支持角色列表、详情、创建、更新和删除接口 - 默认角色通过 `npm run init:auth:dev` 初始化,应用启动时不会自动创建 - 注册角色模块 API 自动验证用例 默认角色: | 角色编码 | 角色名称 | 说明 | | --- | --- | --- | | `admin` | 管理员 | 系统管理员角色 | | `user` | 普通用户 | 普通用户角色 | ### 9. UserModule 位置:`src/modules/user/` 功能: - 提供用户表 `users` 维护能力 - 使用 Node.js 内置 `crypto.scrypt` 存储密码哈希和独立 salt,不保存明文密码 - 使用 `user_roles` 关系表支持一个用户绑定多个角色 - 默认新用户绑定普通用户角色 `user` - 删除用户使用软删除:设置 `is_active=false` 并写入 `deleted_at` - 默认查询不返回已软删除用户,用户角色关系会保留 - 默认管理员通过 `npm run init:auth:dev` 初始化,应用启动时不会自动创建 - 注册用户模块 API 自动验证用例 默认管理员: ```text username: admin password: Admin@123 role: admin(通过 user_roles 关系表绑定) ``` > 默认密码只在开发初始化命令未指定 `ADMIN_PASSWORD` 时使用,数据库中保存的是密码哈希和 salt。生产环境必须指定安全密码。 ### 10. ApiVerifierModule 位置:`src/api-verifier/` 功能: - 自动收集实现 `ApiVerifierProvider` 的验证用例 - 按模块、用例 ID、安全级别过滤验证用例 - 执行 HTTP 请求并断言状态码 / 响应类型 / 自定义断言 - 支持 fail-fast - 默认只执行 safe 用例 - 生成 Markdown 验证报告 当前内置验证用例: | 用例 ID | 模块 | 方法 | 路径 | 说明 | | --- | --- | --- | --- | --- | | `health.check` | health | GET | `/health` | 健康检查接口 | | `logging.query.validRange` | logging | GET | `/log/query` | 日志查询合法时间范围 | | `logging.query.invalidRange` | logging | GET | `/log/query` | 日志查询非法时间范围 | | `role.list` | role | GET | `/role` | 角色列表接口 | | `role.create.invalid` | role | POST | `/role` | 角色创建非法参数验证 | | `user.list.unauthorized` | user | GET | `/user` | 用户列表未登录验证 | | `user.create.unauthorized` | user | POST | `/user` | 用户创建未登录验证 | | `auth.login.invalidBody` | auth | POST | `/auth/login` | 登录非法参数验证 | | `auth.login.invalidPassword` | auth | POST | `/auth/login` | 登录错误密码验证 | > API 验证用例中的路径不包含全局前缀,CLI 会基于 `baseUrl` 统一拼接。 ### 11. Utils 工具模块 位置:`src/utils/utils.ts` 功能: - 统一聚合导出 `cross-env-plugins` 的 `utils` - 项目内工具函数统一从该文件引入 推荐写法: ```ts import { utils } from '@/utils/utils'; ``` ## 环境配置 项目使用以下环境文件: ```text .env .env.development .env.production .env.example ``` 加载顺序: ```text .env.${NODE_ENV} .env ``` `.env.example` 是配置模板,只能放示例值或占位值,不应放真实密码、Token、生产连接串。 ### 环境变量列表 | 变量 | 说明 | 默认 / 示例 | | --- | --- | --- | | `NODE_ENV` | 运行环境,可选 `development`、`production` | `development` | | `APP_NAME` | 应用名称 | `nextjs-server` | | `APP_PORT` | HTTP 服务端口 | `3000` | | `APP_API_PREFIX` | 全局 API 前缀 | `api` | | `DB_HOST` | MySQL 主机地址 | 必填 | | `DB_PORT` | MySQL 端口 | `3306` | | `DB_USERNAME` | MySQL 用户名 | 必填 | | `DB_PASSWORD` | MySQL 密码,可为空 | 空字符串 | | `DB_NAME` | MySQL 数据库名 | 必填 | | `DB_SYNC` | 是否自动同步实体结构 | `false` | | `DB_LOGGING` | 是否输出 TypeORM SQL 日志 | `false` | | `JWT_SECRET` | JWT 签名密钥,生产环境必须使用强随机值 | 必填,至少 32 位 | | `JWT_EXPIRES_IN` | JWT 过期时间,支持 `60s`、`30m`、`2h`、`7d` | `2h` | | `ADMIN_PASSWORD` | 认证初始化命令使用的默认管理员密码 | 开发可省略,生产必填 | | `ADMIN_RESET_PASSWORD` | 初始化命令是否重置已有 admin 密码 | `false` | | `REDIS_HOST` | Redis 主机地址 | 必填 | | `REDIS_PORT` | Redis 端口 | `6379` | | `REDIS_PASSWORD` | Redis 密码,可为空 | 可选 | | `REDIS_DB` | Redis DB 编号 | `0` | | `LOG_LEVEL` | 日志级别,可选 `fatal`、`error`、`warn`、`info`、`debug` | `info` | | `LOG_DIR` | 日志文件根目录 | `logs` | | `LOG_CONSOLE_ENABLED` | 是否输出控制台日志 | `true` | | `LOG_FILE_ENABLED` | 是否写入本地日志文件 | `true` | | `LOG_HEALTH_LOG_ENABLED` | 是否记录成功的健康检查请求日志 | `false` | | `LOG_DEPENDENCY_CHECK_INTERVAL_MS` | MySQL / Redis 状态检查间隔,单位毫秒 | `30000` | | `LOG_MAX_FILE_SIZE_MB` | 单个日志文件最大大小,单位 MB | `20` | | `LOG_RETENTION_DAYS` | 日志保留天数 | `30` | ### 鉴权与默认账号初始化 用户接口使用 JWT 鉴权。登录接口: ```http POST /api/auth/login Content-Type: application/json { "username": "admin", "password": "Admin@123" } ``` 登录成功后,后续请求携带: ```http Authorization: Bearer ``` 登录凭证会以 SHA-256 哈希形式写入 Redis,同一用户只保留一个有效登录态: ```text auth:login_token:user: = sha256(accessToken) ``` 再次登录会覆盖 Redis 中的 token 哈希,旧 token 会在下一次请求时返回 401,从而实现顶号。Redis 中不保存完整 JWT,避免 Redis 数据泄漏后 token 被直接拿来使用。 默认角色和默认管理员不再由应用启动自动创建,需要在表结构存在后执行初始化命令: ```bash npm run init:auth:dev ``` 已构建环境可执行: ```bash npm run init:auth ``` 生产环境必须指定安全密码: ```bash npx cross-env ADMIN_PASSWORD= npm run init:auth ``` 如需重置已有 admin 密码: ```bash npx cross-env ADMIN_PASSWORD= ADMIN_RESET_PASSWORD=true npm run init:auth ``` 开发初始化命令默认账号为 `admin / Admin@123`,生产环境不能使用默认密码。 用户模块权限规则: | 接口 | 权限 | | --- | --- | | `GET /api/user` | 仅 admin | | `GET /api/user/:id` | admin 可看任意用户;普通用户只能看自己 | | `POST /api/user` | 仅 admin,且不能创建 `admin` | | `PATCH /api/user/:id` | 仅 admin,且不能修改 `admin` | | `PUT /api/user/:id/roles` | 仅 admin,且不能改绑 `admin` 角色 | | `PATCH /api/user/:id/password` | admin 可改普通用户密码;普通用户可改自己密码;任何人不能改 `admin` 密码 | | `DELETE /api/user/:id` | 仅 admin,且不能删除 `admin` | ### API 前缀规则 所有接口统一走全局前缀: ```env APP_API_PREFIX=api ``` 默认接口路径: ```text /api/health /api/log/query ``` 如果配置为: ```env APP_API_PREFIX=api_v2 ``` 则接口变为: ```text /api_v2/health /api_v2/log/query ``` Controller 中不要写全局前缀,只写模块名和动作名,例如: ```ts @Controller('user') export class UserController { @Get('list') list() {} } ``` ## 启动与构建命令 ### 安装依赖 ```bash npm install ``` ### 开发环境启动 ```bash npm run dev ``` 说明: - 设置 `NODE_ENV=development` - 使用 `nodemon` - 监听 `src`、`.env`、`.env.development` - 通过 `ts-node -r tsconfig-paths/register src/main.ts` 启动 ### 生产环境 watch 启动 ```bash npm run dev:prd ``` 说明: - 设置 `NODE_ENV=production` - 使用 `nest start --watch` - 适合本地按生产配置进行 watch 调试 ### 开发环境构建 ```bash npm run build ``` 说明: - 设置 `NODE_ENV=development` - 执行 `nest build` - 输出目录:`dist/` ### 生产环境构建 ```bash npm run build:prd ``` 说明: - 设置 `NODE_ENV=production` - 执行 `nest build` - 生产环境下 TypeORM `synchronize` 会强制为 `false` ### 执行 API 自动验证 需要先启动服务: ```bash npm run dev ``` 再执行: ```bash npm run verify:api:dev ``` 说明: - 先执行 `npm run build` - 再执行 `npm run verify:api` - 默认目标地址:`http://127.0.0.1:${APP_PORT}/${APP_API_PREFIX}` - 默认报告输出:`logs/verify/api-verify-result-YYYYMMDDHHmmss.md` 也可以直接验证已构建产物: ```bash npm run verify:api ``` ## 接口列表 ### 健康检查 ```http GET /api/health ``` 返回示例: ```json { "status": "ok", "app": { "name": "nextjs-server", "env": "development" }, "dependencies": { "mysql": { "name": "mysql", "status": "up", "lastCheckedAt": "2026-06-14T10:00:00.000Z", "lastChangedAt": "2026-06-14T10:00:00.000Z" }, "redis": { "name": "redis", "status": "up", "lastCheckedAt": "2026-06-14T10:00:00.000Z", "lastChangedAt": "2026-06-14T10:00:00.000Z" } }, "timestamp": "2026-06-14T10:00:00.000Z" } ``` 依赖状态可能为: ```text up down ``` ### 用户列表 ```http GET /api/user ``` 支持按 `keyword`、`roleCode`、`isActive`、`includeDeleted`、`limit`、`offset` 查询,返回用户基础信息和角色列表,不返回 `passwordHash` / `passwordSalt`。默认只返回 `deleted_at IS NULL` 的用户;传 `includeDeleted=true` 可包含软删除用户。 ### 用户详情 ```http GET /api/user/:id ``` 返回用户基础信息和已绑定角色。已软删除用户默认返回 `404`。 ### 创建用户 ```http POST /api/user ``` 请求体示例: ```json { "username": "test_user", "password": "Test@123", "nickname": "测试用户", "roleIds": [2] } ``` ### 更新用户 ```http PATCH /api/user/:id ``` 可更新 `nickname`、`isActive`,并兼容更新 `roleIds`。推荐使用独立角色绑定接口维护用户角色关系。 ### 更改用户绑定角色 ```http PUT /api/user/:id/roles ``` 请求体示例: ```json { "roleIds": [1, 2] } ``` 该接口会整体替换用户当前绑定角色,支持一个用户绑定多个角色,传空数组会清空角色绑定。 ### 重置用户密码 ```http PATCH /api/user/:id/password ``` 请求体示例: ```json { "password": "NewPass@123" } ``` ### 删除用户 ```http DELETE /api/user/:id ``` 删除用户为软删除:设置 `is_active=false` 并写入 `deleted_at`。默认查询不再返回该用户,`user_roles` 关系会保留。 ### 角色列表 ```http GET /api/role ``` 支持按 `keyword`、`limit`、`offset` 查询。 ### 角色详情 ```http GET /api/role/:id ``` ### 创建角色 ```http POST /api/role ``` 请求体示例: ```json { "code": "operator", "name": "运营人员", "description": "运营后台角色" } ``` ### 更新角色 ```http PATCH /api/role/:id ``` ### 删除角色 ```http DELETE /api/role/:id ``` 删除角色时会级联删除用户角色关系。 ### 日志查询 ```http GET /api/log/query ``` 查询参数: | 参数 | 必填 | 说明 | | --- | --- | --- | | `startAt` | 是 | 查询开始时间,ISO8601 格式 | | `endAt` | 是 | 查询结束时间,ISO8601 格式 | | `level` | 否 | 日志级别:`fatal`、`error`、`warn`、`info`、`debug` | | `category` | 否 | 日志分类,精确匹配 | | `service` | 否 | 服务名,精确匹配 | | `env` | 否 | 运行环境,精确匹配 | | `requestId` | 否 | 请求 ID,精确匹配 | | `traceId` | 否 | 链路 ID,精确匹配 | | `source` | 否 | 日志来源,精确匹配 | | `message` | 否 | 日志消息,包含匹配 | | `method` | 否 | HTTP 方法,匹配日志 `meta.method` | | `path` | 否 | HTTP 路径,包含匹配日志 `meta.path` | | `statusCode` | 否 | HTTP 状态码,匹配日志 `meta.statusCode` | | `limit` | 否 | 返回条数,范围 1-500,默认 100 | | `cursor` | 否 | 分页游标 | | `order` | 否 | 排序方向:`asc`、`desc`,默认 `desc` | 限制: - 单次最大查询时间范围:24 小时 - 单次最多扫描文件数:100 - 单次最多扫描行数:200000 示例: ```http GET /api/log/query?startAt=2026-06-14T00:00:00.000Z&endAt=2026-06-14T23:59:59.999Z&level=info&limit=20 ``` 返回结构: ```json { "items": [], "page": { "limit": 20, "nextCursor": "...", "hasMore": false }, "summary": { "scannedFiles": 0, "scannedLines": 0, "parseErrors": 0, "truncated": false, "timeRange": { "startAt": "2026-06-14T00:00:00.000Z", "endAt": "2026-06-14T23:59:59.999Z" } } } ``` ## 日志说明 日志模块会输出: - 控制台日志 - 本地结构化日志文件 - API 请求日志 - MySQL / Redis 依赖状态变化日志 - 服务启动 / 生命周期日志 日志文件根目录由 `LOG_DIR` 控制,默认: ```text logs/ ``` 日志文件按本地时间的年月日小时拆分: ```text logs/YYYY/MM/DD/HH.jsonl ``` 示例: ```text logs/2026/06/14/00.jsonl logs/2026/06/14/23.jsonl ``` 单文件超过 `LOG_MAX_FILE_SIZE_MB` 后会生成同小时分片: ```text logs/2026/06/14/00-02.jsonl logs/2026/06/14/00-03.jsonl ``` 日志保留天数由 `LOG_RETENTION_DAYS` 控制。写入日志时会触发过期日志目录清理。 日志记录基础字段: | 字段 | 说明 | | --- | --- | | `timestamp` | 日志时间 | | `level` | 日志级别 | | `category` | 日志分类 | | `message` | 日志消息 | | `service` | 服务名称 | | `env` | 运行环境 | | `requestId` | 请求 ID | | `traceId` | 链路 ID | | `source` | 日志来源 | | `meta` | 扩展信息 | ## API 自动验证 API 自动验证模块用于初步检查接口是否可用,并生成 Markdown 报告。它不替代单元测试、集成测试或完整业务测试。 ### 默认验证 ```bash npm run verify:api:dev ``` ### 指定目标服务 ```bash npm run verify:api:dev -- --base-url=http://127.0.0.1:3000/api ``` ### 只验证指定模块 ```bash npm run verify:api:dev -- --include=health ``` ### 排除指定模块 ```bash npm run verify:api:dev -- --exclude=logging ``` ### 只执行指定用例 ```bash npm run verify:api:dev -- --case=health.check ``` 多个用例使用英文逗号分隔: ```bash npm run verify:api:dev -- --case=health.check,logging.query.validRange ``` ### 设置超时时间 ```bash npm run verify:api:dev -- --timeout=10000 ``` ### 指定报告输出路径 ```bash npm run verify:api:dev -- --output=logs/verify/custom-report.md ``` ### 失败即停止 ```bash npm run verify:api:dev -- --fail-fast ``` ### 允许执行 unsafe 用例 ```bash npm run verify:api:dev -- --allow-unsafe ``` > 默认只执行 `safe` 用例。写操作、删除操作或有副作用的接口必须标记为 `unsafe`,只有显式传入 `--allow-unsafe` 时才执行。 ### 新增 API 验证用例 新增业务模块时,可以在模块目录下新增: ```text .api-verifier.ts ``` 并在对应模块的 `providers` 中注册。只要该模块被 `AppModule` 引入,验证命令就会自动收集对应验证用例。 验证用例提供类需要实现: ```ts import { ApiVerificationCase, ApiVerifierProvider } from '@/api-verifier/api-verifier.types'; export class DemoApiVerifier implements ApiVerifierProvider { getApiVerificationCases(): ApiVerificationCase[] { return [ { id: 'demo.list', module: 'demo', name: '示例列表接口', method: 'GET', path: '/demo/list', safety: 'safe', expect: { status: 200, contentTypeIncludes: 'application/json', }, }, ]; } } ``` ## 开发约定 ### 路由约定 - 所有接口必须经过 `APP_API_PREFIX` - Controller 中只写模块名和动作名,不写 `/api` - 模块接口建议按以下格式设计: ```text /api/{模块名}/{动作或资源} ``` 示例: ```text /api/user/list /api/user/detail /api/user/create /api/log/query /api/health ``` ### 业务模块约定 业务模块统一放在: ```text src/modules// ``` 建议结构: ```text src/modules/demo/ ├─ demo.controller.ts ├─ demo.service.ts ├─ demo.module.ts ├─ demo.api-verifier.ts ├─ dto/ └─ entities/ ``` ### 路径别名约定 项目已配置 `@` 指向 `src` 根目录。 推荐: ```ts import { utils } from '@/utils/utils'; ``` 避免过深相对路径: ```ts ../../../utils/utils ``` ### 工具函数约定 项目已接入 `cross-env-plugins`,但业务代码不要直接从 `cross-env-plugins` 引用工具函数。 统一从: ```ts import { utils } from '@/utils/utils'; ``` 如果 `cross-env-plugins` 没有对应方法,再在 `src/utils/utils.ts` 中扩展。 ## 注意事项 - MySQL / Redis 连接失败不会阻断 Nest 服务启动,连接状态通过健康检查和日志体现。 - 默认角色和默认管理员只通过 `npm run init:auth:dev` 初始化,应用启动不会自动创建;默认开发账号为 `admin / Admin@123`,部署后应尽快修改。 - 密码使用 `crypto.scrypt` 生成哈希和独立 salt,接口响应不会返回密码字段。 - 生产环境禁止开启 `DB_SYNC=true`,代码中生产环境也会强制关闭 TypeORM `synchronize`。 - `DB_LOGGING=true` 仅建议开发排查时使用,生产环境应保持 `false`。 - Redis 操作统一通过 `src/redis/redis.service.ts`,不要在业务模块中直接创建 ioredis 客户端。 - `.env.example` 只放示例值或占位值,不能放真实密码、Token 或生产连接串。 - 日志查询基于本地文件扫描,适合初期排查;日志量变大后建议扩展到 MySQL、ELK、Loki 等系统。 - API 验证用于接口可用性初步检查,不替代完整业务测试。 - 日志、验证报告、运行产物放在 `logs/` 下,不提交 Git。