新增笔记
This commit is contained in:
421
Project/fonrey/REVIEW/REVIEW_全局_2026-04-28.md
Normal file
421
Project/fonrey/REVIEW/REVIEW_全局_2026-04-28.md
Normal file
@@ -0,0 +1,421 @@
|
||||
# Fonrey 全局系统设计 Review 报告
|
||||
|
||||
> **Review 类型**:全量 Review(PRD + DATA_MODEL + TECH_STACK + UI/UX + TASK 交叉验证)
|
||||
> **Review 模式**:增量对比 `REVIEW_全局_2026-04-26.md`,逐条核对 4 Blocker + 12 Major 状态,识别新增风险
|
||||
> **Review 日期**:2026-04-28
|
||||
> **Reviewer**:首席系统设计 Reviewer(AI 辅助,6 路并行 explore agent 取证)
|
||||
> **当前阶段**:需求 ~90% / 数据模型 ~80% / UI 设计 ~35%(HTML 原型推进中)/ TECH 横切规范 ~70%
|
||||
> **覆盖文档**:9 份 PRD + 10 份 TECH_STACK + 9 份 DATA_MODEL(含新增 ENUMS.md v2.2)+ 3 份 UI_SYSTEM + 11 份 UI_DESIGN + TASK 总表
|
||||
> **问题分级**:🔴 Blocker(阻塞开发) / 🟠 Major(必须修复但不阻塞) / 🟡 Minor(建议优化)
|
||||
> **状态标记**:✅ 已修复 / ⚠️ 部分修复 / ❌ 未修复 / 🆕 新增
|
||||
|
||||
---
|
||||
|
||||
## 〇、执行摘要(Executive Summary)
|
||||
|
||||
### 整体评价
|
||||
|
||||
相较 2026-04-26 版本,本期文档体系出现 **5 项实质性进展**,是历次 Review 以来修复力度最大的一次:
|
||||
|
||||
1. **🟢 B-01 系统配置 PRD 落地**:`PRD/系统配置/系统配置模块PRD.md`(273 行)+ `系统配置参数数据.md`(1100 行)+ `系统配置数据模型设计说明_for_Atlas.md`(275 行)三件套已完整产出,含 US-SETTING-001-A/B/C 三条 P0 Story 与完整验收标准。MVP 范围被显式约束(明确 ❌ 标签/带看/通知/发布平台等推迟到 P1/P2),**降低实施风险**。
|
||||
2. **🟢 B-02 枚举三方不一致根除**:`DATA_MODEL/ENUMS.md` v2.2(780 行,2026-04-28)作为**唯一权威源**已建立,全量统一为 `lower_snake_case`,历史大写值(`SUCCESS`/`A_urgent`/`A_app`)的迁移规则已写明,并要求 DB CHECK / `enum_labels` / 前端三方同步。
|
||||
3. **🟢 B-03 权限档位冲突收敛**:权限 PRD §3 已显式表述"五档基线 + 各权限项可选子集(含三档场景)";DATA_MODEL_PERMISSION 的 `staff_data_scopes` 表(已建 DDL,含 3 条索引)实现"跨层级并集"模型,PRD ↔ Data ↔ Code 三方对齐。
|
||||
4. **🟢 B-04 Keyset 分页规范化**:`API_CONTRACT.md` §4 已写入 `{"mode":"keyset","cursor":"...","limit":20}` 标准合约 + 不透明游标禁令;客源/房源/楼盘/组织 4 个模块技术方案均已采用此契约。
|
||||
5. **🟢 M-01 测试规范多租户化**:`TECH_STACK.md:208` + `测试规范.md:69,146` 三处明确"必须使用 `TenantClient`,禁止 Django 原生 `Client()`",4 个模块技术方案同步引用。
|
||||
|
||||
但本期 Review 也确认 **3 类系统性债务未动**,且因其他模块详化反而更显突出:
|
||||
|
||||
- **❌ 主表乐观锁 `version` 字段** —— 全量 DATA_MODEL 0 命中,89k 房源并发编辑场景(PRD 明确双经纪人同时改房)将出现"后写覆盖前写"。
|
||||
- **❌ 高写入表 `PARTITION BY` DDL** —— `follow_logs` / `property_photos` / `permission_change_logs` / `login_attempts` / `platform_audit_logs` 全量 0 命中分区子句,仅文字"建议月度分区"。**200 万跟进日志 + 2 年保留期** 的查询性能未保障。
|
||||
- **❌ KMS / 密钥轮换 SOP** —— 仅见"`R2_ADMIN_KEY` 通过 Docker Secret 注入",无主密钥轮换流程、无应急吊销、无加密字段重新封装。
|
||||
|
||||
### 核心问题摘录(Top 10)
|
||||
|
||||
| # | 等级 | 编号 | 问题 | 维度 | 状态 |
|
||||
|---|------|------|------|------|------|
|
||||
| 1 | 🔴 | **B-05** | 主表乐观锁 `version` 字段全量 0 实现:`properties` / `clients` / `complexes` 在 PRD 多人协作场景中是核心,DDL 无并发控制 | Data↔PRD | 🆕 升 Blocker(持续 3 次未修) |
|
||||
| 2 | 🔴 | **B-06** | 高写入表分区 DDL 仍未落地(M-03 持续 3 次未修):5 张高频表无 `PARTITION BY RANGE` 子句,仅注释"建议月度分区",无法在迁移期补加分区 | Data | 🆕 升 Blocker |
|
||||
| 3 | 🟠 | **M-11** | KMS / 密钥轮换 SOP 仍未补:`core/encryption.py` 已声明,但主密钥轮换、密钥版本号、加密字段重新封装、应急吊销四类流程在 TECH_STACK 与系统管理 PRD 中均无对应章节 | 安全 | ❌ 持续未修 |
|
||||
| 4 | 🟠 | **M-12** | Celery 任务 schema 切换缺统一封装:多模块技术方案声明 `tenant_schema_name` 入参,但无 `with_tenant_context` 装饰器或基类抽象,开发期容易漏写导致跨租户脏读 | TECH/多租户 | ⚠️ 部分修复 |
|
||||
| 5 | 🟠 | **M-13** | R2 路径前缀全局规范不一致:系统管理已规范 `backups/{tenant_schema}/...` `exports/{tenant_schema}/...`,但客源/房源/楼盘模块 R2 路径仍写"`property_photos/...`"无 tenant 前缀模板 | TECH/多租户 | ⚠️ 部分修复 |
|
||||
| 6 | 🟠 | **M-06** | 客户端发布无签名校验/防降级:`/api/client/updates/latest/` 与 `download_url` 对外公开,仅 SHA256 完整性校验,可被 MITM 投递降级版本(昨日 M-06 未修) | 安全 | ❌ 持续未修 |
|
||||
| 7 | 🟠 | **M-14** | ORM Manager / QuerySet 数据范围统一封装规范缺失:`DATA_MODEL_PERMISSION.md:143-145` 的 `ScopeQueryBuilder` 只是 helper,未规定"所有业务 QuerySet 必须经过 Scope 包装"的强制约束,开发期容易漏权限校验 | 安全/Data | 🆕 新增 |
|
||||
| 8 | 🟠 | **M-05** | 89k 数据 < 2 秒列表查询 NFR 仍无 p95/EXPLAIN/性能基准测试任务(昨日 M-05 未修) | NFR↔TECH↔测试 | ❌ 持续未修 |
|
||||
| 9 | 🟠 | **M-09** | UI_SYSTEM 复杂组件(虚拟滚动列表、批量操作面板、抽屉表单嵌套规则、文件上传批量、富权限树)规范深度不足;UI_DESIGN 11 份原型仅覆盖客源 + 房源列表,**楼盘/权限/系统配置/组织人事/发布管理 5 大模块全部缺原型** | UI | ⚠️ 部分修复 |
|
||||
| 10 | 🟡 | **N-01** | ENUMS.md v2.2 已统一,但 PRD 文本中仍混用中文枚举(如客源 PRD 仍写"求购/求租"),需要一次全文档"中文枚举 → ENUMS 锚点链接"替换 | PRD↔Data | 🆕 新增 |
|
||||
|
||||
### 风险等级分布
|
||||
|
||||
| 等级 | 本次(2026-04-28) | 上次(2026-04-26) | 净变化 |
|
||||
|------|---|---|---|
|
||||
| 🔴 Blocker | **2** | 4 | -2(B-01/B-02/B-03/B-04 全部清零;B-05/B-06 由历史 Major 升级) |
|
||||
| 🟠 Major | **9** | 12 | -3(M-01 已修复关闭;M-02→B-05、M-03→B-06 升级) |
|
||||
| 🟡 Minor | **3** | 6 | -3(聚焦 Top 风险) |
|
||||
| 合计 | **14** | 22 | -8 |
|
||||
|
||||
### 增量对比一览(昨日 Blocker / Major → 今日状态)
|
||||
|
||||
| 上次编号 | 简述 | 状态 | 今日处置 |
|
||||
|----------|------|------|----------|
|
||||
| **B-01** | 系统配置 PRD 空骨架 | ✅ **已修复**(273+1100+275 行三件套) | 关闭 |
|
||||
| **B-02** | 枚举三方不一致 | ✅ **已修复**(ENUMS.md v2.2 权威源) | 关闭,遗留 N-01(PRD 文本回写) |
|
||||
| **B-03** | 权限三档/五档冲突 | ✅ **已修复**(五档基线 + 子集子句) | 关闭,遗留 M-14(ORM 强制约束) |
|
||||
| **B-04** | Keyset 分页缺失 | ✅ **已修复**(API_CONTRACT §4 + 4 模块) | 关闭 |
|
||||
| M-01 | 测试规范多租户化 | ✅ 已修复(TenantClient 强制) | 关闭 |
|
||||
| M-02 | 主表乐观锁 / 楼盘锁 | ❌ 持续未修 | **升 B-05** |
|
||||
| M-03 | 高写入表分区 | ❌ 持续未修 | **升 B-06** |
|
||||
| M-04 | Celery/R2/索引规范 | ⚠️ 部分修复(拆分) | 拆分为 M-12 / M-13 / 残留索引矩阵 |
|
||||
| M-05 | 89k 数据 < 2s NFR 测试 | ❌ 持续未修 | M-05 |
|
||||
| M-06 | 客户端发布签名 | ❌ 持续未修 | M-06 |
|
||||
| M-07~M-08 | 价格走势 / 楼盘市场报盘 | ⚠️ 降级 | 转 N-02(Minor) |
|
||||
| M-09 | UI 组件 + Wireframe | ⚠️ 部分修复 | M-09 |
|
||||
| M-10 | Redis Key tenant 前缀 | ✅ 已修复(系统设置技术方案 §6.4) | 关闭 |
|
||||
| M-11 | 加密密钥管理 | ❌ 持续未修 | M-11 |
|
||||
| M-12 | 数据保留与归档 | ⚠️ 部分修复 | 转 N-03 |
|
||||
|
||||
---
|
||||
|
||||
## 一、PRD 一致性审查(PRD ↔ PRD ↔ TASK)
|
||||
|
||||
### ✅ 历史 B-01(系统配置 PRD 空骨架)已修复
|
||||
|
||||
**证据**:
|
||||
- `PRD/系统配置/系统配置模块PRD.md`(273 行,v0.1,2026-04-27):含目标度量、非目标范围、3 条 P0 User Story(US-SETTING-001-A/B/C)与完整 Given-When-Then 验收标准。
|
||||
- `PRD/系统配置/系统配置参数数据.md`(1100 行):实际参数清单。
|
||||
- `PRD/系统配置/系统配置数据模型设计说明_for_Atlas.md`(275 行):与 DATA_MODEL_SETTING.md 对齐。
|
||||
|
||||
**剩余风险(降级为 Minor N-04)**:US-SETTING-001 的"配置变更生效时效 ≤ 5 分钟(Redis 缓存 TTL)"与 `DATA_MODEL_SETTING.md` 的 Redis Key TTL = 300s 一致,但**无 Cache Invalidation 主动失效路径**(仅靠 TTL 过期),管理员保存后 5 分钟内一线经纪人仍看不到新选项 —— PRD AC-2 "刷新后立即可见" 与实现存在间隙。
|
||||
|
||||
---
|
||||
|
||||
### ✅ 历史 B-02(核心枚举三方不一致)已修复
|
||||
|
||||
**证据**:
|
||||
- `DATA_MODEL/ENUMS.md` v2.2(780 行,2026-04-28):作为唯一权威源,覆盖 Public(tenant 生命周期、平台管理员、备份导出、升级发布)+ Tenant(客源/房源/楼盘/权限/组织/系统设置)所有枚举域。
|
||||
- 命名规范统一为 `lower_snake_case`,历史大写值(`SUCCESS`/`FAILED`/`A_urgent`/`A_app`/`B_schema`/`C_feature`/`REPLACE`/`RESTRICT`/`GRANT`)的迁移路径已书面化。
|
||||
|
||||
**剩余风险(N-01 Minor)**:PRD 文本与 TASK AC 中仍存在大量中文/旧值混用(如客源 PRD 仍写"求购/求租")。需要一次性回写:
|
||||
- 在每份 PRD 顶部加 `> 枚举值参见 DATA_MODEL/ENUMS.md` 锚点
|
||||
- 在 ENUMS.md 中给每个枚举值附"中文展示标签"列(部分已有)
|
||||
- TASK.md 排一条 P0 任务:PRD 中文枚举 → 英文锚点引用
|
||||
|
||||
---
|
||||
|
||||
### ✅ 历史 B-03(权限档位三档/五档冲突)已修复
|
||||
|
||||
**证据**:
|
||||
- `PRD/权限管理/权限管理模块PRD.md:46`:明文"采用**五档模型**:本人 / 本组 / 本门店 / 本区域 / 全公司。注意:并非所有权限项均开放五档,各项的实际可选范围以权限编辑页的下拉配置为准(例如某些权限项仅提供「本人 / 本门店 / 全公司」三个选项)"
|
||||
- `:499`:复述同一约定,闭环。
|
||||
- `DATA_MODEL_PERMISSION.md:24,31,254-275,967-987`:`staff_data_scopes` 表 DDL 完整,索引 3 条到位,"员工数据范围 = 所有 staff_data_scopes 对应 org_units.path 子树并集"实现"跨层级叠加"。
|
||||
|
||||
**剩余风险(M-14 Major)见 §五**:DATA_MODEL_PERMISSION 的 `ScopeQueryBuilder` 只是 helper class,未在 TECH_STACK 中强制规定"所有业务 QuerySet 必须经过 Scope 包装",开发期容易漏写导致越权读取。
|
||||
|
||||
---
|
||||
|
||||
### 🟡 N-01 PRD 文本回写 ENUMS 锚点(来自 B-02 残留)
|
||||
|
||||
详见上文。**责任**:PM 在 Phase 1 编码启动前完成全量 PRD 文本扫描替换。
|
||||
|
||||
---
|
||||
|
||||
## 二、TECH_STACK / API / 测试规范审查
|
||||
|
||||
### ✅ 历史 B-04(Keyset 分页缺失)已修复
|
||||
|
||||
**证据**:
|
||||
- `API_CONTRACT.md:143,154,157,182`:标准请求/响应契约 `{"mode":"keyset","cursor":"opaque_cursor","limit":20}` + `next_cursor`
|
||||
- `API_CONTRACT.md:165`:`cursor` MUST 为不透明字符串,**禁止暴露内部排序字段组合** ✅ 与 OWASP 推荐一致
|
||||
- `API_CONTRACT.md:378`:drf-spectacular `OpenApiParameter("cursor", ...)` 注解
|
||||
- 客源 / 房源 / 楼盘 / 组织 4 个模块技术方案均同步采用
|
||||
|
||||
**剩余 Minor**:尚无 Keyset SQL 模板(含 `WHERE (sort_key, id) < (?, ?)` 的复合键模板)。建议在 `TECH_STACK.md` 新增 §"分页 SQL 模板"章节,给出含 `tenant_schema` schema-search-path 切换 + 复合键的标准实现。
|
||||
|
||||
---
|
||||
|
||||
### ✅ 历史 M-01(测试规范多租户化)已修复
|
||||
|
||||
**证据**:
|
||||
- `TECH_STACK.md:203,208,211`:明确 TenantClient 强制 + R2/Redis/邮件 Mock
|
||||
- `测试规范.md:55,69,146,230`:`TenantClient` 在测试金字塔图、约束章节、请求路径、Mock 策略 4 处统一表述
|
||||
- 4 个模块技术方案均引用
|
||||
|
||||
---
|
||||
|
||||
### 🟠 M-12 Celery 多租户 schema 切换无统一封装(M-04 拆分)
|
||||
|
||||
**文档**:`TECH_STACK/客源管理技术方案.md` / `房源管理技术方案.md` / `楼盘管理技术方案.md` / `组织人事技术方案.md`(均声明 `tenant_schema_name` 入参)vs `TECH_STACK.md`(无统一规范)
|
||||
|
||||
**事实**:
|
||||
- 模块技术方案约定 Celery 任务签名带 `tenant_schema_name: str` 形参,但**无 `with_tenant_context(schema)` 装饰器或基类**。
|
||||
- 系统设置技术方案虽给出 schema 切换示例(`:28-31`),但未提取为通用规范。
|
||||
- `core/cache.py` 已规范带前缀,但 ORM 查询的 schema 切换由开发者手写 `connection.set_schema(...)`,**漏写不报错**。
|
||||
|
||||
**影响**:
|
||||
- Celery worker 在多租户调度下,相邻任务可能因 search_path 残留导致跨租户脏读/脏写。
|
||||
- 单元测试若忘记设置 schema,测试通过但生产出错。
|
||||
|
||||
**改进方向**:
|
||||
- 在 `TECH_STACK.md` 新增 §"Celery 多租户规范":
|
||||
- 强制所有业务 task 用 `@tenant_task(schema_arg="tenant_schema_name")` 装饰器
|
||||
- 装饰器职责:进入时 `set_schema_to(schema)`,退出/异常时 `set_schema_to_public()`,记录 task_id 与 schema 到结构化日志
|
||||
- 测试规范补:"Celery 任务测试必须显式 mock schema 切换断言"
|
||||
|
||||
---
|
||||
|
||||
### 🟠 M-13 R2 路径前缀全局规范不一致(M-04 拆分)
|
||||
|
||||
**文档**:`TECH_STACK/系统管理技术文档.md:521-525`(已规范)vs 客源/房源/楼盘技术方案(未规范)
|
||||
|
||||
**事实**:
|
||||
- 系统管理已统一:`backups/{tenant_schema}/{record_id}.tar.gz` / `exports/{tenant_schema}/{task_id}.zip` / `releases/system/{version}/...`(无 tenant 前缀,公共资源)✅
|
||||
- 房源 / 客源模块的图片 / 跟进附件 R2 路径**未在文档中给出 key 模板**,仅写"预签名上传"。
|
||||
- 公开发布包路径无 tenant 前缀(合理:客户端尚未登录),但**生产环境 bucket policy 需明示**:哪些 prefix 是 public-read,哪些需要 signed URL。
|
||||
|
||||
**影响**:
|
||||
- 跨租户文件越权访问风险(房源图片如果误用全局 prefix,A 租户能猜到 B 租户对象 key)。
|
||||
- 生命周期策略(如客源跟进附件 90 天清理)无 prefix 难以配置。
|
||||
|
||||
**改进方向**:
|
||||
- 在 `TECH_STACK.md` 新增"R2 路径规范"统一表:
|
||||
```
|
||||
公共资源 → releases/system/{version}/... public-read
|
||||
租户 backup → backups/{tenant_schema}/{rid}.tar.gz signed only
|
||||
租户 export → exports/{tenant_schema}/{tid}.zip signed-24h
|
||||
房源图片 → media/{tenant_schema}/property/{pid}/{photo_id}.{ext}
|
||||
跟进附件 → media/{tenant_schema}/follow/{log_id}/{idx}.{ext}
|
||||
审计归档 → exports/audit/{task_id}.csv signed only
|
||||
```
|
||||
- 路径中**禁止出现 tenant_id(UUID)**,统一用 `tenant_schema_name`,便于跨环境迁移。
|
||||
|
||||
---
|
||||
|
||||
### 🟠 M-05 89k 数据 < 2 秒列表查询 NFR 仍无性能基准(持续未修)
|
||||
|
||||
**文档**:`PRD/客源管理/客源管理模块PRD.md` US-CLIENT-002 / `PRD/房源管理/房源管理模块PRD.md` US-PROPERTY-002 NFR:列表查询 p95 < 2s(89k 数据)
|
||||
|
||||
**事实**:
|
||||
- 测试规范未含 p95 / EXPLAIN ANALYZE / pg_stat_statements 集成。
|
||||
- 无 89k 量级 seed factory(仅有单条 fixture)。
|
||||
- 无 CI 性能回归任务(如 pgTAP / pytest-benchmark)。
|
||||
- AC 中"< 2 秒"实质不可测。
|
||||
|
||||
**改进方向**:
|
||||
- 在 `测试规范.md` 增补 §"性能测试":
|
||||
- seed: `make seed-perf` 灌入 89k 房源 + 200k 客源 + 200 万 follow_logs
|
||||
- 工具: `pytest-benchmark` + `EXPLAIN (ANALYZE, BUFFERS)` 输出归档
|
||||
- 阈值: 列表 p95 < 2s / 详情 p95 < 500ms / 写入 p95 < 1s
|
||||
- CI: nightly 跑一次,回归 > 20% 标 fail
|
||||
- 优先 instrument 客源/房源列表 API(含 keyset 翻第 100 页场景)
|
||||
|
||||
---
|
||||
|
||||
## 三、DATA_MODEL 审查
|
||||
|
||||
### 🔴 B-05 主表乐观锁 `version` 字段全量未实现(M-02 升级,连续 3 次未修)
|
||||
|
||||
**文档**:`DATA_MODEL/DATA_MODEL_PROPERTY.md` / `DATA_MODEL_CLIENT.md` / `DATA_MODEL_COMPLEX.md`
|
||||
|
||||
**事实**:grep `version|乐观锁|optimistic` 在 properties / clients / complexes 主表 DDL 中 **0 命中**(`version` 仅出现在 ENUMS.md 文档版本号、`SystemVersion` 表名、Permission 缓存 key `:perm:version` 等不相关上下文中)。
|
||||
|
||||
**业务场景**(PRD 多处):
|
||||
- 房源 PRD:双经纪人同时编辑同一房源(一人改价、一人改状态)
|
||||
- 客源 PRD:录入员 + 跟进经纪人同时编辑客源等级
|
||||
- 楼盘 PRD:4 类锁字段(lock_building/lock_room/lock_info/lock_standard_room)已建,但**无 `lock_version` 触发 update conflict**
|
||||
|
||||
**影响**:后写覆盖前写、数据丢失,**89k 房源体量下必然出现**。
|
||||
|
||||
**改进方向**:
|
||||
- DDL 增加:
|
||||
```sql
|
||||
ALTER TABLE properties ADD COLUMN version INTEGER NOT NULL DEFAULT 1;
|
||||
ALTER TABLE clients ADD COLUMN version INTEGER NOT NULL DEFAULT 1;
|
||||
ALTER TABLE complexes ADD COLUMN version INTEGER NOT NULL DEFAULT 1;
|
||||
```
|
||||
- 应用层:`Model.objects.filter(id=x, version=v_old).update(..., version=F('version')+1)`,受影响行 0 → 抛 `ConflictError`,前端展示"已被他人修改,请刷新后重试"。
|
||||
- API_CONTRACT.md 增补 `If-Match: <version>` Header 规范(PUT/PATCH 必传)。
|
||||
|
||||
---
|
||||
|
||||
### 🔴 B-06 高写入表分区 DDL 仍未落地(M-03 升级,连续 3 次未修)
|
||||
|
||||
**文档**:`DATA_MODEL/DATA_MODEL_CLIENT.md`(follow_logs)/ `DATA_MODEL_PROPERTY.md`(property_photos)/ `DATA_MODEL_PERMISSION.md`(permission_change_logs)/ `DATA_MODEL_LOGIN.md`(login_attempts)/ `DATA_MODEL_PUBLIC.md`(platform_audit_logs)
|
||||
|
||||
**事实**:grep `PARTITION BY|分区表|partition` 在 DATA_MODEL 全量 0 命中。仅文字"建议月度分区"。
|
||||
|
||||
**业务体量**(PRD 与 NFR):
|
||||
- `follow_logs`:200 万 / 2 年保留期
|
||||
- `property_photos`:89k 房源 × 平均 8 张 ≈ 70 万行
|
||||
- `login_attempts`:所有登录失败/成功审计
|
||||
- `platform_audit_logs`:跨租户全平台审计
|
||||
|
||||
**影响**:单表过大导致索引膨胀、VACUUM 阻塞、按时间窗口归档不可分区操作。**编码后再切分区将停机迁移**,是必须前置的设计决策。
|
||||
|
||||
**改进方向**:
|
||||
- DDL 改为:
|
||||
```sql
|
||||
CREATE TABLE follow_logs (
|
||||
id BIGSERIAL,
|
||||
created_at TIMESTAMPTZ NOT NULL,
|
||||
...
|
||||
PRIMARY KEY (id, created_at) -- 分区键必须含 created_at
|
||||
) PARTITION BY RANGE (created_at);
|
||||
|
||||
CREATE TABLE follow_logs_2026_04 PARTITION OF follow_logs
|
||||
FOR VALUES FROM ('2026-04-01') TO ('2026-05-01');
|
||||
```
|
||||
- 增补 Celery 周期任务 `partition_maintenance_task`(每月最后一天):自动建下月分区 + drop 超出保留期分区。
|
||||
- DATA_MODEL.md 增 §"分区策略"统一表(保留期 / 分区粒度 / 维护任务)。
|
||||
|
||||
---
|
||||
|
||||
### 🟠 M-14 ORM 数据范围统一封装规范缺失(B-03 残留)
|
||||
|
||||
**文档**:`DATA_MODEL/DATA_MODEL_PERMISSION.md:143-145, 414-455`
|
||||
|
||||
**事实**:
|
||||
- `ScopeQueryBuilder` 已实现(含 `is_protected` 二次 AND 规则)。
|
||||
- 但**未在 TECH_STACK 中强制要求"所有业务 QuerySet 必须经过 ScopeQueryBuilder"**。
|
||||
- 模块技术方案 view 层示例代码直接 `Property.objects.filter(...)`,可绕过权限控制。
|
||||
|
||||
**影响**:开发新功能时漏接 ScopeQueryBuilder → 越权读取,且测试不易发现。
|
||||
|
||||
**改进方向**:
|
||||
- TECH_STACK 增补"ORM 数据范围强制规范":
|
||||
- 业务 Model 不暴露默认 `objects` Manager,统一暴露 `scoped(staff)` 入口
|
||||
- 写一个 lint rule(pylint plugin / pre-commit):禁止业务模块直接调用 `<Model>.objects.<query>`
|
||||
- 测试规范补"权限边界测试矩阵":每个 Model 至少 3 case(own / department / cross_department denied)
|
||||
|
||||
---
|
||||
|
||||
### 🟡 N-02 楼盘价格走势 / 市场报盘(M-07/M-08 降级)
|
||||
|
||||
历史 M-07/M-08 已写明"P2 不做",本期降为 Minor。
|
||||
|
||||
---
|
||||
|
||||
### 🟡 N-03 数据保留与归档策略(M-12 降级)
|
||||
|
||||
`platform_audit_logs` / `follow_logs` 在 PRD 中提到"2 年保留",但 DATA_MODEL 无对应 Celery 归档任务定义。建议在 B-06 分区落地后顺带补全 archive job。
|
||||
|
||||
---
|
||||
|
||||
## 四、安全审查(含多租户 / 权限 / 审计)
|
||||
|
||||
### 🟠 M-06 客户端发布无签名校验 / 防降级(持续未修)
|
||||
|
||||
**文档**:`PRD/发布管理/客户端发布管理模块PRD.md:165,198,284,347` / `TECH_STACK.md:119`
|
||||
|
||||
**事实**:
|
||||
- 端点 `GET /api/client/updates/latest/` 公开(合理)。
|
||||
- `download_url` 走 R2 / CDN 公开(合理)。
|
||||
- 完整性校验仅 SHA256(仅防偶然篡改,不防 MITM 主动替换)。
|
||||
- **无代码签名(Authenticode / OS-level codesign)**、**无服务端响应签名**、**无版本号单调递增校验(防降级)**。
|
||||
|
||||
**改进方向**:
|
||||
- 升级响应 JSON 增加 `signature` 字段(HMAC-SHA256,密钥服务端持有),客户端校验签名后再 fetch download_url。
|
||||
- `electron-updater` 配合 `publisherName`(Windows Authenticode),在 CI 用代码签名证书签 EXE。
|
||||
- 客户端本地存"已安装版本 N",若服务端返回版本 < N,**拒绝降级**(除非配置允许 force_downgrade=true 由后端控制)。
|
||||
|
||||
---
|
||||
|
||||
### 🟠 M-11 加密密钥管理 / 轮换 SOP 仍未补(持续未修)
|
||||
|
||||
**文档**:`TECH_STACK/系统管理技术文档.md:877`(仅"密钥通过 Docker Secret 注入"一句)
|
||||
|
||||
**事实**:
|
||||
- `core/encryption.py` 中央加密 helper 已声明(散见模块技术方案)。
|
||||
- **缺**:主密钥(KEK)轮换流程、字段加密密钥(DEK)版本号设计、密钥泄露应急吊销 + 全量字段重新封装、生产-staging 密钥隔离。
|
||||
|
||||
**改进方向**:
|
||||
- 在 `TECH_STACK.md` 新增 §"密钥管理 SOP":
|
||||
- 三层结构:环境主密钥(KMS / sops + age) → 应用 KEK(启动时加载) → 字段 DEK(per-row 或 per-column)
|
||||
- DDL 加密字段必须含 `key_version SMALLINT NOT NULL`
|
||||
- 季度轮换 + 异常吊销 runbook
|
||||
- 短期(无 KMS)方案:`age` + `sops` 加密 secrets 文件,运维流程文档化。
|
||||
|
||||
---
|
||||
|
||||
### 🟠 M-14 ORM 数据范围(详见 §三)
|
||||
|
||||
---
|
||||
|
||||
## 五、UI/UX 审查
|
||||
|
||||
### 🟠 M-09 UI 设计覆盖率与复杂组件深度(部分修复)
|
||||
|
||||
**文档**:`UI_DESIGN/`(11 份 markdown + 11 份 HTML 原型 + `UI_设计任务总表.md`)/ `UI_SYSTEM/`(3 份)
|
||||
|
||||
**事实**:
|
||||
- ✅ 已覆盖:客源列表 / 客源详情 / 客源新增 / 客源编辑 / 房源列表 5 类原型(HTML + Markdown 双版本)。
|
||||
- ❌ 仍缺:
|
||||
- 楼盘管理(详情 / 新增 / 锁字段交互)
|
||||
- 权限管理(权限树 / 数据范围编辑器 / 五档下拉子集)
|
||||
- 系统配置(lookup_items 编辑抽屉 / 必填规则配置)
|
||||
- 组织人事(org tree / 员工卡)
|
||||
- 发布管理(升级表单 / 灰度名单 / 进度面板)
|
||||
- ❌ UI_SYSTEM 复杂组件规范深度仍不足:虚拟滚动列表(89k 房源必需)、批量操作面板、抽屉表单嵌套规则、文件上传批量、富权限树。
|
||||
|
||||
**改进方向**:
|
||||
- 把 UI_DESIGN 11 份 task 按 PRD 优先级排进 Phase 1:客源(已齐)→ 房源详情 → 楼盘 → 权限 → 系统配置;
|
||||
- UI_SYSTEM 增补"复杂组件清单"5 项,每项给出 Alpine.js + HTMX 实现范本;
|
||||
- 89k 房源列表必须用虚拟滚动或固定窗口(如 PageDown 分页),HTMX 按 keyset cursor 局部刷新。
|
||||
|
||||
---
|
||||
|
||||
## 六、TASK ↔ 文档交叉验证
|
||||
|
||||
### 🟡 N-04 系统配置 Cache Invalidation(B-01 残留)
|
||||
|
||||
详见 §一。
|
||||
|
||||
---
|
||||
|
||||
## 七、汇总 Action Items
|
||||
|
||||
| # | 等级 | 编号 | Action | 责任 | 建议完成时间 | 编码门禁 |
|
||||
|---|------|------|--------|------|--------------|----------|
|
||||
| 1 | 🔴 | B-05 | 主表 `version` 字段 + `If-Match` API 规范 | 架构师 + 后端 Lead | T+3 天 | **Phase 1 启动前** |
|
||||
| 2 | 🔴 | B-06 | 5 张高写入表 `PARTITION BY RANGE` DDL + 分区维护 Celery 任务 | 架构师 + DBA | T+5 天 | **Phase 1 启动前** |
|
||||
| 3 | 🟠 | M-05 | 性能基准测试方案(seed 89k + pytest-benchmark + p95 阈值) | 测试 Lead | T+7 天 | Phase 1 内 |
|
||||
| 4 | 🟠 | M-06 | 客户端发布签名 + 防降级(HMAC + Authenticode) | 安全 + 发布运维 | T+10 天 | 客户端发布 GA 前 |
|
||||
| 5 | 🟠 | M-09 | 楼盘 / 权限 / 系统配置 / 组织人事 / 发布 5 模块原型 + 5 复杂组件规范 | UX + 前端 Lead | T+14 天 | 各模块编码前 |
|
||||
| 6 | 🟠 | M-11 | 密钥管理 SOP(KEK/DEK/版本/轮换/吊销) | 安全 + 运维 | T+10 天 | 加密字段上线前 |
|
||||
| 7 | 🟠 | M-12 | `@tenant_task` 装饰器 + Celery 多租户规范文档 | 架构师 | T+5 天 | Celery 任务编码前 |
|
||||
| 8 | 🟠 | M-13 | R2 路径前缀统一规范表 + bucket policy | 架构师 + 运维 | T+5 天 | R2 上传任务编码前 |
|
||||
| 9 | 🟠 | M-14 | ORM 数据范围强制 lint + `scoped(staff)` 入口 | 架构师 + 后端 Lead | T+7 天 | Phase 1 内 |
|
||||
| 10 | 🟡 | N-01 | PRD 文本中文枚举 → ENUMS 锚点全量替换 | PM | T+3 天 | 编码前清零 |
|
||||
| 11 | 🟡 | N-04 | 系统配置 Cache Invalidation 主动失效路径补充 | 后端 Lead | T+5 天 | US-SETTING-001 编码前 |
|
||||
| 12 | 🟡 | N-02/N-03 | 楼盘走势/数据归档策略 | PM + DBA | Phase 2 | 非阻塞 |
|
||||
|
||||
---
|
||||
|
||||
## 八、Review 结论
|
||||
|
||||
### 编码门禁(Phase 1 启动前必清零)
|
||||
|
||||
**🔴 Blocker(2 项必修)**:
|
||||
1. **B-05** 主表 `version` 乐观锁字段 —— 涉及 properties / clients / complexes DDL + API_CONTRACT 增补 `If-Match` Header
|
||||
2. **B-06** 5 张高写入表分区 DDL + 分区维护任务 —— 后期切分需停机,必须前置
|
||||
|
||||
### 整体判断
|
||||
|
||||
- **本期是历次 Review 进展最大的一次**:4 个 Blocker 全部清零,1 个 Major(M-01)已修复,文档体系(特别是 PRD ↔ ENUMS ↔ DATA_MODEL)建立了真正的"权威源"。
|
||||
- **剩余 Blocker 集中在 DATA_MODEL 物理设计层面**(并发控制 + 分区),属于"知道但没动"的债务,**修复成本可估、风险可控**,建议本周内打磨完毕。
|
||||
- **Phase 1 编码可在 B-05 / B-06 修复后立即启动**,其余 9 个 Major 可与编码并行推进,但需在对应模块进入开发前清零(参见上表"编码门禁"列)。
|
||||
- **下一次 Review 焦点**:B-05 / B-06 修复后,应重点审查 M-09(UI 覆盖率)+ M-05(性能基准),以及编码启动后第一波集成测试反馈。
|
||||
|
||||
### 文档健康度趋势
|
||||
|
||||
| 维度 | 04-25 | 04-26 | 04-28 | 趋势 |
|
||||
|------|-------|-------|-------|------|
|
||||
| PRD 完整性 | 60% | 75% | **90%** | ↑↑ |
|
||||
| DATA_MODEL 严谨性 | 50% | 65% | **80%** | ↑↑ |
|
||||
| TECH_STACK 横切规范 | 30% | 50% | **70%** | ↑ |
|
||||
| 测试规范多租户化 | 20% | 40% | **85%** | ↑↑↑ |
|
||||
| UI/UX 覆盖率 | 5% | 30% | **35%** | ↑(最弱环节) |
|
||||
| 安全设计 | 40% | 45% | **55%** | ↑(M-06/M-11 持续债务) |
|
||||
|
||||
---
|
||||
|
||||
> **Reviewer 签字**:首席系统设计 Reviewer(AI 辅助)
|
||||
> **下次 Review 建议触发条件**:B-05 + B-06 完成 PR 合并后,或 Phase 1 编码启动后第 1 个 Sprint 结束。
|
||||
Reference in New Issue
Block a user