feat(v2.2): 建立分区关系表和AppData迁移预演

This commit is contained in:
Script Generator
2026-07-03 10:23:18 +08:00
parent 0d9e6fee29
commit 5a90923031
16 changed files with 2440 additions and 8 deletions

View File

@@ -220,3 +220,26 @@ Managers with `xiaobao.warning:manage` can see all unfinished versions. Non-mana
AI explains rule results only. It writes interpretation cache to `xiaobao-risk-insights` and never mutates Version, Requirement, DevTask, TestCase, Bug, or Member data. Risk snapshots are saved to `xiaobao-risk-snapshots` when the page is opened. The first version uses page-triggered analysis rather than a background scheduled Agent.
Per-user warning read state is saved to `xiaobao-warning-views`. The read marker stores `userId + versionId + risk signature`, so the sidebar can turn the Xiaobao badge blue when any visible risk has a completed unread update, then return to the red risk-count badge after the user opens every updated warning. AI interpretation that is still generating only shows the "updating" notice and must not produce the blue update badge yet.
## V2.2 Partitioned Domain Data Layer (2026-07-03)
V2.2 starts the move from AppData JSON documents to relation tables for high-volume domains. The first database foundation is partitioned from the start so future growth does not require a disruptive rewrite of primary keys, unique constraints, and foreign-key references.
High-growth business tables use fixed hash partitions:
- `requirements`: hash partitioned by `product_id`; primary key is `(id, product_id)`.
- `dev_tasks`, `test_cases`, and `bugs`: hash partitioned by `version_id`; primary key is `(id, version_id)`.
Append-only evidence and history tables use range partitions by `created_at`:
- `work_activities`
- `task_worklogs`
- `overtime_records`
- `xiaobao_risk_snapshots`
- `xiaobao_risk_insights`
- `ai_logs`
Partitioned tables must include the partition key in every primary key and business unique constraint. Cross-table references to partitioned tables use composite foreign keys when the referencing row naturally carries the partition key, for example `(requirement_id, requirement_product_id)` and `(test_case_id, test_case_version_id)`. Polymorphic activity references remain logical references.
Xiaobao uses two storage shapes: `xiaobao_risk_summaries` keeps one current row per version for fast reads, while `xiaobao_risk_snapshots` stores append-only history for trend analysis.
The AppData migration path is staged through a pure mapper plus preview service. `AppDataV22MigrationService.preview()` reads the allowed `app_data` keys, maps legacy JSON into partition-key-ready rows, and reports row counts plus skipped records before any insert path is enabled.

View File

@@ -516,3 +516,16 @@
- 人工新建任务表单继续使用任务类型字典作为可选项,但这个字典会随着 AI 草案采纳自动扩展。
**理由**:人工表单的任务类型是录入辅助,不应该成为 AI 拆解边界。但任务类型字典也不能被单个原型的业务对象污染。`taskTypeName` 只承载可复用分类,具体功能点放在 `title``description`;采纳时有门槛地补字典,让后续筛选、统计和人工创建复用真正稳定的类型,同时避免 AI 直接写数据库 `categoryId`
## 42. V2.2 高增长业务表从一开始采用分区表
**问题**需求池、开发任务、测试用例、BUG、工作活动和小宝快照会按年持续增长。若先用普通表后续再切分区表不只是搬旧数据还会牵动主键、唯一约束、外键、迁移窗口和回滚方案。
**决策**
- `requirements``product_id` 做固定 HASH 分区,主键为 `(id, product_id)`
- `dev_tasks` / `test_cases` / `bugs``version_id` 做固定 HASH 分区,主键为 `(id, version_id)`
- `work_activities` / `task_worklogs` / `overtime_records` / `xiaobao_risk_snapshots` / `xiaobao_risk_insights` / `ai_logs``created_at` 做 RANGE 分区并保留 default partition。
- 所有分区表主键和业务唯一约束必须包含分区键,例如 `(version_id, code)`
- 引用分区表时优先使用复合外键,例如 `(requirement_id, requirement_product_id)``(test_case_id, test_case_version_id)`;多态活动记录使用逻辑外键。
- `xiaobao_risk_summaries` 不分区,保持 `version_id` 单行汇总;历史趋势进入分区快照表。
**理由**:把分区键纳入主键和唯一约束是 PostgreSQL 分区表的结构性要求。提前做这件事,可以避免客户数据变大后再重塑主键和外键。固定 HASH 分区避免每个项目/版本单独建分区的维护负担RANGE 分区只用于天然追加、按时间维护的历史数据。

View File

@@ -6,6 +6,13 @@
### 已完成(按时间倒序)
**2026-07-03**
- V2.2 partitioned domain schema foundation added: `requirements` uses HASH partitioning by `product_id`; `dev_tasks`, `test_cases`, and `bugs` use HASH partitioning by `version_id`.
- Partitioned table primary keys and business unique constraints now include partition keys, for example `(id, version_id)` and `(version_id, code)`.
- Xiaobao precompute storage foundation added: `xiaobao_risk_summaries` stores the current version risk, and `xiaobao_risk_snapshots` stores historical snapshots.
- Prisma schema now includes the V2.2 relational model skeleton, and the legacy `RequirementService` now uses the `(id, product_id)` composite key.
- AppData V2.2 migration mapper and preview service added, so legacy JSON can be rehearsed into relation-table rows with counts and skipped-record diagnostics before inserts are enabled.
**2026-07-02**
- `app_data` 读写增加乐观锁版本:`GET` 返回 `version`,前端保存携带最近版本,后端用 `key + updatedAt` 原子更新
- stale version / create race 返回 `409 APP_DATA_CONFLICT`,阻止多人同时编辑时的静默覆盖