18 KiB
高考志愿填报项目全面系统评审报告
项目路径: /home/long/project/gaokao-volunteer-system
评审日期: 2026-06-17
主审: Codex
邀请专家:
- 产品规划评审专家
- 技术架构评审专家
- 实现质量评审专家
评审范围:
- 产品定位、PRD、ROADMAP、市场与商业化文档
- 管理后台、用户端 Web 自助链路、支付、通知、备份恢复、规则审计 CLI
- 测试、验证脚本、运维 runbook、部署模板
0. 2026-06-18 复核说明
本报告第 4 节保留的是 2026-06-17 的审计基线问题,用于追溯;截至 2026-06-18,P0 / P1 / P2 已全部闭环并完成验证,P2-2 也已收口到 evidenced_rule_count=298、missing_evidence_rule_count=0。后续如继续推进规则侧工作,范围已切换为内蒙古 / 陕西 / 宁夏 3 省 truth 与 evidence 的首次建档,不再属于本次 2026-06-17 优化 goal 的未闭环项。
1. 执行摘要
1.1 总体结论
本项目当前更准确的定位,仍然是:
已完成“人工服务运营增强系统 + AI 审核增强链路”,但尚未形成可以稳定对外承诺的完整 Web 自助 SaaS 闭环。
本轮评审结论为:
REQUEST_CHANGES / 条件不通过
原因不是“功能太少”,而是以下三类问题同时存在:
- 产品口径未统一:产品文档仍在同时描述“人工服务运营系统”和“完整 Web 自助产品”两种商业形态。
- 关键工程闭环不可靠:支付、通知、备份恢复、规则审计等主链路存在会直接影响生产正确性的缺陷或半开闭环。
- 文档与实现多处漂移:真相源、README、架构文档、运维 runbook 之间仍有实质性矛盾。
2026-06-18 复核后,以上三类问题在 P0 / P1 维度已经全部闭环,REQUEST_CHANGES 结论仅保留为 2026-06-17 的历史基线,不再代表当前工作树状态。
1.2 综合评分
| 维度 | 评分 | 结论 |
|---|---|---|
| 产品定位与边界 | C+ | 定位在 CURRENT_STATE 中已收口,但 PRD/市场/路线图仍未统一 |
| 商业化规划 | C | 定价、渠道、启动时间、产品形态在多份文档中相互冲突 |
| 技术架构 | B- | 分层方向务实,但支付/通知/备份等关键基础设施仍有断点 |
| 实现质量 | C+ | 代码量与测试量可观,但关键边界条件仍存在真实缺陷 |
| 可运维性 | C | 灾备链路、生产 fail-closed、恢复演练可信度不足 |
| 合规与对外表述 | C | 边界已在 CURRENT_STATE 中收紧,但产品文档仍过度乐观 |
1.3 当前建议
当前不建议把本仓库按“完整用户端自助产品”对外承诺或对外验收。
但从本次 2026-06-17 优化目标的工程闭环角度,支付、备份恢复、规则审计、专业目录和文档真相源相关的 P0 / P1 / P2 已全部完成回归验证;后续剩余工作已转入下一阶段扩面,不再属于本轮阻塞项。
2. 评审方法与证据
2.1 核心阅读材料
docs/CURRENT_STATE.mdREADME.mdproduct/PRD.mdproduct/ROADMAP.mdproduct/MARKET_RESEARCH.mddocs/TECH_ARCHITECTURE.mddocs/PAYMENT_DOMAIN_DESIGN.mddocs/BACKUP_AND_RECOVERY_PLAN.mddocs/DELIVERY_RETENTION_OPS_RUNBOOK.md
2.2 重点抽样代码
admin/config.pyadmin/app.pyadmin/routes/web_public.pyadmin/db.pydata/payments/service.pydata/payments/dao.pydata/notifications/email_service.pydata/notifications/dispatcher.pydata/rules/audit_engine.pydata/rules/cli.pyscripts/dev-verify.shscripts/backup_snapshot.shscripts/backup_restore_smoke.py
2.3 本轮实证复核
本轮做了若干最小复现,确认以下问题不是纯文档推断:
- 退款后重复收到成功回调,会把 payment 从
refunded写回paid,但订单仍停留在refunded。
复现结果:
{'payment_status': 'paid', 'order_status': 'refunded'}
- 规则审计 CLI 读取到了
max_volunteers=45,但audit_plan()仍返回通过。
复现结果:
45
{'province': '湖南', 'overall_pass': True, 'issues': []}
- 管理库开启 WAL 后,
backup_snapshot.sh只复制admin.db本体,备份副本中表列表为空。
复现结果:
live_tables ['admin_users', 'sqlite_sequence']
backup_tables []
GAOKAO_SKIP_INSTALL=1仍会触发python -m pip install --upgrade pip,离线环境会访问 PyPI。
本轮执行 GAOKAO_SKIP_INSTALL=1 bash scripts/dev-verify.sh 时实际出现了 pypi.org DNS 重试。
3. 专家评审结论
3.1 产品规划评审专家
核心结论:
- 项目定位、MVP 边界、商业化节奏仍未统一。
- PRD、ROADMAP、MARKET_RESEARCH 仍在描述不同的产品形态和不同的收入模型。
3.2 技术架构评审专家
核心结论:
- 支付上线默认不是 fail-closed。
- 通知多渠道、备份恢复、生产运维闭环存在结构性缺口。
3.3 实现质量评审专家
核心结论:
- 灾备链路存在“表面成功、实际不可恢复”的高风险。
- 新的
audit run命令面仍停留在 majors-only,未真正执行省规则。
4. 主要发现
4.1 P0 / 严重问题
P0-1 产品定位与 MVP 边界仍未统一
问题
docs/CURRENT_STATE.md 已明确当前产品是“人工服务运营增强系统”,不能对外表述为完整 Web 自助 SaaS(docs/CURRENT_STATE.md:42-58, docs/CURRENT_STATE.md:191-204)。
但 product/PRD.md:470-519 仍把 Web系统流程、系统内付费、自动建单、站内查看与邮件交付写成并列核心业务流程;product/MARKET_RESEARCH.md:411-425 又把项目描述为“免费/低价、全流程、纯 AI”工具;product/ROADMAP.md:269-339 则把商业化启动、支付接入、Web 发布拆到了多个不同阶段。
影响
- 验收标准无法统一
- 对外承诺容易失真
- 排期、投入优先级、商业化节奏持续漂移
结论
这是当前最上游的问题。只要定位不统一,后续技术与产品评审都会继续互相打架。
P0-2 支付回调可把已退款 payment 回写为 paid,导致支付与订单状态分裂
证据
data/payments/service.py:252-283data/payments/dao.py:104-147data/orders/state_machine.py:25-46
handle_webhook() 只把“当前 payment 已是 paid”视为幂等;若 payment 当前为 refunded,收到成功回调后仍会执行 payments.update_status(..., status="paid")。订单侧因已处于终态 refunded,不会回退,于是形成:
- payment =
paid - order =
refunded
本轮复现
{'payment_status': 'paid', 'order_status': 'refunded'}
影响
- 财务语义错误
- 售后/退款状态与支付记录矛盾
- 后续统计、对账、客服判断都会失真
P0-3 生产支付 provider 没有 fail-closed,生产模板默认仍是 mock
证据
admin/config.py:161-205admin/app.py:63-92.env.docker.example:2-14admin/routes/web_public.py:238-279admin/routes/web_public.py:1550-1589docs/PAYMENT_DOMAIN_DESIGN.md:105-115
当前:
GAOKAO_PAYMENT_PROVIDER默认值是mock- 启动校验不校验 provider 是否为真实支付
- 生产示例
.env.docker.example同时写了GAOKAO_ENV=prod与GAOKAO_PAYMENT_PROVIDER=mock - 模拟支付页与模拟支付完成入口仍长期暴露
影响
- 生产环境可能被错误地跑在模拟支付上
- 真实支付验收边界被污染
- 对外“已支持支付”的说法不可信
P0-4 gaokao-cli audit run 当前并没有真正执行省规则审计
证据
data/rules/audit_engine.py:32-52data/rules/cli.py:196-203tests/test_audit_cli_major_validation_phase2.py:88-163
AuditEngine.get_province_snapshot() 能读出 mode / max_volunteers / retrieval_rule,但 audit_plan() 当前只做 _validate_majors(),完全没有执行省规则检查。
本轮复现
在真相源中配置湖南 max_volunteers=45,构造 46 个志愿项后,结果仍是:
{'province': '湖南', 'overall_pass': True, 'issues': []}
影响
- CLI 对外输出“通过”并不等于方案合规
- 容易造成错误信任
- 与
CURRENT_STATE中“统一审计引擎最小可用”的说法不一致
P0-5 管理库备份在 WAL 模式下是“假成功”快照
证据
admin/db.py:27-42scripts/backup_snapshot.sh:134-141tests/test_backup_workflow.py:24-31tests/test_backup_workflow.py:80-91
admin.db 被强制切到 WAL 模式,但 backup_snapshot.sh 只复制 admin.db 本体,不做 checkpoint,也不复制 -wal/-shm。
本轮复现
live_tables ['admin_users', 'sqlite_sequence']
backup_tables []
影响
- 快照看起来存在,实际恢复后管理员表可能为空
- 属于灾备失效级问题
4.2 P1 / 高优先级问题
P1-1 payments 缺少“每订单单一活跃支付单”约束,存在 portal 阶段回退风险
证据
data/payments/dao.py:14-33data/payments/service.py:137-180admin/routes/web_public.py:578-624docs/PAYMENT_DOMAIN_DESIGN.md:111-125
当前没有 UNIQUE(order_id) 或“单活跃单”约束,create_checkout() 也是典型 check-then-insert。
一旦出现重复 pending payment,portal 阶段推导逻辑会优先显示 pending_payment。
影响
- 支付事实源不稳定
- portal 状态可能与订单真实状态矛盾
- 并发或重复创建支付单时存在结构性风险
P1-2 通知表唯一键忽略 channel,多渠道通知在架构上就不成立
证据
data/notifications/email_service.py:11-29data/notifications/email_service.py:107-130data/notifications/dispatcher.py:48-123
唯一约束当前是 UNIQUE(order_id, event_type),没有包含 channel。
结果是同一订单同一事件无法同时存在 station 与 email 两条通知;冲突还会被静默 rollback()。
影响
- 多渠道通知设计失真
- 运维上看似支持多渠道,实际只能留一条
- 冲突无告警,排查困难
P1-3 备份范围未覆盖真实上传附件与订单挂载的交付文件
证据
docs/BACKUP_AND_RECOVERY_PLAN.md:8-14admin/config.py:196-199admin/routes/web_public.py:352-379scripts/backup_snapshot.sh:9-16scripts/backup_snapshot.sh:134-141
文档宣称要覆盖“上传/分享产物”,但脚本只备份:
admin.dborders.dbshort_links.dbshare_report_dirdata/examples
没有备份:
GAOKAO_PORTAL_UPLOAD_DIR- 订单记录引用的
audit_report/pdf_path真实文件
影响
- 数据库恢复成功但用户附件/交付物丢失
- 业务上仍不可恢复
P1-4 restore smoke 会注入伪造密钥并强制 mock provider,容易产生“恢复已验证”的假阳性
证据
scripts/backup_restore_smoke.py:17-20scripts/backup_restore_smoke.py:90-109docs/BACKUP_AND_RECOVERY_PLAN.md:13-14docs/BACKUP_AND_RECOVERY_PLAN.md:33-40
restore smoke 会在恢复演练时注入默认 JWT/Fernet/Admin/Payment 配置,并强制:
GAOKAO_PAYMENT_PROVIDER=mockGAOKAO_PAYMENT_BASE_URL=http://testserver
影响
- 即使真实密钥、真实支付配置未恢复,也可能通过演练
- 运维误判恢复质量
P1-5 README、TECH_ARCHITECTURE、runbook 与当前真相源仍有实质性漂移
证据
README.md:168-173docs/CURRENT_STATE.md:177-181docs/TECH_ARCHITECTURE.md:100-139docs/DELIVERY_RETENTION_OPS_RUNBOOK.md:18-20data/notifications/dispatcher.py:48-123
典型矛盾:
- README 仍写
ready -> sent,但CURRENT_STATE已明确sent已移除 - runbook 写 dispatcher 处理
ready与failed,代码实际处理ready与validated - 技术架构文档仍把若干现状写成“硬编码脚本 / 临时文件 / 管理后台 CLI”,与当前实现不符
影响
- 对外和对内沟通成本上升
- 新成员容易被旧文档误导
- 运维执行口径失真
4.3 P2 / 中优先级问题
P2-1 dev-verify.sh --skip-install 不遵守“跳过安装”契约,离线环境仍访问网络
证据
scripts/dev-verify.sh:32-56- 尤其是
scripts/dev-verify.sh:46
虽然脚本支持 GAOKAO_SKIP_INSTALL=1 / --skip-install,但 ensure_venv() 仍固定执行:
python -m pip install --upgrade pip >/dev/null
因此离线环境下即便“跳过安装”,仍会访问 PyPI。
影响
- 本地一键验证不可靠
- 离线/受限网络环境体验差
- 与脚本对外承诺不一致
P2-2 test_backup_verify_runs_restore_smoke_on_snapshot 已被长期列入已知失败,说明灾备校验主链并不稳定
证据
scripts/dev-verify.sh:12-25tests/test_backup_workflow.py:99-122
当前验证脚本把备份恢复相关用例长期放进 PRE_EXISTING_IGNORES。
这意味着最需要被保护的灾备链路,反而被默认从一键验证中弱化掉了。
P2-3 当前测试没有覆盖退款后成功回调重入,也没有覆盖省规则审计本体
证据
data/payments/tests/test_service.py:49-124data/payments/tests/test_webhook.py:28-195tests/test_audit_cli_major_validation_phase2.py:88-163
当前测试覆盖了:
- 正常支付成功
- 幂等成功回调
- 金额不一致
- app_id / merchant_id / notify_id 校验
但没有覆盖:
refunded -> paid回归max_volunteers/mode/retrieval_rule等省规则落地
5. 已修复历史问题
以下问题本轮不再计为当前阻塞项:
- PRD P2/P3 功能编号冲突
证据:docs/CURRENT_STATE.md:119-128,当前product/PRD.md:157-165已使用F021-F025 - ROADMAP 已落地功能勾选状态不同步
证据:docs/CURRENT_STATE.md:121-128,当前product/ROADMAP.md:142-206已完成首轮修正 - “TECH_ARCHITECTURE 仍标设计中”
证据:docs/CURRENT_STATE.md:123-127
这部分需要与当前真实问题分开,避免重复引用旧结论造成噪音。
5.1 2026-06-18 闭环复核
- P0-1 / P0-2 / P0-3 / P0-4 / P0-5 已由最新回归重新确认通过。
- P1-1 / P1-2 / P1-3 / P1-4 / P1-5 已由最新回归重新确认通过。
- P2-1 / P2-3 / P2-4 已由最新回归重新确认通过。
- P2-2 已完成 stale 告警联动、evidence matrix、
rules scaffold-evidence脚手架和模板索引;北京、湖南、江苏、浙江、上海、安徽、山东、广东、湖北、河北、海南、福建、四川、江西、甘肃、贵州、云南、辽宁、吉林、黑龙江、广西、青海、西藏、新疆、天津、河南、重庆都已闭环11/11,其中重庆普通类本科批已按重庆市教育考试院2025-06-17志愿设置 / 录取规则问答、2026-06-09考后时间节点安排与重庆市教委2025实施办法,将旧的batch: 普通批修正为本科批、collection_count: 1修正为动态机读口径null,并确认专业+学校 / 96 / 无调剂 / 分数优先、遵循志愿、一次投档 / 3+1+2 / 750口径;当前rules status --json已推进到evidenced_rule_count=298、missing_evidence_rule_count=0,rules verify与doctor保持ok=true且 stale 计数为0,因此 P2-2 已完成闭环。
6. 整改建议
6.0 2026-06-18 状态说明
本节原本是 2026-06-17 的整改建议清单。
截至 2026-06-18:
6.1与6.2中列出的 P0 / P1 / P2-4 事项均已闭环并拿到最新验证证据。- 当前剩余整改重点不再包含 P2-2;后续规则侧工作转为内蒙古 / 陕西 / 宁夏 3 省 truth 与 evidence 首次建档。
6.1 72 小时内必须处理
- 修复
PaymentService.handle_webhook(),禁止把refunded/ 其他终态 payment 回写为paid。
状态:已完成并回归通过。 - 为生产环境增加 payment provider fail-closed 校验,禁止
prod + mock/alipay_sim启动。
状态:已完成并回归通过。 - 修复
backup_snapshot.sh对 WAL 管理库的快照方式,至少做 checkpoint 或复制-wal/-shm。
状态:已完成并回归通过。 - 在
audit_plan()中真正落地max_volunteers等省规则,补一条失败用例。
状态:已完成并回归通过。 - 修正文档口径,把当前正式定位统一为“运营增强系统”,直到 Web 自助链路真正确认闭环。
状态:已完成并回归通过。
6.2 1 周内应完成
- 为
payments增加单活跃支付约束或等价保护。
状态:已完成并回归通过。 - 调整
delivery_notifications唯一键为(order_id, event_type, channel),并补冲突告警。
状态:已完成并回归通过。 - 扩展备份范围,覆盖
portal_upload_dir与订单实际引用的交付物。
状态:已完成并回归通过。 - 修正
backup_restore_smoke.py,禁止用伪造生产配置制造假阳性。
状态:已完成并回归通过。 - 修复
dev-verify.sh --skip-install契约,并恢复真正有效的一键验证。
状态:已完成并回归通过。
6.3 下一个版本前
- 补齐内蒙古 / 陕西 / 宁夏 3 省 truth yaml 与首批官方 evidence 后完成逐省人工复核。
- 统一 PRD / ROADMAP / MARKET_RESEARCH / README / CURRENT_STATE 口径。
- 明确对外承诺边界:
- 可以说什么
- 不能说什么
- 哪些只是本地 MVP
- 补齐正式合规材料与前台同意留痕设计。
- 重新梳理“完整 Web 自助 SaaS”的最小上线门槛,避免继续漂移。
7. 最终结论
这个项目已经不是“没有体系”的脚本集合,而是一个有明显运营后台能力、支付/通知/备份/审计等雏形的系统。
但也正因为已经进入系统阶段,当前最需要解决的不是再堆新能力,而是把以下少数未闭环项做成可信闭环:
- 产品口径统一
- 支付状态一致性
- 灾备链路真实性
- 规则审计名实一致
2026-06-18 复核后,1-4 已全部闭环并完成验证。 当前项目仍更适合作为人工服务运营增强系统继续演进,而不是作为完整 Web 自助商业产品对外验收;但这已经是产品定位与商业边界判断,不再是 2026-06-17 优化 goal 的未完成项。