From e9ff986bac9732bcff23742fdb11a79ccd7dbc5d Mon Sep 17 00:00:00 2001 From: Script Generator Date: Fri, 3 Jul 2026 13:00:21 +0800 Subject: [PATCH] =?UTF-8?q?docs(v2.3):=20=E8=AE=B0=E5=BD=95=E5=85=B3?= =?UTF-8?q?=E7=B3=BB=E8=A1=A8=E5=86=99=E5=85=A5=E9=97=AD=E7=8E=AF=E6=96=B9?= =?UTF-8?q?=E6=A1=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../plans/2026-07-03-v23-relational-writes.md | 79 +++++++++++++++++++ ...2026-07-03-v23-relational-writes-design.md | 67 ++++++++++++++++ 2 files changed, 146 insertions(+) create mode 100644 docs/superpowers/plans/2026-07-03-v23-relational-writes.md create mode 100644 docs/superpowers/specs/2026-07-03-v23-relational-writes-design.md diff --git a/docs/superpowers/plans/2026-07-03-v23-relational-writes.md b/docs/superpowers/plans/2026-07-03-v23-relational-writes.md new file mode 100644 index 0000000..8ea5ab3 --- /dev/null +++ b/docs/superpowers/plans/2026-07-03-v23-relational-writes.md @@ -0,0 +1,79 @@ +# V2.3 Relational Writes Implementation Plan + +> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking. + +**Goal:** Complete the V2.3 write-side bridge so AppData saves keep V2.2 relation-table read paths fresh and observable. + +**Architecture:** Add a focused sync service behind `DataService.put()` that reuses the V2.2 mapper, syncs only affected relation tables, marks Xiaobao summaries dirty when risk inputs change, and logs sync failures without blocking AppData saves. Add lightweight NestJS and Prisma timing logs with environment-configurable thresholds. + +**Tech Stack:** NestJS, Prisma, PostgreSQL partitioned tables, Jest, TypeScript, existing AppData JSONB compatibility layer. + +--- + +### Task 1: AppData Write Hook + +**Files:** +- Modify: `apps/server/src/modules/data/data.service.spec.ts` +- Modify: `apps/server/src/modules/data/data.service.ts` +- Modify: `apps/server/src/modules/data/data.module.ts` +- Modify: `apps/server/src/modules/migration/migration.module.ts` + +- [ ] Add tests proving `DataService.put()` calls the sync service only after successful create/update/upsert. +- [ ] Add tests proving stale version conflicts and create races do not trigger sync. +- [ ] Add tests proving sync errors are logged and AppData responses still return success. +- [ ] Inject `AppDataV23SyncService` into `DataService` as an optional dependency for tests. +- [ ] Import `MigrationModule` from `DataModule`. + +### Task 2: Relation Sync Service + +**Files:** +- Create: `apps/server/src/modules/migration/app-data-v23-sync.service.spec.ts` +- Create: `apps/server/src/modules/migration/app-data-v23-sync.service.ts` +- Modify: `apps/server/src/modules/migration/app-data-v22.migration.service.ts` +- Modify: `apps/server/src/modules/migration/migration.module.ts` + +- [ ] Add tests for requirement sync by `productId` scope. +- [ ] Add tests for version detail tables by `versionId` scope: plans, dev tasks, test cases, and bugs. +- [ ] Add tests for snapshot-driven Xiaobao summary refresh. +- [ ] Add tests for risk-input dirty marking. +- [ ] Implement `syncAfterAppDataPut(key)` by loading current AppData snapshot, mapping with `mapAppDataToV22Rows()`, normalizing date fields, and writing affected delegates in a transaction. +- [ ] Export the sync service from `MigrationModule`. + +### Task 3: Lightweight Monitoring + +**Files:** +- Create: `apps/server/src/common/interceptors/api-timing.interceptor.spec.ts` +- Create: `apps/server/src/common/interceptors/api-timing.interceptor.ts` +- Create: `apps/server/src/prisma/prisma-monitoring.ts` +- Create: `apps/server/src/prisma/prisma-monitoring.spec.ts` +- Modify: `apps/server/src/prisma/prisma.service.ts` +- Modify: `apps/server/src/app.module.ts` + +- [ ] Add tests for timing threshold parsing and slow request logging. +- [ ] Add tests for Prisma slow query threshold parsing. +- [ ] Register `ApiTimingInterceptor` globally with `APP_INTERCEPTOR`. +- [ ] Configure `PrismaService` query event logging without changing connection lifecycle. + +### Task 4: Documentation + +**Files:** +- Modify: `docs/architecture.md` +- Modify: `docs/decisions.md` +- Modify: `docs/roadmap.md` + +- [ ] Document V2.3 write-side bridge in architecture. +- [ ] Add a decision for non-blocking AppData-to-relation sync and Xiaobao dirty summaries. +- [ ] Move roadmap current stage from V2.2 completion to V2.3 completion. + +### Task 5: Verification And Commit + +**Commands:** +- `pnpm --filter server type-check` +- `pnpm --filter server exec prisma validate --schema prisma/schema.prisma` +- From `apps/server`: `$env:NODE_OPTIONS='--max-old-space-size=4096'; .\node_modules\.bin\jest.CMD --runInBand` +- `pnpm --filter web type-check` +- `pnpm --filter web test` + +- [ ] Run all verification commands. +- [ ] Commit with `feat(v2.3): 完成关系表写入闭环`. + diff --git a/docs/superpowers/specs/2026-07-03-v23-relational-writes-design.md b/docs/superpowers/specs/2026-07-03-v23-relational-writes-design.md new file mode 100644 index 0000000..5d560c3 --- /dev/null +++ b/docs/superpowers/specs/2026-07-03-v23-relational-writes-design.md @@ -0,0 +1,67 @@ +# V2.3 关系表写入与预计算闭环设计 + +## 背景 + +V2.2 已经完成分区关系表、迁移预演、读优化 API,以及版本详情、需求池、与我相关、小宝预警的快读接入。剩余风险在写路径:前端保存仍写入 AppData,如果关系表不同步,V2.2 快读数据会逐渐变旧,用户仍可能在大数据量下回落到完整 JSON 文档加载。 + +V2.3 的目标是在不改前端 Store 写入形状的前提下,把 AppData 保存后的稳定业务数据同步到关系表,并让小宝预警摘要进入可标脏、可预计算的状态。 + +## 范围 + +本阶段做: + +- AppData 写入成功后触发关系表增量同步。 +- 覆盖 V2.2 快读依赖的核心 key:`products-overview`、`members`、`task-categories`、`requirements`、`version-plans`、`dev-tasks`、`test-cases`、`bugs`、`work-activities`、`task-worklogs`、`overtime`、`xiaobao-risk-snapshots`、`xiaobao-risk-insights`。 +- 对会影响发版风险的变更标记 `xiaobao_risk_summaries.dirty = true`,并在已有快照数据存在时写入当前摘要。 +- 增加轻量 API 响应耗时日志和 Prisma 慢查询日志。 +- 保留 V2.2 读 API 和前端 fallback 机制。 + +本阶段不做: + +- 不直接新增全量领域 CRUD 替代前端 AppData Store。 +- 不引入 Redis、Elasticsearch、Prometheus 或 Grafana。 +- 不把小宝完整规则引擎搬到后端;后端只维护快读摘要和 dirty 状态。 +- 不做跨客户端字段级合并,AppData 乐观锁仍是当前并发边界。 + +## 架构 + +新增 `AppDataV23SyncService`,由 `DataService.put()` 在 AppData 成功写入之后调用。同步服务读取当前所有允许的 AppData key,复用 `mapAppDataToV22Rows()` 生成关系行,然后只同步本次 key 影响的表。 + +写入策略按数据形状分两类: + +- 当前态表:按分区作用域先删后建,保证 AppData 删除的数据能从关系表消失。需求按 `productId` 作用域;版本计划、开发任务、测试用例、BUG 按 `versionId` 作用域;产品、项目、版本、成员、任务类型按当前快照整体刷新。 +- 证据/历史表:使用 `createMany(skipDuplicates: true)` 写入追加记录,避免重复导入;已有历史不因 AppData 当前文档缺失而删除。 + +`DataService.put()` 的错误策略是 AppData 成功即返回成功。同步失败时记录错误日志,不回滚 AppData,不让用户保存动作卡死。原因是兼容窗口内 AppData 仍是写入事实源,V2.2 快读有 fallback 能兜底;把同步失败暴露为保存失败会造成更差的可用性。 + +## 小宝摘要 + +小宝摘要采用两层策略: + +- `xiaobao-risk-snapshots` 保存时,从最新快照写入或更新 `xiaobao_risk_summaries`,`dirty=false`。 +- 版本计划、开发任务、测试用例、BUG、工作活动、工时和加班变更时,找出受影响版本,标记对应摘要 `dirty=true`。如果摘要尚不存在,创建一条保守的 `attention` 摘要,提示前端关系表快读可用但需要重新计算。 + +摘要 `summary` 字段保留兼容形状:至少包含 `versionId`、`riskLevel`、`riskScore`、`confidence`、`riskSignature`、`dirty`、`updatedAt`。前端仍可继续使用 V2.2 映射层消费。 + +## 监控 + +轻量监控只写日志: + +- 全局 `ApiTimingInterceptor` 记录超过阈值的 HTTP 请求,默认阈值 1000ms,可用 `API_SLOW_REQUEST_MS` 调整。 +- `PrismaService` 开启 query event,记录超过阈值的 SQL,默认阈值 300ms,可用 `PRISMA_SLOW_QUERY_MS` 调整。 + +这为后续接 Prometheus/Grafana 保留观测点,但 V2.3 不引入新基础设施。 + +## 测试策略 + +后端测试优先覆盖边界: + +- AppData stale version 冲突不触发同步。 +- AppData 写入成功后才触发同步。 +- 同步失败只记录日志,不影响 AppData 响应。 +- 需求同步按 product 分区作用域替换。 +- 版本详情核心表按 version 分区作用域替换。 +- 小宝快照能刷新摘要;任务/用例/BUG/计划变更能标脏摘要。 +- API timing interceptor 只记录慢请求。 +- Prisma 慢查询配置解析可测试。 +