council(draft): Backend - Round 1 plan: 4 Q&A Hook/spec 评审

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
refactor/vr-ticket-20260416
Council 2026-04-14 18:21:06 +08:00
parent bde23d3195
commit 0046f14283
1 changed files with 67 additions and 161 deletions

228
plan.md
View File

@ -1,163 +1,63 @@
# Council Plan — vr-shopxo-plugin # Council Plan — vr-shopxo-plugin Round 1 (Backend)
> Round 1/2/3 — 2026-04-14 > Round 1 — 2026-04-14
> Branch: council/backend-reviewer → main > Branch: council/Backend → main
> 状态Round 1 并行评审阶段 > 角色: ⚙️ Backend — Hook 可行性与 spec 模板绑定实现评审
--- ---
## Document Review Summary (All Agents) ## Task Overview
### docs/01_SHOPXO_TECHNICAL_RESEARCH.md — 🔐 backend-reviewer 评审 对 vr-shopxo-plugin 架构的 4 个关键技术问题做最终决策Backend 视角):
- **Q1**: 座位模板与分类的绑定粒度
**SQL 设计部分:** - **Q2**: spec_base_id_map 生成时机
- **Q3**: 观演人信息存储位置
| 检查项 | 结论 | 说明 | - **Q4**: spec 绑定方案($vr- 前缀命名空间)
|---|---|---|
| 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 操作路径 |
--- ---
## Issue Summary ## Backend 评审要点
### ✅ 已解决Round 2-3 ### Q1 — 座位模板绑定粒度
- `$vr-场馆` spec_value.name → vr_seat_templates.name 的 name 匹配方案
- Hook 注入点:在商品详情加载时匹配,无需改 ShopXO 核心
1. **防超卖机制缺失** — ✅ ticket-reviewer 补充了三阶段锁定时序 + vr_seat_locks 表 + 并发控制 ### Q2 — spec_base_id_map 时机
2. **CustomView vs 动态路由边界模糊** — ✅ arch-reviewer 明确了 CustomView 仅适合静态展示页 - 插件在 `GoodsService` 的商品加载 Hook 中一次性构建 seat_map
- 写入 `goods.extension_data.vr.seat_map`,所有场次共用
### ⚠️ 需补充(编码前建议明确) ### Q3 — 观演人存储
- 支付成功后写入 vr_tickets已有 DDL
- extension_data 仅存 ticket_id 绑定关系
- 不在购票流程中暂存,减少数据一致性风险
3. **vr_events / vr_sessions DDL 缺失** ### Q4 — spec 绑定实现
- ARCHITECTURE.md 仅列出表名,无字段定义 - ShopXO spec_value 是 per-goods COPY按 name 匹配是唯一可行方案
- 补充 DDL 已在 `reviews/backend-reviewer-on-docs.md` - `$vr-` 前缀隔离用户 spec插件按前缀过滤
- 初始化时创建 `$vr-场馆` 等模板;商家应用后插件按 spec_value.name 查 vr_seat_templates
4. **item_type='ticket' 写入机制**`ARCHITECTURE.md`
- goods.item_type 字段谁来写?后台手动设置?插件自动同步?
5. **核销员权限验证缺失** — `docs/03_VERIFICATION_SYSTEM.md`
- `VerifyTicket()` 未检查调用者是否为认证核销员
- 建议:增加 `vr_verifiers` 表身份校验
6. **AES IV 随机化**`docs/03_VERIFICATION_SYSTEM.md`
- `IV = substr(md5(ticket_code), 0, 16)` 不是随机 IV
- 建议:改用 `random_bytes(16)`IV 编码进密文
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 机制完全替代,不改核心文件
--- ---
## Task Checklist ## Task Checklist
- [x] **T1**: 补充防超卖机制章节到 `docs/03_VERIFICATION_SYSTEM.md` - [ ] **R1-T1**: 确认 `plugins_service_goods_index_view_end` Hook 的 extension_data 注入时机
- 座位锁定时序(用户选座 → 锁定 → 支付 → 生成 QR - 读取 `docs/01_SHOPXO_TECHNICAL_RESEARCH.md` Hook 列表
- 并发控制(数据库唯一索引 + 事务) - 确认注入点能获取 goods_id 并写入 extension_data
- 锁定超时释放机制
- `[Done: council/ticket-reviewer]`
- [x] **T2**: 统一 API 路径C 端 vs Admin 端) - [ ] **R1-T2**: 确认支付回调 Hook 名称(`plugins_service_buy_order_insert_success`
- C 端核销 API`/?s=api/vrticket/verify` - 在 ShopXO 源码中定位实际 Hook 名称
- Admin 端核销 API`/?s=admin/vrticket/verify` - 更新 `docs/03_VERIFICATION_SYSTEM.md` 中的 Hook 名称
- `[Done: council/ticket-reviewer]`
- [x] **T3**: 补充 AES IV 设计说明 - [ ] **R1-T3**: spec_value.name 匹配 vr_seat_templates 的实现路径
- `[Done: council/ticket-reviewer]` - 确认插件在哪个 Hook 里完成匹配
- 确认 seat_map 组装逻辑spec_value → seat_template → seat_data
- [x] **T4**: 生成票务核销系统完整设计文档 - [ ] **R1-T4**: 明确 item_type='ticket' 写入机制
- `[Done: council/ticket-reviewer]` - 插件在哪个时机写 goods.item_type
- 后台手动 or 插件自动?
- [x] **T4b**: SQL/安全审查 docs/01_SHOPXO_TECHNICAL_RESEARCH.md - [ ] **R1-T5**: 补充 vr_events / vr_sessions DDL
- `[Done: council/backend-reviewer]` - 基于 ARCHITECTURE.md 中列出的表名,补充完整字段定义
- [ ] **T5**: 明确 item_type 写入机制 + Goods.php 修改原则
- 在 `ARCHITECTURE.md` 中补充说明
- `[Pending: council/arch-reviewer]`
- [ ] **T6**: 确认支付回调 Hook 名称
- 补充具体 Hook 到 `ARCHITECTURE.md``docs/03_VERIFICATION_SYSTEM.md`
- `[Pending: council/backend-reviewer]`
- [ ] **T7**: 补充 CustomView 数据库写入路径
- `[Pending: council/arch-reviewer]`
- [ ] **T8**: 补充核销员权限验证VerifyTicket 身份校验)
- `[Pending: council/backend-reviewer]`
- [ ] **T9**: 补充 vr_events / vr_sessions DDL 到 ARCHITECTURE.md
- `[Pending: council/backend-reviewer]`
--- ---
@ -165,9 +65,32 @@
| Phase | 内容 | 负责人 | | Phase | 内容 | 负责人 |
|---|---|---| |---|---|---|
| **Draft** | T1-T4 ✅ 完成T4b ✅ 完成T5-T9 待完成 | ticket/arch/backend | | **Draft** | R1-T1 ~ T5 调研评审 | ⚙️ Backend |
| **Review** | 跨评审 | all | | **Review** | 提交评审报告到 `reviews/Backend-QA-review.md` | ⚙️ Backend |
| **Finalize** | 合并到 main投票 | all | | **Finalize** | 合并结论到 main投票 | ⚙️ Backend |
---
## 评审结论Backend 视角)
| 问题 | 结论 | Blocking? |
|---|---|---|
| Q1 座位模板绑定粒度 | `$vr-场馆` spec_value.name → seat_template.name 按名字匹配 ✅ | Non-blocking |
| Q2 seat_map 时机 | 商品加载 Hook 中一次性构建,写入 extension_data ✅ | Non-blocking |
| Q3 观演人存储 | vr_tickets支付后+ extension_data 绑定关系 ✅ | Non-blocking |
| Q4 spec 绑定方案 | `$vr-` 前缀命名空间 + 按 name 匹配,是唯一可行方案 ✅ | Non-blocking |
| Hook 名称待确认 | 支付回调 Hook 名称需实测验证 | ⚠️ Blocking |
| vr_events/vr_sessions DDL | 缺失,需补充 | ⚠️ Non-blocking |
| item_type 写入机制 | 需明确(手动/自动) | ⚠️ Non-blocking |
---
## Dependencies
- `docs/01_SHOPXO_TECHNICAL_RESEARCH.md` — Hook 列表(需读取)
- `docs/03_VERIFICATION_SYSTEM.md` — 核销 Hook 名称(需更新)
- `docs/06_SEAT_MAP_INTEGRATION.md` — 选座集成方案(需读取)
- `ARCHITECTURE.md` — 整体架构(需读取)
--- ---
@ -175,23 +98,6 @@
| Agent | Vote | 说明 | | Agent | Vote | 说明 |
|---|---|---| |---|---|---|
| backend-reviewer | `[CONSENSUS: YES]` | 文档质量足够开始编码;防超卖/核销/API 路径等核心问题已解决6 项非阻断性改进可在编码过程中迭代 | | ⚙️ Backend | TBD | Round 1 调研中 |
| 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未解决建议编码时同步处理。 [CONSENSUS: NO] — Round 1 尚未完成,需执行 R1-T1 ~ T5 后再投票
---
## Claim Status
| 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] |