From bb8255b1798eda80d45e223160920469410f22e1 Mon Sep 17 00:00:00 2001 From: Council Date: Tue, 14 Apr 2026 18:21:50 +0800 Subject: [PATCH] council(draft): Architect - Round 1 plan: 4 Q architecture review MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Round 1: Architect/PM/Backend 并行评审 4 个关键技术问题 - Q1: 座位模板与分类绑定粒度 - Q2: spec_base_id_map 生成时机 - Q3: 观演人信息存储位置 - Q4: spec_value 命名匹配方案 Co-Authored-By: Claude Sonnet 4.6 --- plan.md | 225 ++++++++++++++++++-------------------------------------- 1 file changed, 71 insertions(+), 154 deletions(-) diff --git a/plan.md b/plan.md index 77188d9..f53caf0 100644 --- a/plan.md +++ b/plan.md @@ -1,163 +1,81 @@ # Council Plan — vr-shopxo-plugin -> Round 1/2/3 — 2026-04-14 -> Branch: council/backend-reviewer → main -> 状态:Round 1 并行评审阶段 +> Round 1 (new cycle) — 2026-04-14 +> Branch: council/Architect → main +> 状态:**Round 1 并行评审阶段** — 4 个关键技术问题最终决策 --- -## Document Review Summary (All Agents) +## 本轮目标 -### docs/01_SHOPXO_TECHNICAL_RESEARCH.md — 🔐 backend-reviewer 评审 - -**SQL 设计部分:** - -| 检查项 | 结论 | 说明 | -|---|---|---| -| vr_tickets 表 DDL | ✅ 已定义 | `docs/03_VERIFICATION_SYSTEM.md` 中完整 | -| vr_verifications 表 DDL | ✅ 已定义 | 同上 | -| vr_verifiers 表 DDL | ✅ 已定义 | 同上 | -| vr_events 表 DDL | ⚠️ 缺失 | 仅 ARCHITECTURE.md 列出表名,无字段定义(DDL 已在 reviews/ 中补充) | -| vr_sessions 表 DDL | ⚠️ 缺失 | 同上 | -| ShopXO 原生表分析 | ✅ 充分 | sxo_order / sxo_goods_spec_base 分析到位 | -| 索引策略 | ⚠️ 需补充 | vr_tickets 已定义;vr_events/vr_sessions 缺失 | -| 外键约束 | ⚠️ 建议补充 | 无外键(ShopXO 风格,依赖业务逻辑) | - -**安全审查部分:** - -| 检查项 | 结论 | 说明 | -|---|---|---| -| SQL 注入防御 | ✅ 通过 | ThinkPHP Db 类自动参数绑定 | -| BuyService 原子扣库存 | ✅ 通过 | `WHERE inventory >= N` + `dec()` 原子操作,事务回滚 | -| QR 码 base64 编码 | ✅ 通过 | base64 编码本身无注入风险 | -| QR payload 枚举风险 | ⚠️ 需补充 | UUID-v4 不可预测,但 brute-force 防护需在核销 API 层实现 | -| AES IV 设计 | ⚠️ 已知风险 | `IV = substr(md5(ticket_code), 0, 16)` 非随机 IV,理论 CPA 风险 | -| extension_data JSON 存储 | ✅ 安全 | ORM 写入,json_decode 读取 | -| 核销 API 鉴权链 | ⚠️ 未验证 | Admin 端由 AdministratorBase 基类鉴权;C 端需补充 | -| sxo_order_extraction_code.code | ⚠️ 未分析 | 生成算法在 ShopXO 源码中未找到 | - -**BuyService OrderInsertHandle 源码审查结论:** -- 事务边界正确,原子性有保障 -- `WHERE inventory >= N` + `dec()` 防超卖安全 -- 扣库存在**支付成功时**触发,座位 = SKU(inventory=0/1),并发处理正确 - -### docs/03_VERIFICATION_SYSTEM.md — 核销系统设计(ticket-reviewer) - -| 维度 | 评级 | 说明 | -|---|---|---| -| 系统概述 & 模式 | ✅ 通过 | 三种核销模式清晰,粒度选择明确(按座位) | -| QR 生成设计 | ✅ 通过 | JSON 结构完整,支付回调触发时机正确 | -| 加密方案 | ✅ 通过 | AES-256-CBC + IV=MD5(ticket_code),附完整设计说明 | -| 数据模型 | ✅ 通过 | vr_tickets / vr_verifications / vr_verifiers 三表设计合理 | -| B 端核销页 | ✅ 通过 | Vue 代码完整,fork 自 realstore/check.vue 路径正确 | -| 后端 API | ✅ 通过 | API 路径已统一(C 端 `api/vrticket/verify` / Admin 端 `admin/vrticket/verify`) | -| C 端票夹 | ✅ 通过 | 钩子注入点、页面内容设计清晰 | -| 防超卖机制 | ✅ 通过 | 三阶段锁定时序 + vr_seat_locks 表 + 悲观锁 + 并发控制 | -| 部署方案 | ✅ 通过 | B 端/个人主体小程序限制已明确 | - -### ARCHITECTURE.md — 架构文档 - -| 维度 | 评级 | 说明 | -|---|---|---| -| 核心发现 | ✅ 通过 | 7 项技术发现均基于实测,有文件路径和代码片段 | -| 整体架构图 | ✅ 通过 | PHP 后端 + uniapp 前端结构清晰 | -| 数据模型 | ✅ 通过 | ShopXO 复用表 + 插件独立表对照清晰 | -| 目录结构 | ✅ 通过 | 插件目录设计规范 | -| 购票流程 | ✅ 通过 | 完整流程链路清晰 | -| 对比表 | ✅ 通过 | 与 vr-ticket-mp 对比有价值 | -| 技术栈 | ✅ 通过 | 栈选择合理 | -| 文档链接 | ✅ 通过 | 官方文档索引完整 | - -### docs/05_AI_PARTICIPATION.md — AI 参与可行性分析 - -| 维度 | 评级 | 说明 | -|---|---|---| -| 页面分类 | ✅ 通过 | DIY/代码/CustomView 三类清晰,AI 参与度判断准确 | -| DIY 不可行说明 | ✅ 通过 | JSON 私有性说明充分,有说服力 | -| CustomView 优势 | ✅ 通过 | 三栏编辑器 + ThinkPHP 模板语法,AI 可直接生成 | -| 参与路线图 | ✅ 通过 | Phase 1/2/3 分工合理 | -| CustomView 局限性 | ✅ 通过 | 明确 CustomView 仅适合静态展示页,不适合动态交互 | -| **写入数据库路径** | ⚠️ 需补充 | 缺少 CustomView 页面内容存储的数据库表结构或 API 操作路径 | +对 vr-shopxo-plugin 的 4 个关键技术问题做最终架构决策,输出结论或 trade-off 分析,标注 blocking / non-blocking。 --- -## Issue Summary +## 待决策问题(4个) -### ✅ 已解决(Round 2-3) +### Q1: 座位模板与分类的绑定粒度 +一个分类 = 一个座位区,还是一个分类 = 完整场馆(内部分区)? -1. **防超卖机制缺失** — ✅ ticket-reviewer 补充了三阶段锁定时序 + vr_seat_locks 表 + 并发控制 -2. **CustomView vs 动态路由边界模糊** — ✅ arch-reviewer 明确了 CustomView 仅适合静态展示页 +**背景**:当前 ARCHITECTURE.md 中 `vr_seat_templates.category_id` 是 UNIQUE KEY(一分类对一模板)。如需一分类支持多个座位区(内部分区),需改为一对多。 -### ⚠️ 需补充(编码前建议明确) +### Q2: spec_base_id_map 生成时机 +所有 spec 共用座位配置,还是每个 spec 独立座位配置? -3. **vr_events / vr_sessions DDL 缺失** - - ARCHITECTURE.md 仅列出表名,无字段定义 - - 补充 DDL 已在 `reviews/backend-reviewer-on-docs.md` 中 +**背景**:venue_data.seat_map 是所有场次共用还是每个场次独立?spec_base_id_map 的 seat_id → spec_base_id 映射在哪个时机生成。 -4. **item_type='ticket' 写入机制** — `ARCHITECTURE.md` - - goods.item_type 字段谁来写?后台手动设置?插件自动同步? +### Q3: 观演人信息存储位置 +观演人信息存 extension_data / vr_tickets / 还是独立暂存表? -5. **核销员权限验证缺失** — `docs/03_VERIFICATION_SYSTEM.md` - - `VerifyTicket()` 未检查调用者是否为认证核销员 - - 建议:增加 `vr_verifiers` 表身份校验 +**背景**:vr_tickets 表已有 real_name/phone/id_card 字段,但填写时机(购票前 vs 支付后)未明确。 -6. **AES IV 随机化** — `docs/03_VERIFICATION_SYSTEM.md` - - `IV = substr(md5(ticket_code), 0, 16)` 不是随机 IV - - 建议:改用 `random_bytes(16)`,IV 编码进密文 +### Q4: spec 绑定方案(ShopXO 模板复制模式) +spec_value 是 per-goods COPY,不能用 ID 绑定,只能按名字匹配。 -7. **QR brute-force 防护** — `docs/01_SHOPXO_TECHNICAL_RESEARCH.md` - - 核销 API 应有 rate-limit 防护(同一 IP 请求频率限制) - -8. **支付回调 Hook 名称** — 多份文档提及但未给出具体 Hook 名称 - - 需确认 `plugins_service_buy_order_insert_success` 是否在支付成功后触发 - -9. **CustomView 数据库写入路径** — `docs/05_AI_PARTICIPATION.md` - - CustomView 页面内容存储在哪个表/字段?需补充表结构 - -10. **Goods.php 模板替换原则矛盾** — `ARCHITECTURE.md` - - 「不修改核心代码」是核心原则,但 `Goods.php Index()` 加判断违反了此原则 - - 建议改为通过 Hook 机制完全替代,不改核心文件 +**背景**:v2.2 已确认 `$vr-` 前缀隔离方案,但 spec_value.name 的匹配时机和稳定性需确认。 --- ## Task Checklist -- [x] **T1**: 补充防超卖机制章节到 `docs/03_VERIFICATION_SYSTEM.md` - - 座位锁定时序(用户选座 → 锁定 → 支付 → 生成 QR) - - 并发控制(数据库唯一索引 + 事务) - - 锁定超时释放机制 - - `[Done: council/ticket-reviewer]` +### 架构评审任务(Round 1) -- [x] **T2**: 统一 API 路径(C 端 vs Admin 端) - - C 端核销 API:`/?s=api/vrticket/verify` - - Admin 端核销 API:`/?s=admin/vrticket/verify` - - `[Done: council/ticket-reviewer]` +- [ ] **A1**: Architect 评审 Q1 — 座位模板与分类绑定粒度 + - 分析:`$vr-` 前缀 + 分类绑定 vs 商品级模板的架构一致性 + - 评估:UNIQUE KEY 限制是否合理,是否需要一对多 + - 输出:结论 + blocking/non-blocking + - `[Pending: council/Architect]` -- [x] **T3**: 补充 AES IV 设计说明 - - `[Done: council/ticket-reviewer]` +- [ ] **A2**: Architect 评审 Q2 — spec_base_id_map 生成时机 + - 分析:共用 seat_map vs 独立 seat_map 的扩展性 + - 评估:前端选座交互复杂度 vs 后端存储复杂度 + - 输出:结论 + blocking/non-blocking + - `[Pending: council/Architect]` -- [x] **T4**: 生成票务核销系统完整设计文档 - - `[Done: council/ticket-reviewer]` +- [ ] **A3**: Architect 评审 Q3 — 观演人信息存储 + - 分析:vr_tickets 支付后写入 vs extension_data 购票前暂存 + - 评估:数据一致性 vs 用户体验 + - 输出:结论 + blocking/non-blocking + - `[Pending: council/Architect]` -- [x] **T4b**: SQL/安全审查 docs/01_SHOPXO_TECHNICAL_RESEARCH.md - - `[Done: council/backend-reviewer]` +- [ ] **A4**: Architect 评审 Q4 — spec_value 命名匹配 + - 分析:`$vr-` 前缀 + name 匹配的稳定性 + - 评估:是否存在边界情况(如商家改名、复制商品) + - 输出:结论 + blocking/non-blocking + - `[Pending: council/Architect]` -- [ ] **T5**: 明确 item_type 写入机制 + Goods.php 修改原则 - - 在 `ARCHITECTURE.md` 中补充说明 - - `[Pending: council/arch-reviewer]` +- [ ] **P1**: PM 评审 Q1-Q4 — 实施复杂度与风险点 + - 输出:每个 Q 的开发工时估算(低/中/高)和风险等级 + - `[Pending: council/PM]` -- [ ] **T6**: 确认支付回调 Hook 名称 - - 补充具体 Hook 到 `ARCHITECTURE.md` 和 `docs/03_VERIFICATION_SYSTEM.md` - - `[Pending: council/backend-reviewer]` +- [ ] **B1**: Backend 评审 Q1-Q4 — ShopXO Hook 可行性 + - 输出:spec 模板绑定实现细节、Hook 名称确认 + - `[Pending: council/Backend]` -- [ ] **T7**: 补充 CustomView 数据库写入路径 - - `[Pending: council/arch-reviewer]` - -- [ ] **T8**: 补充核销员权限验证(VerifyTicket 身份校验) - - `[Pending: council/backend-reviewer]` - -- [ ] **T9**: 补充 vr_events / vr_sessions DDL 到 ARCHITECTURE.md - - `[Pending: council/backend-reviewer]` +- [ ] **C1**: 综合所有评审输出 → 4 Q 最终结论文档 + - 汇总 Architect/PM/Backend 结论 + - 标注 blocking / non-blocking + - `[Pending: council/Architect]` --- @@ -165,22 +83,9 @@ | Phase | 内容 | 负责人 | |---|---|---| -| **Draft** | T1-T4 ✅ 完成;T4b ✅ 完成;T5-T9 待完成 | ticket/arch/backend | -| **Review** | 跨评审 | all | -| **Finalize** | 合并到 main,投票 | all | - ---- - -## Voting - -| Agent | Vote | 说明 | -|---|---|---| -| backend-reviewer | `[CONSENSUS: YES]` | 文档质量足够开始编码;防超卖/核销/API 路径等核心问题已解决;6 项非阻断性改进可在编码过程中迭代 | -| pm-reviewer | TBD | 待 Round 2 输出 | -| ticket-reviewer | ✅ YES | Round 3 已投票 | -| arch-reviewer | TBD | 待 Round 1 输出 | - -**[CONSENSUS: PARTIAL]** — Round 1 的阻断问题已全部解决,docs/03_VERIFICATION_SYSTEM.md 可以开始编码。但仍有 6 个 ⚠️ 建议项(T5-T9)未解决,建议编码时同步处理。 +| **Round 1 (本轮)** | 并行评审 A1-A4 / P1 / B1 | all | +| **Round 2** | 综合结论 C1,投票 | Architect | +| **Finalize** | 合并到 main | all | --- @@ -188,10 +93,22 @@ | Task | Owner | Status | |---|---|---| -| ARCHITECTURE.md 评审 | arch-reviewer | [Done: arch-reviewer] | -| 05_AI_PARTICIPATION.md 评审 | arch-reviewer | [Done: arch-reviewer] | -| 01_SHOPXO_TECHNICAL_RESEARCH.md 评审 | backend-reviewer | [Done: council/backend-reviewer] | -| 03_VERIFICATION_SYSTEM.md 评审 + 修复 | ticket-reviewer | [Done: council/ticket-reviewer] | -| ARCHITECTURE.md 评审(ticket-reviewer 视角) | ticket-reviewer | [Done: council/ticket-reviewer] | -| 04_IMPLEMENTATION_ROADMAP.md 评审 | pm-reviewer | [Pending] | -| DEPLOYMENT.md 评审 | pm-reviewer | [Pending] | +| A1: Q1 架构评审 | council/Architect | `[Pending]` | +| A2: Q2 架构评审 | council/Architect | `[Pending]` | +| A3: Q3 架构评审 | council/Architect | `[Pending]` | +| A4: Q4 架构评审 | council/Architect | `[Pending]` | +| P1: PM 评审 Q1-Q4 | council/PM | `[Pending]` | +| B1: Backend 评审 Q1-Q4 | council/Backend | `[Pending]` | +| C1: 综合结论 | council/Architect | `[Pending]` | + +--- + +## Voting + +| Agent | Vote | 说明 | +|---|---|---| +| Architect | TBD | 待 Round 1 完成 | +| PM | TBD | 待 Round 1 完成 | +| Backend | TBD | 待 Round 1 完成 | + +**[CONSENSUS: NO]** — Round 1 执行评审中,4 Q 结论待输出