vr-shopxo-plugin/docs/council-eval-FINAL.md

160 lines
7.0 KiB
Markdown
Raw Permalink Normal View History

# VR 票务插件项目 Council 评估 — 最终综合报告
> 评估时间2026-05-26 17:12 GMT+8
> 协调者西莉雅Sileya
> 评估成员BackendArchitect · FrontendDeveloper · SecurityEngineer · PerformanceBenchmarker
---
## 一、投票结果
| 成员 | 投票 | 状态 |
|------|------|------|
| BackendArchitect后端架构师 | **C — 双线并行** | ✅ 已投票 |
| FrontendDeveloper前端开发专家 | **C — 双线并行** | ✅ 已投票 |
| SecurityEngineer安全工程师 | **C — 双线并行** | ✅ 已投票 |
| PerformanceBenchmarker性能压测专家 | ⏳ 进行中 | — |
**结论3:0压倒性共识选择 C双线并行**
---
## 二、各维度现状评估
### 2.1 后端现状BackendArchitect
| 组件 | 状态 | 说明 |
|------|------|------|
| Phase 0/1插件骨架+票务详情页) | ✅ 完成 | — |
| Phase BB端核销 | ✅ 完成 | Admin 核销页 + TicketVerify API |
| Phase 2SeatMapService + seatmap API | ⚠️ **半完成** | `SeatSkuService::getSoldSeats()` 方法缺失 |
| Phase 3前端模板+购物车) | ✅ 完成 | `submit()` 修复,购物车集成 |
| Phase 4Tree API | 📋 仅设计文档 | 无实现代码 |
| Issue #6 安全问题 | ⚠️ 部分待修复 | 5个严重 → SecurityEngineer 定级 P1-P3 |
**关键断裂点BackendArchitect 发现):**
- **P0-1**`SeatSkuService::getSoldSeats()` 方法被引用但未实现
- **P0-2**:商品详情 API 无 `seatSpecMap` 注入(`plugins_service_goods_data` Hook 未注册)
- **P0-3**:购物车 CartSave 无法传递座位信息(`sxo_cart` 表无 extension_data 字段)
### 2.2 前端现状FrontendDeveloper
| 组件 | 状态 | 说明 |
|------|------|------|
| vr-shopxo-uniapp fork | ✅ 完成 | 基础框架已搭建 |
| goods-vr-ticket 组件 | ⚠️ **未建立** | 票务组件目录不存在 |
| ticket_detail.htmlH5 | ⚠️ 部分完成 | `loadSoldSeats()` 未实现TODO 遗留) |
| 票务核心页面 | ⚠️ **空白** | 选座/票夹/核销页均无实现 |
**API Gap 对前端的影响:**
- Gap 1seatSpecMap 未返回):🔴 致命阻塞,选座组件完全无法开发
- Gap 2extension_data 链路未确认):🟠 重度阻塞,多座位流程无法开发
- Gap 3QR payload 缺少 code🟡 中度影响,可变通处理
### 2.3 安全现状SecurityEngineer
**重要结论:支付链路本身安全水位中高,无发现 P0 级别漏洞。**
| 威胁 | 保护机制 | 状态 |
|------|---------|------|
| 超卖(并发下单扣库存) | ShopXO `dec()` 原子条件 UPDATE | ✅ 有效 |
| 伪造 QR 票 | HMAC-SHA256 签名 | ✅ 有效 |
| 伪造短码 | Feistel 混淆 + goods_id 派生 | ✅ 有效 |
| 重复核销 | verifyTicket FOR UPDATE | ✅ 有效 |
| 并发发票 | issueTicket 幂等检查(无行锁) | ⚠️ 建议加唯一索引 |
| 环境密钥泄露 | VR_TICKET_QR_SECRET 硬编码 fallback | ⚠️ 需确认 .env 配置 |
| 前端 XSS | 观演人信息渲染方式未确认 | ⚠️ 需确认 |
**Issue #6 定级结论:** 所有问题均属 P1-P3不应阻塞主攻方向。
### 2.4 性能现状PerformanceBenchmarker
⏳ 评估进行中(未完成)
---
## 三、投票分析
### 为什么全票投 C双线并行
**BackendArchitect 理由:**
> 后端 P0 Gap`getSoldSeats` 缺失、Hook 未注册)属于"修完就能用"的阻断性问题工作量小但价值高2-3 小时)。前端当前有 H5 票务页作为保底,可以独立推进 uniapp 选座组件开发,无需等待全部 API。
**FrontendDeveloper 理由:**
> H5 ticket_detail.html 完全独立于 API Gap可立即推进实现 loadSoldSeats + 表单优化UniApp 的 Gap 1/2 需要后端配合,但可并行确认。
**SecurityEngineer 理由:**
> 安全维度所有问题均为 P1-P3无 P0。双线并行可以最大化团队效率同时保证安全改进不遗漏。
### C vs 其他选项
| 选项 | 为什么被否决 |
|------|------------|
| A后端优先 | 完全阻塞前端,浪费 H5 保底能力和前端团队资源 |
| B前端优先 | uniapp 开发被 Gap 1/2 阻断,忽视长期目标 |
| DPhase 4 优先) | Tree API 是锦上添花Phase 3 核心流程尚未完成 |
---
## 四、具体行动计划C 双线并行)
### 后端行动项
| 优先级 | 任务 | 预计工时 | 说明 |
|--------|------|---------|------|
| 🔴 P0 | **实现 `SeatSkuService::getSoldSeats()`** | 1h | 修复 soldSeats API |
| 🔴 P0 | **注册 `plugins_service_goods_data` Hook**,注入 seatSpecMap | 1h | 解锁前端 seatSpecMap 获取 |
| 🔴 P0 | **决策 CartSave 路径**:票务走绕过购物车的直购模式 | 0.5h | 参股大麦/猫眼,选座→立即下单 |
| 🟡 P1 | **实现完整 `/seatmap` API**(统一座位数据接口) | 2h | seat_map + sold_seats + sessions + spec_base_id_map |
| 🟡 P1 | **确认 extension_data 写入 order_detail 链路** | 1h | 多座位每座独立 attendee 信息 |
| 🟢 P2 | 完善 Phase 4 Tree API 设计文档 | — | API 契约 + 路由设计 |
### 前端行动项
| 优先级 | 任务 | 说明 |
|--------|------|------|
| 🟡 P1 | **ticket_detail.html** 实现 `loadSoldSeats()` | 调用 seatmap API 填充已售座位 |
| 🟡 P1 | **ticket_detail.html** 观演人表单 UX 优化 | 过渡方案,立即可用 |
| 🟡 P1 | **ticket_detail.html** 核销码展示QR + 短码) | 完成票务闭环 |
| 🟡 P1 | **vr-shopxo-uniapp** goods-vr-ticket 组件框架 | Gap 1 解决后立即启动 |
| 🟢 P2 | UniApp 商品详情页集成 seatSpecMap | 等后端 Hook 注册完成 |
| 🟢 P2 | UniApp 选座页 + 购票确认 + 支付 | 依赖 Gap 1/2 全部解决 |
### 安全行动项(与主攻方向并行)
| 优先级 | 任务 | 说明 |
|--------|------|------|
| 🟡 P1 | 确认生产环境 `.env` 配置了 `VR_TICKET_SECRET``VR_TICKET_QR_SECRET` | 防密钥硬编码泄露 |
| 🟡 P1 | 在 `vrt_vr_tickets` 表添加唯一索引 `(order_id, seat_info)` | 从根本上防止并发发票超卖 |
| 🟡 P2 | 确认 ticket_detail.html 观演人信息渲染有 XSS 过滤 | 防持久型 XSS |
---
## 五、Gitea Issue 行动建议
建议将以下 P0 任务创建为独立 Issue
| Issue | 标题 | 负责 |
|-------|------|------|
| 新建 | 实现 `SeatSkuService::getSoldSeats()` 方法 | 后端 |
| 新建 | 注册 `plugins_service_goods_data` Hook注入 seatSpecMap | 后端 |
| 新建 | 票务购票路径决策:绕过购物车直购模式 | 后端 + 大头确认 |
| 新建 | ticket_detail.html 实现 `loadSoldSeats()` | 前端 |
---
## 六、原始投票文件索引
| 文件 | 成员 |
|------|------|
| `docs/council-eval-backendarchitect.md` | BackendArchitect |
| `docs/council-eval-frontenddeveloper.md` | FrontendDeveloper |
| `docs/council-eval-securityengineer.md` | SecurityEngineer |
| `docs/council-eval-performancebenchmarker.md` | PerformanceBenchmarker⏳ 未完成) |
---
*综合报告:西莉雅 | 2026-05-26*
*本文件为最终输出,所有成员投票结果均已记录。*