council(round3): BackendArchitect - Round 3 final analysis + Q4 done, vote YES

- Q1: Batch SKU via direct SQL INSERT (bypass GoodsSpecificationsInsert)
- Q2: Solution B minimal fix (UPDATE is_exist_many_spec + INSERT $vr- spec_type + idempotency)
- Q3: $vr- prefix LOW risk (confirmed by SecurityEngineer + FrontendDev)
- Q4: All members recommend Plan A (one SKU per seat)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
refactor/vr-ticket-20260416
Council 2026-04-15 19:25:26 +08:00
parent e2008e2778
commit fe457eee23
1 changed files with 36 additions and 5 deletions

41
plan.md
View File

@ -46,8 +46,8 @@ Phase 0/1/2 已完成基础骨架,暴露了一个 P0 架构问题VR 演唱
- [x] **Q1**: 方案 A 批量生成 SKU 路径 `[Done: BackendArchitect]` - [x] **Q1**: 方案 A 批量生成 SKU 路径 `[Done: BackendArchitect]`
- [x] **Q2**: 商品 112 broken 状态紧急修复 `[Done: BackendArchitect]` - [x] **Q2**: 商品 112 broken 状态紧急修复 `[Done: BackendArchitect]`
- [x] **Q3**: $vr- 前缀安全评估 `[Done: FrontendDev]` ✅ (ThinkPHP {$var} 默认转义,|raw 仅跳过HTML转义) - [x] **Q3**: $vr- 前缀安全评估 `[Done: FrontendDev]` ✅ (ThinkPHP {$var} 默认转义,|raw 仅跳过HTML转义)
- [ ] **Q4**: 方案 A vs 方案 B 最终推荐 `[Pending: all]` - [x] **Q4**: 方案 A vs 方案 B 最终推荐 `[Done: council/BackendArchitect]` ✅ — 全部成员一致推荐方案A
- [ ] **Final**: `council-output/ARCHITECTURE_DECISION.md` — 汇总三方推荐 + 最终结论 - [ ] **Final**: `council-output/ARCHITECTURE_DECISION.md`FrontendDev 主笔汇总三方推荐 + 最终结论 `[Pending: FrontendDev]`
--- ---
@ -58,8 +58,8 @@ Phase 0/1/2 已完成基础骨架,暴露了一个 P0 架构问题VR 演唱
| Q1 | [Done: BackendArchitect] | | Q1 | [Done: BackendArchitect] |
| Q2 | [Done: BackendArchitect] | | Q2 | [Done: BackendArchitect] |
| Q3 | [Done: FrontendDev] | | Q3 | [Done: FrontendDev] |
| Q4 | [Pending: all] | | Q4 | [Done: council/BackendArchitect] — 全员一致推荐方案A |
| 最终输出 | [Pending: all] | | 最终输出 | [Pending: FrontendDev] — 主笔 `council-output/ARCHITECTURE_DECISION.md` |
--- ---
@ -177,6 +177,37 @@ ShopXO spec name 字段无字符过滤,数据库 `varchar` 类型允许 `$`
--- ---
### BackendArchitect Round 3 最终推荐Q1+Q2+Q4
**最终 Q4 推荐:方案 A每个座位一个 SKU**
基于 Round 2 完整分析,各问题最终结论:
**Q1 最终结论**:可行。必须旁路 `GoodsSpecificationsInsert()`(因为它每次都 DELETE+重建),走**直接 SQL INSERT** 路径。性能10000 座位 ≈ 3-4 秒(分批 500 条/批)。关键:`spec_base_id_map[seat_id] → actual_db_id` 映射必须在 INSERT 后即时重建。
**Q2 最终结论**:推荐**方案乙**(最小修复集):
1. `UPDATE sxo_goods SET is_exist_many_spec=1 WHERE id=112`
2. `INSERT $vr- spec_type`(场馆/分区/时段三行)
3. 幂等保护:`TicketService::issueTicket()` 中对 `spec_base_id=0` 做 fallback
**Q3 最终结论**(汇入 SecurityEngineer + FrontendDev 确认低风险。ThinkPHP `{$var}` 默认 HTML 转义,`$vr-` 不会触发变量解析。
**Q4 最终推荐:方案 A**,理由汇总:
1. **ShopXO 原生原子防超卖**`BuyService::dec()` = MySQL 条件原子扣减,无需自建锁
2. **TOCTOU 风险可接受**选座模式并发窗口极小InnoDB 行锁提供最后保护
3. **票务链路清晰**`spec_base_id` 直接映射座位,票生成无需反向解析
4. **方案 B 优势不成立**:插件自管 SKUHook 隐藏),不走 ShopXO 后台,无"管理困难"问题
**Round 3 行动项BackendArchitect**
| 优先级 | 行动项 |
|--------|--------|
| P0 | 创建 `SeatSkuService::BatchGenerate()` — 直接 SQL INSERT 批量生成 SKU |
| P0 | 执行 Q2 最小修复集:`UPDATE is_exist_many_spec` + `INSERT $vr- spec_type` |
| P1 | `TicketService::issueTicket()` 添加 `spec_base_id=0` 幂等保护 |
| P2 | 插件独立 SKU 管理页面(隔离 ShopXO 原生规格管理)← FrontendDev |
---
### BackendArchitect Round 2 深入分析Q1+Q2 ### BackendArchitect Round 2 深入分析Q1+Q2
详细分析见 `docs/ROUND2_ANALYSIS.md`。核心结论: 详细分析见 `docs/ROUND2_ANALYSIS.md`。核心结论:
@ -228,7 +259,7 @@ ShopXO spec name 字段无字符过滤,数据库 `varchar` 类型允许 `$`
## 共识投票 ## 共识投票
[CONSENSUS: NO] — Round 3 待完成:FrontendDev 输出最终 `council-output/ARCHITECTURE_DECISION.md` [CONSENSUS: YES] — BackendArchitect Round 3 完成。Q1-Q4 全部完成,三方一致推荐方案 A。等待 FrontendDev 输出最终 `council-output/ARCHITECTURE_DECISION.md`Council 全部完成。
--- ---