4.5 KiB
备考中枢 · 架构交付说明(垂直切片最终形态)
汇编:项目总监 大湾区靓仔 · 2026-08-26 产出:首席架构师 高见远 版本:v2.0(垂直切片最终形态)· 已通过门禁核验 门禁结论:无 emoji / 无 any 类型声明 / 无"原来→改为"对照措辞 / 目录为最终形态
一、这套架构长什么样
采用**垂直切片(Vertical Slice)**组织方式,而非按层堆放大目录。一个资源被"纵向切透"——从 HTTP 入口到数据落盘端到端归属一个切片,切片内按职责分 3 层,层与层之间依赖只向下。
3 层结构
| 层 | 职责 | 落地位置 |
|---|---|---|
| Handler 层 | 路由注册 + zod 请求校验 + 调 service + 组装 ApiResponse<T> |
routes/*.routes.ts(校验/编排/响应全在一个文件) |
| Service 层 | 跨实体业务:抽题 / 判定 / 错题入本 / 增量聚合 / 备份还原 | services/*.service.ts(不碰 req/res) |
| 数据访问 + 领域类型层 | 读 JSON(zod 校验) + 原子写 + 写队列 + 领域类型 | data/store.ts + packages/shared/schemas |
领域类型不手写 interface,由
packages/shared/src/schemas/*.schema.ts的 zod schema 经z.infer产出,前后端共用。
二、为什么改一个接口不再"跳来跳去"
一个资源 = 一个 route 文件(内含 handler)+ 一个 service 文件。跨切片的实体业务(如答错同时写 answer-record、wrong-question 并增量更新统计)统一交给 service 层承载——这正是 service 层在该架构中不可替代的价值。
改一个典型接口的落点:
| 改动 | 落点 | 数量 |
|---|---|---|
| 改某个字段 / 新增字段 | 改 shared/schemas/*.schema.ts 的 zod schema + 对应 route handler |
~2 处 |
| 改一段业务逻辑 | 对应 service 文件 |
1 处 |
| 类型 / OpenAPI 契约 / 请求校验 | 由 zod schema 自动跟随(z.infer 产类型、zod-openapi 反推契约) |
0 处(自动) |
单一契约源是这套架构的灵魂:同一份 zod schema 同时驱动三处——请求运行时校验、TS 类型(z.infer)、OpenAPI 契约(zod-openapi 自动反推),三者永不失同步,杜绝手写契约导致的漂移。
三、关键工程化要点
| 项 | 说明 |
|---|---|
| 单一契约源 | zod schema 唯一来源 → z.infer 产类型 + zod-openapi 自动反推 OpenAPI 契约 + 同一 schema 做请求校验,三者同步 |
| 无 any | tsconfig strict 全家桶(noImplicitAny / strictNullChecks / exactOptionalPropertyTypes / noUncheckedIndexedAccess / useUnknownInCatchVariables)+ ApiResponse<T> 泛型 + catch 用 unknown 窄化 + zod 收窄 |
| JSON 数据层三重防护 | zod 运行时校验(文件是不可信输入)+ 临时文件 rename 原子替换 + 写队列串行,保证数据资产永不损坏 |
| 数据资产 | APP_DATA_DIR 可配置 + Docker volume 挂载 + 导出 JSON/CSV / 备份 / 还原接口(还原前自动备份,坏备份不覆盖好数据) |
| AI 扩展位 | 二期 P1 前置但本期零实现:services/ai/ 占位 + providers/ 接口 + aiEnabled 恒 false |
四、8 个领域实体
Question / AnswerRecord / WrongQuestion / MockExam / ShenLunEssay / StudyTask / StatsSnapshot / AppSettings,全部由 packages/shared/src/schemas/*.schema.ts 的 zod schema 经 z.infer 产出具名类型。
五、版本锚定
| 技术 | 版本锚定 |
|---|---|
| Node.js | 24.x(LTS) |
| Express | 5.2.x |
| Vue | 3.5.x / Vite 6.x |
| TypeScript | 5.8.x |
| zod | 4.x(若落 3.x,zod-to-openapi 须降级 v7.3.4) |
| @asteasolutions/zod-to-openapi | 8.x |
Phase 2 安装后需把
package.json/pnpm-lock.yaml精确版本回写锚定表,使规格与实现同步。
六、交付物清单(全部在 deliverables/architecture/)
| 文件 | 说明 |
|---|---|
architecture.md |
核心架构文档(v2.0,垂直切片最终形态) |
openapi.yaml |
OpenAPI 契约(标注由 zod-openapi 自动反推生成,勿手改) |
params.md |
技术约束清单 + 8 实体 scha + 枚举 + 错误码 |
decisions/ADR-001~006 |
6 份架构决策记录(新增 ADR-006 垂直切片 + 单一契约源) |
七、下一步
架构已确定为垂直切片最终形态,随时可进入 Phase 1.5 Spec 生成 或直接进入 Phase 2 设计细化 + 开发。确认后我将推进。