NestJS (6 services): implement @RequirePermission decorator with SetMetadata+Reflector, register APP_GUARD globally, fix as assertions to type guards, add explicit return types, fix import type for express, fix /metrics implicit any, replace native Error with ApplicationError, remove typeorm remnants, register LifecycleService. teacher-bff: add logger, ApplicationError, GlobalErrorFilter, forward real userId to downstream, log downstream failures, migrate health controller to shared/health. Go (2 services): interface to any, doc comments, CORS dev whitelist, JWT secret fail-fast, push-gateway internal API auth, metrics and readyz endpoints, remove dead code. Python (2 services): lifespan return type, dev_mode to bool, data-ana APIRouter, ai POST body model, ClickHouse async wrapping.
9.2 KiB
服务审计表 — ai04
AI 标识:ai04 阶段:阶段 1(自检) 日期:2026-07-09 审计对象:student-bff(P3 待实现)、parent-bff(P4 待实现) 对照基准:classes 黄金模板(已实现)+ teacher-bff BFF 模板(已实现) 模板来源:ai-allocation.md §10
1. 审计状态说明
| 标记 | 含义 |
|---|---|
| ✅ | 已对齐黄金模板(实施时复制 + 改名即可) |
| ⚠️ | 有差异但已识别缓解方案(需 coord 仲裁或实施时调整) |
| ❌ | 未对齐,需补齐 |
| 🆕 | 全新服务,尚未实现,审计结果为"设计目标" |
由于 student-bff 和 parent-bff 均为全新服务(未实现),本审计表为设计目标审计,列出实施时需对齐的各项。
2. ai04 服务审计表
| 服务 | 权限装饰器 | 错误码前缀 | logger | metrics | tracer | /healthz | /readyz | 优雅关闭 | 测试覆盖率 | Dockerfile |
|---|---|---|---|---|---|---|---|---|---|---|
| student-bff(P3 待实现) | ⚠️ 不对齐 | ✅ STUDENT_BFF_ |
✅ pino | ✅ prom-client | ✅ OTel | ✅ | ✅ | ✅ SIGTERM | 🆕 目标 ≥80% | ✅ 多阶段 |
| parent-bff(P4 待实现) | ⚠️ 不对齐 | ✅ PARENT_BFF_ |
✅ pino | ✅ prom-client | ✅ OTel | ✅ | ✅ | ✅ SIGTERM | 🆕 目标 ≥80% | ✅ 多阶段 |
3. 审计项详解
3.1 权限装饰器 @RequirePermission — ⚠️ 不对齐
classes 黄金模板:全部 Controller 方法用 @RequirePermission(Permissions.XXX) 装饰,全局 PermissionGuard 校验。
ai04 服务决策:不对齐。理由:
- BFF 是纯聚合层,权限由下游业务服务校验(对齐 teacher-bff 现状)
- BFF 透传
x-user-id头给下游,下游 Repository 按 DataScope 过滤 - parent-bff 在 BFF 层做"DataScope=CHILDREN 越权校验"(家长查询的 childId 必须在绑定列表内),但用普通 Service 层校验,不用装饰器
风险:若 coord 要求 BFF 也加权限装饰器(双重校验),需在 student-bff/parent-bff 引入 middleware/permission.guard.ts(复制 classes 实现)。
3.2 错误码前缀 — ✅ 对齐
| 服务 | 前缀 | 示例 |
|---|---|---|
| student-bff | STUDENT_BFF_ |
STUDENT_BFF_UNAUTHORIZED、STUDENT_BFF_BAD_GATEWAY |
| parent-bff | PARENT_BFF_ |
PARENT_BFF_UNAUTHORIZED、PARENT_BFF_BAD_GATEWAY、PARENT_BFF_CHILD_NOT_BOUND |
对齐 teacher-bff 的 TEACHER_BFF_ 模式。
3.3 logger — ✅ 对齐
复制 teacher-bff shared/observability/logger.ts,仅改 service 字段:
- student-bff:
service: 'student-bff' - parent-bff:
service: 'parent-bff'
3.4 metrics — ✅ 对齐
复制 teacher-bff shared/observability/metrics.ts + main.ts 中 /metrics 端点注册,仅改指标名前缀:
- student-bff:
student_bff_requests_total、student_bff_request_duration_seconds - parent-bff:
parent_bff_requests_total、parent_bff_request_duration_seconds
3.5 tracer — ✅ 对齐
复制 teacher-bff shared/observability/tracer.ts,仅改 serviceName:
- student-bff:
serviceName: 'student-bff' - parent-bff:
serviceName: 'parent-bff'
3.6 /healthz — ✅ 对齐
复制 teacher-bff shared/health/health.controller.ts,仅改 SERVICE_NAME:
- student-bff:
service: 'student-bff' - parent-bff:
service: 'parent-bff'
3.7 /readyz — ✅ 对齐
BFF 不查 DB,/readyz 直接返回 ok(对齐 teacher-bff)。
可选增强(P3 后期):检查下游服务可达性(HEAD 请求 iam/core-edu 的 /healthz),但 P3 阶段建议先简单返回 ok,下游可达性由 Prometheus 监控。
3.8 优雅关闭 — ✅ 对齐
复制 teacher-bff main.ts 中 SIGTERM 处理:
process.on("SIGTERM", async () => {
await app.close();
await shutdownTracer();
});
BFF 无 DB 连接需关闭(无 LifecycleService),仅需关闭 HTTP server + tracer。
3.9 测试覆盖率 — 🆕 目标 ≥ 80%
测试重点:
- Service 层聚合逻辑(mock 下游 fetch,验证 Promise.allSettled 容错)
- Controller 层入参校验(Zod schema)
- 错误处理(BadGatewayError、UnauthorizedError、ValidationError)
- parent-bff 特有:DataScope=CHILDREN 越权校验
测试框架:Jest(对齐 classes,待确认 classes 是否已配置 Jest)。
3.10 Dockerfile — ✅ 对齐
复制 teacher-bff Dockerfile(多阶段构建:builder + runtime),仅改 EXPOSE:
- student-bff:
EXPOSE 3009 - parent-bff:
EXPOSE 3010
4. 与 teacher-bff 模板对比(克隆基线)
teacher-bff 是已实现的最小 BFF 模板,student-bff/parent-bff 应 1:1 克隆后改造。
4.1 完全复制的部分(无需改动)
| 文件/目录 | 说明 |
|---|---|
shared/errors/global-error.filter.ts |
全局错误过滤器(仅错误码前缀不同) |
shared/health/health.module.ts |
健康检查模块 |
shared/observability/logger.ts |
pino logger(仅 service 名不同) |
shared/observability/metrics.ts |
prom-client(仅指标名前缀不同) |
shared/observability/tracer.ts |
OTel tracer(仅 serviceName 不同) |
app.module.ts |
根模块(仅 imports 的业务模块不同) |
main.ts |
启动流程(仅端口和日志不同) |
tsconfig.json |
ESM 配置 |
nest-cli.json |
NestJS CLI 配置 |
4.2 需要改造的部分
| 文件 | 改造点 |
|---|---|
package.json |
name 字段、dependencies(按下游服务需求扩展) |
src/config/env.ts |
PORT default、下游服务 URL 配置项 |
src/<context>/ 目录名 |
teacher → student / parent |
src/<context>/<context>.controller.ts |
@Controller 装饰器前缀、端点路由 |
src/<context>/<context>.service.ts |
聚合逻辑(按场景域不同) |
src/<context>/<context>.module.ts |
模块注册 |
shared/errors/application-error.ts |
错误码前缀、新增错误类(parent-bff 加 ChildNotBoundError) |
shared/health/health.controller.ts |
SERVICE_NAME |
Dockerfile |
EXPOSE 端口 |
4.3 teacher-bff 模板的可改进点(ai04 实施时可优化)
| 改进点 | teacher-bff 现状 | ai04 建议改进 |
|---|---|---|
| 聚合响应类型 | 大量用 unknown |
用 Zod schema 推导强类型响应 |
| 下游调用封装 | 原生 fetch() 散落在 Service |
抽取 DownstreamClient 工具类(带超时、重试、traceId 透传) |
| 错误信封 | 下游错误直接吞掉返回 null | 下游错误结构化记录(service/endpoint/status),透传 traceId |
| 缓存 | 无缓存 | 引入 NestJS CacheInterceptor + Redis(5-30s 短缓存) |
⚠️ 这些改进点需 coord 仲裁是否回写到 teacher-bff(避免技术栈分裂),还是仅用于 student-bff/parent-bff。
5. 审计结论
| 服务 | 总体对齐度 | 阻塞项 | 备注 |
|---|---|---|---|
| student-bff | 🟢 高(90%) | 无 P0 阻塞 | P3 阶段可直接克隆 teacher-bff 实施,data-ana/ai 端点延后到 P4/P5 |
| parent-bff | 🟡 中(70%) | P0 阻塞:iam 家长-学生关联接口缺失 | 需 coord 协调 ai02 在 P3 阶段补全 iam 接口,否则 P4 无法启动实施 |
ai04 阶段 1 审计完成。两份理解确认书 + 本审计表已交付,请 coord 审核。