feat(v2.2): 建立分区关系表和AppData迁移预演
This commit is contained in:
@@ -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.
|
||||
|
||||
@@ -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 分区只用于天然追加、按时间维护的历史数据。
|
||||
|
||||
@@ -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`,阻止多人同时编辑时的静默覆盖
|
||||
|
||||
Reference in New Issue
Block a user