2026-06-28-backend-standard-business-skeleton-design.md 11 KB

后端标准业务骨架初始化设计

背景

当前仓库已有 frontend/ React 前端,并且前端已经按真实接口模式组织了服务层,默认通过 /api/v1 调用后端。backend/ 目录目前只有数据库设计文档,尚未存在可运行的服务端项目。因此需要先初始化一个可扩展的业务后端骨架,作为后续真实接口实现与前后端联调的基础。

本次确认后的技术栈采用 NestJS,初始化目标不是只生成一个空工程,而是生成可直接承接认证、顾客、模板、模拟任务等业务域的标准服务端骨架。

目标

  • 在 backend/ 下初始化一个基于 NestJS 的服务端项目。
  • 统一 API 前缀为 /api/v1,与前端现有请求方式保持一致。
  • 统一响应包结构为 { ok, data, error }。
  • 初始化 Prisma + MySQL + Redis 的工程接入能力。
  • 按前端业务域创建模块骨架,包括 auth、customers、templates、simulations、health。
  • 建立可持续扩展的工程基础设施,包括配置管理、异常处理、响应拦截、参数校验、Swagger。
  • 保持“零 Mock”原则: 未完成功能应返回明确错误或未实现响应,而不是伪造业务数据。

非目标

  • 本次不实现完整业务逻辑。
  • 本次不接入真实 AI 生成服务。
  • 本次不完成对象存储能力接入。
  • 本次不覆盖全部数据库表的完整 CRUD。
  • 本次不强制完成所有前端接口的真实可用实现,只要求先把模块边界、工程能力和基础接口入口搭建好。

设计原则

  • 优先保证与前端当前契约兼容,而不是追求过度抽象。
  • 工程骨架一步到位,避免后续因目录、基础设施或协议不一致而返工。
  • 所有未完成能力都应显式失败,不提供 mock 数据。
  • 模块边界按业务域划分,避免单体 service 堆积。
  • 异步任务、鉴权和数据层设计要为后续真实实现留出稳定扩展点。

项目结构

初始化后的目标结构如下:

backend/
  src/
    main.ts
    app.module.ts
    common/
      dto/
      filters/
      interceptors/
      response/
      constants/
    config/
      app.config.ts
      env.schema.ts
    prisma/
      prisma.module.ts
      prisma.service.ts
    redis/
      redis.module.ts
      redis.service.ts
    modules/
      health/
      auth/
      customers/
      templates/
      simulations/
  prisma/
    schema.prisma
  test/
  .env.example
  package.json
  tsconfig.json
  nest-cli.json
  README.md

说明:

  • common/ 放全局共享能力,不放业务逻辑。
  • modules/ 下每个域独立包含 controller、service、dto、module。
  • prisma/ 独立为基础设施模块,后续供各业务模块注入。
  • redis/ 作为异步任务、轮询状态、会话扩展的预留基础设施。

基础设施设计

1. 应用启动

main.ts 负责:

  • 启动 Nest 应用。
  • 设置全局前缀 /api/v1。
  • 启用全局 ValidationPipe。
  • 注册统一异常过滤器。
  • 注册统一响应拦截器。
  • 启用 CORS,来源通过环境变量配置。
  • 启用 Swagger 文档,便于前后端联调。

2. 配置管理

使用 @nestjs/config 管理环境变量,并在启动阶段对变量做 schema 校验。首批环境变量包括:

  • PORT
  • APP_BASE_URL
  • DATABASE_URL
  • REDIS_URL
  • JWT_SECRET
  • JWT_EXPIRES_IN
  • CORS_ORIGIN
  • NODE_ENV

提供 .env.example,保证本地初始化后即可复制为 .env 使用。

3. 统一响应协议

所有成功响应使用统一结构:

{
  "ok": true,
  "data": {},
  "error": null
}

所有失败响应使用统一结构:

{
  "ok": false,
  "data": null,
  "error": {
    "code": "ERROR_CODE",
    "message": "错误说明"
  }
}

这与前端 frontend/src/services/http/client.ts 中的解析方式保持一致。

4. 数据层

使用 Prisma 作为 ORM,数据库为 MySQL。初始化阶段完成:

  • Prisma 依赖安装。
  • schema.prisma 创建。
  • PrismaService 封装。
  • 应用退出时的 Prisma 连接回收。

首批模型以现有 数据库设计.md 为依据,优先覆盖:

  • hairstylist_user
  • customer_treatment_record
  • ai_hair_simulation
  • ai_hair_simulation_task
  • hair_template
  • hair_template_make_task

初始化阶段先把模型映射落地到 Prisma schema,为后续真实实现做准备。

5. Redis 接入

初始化阶段接入 Redis 模块,但不强制马上引入队列框架。当前只要求:

  • 完成 Redis 客户端创建与健康注入。
  • 为后续异步任务状态缓存、轮询、会话扩展预留服务封装。

是否后续引入 BullMQ,不在本轮初始化中决定。

业务模块设计

1. Health 模块

目标:

  • 提供最小可用健康检查接口。

接口:

  • GET /api/v1/health

返回:

  • 服务状态。
  • 可选地包含数据库与 Redis 连接状态摘要。

2. Auth 模块

目标:

  • 为前端登录态建立真实的接口边界。

首批接口:

  • POST /api/v1/auth/stylist/login
  • POST /api/v1/auth/logout

约束:

  • 登录成功返回 token、tokenName、stylistId、name、email。
  • tokenName 默认与前端一致,使用 Authorization。
  • 初始化阶段优先建立 DTO、控制器、JWT 基础设施和鉴权守卫挂载方式。
  • 若数据库校验逻辑尚未完成,接口应返回明确的未实现或受控错误,而非假登录成功。

3. Customers 模块

目标:

  • 对应前端顾客列表、详情、编辑、记录、提醒接口。

首批接口:

  • GET /api/v1/customers
  • GET /api/v1/customers/:id
  • POST /api/v1/customers
  • PATCH /api/v1/customers/:id
  • GET /api/v1/customers/:id/records
  • POST /api/v1/customers/:id/reminders
  • GET /api/v1/stylist/dashboard/customer-summary

初始化阶段要求:

  • 创建 DTO 和 controller 路由入口。
  • 为分页、筛选、关键字查询预留参数结构。
  • service 中按“真实实现待补充”的方式组织,不使用 mock 数据源。

4. Templates 模块

目标:

  • 对应模板列表、详情、保存、删除、生成任务、模板统计等能力。

首批接口:

  • GET /api/v1/templates
  • GET /api/v1/templates/:id
  • POST /api/v1/templates
  • PATCH /api/v1/templates/:id
  • DELETE /api/v1/templates/:id
  • POST /api/v1/templates/bulk-delete
  • POST /api/v1/templates/generation-jobs
  • GET /api/v1/templates/generation-jobs/:id
  • POST /api/v1/templates/generate-and-save
  • GET /api/v1/templates/:id/results
  • GET /api/v1/templates/:id/stats
  • GET /api/v1/stylist/dashboard/template-summary

初始化阶段要求:

  • 建立模板生成任务与模板实体的模块边界。
  • 先保留“创建记录并返回状态”的任务入口设计,为后续异步化实现做铺垫。
  • 明确模板生成任务状态字段与错误字段的返回形态。

5. Simulations 模块

目标:

  • 对应顾客模拟、结果查询、结果保存、微调与术后跟进。

首批接口:

  • POST /api/v1/simulations
  • GET /api/v1/simulations/:id
  • GET /api/v1/simulations/:id/results
  • POST /api/v1/simulation-results/:id/save
  • POST /api/v1/simulation-results/:id/adjustments
  • POST /api/v1/aftercare-results/:id/follow

初始化阶段要求:

  • 建立任务创建、任务状态查询、结果资源查询的 API 边界。
  • 状态模型优先兼容前端当前轮询方式。
  • 对未完成的 AI 调用链返回明确错误,不伪造结果。

与前端契约对齐

前端当前关键契约来自以下文件:

  • client.ts
  • auth.ts
  • customers.ts
  • templates.ts
  • simulations.ts

初始化阶段必须保证以下契约:

  • API 根路径可配置,但默认兼容 /api/v1。
  • 成功/失败响应体结构与前端 ApiEnvelope 一致。
  • 登录接口字段名与前端 LoginResult 一致。
  • 列表接口可返回 { items, total } 的列表数据结构,作为 data 内容。
  • 鉴权头默认兼容前端存储方式,即 Authorization: <token>。

数据模型策略

初始化时不追求一次性完整建模所有历史字段,但以下要求必须满足:

  • Prisma 模型字段命名尽量对齐数据库表语义。
  • 保留 is_deleted、create_time、update_time 等现有设计约定。
  • 对枚举状态使用 Prisma enum 或字符串字段明确定义。
  • 对 JSON 字段或数组文本存储字段在 schema 中显式备注,避免后续歧义。

对 hair_template_make_task 与 ai_hair_simulation_task 两类异步任务表,应优先保留状态字段、错误信息字段、结果字段与外部任务 ID 字段。

错误处理策略

初始化阶段的错误处理约束如下:

  • 参数校验失败返回统一错误结构。
  • 未登录或 token 无效返回 401。
  • 资源不存在返回 404。
  • 尚未实现的业务逻辑返回明确业务错误,不返回假数据。
  • 所有未捕获异常经全局异常过滤器转换为统一响应结构。

测试策略

初始化阶段测试目标以工程可用性为主,不追求业务覆盖率:

  • 至少保留 Nest 默认 e2e 测试入口,并改造为适配统一响应协议。
  • 增加对 GET /api/v1/health 的基础 e2e 测试。
  • 如初始化阶段加入响应拦截器,可为统一响应结构补一个基础测试。

文档与开发体验

初始化阶段应同步生成:

  • backend/README.md,说明安装、环境变量、运行、测试、数据库初始化方式。
  • .env.example,提供本地开发必需变量。
  • Swagger 文档入口说明。

这样可直接替代或修正前端 README 中目前对后端“已存在”的描述偏差。

实施边界

本设计只覆盖“标准业务骨架初始化”这一阶段,不包含以下后续专题:

  • 真实登录认证流程落地。
  • Prisma migration 策略最终定稿。
  • 模板生成异步任务与外部 AI 平台联动。
  • 媒体存储驱动接入。
  • Redis 队列消费与后台 worker 拆分。

这些内容应在后续实现计划中拆成独立步骤。

验收标准

完成初始化后,应至少满足以下条件:

  • backend/ 成为一个可安装依赖并启动的 NestJS 项目。
  • 本地可通过环境变量连接 MySQL 和 Redis。
  • 访问 GET /api/v1/health 可得到统一响应结构。
  • Swagger 可访问。
  • 业务模块目录、控制器、服务、DTO 骨架已经建立。
  • Prisma schema 已建立并覆盖首批核心表。
  • 未完成接口不会返回 mock 数据。

推荐的下一步

下一步应进入实现计划阶段,分解为:

  1. 初始化 NestJS 工程与基础依赖。
  2. 接入配置、统一响应、异常处理与健康检查。
  3. 接入 Prisma 与 Redis 基础设施。
  4. 建立业务模块骨架与占位接口。
  5. 补充 README、环境变量示例与基础测试。

待实现计划确认后,再进入正式编码。