Hermes Agent
8815f85ec4
feat(crowd_db): 27省全量完成 usable/high 升级 + review 修复
...
CI / pytest (Python 3.10) (push) Has been cancelled
CI / pytest (Python 3.11) (push) Has been cancelled
CI / pytest (Python 3.12) (push) Has been cancelled
- 27 省全部达到 usable 及以上(7 high + 20 usable + 0 skeleton)
- high 白名单: 湖南/广东/江苏/山东/河北/浙江/福建
- 可信来源元数据补齐: 湖南/四川 province_official URL 修复
- 共享测试同步: test_provenance_query.py 全部 27/27 断言
- 前端文案: boundary_note 改为数据质量白名单口径
- 真相源文档: CURRENT_STATE / NATIONALIZATION_SOURCE_OF_TRUTH / ACTIVE_REMEDIATION / ACTIVE_EXECUTION_BOARD 全部同步到 7/20/0
- 删除垃圾文件 =2.0.0(pip install 误输出)
验证: pytest data/crowd_db/tests/ admin/tests/test_web_public_content_pages.py → 57 passed
2026-06-25 00:17:20 +08:00
Hermes Agent
0bc1306a1f
feat(crowd_db): 27省全部升级到 usable+ 数据基线
...
- 27 省全部达到 usable 及以上(HIGH=7 / USABLE=20 / LOW=0)
- README.md / SCHEMA.md 同步更新质量等级说明
- test_crowd_db_data_quality.py 锁定 27 省数量与质量基线
- test_provenance_query.py 更新 filter_provinces 动态断言
数据来源: 2025 官方分数线锚点 + 省内重点高校常见报考池 + 国家专业目录 MVP 子集
2026-06-24 22:31:07 +08:00
Hermes Agent
2e9d668d1e
fix(tests): admin conftest RouteClient.post headers bug + intake candidate_province
...
- conftest.py: RouteClient.post() 在 mock webhook 分支引用未定义 headers 变量
- test_web_public_alipay_sim_e2e.py: submit payload 漏传 candidate_province(schema 升级后变必填)
- web_public.py: 删除未使用的 primary_action_label/href 变量(ruff F841)
- test_schema.py: 修正 import 位置(E402)+ 补充 IntakePayload import
根因: 之前改动留下的回归 bug,dev-verify 全绿后再次验证通过
2026-06-24 22:30:22 +08:00
Hermes Agent
2baa8c2422
fix(crowd_db): 27省全部usable+后测试期望同步 + source_url http→https
...
- 山西/天津 source_url 从 http:// 改为 https://(可信来源入口规范)
- test_loader_low_confidence_warning: 改用 monkeypath 注入 0.45 数据(27省已无 low confidence)
- test_filter_provinces_*: 动态断言取代硬编码列表,避免未来数据升级再次回归
- test_cross_province_beijing_at_690: 改用实际存在的 北京大学-临床医学 组合
- 新增 CROWD_DB_NATIONALIZATION_SOURCE_OF_TRUTH.md + 全国高信任建设计划文档
现状: HIGH=7 / USABLE=20 / LOW=0 (27省口径)
2026-06-24 22:29:59 +08:00
Hermes Agent
09caa3309f
feat(legal+data): harden legal drafts and crowd_db provenance
CI / pytest (Python 3.10) (push) Has been cancelled
CI / pytest (Python 3.11) (push) Has been cancelled
CI / pytest (Python 3.12) (push) Has been cancelled
2026-06-21 11:54:16 +08:00
hermes
240c38e312
feat(scripts 6/20 v2.1.4): 性能+集成+模拟+部署 4 维度验证
...
CI / pytest (Python 3.10) (push) Has been cancelled
CI / pytest (Python 3.11) (push) Has been cancelled
CI / pytest (Python 3.12) (push) Has been cancelled
## 4 个新脚本
| 脚本 | 用途 | 结果 |
|---|---|---|
| scripts/perf_benchmark.py | 性能 baseline + 10 并发压测 | p95=3ms/10.68ms, 1250 rps |
| scripts/integration_test.py | 全链路 E2E (DB+admin+portal+retention) | 7/7 PASS |
| scripts/user_simulation.py | Playwright 5 跳 × 2 视口 | 10/10 PASS |
| scripts/deploy_ops_verify.py | 12 项 health/auth/CRUD/ops-alerts | 12/12 PASS |
## reports 落地
- reports/perf_2026_06_20.json
- reports/integration_2026_06_20.json
- reports/deploy_ops_2026_06_20.json
- reports/user_simulation_2026_06_20/ (10 PNG + captures.json)
- reports/PRODUCTION_LAUNCH_READINESS_2026-06-20.md (总报告 + PRODUCTION_DEPLOYMENT_CHECKLIST §7 A 8 项勾选)
- docs/VERIFICATION_SCRIPTS_2026-06-20.md (脚本索引)
## 关键发现 (投产必读)
1. **GAOKAO_ORDERS_FERNET_KEY 必须在 systemd unit Environment= 显式设置**, 否则
订单写入抛 MissingEncryptionKey → 兜底 except 抛 500 E03003 (表面像'数据保存失败')
2. **/api/orders 与 /api/orders/{id} 响应都是嵌套 {order: {...}}**, portal 路径平铺
3. **portal_token 不在 order 响应里**, 需 data/customer_portal/token.issue_portal_token(order_id, secret)
## PRODUCTION_DEPLOYMENT_CHECKLIST §7 A 8 项
本地可推进 5/8 全过: 密钥目录 / 健康端点 / 联调文档 / 隐私政策 / 数据密度
3/8 文档级 (SMTP 真实联调 / 告警渠道 / 备份异机演练 需 PM+Ops+凭据)
## 状态分级
- 整体: CONDITIONAL_APPROVED
- 本地验证: 4 维度 36/36 项全 PASS
- 外部前置: 6 项需 PM/Ops/Legal/真实商户协调 (T12-A / 异机演练 / 法务审定 / 真实告警 / 真实压测 / data_year 更新)
2026-06-20 18:57:45 +08:00
hermes
6eafe1fc9b
feat(ops 6/20 v2.1.3): 生产加固 + L-A 送审前修复 + crowd_db 质量契约
...
CI / pytest (Python 3.10) (push) Has been cancelled
CI / pytest (Python 3.11) (push) Has been cancelled
CI / pytest (Python 3.12) (push) Has been cancelled
## 实现内容 (6 项改动)
1. **admin /health 端点增强** — 主键契约 status:ok 保持 + checks 子对象
- db_writable: connect + CREATE TEMP TABLE + INSERT + SELECT + DROP
- disk_writable: 在 ops_alert_log_path 目录创建临时文件 + 删除
- settings_valid: 复用 is_jwt_secret_secure 判断
2. **_enforce_jwt_secret_policy** — prod env 使用 dev 默认 JWT / 长度<32 → fail-closed
3. **_enforce_default_admin_password_policy** — prod env 用 admin123 / 长度<10 / 字符类<3 → fail-closed
4. **L-A R7: admin UI footer** — dashboard.html (592 行) + ui.py 内联 admin/orders/new
模板加 footer 隐私政策 + 数据删除 + 服务说明链接, 与 portal _render_footer_links() 同口径
5. **L-A R1+R4: LEGAL_PRIVACY_BASELINE 文档同步**
- §6 移除孤儿 'admin' consent_channel 值 (代码侧从未实际产生)
- §7 已具备/尚缺 重写, 显式归到 6/20 增量
6. **Q-A: tests/test_crowd_db_data_quality.py** — 8 个测试锁住
- 27 省总数 + 仅湖南 high + 其它 26 省 ≤ usable
- 高考生源大省 (广东/江苏/北京/上海/山东/河南/四川/湖北) 不在 high 集合
- data_year=2025 (6/25 后需显式更新)
## 测试
- 4/4 RED → GREEN (admin/tests/test_health.py: JWT/admin password 拒绝 dev 默认值)
- 8/8 GREEN (data/crowd_db/tests/test_crowd_db_data_quality.py: 数据质量契约)
- 3 回归修复 (test_app.py + test_routes.py + test_health.py 适配新 /health checks 字段)
- 31/31 GREEN (admin/tests/test_app.py + test_routes.py + test_health.py)
## 报告
- reports/LA_LEGAL_PRIVACY_PRE_AUDIT_2026-06-20.md (363 行, 9 风险 0 阻塞)
- reports/QA_CROWD_DB_NON_HUNAN_DENSITY_AUDIT.md (45 行, CRITICAL 文档失真已规避)
## 文件
M CHANGELOG.md (v2.1.3)
M admin/config.py (2 个 _enforce_*_policy + load_settings post-load)
M admin/routes/health.py (3 个 _check_* + checks 子对象)
M admin/routes/ui.py (admin/orders/new 模板加 footer)
M admin/static/dashboard.html (footer 块)
M admin/tests/test_app.py (适配 checks 字段 + regex 兼容)
M admin/tests/test_health.py (4 个新测试)
M admin/tests/test_routes.py (适配 checks 字段)
M docs/CURRENT_STATE.md (0.3-0.5 增量段)
M docs/LEGAL_PRIVACY_BASELINE.md (§6 清理 + §7 重写)
+ data/crowd_db/tests/test_crowd_db_data_quality.py (8 tests)
+ reports/LA_LEGAL_PRIVACY_PRE_AUDIT_2026-06-20.md
+ reports/QA_CROWD_DB_NON_HUNAN_DENSITY_AUDIT.md
2026-06-20 18:36:23 +08:00
hermes
604c8b3484
docs(6/20 v2): CURRENT_STATE + 整改板 + 执行板 同步 A-2 收口
...
CI / pytest (Python 3.10) (push) Has been cancelled
CI / pytest (Python 3.11) (push) Has been cancelled
CI / pytest (Python 3.12) (push) Has been cancelled
- CURRENT_STATE.md:
- 状态词段升级: A-2 admin/外部渠道补录同意审计统一化已落地
- 新增 0.2 增量段: A-2 现象/根因/修复/落地细节
- 0.3 真相源分层保持
- ACTIVE_REMEDIATION_2026-06-20.md:
- A-2 状态: pending -> completed (6/20)
- 落地详情全列出
- 末尾任务表 A-2 状态: 是 -> 已收口
- ACTIVE_EXECUTION_BOARD_2026-06-20.md:
- A-2 状态: pending -> completed
- Owner / 落地 / 提交信息
dev-verify 验证: 1188 passed / 0 failed
ruff + mypy 通过
2026-06-20 15:31:21 +08:00
Hermes Agent
bd27b01e4e
merge: A-2 admin/外部渠道补录同意审计统一化
2026-06-20 15:29:06 +08:00
hermes
187b2ae634
fix(compliance): A-2 admin/外部渠道补录同意审计统一化
...
LEGAL_PRIVACY_BASELINE §4/§6 要求任何订单创建路径必须记录同意审计字段。
portal 路径已落 consent_channel=portal / consent_operator=guardian (见
web_public.py + intake_store.save), admin 路径 6/20 之前完全不入任何 consent
字段 (admin/routes/orders.py grep 'consent' 0 命中), 形成合规盲区。
落地:
- CreateOrderRequest 新增必填 consent: ConsentInfo
- consent_method Literal: verbal_chat / phone_recording / screenshot /
written_form / self_declared
- consent_note Optional[str]
- 缺失或非法 → HTTP 422
- Order 模型 + DAO _WRITABLE_COLUMNS 加 consent_method / consent_given_at
(冗余落库避免每次列表 join order_intakes)
- schema 增量: ALTER TABLE orders ADD COLUMN consent_method / consent_given_at
(幂等)
- create_order 同步写 order_intakes (独立 IntakeStore.for_db, 不复用 OrdersDAO
conn — T12-D conn ownership 修复保驾)
- consent_channel = payload.source (xianyu/wechat/school/web)
- consent_operator 严格按基线白名单 self/guardian/admin_import:
- web 渠道: 'guardian' (与 intake_store.save 默认值一致)
- 其他渠道: 'admin_import' (后台代录, 同意来源是渠道商)
- consent_method / consent_given_at / consent_note 落库
测试:
- test_create_order_rejects_missing_consent_block[xianyu|wechat|school|web] (4 个)
- test_create_order_writes_intake_record_with_consent_audit
- test_create_order_external_channel_marks_consent_operator_as_admin
- test_create_order_rejects_invalid_consent_method
- test_order_detail_returns_consent_method_and_given_at
- 更新 test_create_order_returns_masked_payload_with_history (加 consent)
- 更新 test_admin_orders_alias_list_and_detail (加 consent)
验证:
- 25/25 admin/tests/{test_routes_orders,test_admin_alias_routes} 通过
- ruff + mypy 通过
- 端到端 smoke: 4 笔订单 (2 terminal + 1 pending + 1 paid-in-window) 实测
包含 consent 字段全部通过
- dev-verify: 1186 passed / 2 failed (失败的 2 个均为 worktree 环境限制:
test_backup_restore_service_level 的 subprocess 路径假设 + 6/19 已知问题,
与本改动无关; main 上单跑同样测试通过)
2026-06-20 15:29:06 +08:00
hermes
f722123c08
docs(6/20): CURRENT_STATE + 整改板 + 执行板同步到 6/20
...
CI / pytest (Python 3.10) (push) Has been cancelled
CI / pytest (Python 3.11) (push) Has been cancelled
CI / pytest (Python 3.12) (push) Has been cancelled
- CURRENT_STATE.md: 顶部升级 6/20,新增 0.1/0.2 增量段
(T12-D conn ownership + 真相源分层)
- ACTIVE_REMEDIATION_2026-06-20.md: 新建 6/20 整改板
- 取代 6/19 历史快照
- 新增 A-2 后台/外部渠道补录同意审计统一化
- 标注 T12-D 端到端 acceptance 步骤就绪 + 实际部署动作待 ops
- ACTIVE_EXECUTION_BOARD_2026-06-20.md: 新建 6/20 执行板
- ACTIVE_REMEDIATION_2026-06-19.md / ACTIVE_EXECUTION_BOARD_2026-06-19.md:
顶部加"⚠ 历史快照"头注 + 6/20 增量跳转
dev-verify 验证: 1179 passed / 0 failed / coverage overall=85.05% / core=100%
ruff + mypy 通过;6 个 retention 测试全过;端到端 smoke 4 笔订单实测通过
2026-06-20 14:29:12 +08:00
Hermes Agent
f9e68ee453
merge: T12-D retention cleanup conn ownership fix
2026-06-20 14:25:19 +08:00
hermes
bcb1e68587
fix(retention): T12-D acceptance — OrdersDAO conn ownership
...
- OrdersDAO.__init__ 新增 owns_conn=False 参数
- __exit__ 仅在 owns_conn=True 时 close
- connect() classmethod 创建的 conn 自动 owns_conn=True
- 修复 retention_cleanup 一次命中 ≥2 笔终端态订单时
第二笔起 Cannot operate on a closed database 的 bug
- 新增 test_retention_cleanup_apply_anonymizes_multiple_old_orders_in_sequence
锁住多订单连续 anonymize 契约
- runbook §8 新增 T12-D 端到端本地 acceptance 步骤 + 部署前 checklist
- CHANGELOG 加 v2.1.1 (2026-06-20) 段
2026-06-20 14:25:19 +08:00
Hermes
2893a45d8b
feat(6/19): 保留期门禁 + 支付失败持久化 + 文档校准
...
CI / pytest (Python 3.10) (push) Has been cancelled
CI / pytest (Python 3.11) (push) Has been cancelled
CI / pytest (Python 3.12) (push) Has been cancelled
A1 删除/匿名化 180 天保留期门禁 (P0):
- admin/errors/codes.py + BIZ_ORDER_RETENTION_NOT_EXPIRED (E02002) -> HTTP 409
- admin/config.py + retention_days / GAOKAO_RETENTION_DAYS (默认 180)
- admin/routes/orders.py + _assert_retention_expired 守卫
- data/orders/deletion_service.py + RETENTION_GUARDED_STATUSES
- admin/tests/test_order_deletion.py + _expire_retention_window + 3 测试
B1 支付失败 webhook 持久化 (P1):
- data/payments/dao.py + failed_at/failure_reason/provider_trade_no/callback_payload
- data/payments/models.py + PaymentRecord 新字段
- data/payments/service.py handle_webhook 失败分支持久化
- data/payments/tests/test_webhook.py test_handle_webhook_persists_failed_status
A2 文档校准 (P1):
- README / PRD / ROADMAP / TECH_ARCHITECTURE 顶部对齐 6/19
B2 真相源分层 (P1):
- 6/13 整改板/执行板加历史快照前缀
- 新建 6/19 整改板/执行板
- CURRENT_STATE 顶部加 6/19 增量段 (在 6/13 真相源之上叠加)
dev-verify: 1175 passed (A1+B1+A2+B2) -> 1179 passed (+ T12-C),
coverage overall=85.05% / core=100%
2026-06-20 00:27:15 +08:00
Hermes
eac956a896
docs(review): 6/19 production strict review baseline
...
- reports/PRODUCTION_STRICT_REVIEW_2026-06-19.md: 当前真相版 review
- reports/STRICT_COMPREHENSIVE_REVIEW_2026-06-18.md: 昨日 review (历史快照)
- docs/plans/2026-06-19-production-readiness-remediation-plan.md: 6/19 整改计划
- docs/plans/2026-06-18-strict-review-remediation-plan.md: 昨日整改计划
2026-06-20 00:27:14 +08:00
Hermes
5a0b2a83ec
feat(portal): T12-C 前台删除工单 + 保留期外可申请交互
...
落地 T12-C: 让用户在 portal 删除工单页/POST 中都能看到该订单
当前所处保留期阶段(pending/within/outside),并按阶段给出明确的
next_step 文案。
- DeletionRequestCreate.scope 锁定到白名单
(order_only | order_and_attachments | full_account); 非法值 → 422
- _resolve_retention_status(order, settings) 复用
RETENTION_GUARDED_STATUSES + settings.retention_days
- POST 端 next_step 三种文案:
outside: 已超过 180 天保留期,可申请删除...
within: 订单仍在 180 天保留期内...
pending: 提交成功后将由人工核验后处理
- GET 端在表单上方插入'保留期状态'提示卡
- admin/tests/test_order_info_form.py 6 个新/增强测试 +
_expire_retention_window helper
dev-verify: 1179 passed (was 1175, +4 net new),
coverage overall=85.05% / core=100%, ruff + mypy clean
2026-06-20 00:26:59 +08:00
Hermes Agent
6d0feeb090
build: prove pdf runtime and strict remediation gates
CI / pytest (Python 3.10) (push) Has been cancelled
CI / pytest (Python 3.11) (push) Has been cancelled
CI / pytest (Python 3.12) (push) Has been cancelled
2026-06-18 17:40:12 +08:00
Hermes Agent
2d26d96eaa
fix: reduce portal and share exposure surfaces
2026-06-18 16:12:22 +08:00
Hermes Agent
ede9ffedd7
fix: align audit and payment failure contracts with real behavior
2026-06-18 16:00:57 +08:00
Hermes Agent
d415d8a494
build: tighten runtime contracts and dependency reproducibility
2026-06-18 15:50:23 +08:00
Hermes Agent
2da926bb5e
fix: tighten audit exposure and consent data handling
2026-06-18 15:36:24 +08:00
Hermes Agent
a82c5b3cca
fix: align retention cleanup across notifications logs and share telemetry
2026-06-18 15:20:16 +08:00
Hermes Agent
9a8ad91216
fix: stop exposing portal tokens across payment URLs and storage
2026-06-18 15:04:46 +08:00
Hermes Agent
c07c998204
fix: enforce admin role on backend order and audit routes
2026-06-18 14:36:38 +08:00
Hermes Agent
444fc8a530
fix: restrict portal report paths to trusted directories
2026-06-18 14:28:04 +08:00
Hermes Agent
af7ae3c6ce
docs: align product positioning with current system truth
2026-06-18 14:14:20 +08:00
Hermes Agent
6b0a4a9038
fix: make coverage gate reflect application code only
2026-06-18 14:07:26 +08:00
Hermes Agent
65f44c9718
fix: make backup verify safe for wal sqlite
2026-06-18 13:39:02 +08:00
Hermes Agent
6e06e150b0
docs(cleanup): archive top-level historical reports
CI / pytest (Python 3.10) (push) Has been cancelled
CI / pytest (Python 3.11) (push) Has been cancelled
CI / pytest (Python 3.12) (push) Has been cancelled
2026-06-18 11:01:15 +08:00
Hermes Agent
17973c6329
docs(cleanup): archive low-reference historical snapshots
CI / pytest (Python 3.10) (push) Has been cancelled
CI / pytest (Python 3.11) (push) Has been cancelled
CI / pytest (Python 3.12) (push) Has been cancelled
2026-06-18 10:58:10 +08:00
Hermes Agent
d2e37a4c61
docs(cleanup): mark historical snapshots in entry docs
CI / pytest (Python 3.10) (push) Has been cancelled
CI / pytest (Python 3.11) (push) Has been cancelled
CI / pytest (Python 3.12) (push) Has been cancelled
2026-06-18 10:53:49 +08:00
Hermes Agent
b3a5bb6d1e
docs(cleanup): add directory inventory for 417 files
CI / pytest (Python 3.10) (push) Has been cancelled
CI / pytest (Python 3.11) (push) Has been cancelled
CI / pytest (Python 3.12) (push) Has been cancelled
2026-06-18 10:49:29 +08:00
Hermes Agent
a015f6780a
docs(cleanup): finalize 417-file review inventory
CI / pytest (Python 3.10) (push) Has been cancelled
CI / pytest (Python 3.11) (push) Has been cancelled
CI / pytest (Python 3.12) (push) Has been cancelled
2026-06-18 10:46:40 +08:00
Hermes Agent
2252157cef
docs(review): close out 2026-06-17 optimization goal
CI / pytest (Python 3.10) (push) Has been cancelled
CI / pytest (Python 3.11) (push) Has been cancelled
CI / pytest (Python 3.12) (push) Has been cancelled
2026-06-18 10:27:54 +08:00
Hermes Agent
246f21c7f2
feat(review): land unified remediation and rules evidence closure
CI / pytest (Python 3.10) (push) Has been cancelled
CI / pytest (Python 3.11) (push) Has been cancelled
CI / pytest (Python 3.12) (push) Has been cancelled
2026-06-18 10:21:38 +08:00
Hermes
56cf2c3ee2
feat(rules): land hunan 2026 evidence layer (phase 4)
...
CI / pytest (Python 3.10) (push) Has been cancelled
CI / pytest (Python 3.11) (push) Has been cancelled
CI / pytest (Python 3.12) (push) Has been cancelled
Landing the first province sample of the rules/_evidence/ tree.
Locks down the hunan-2026 本科批 院校专业组 rule set so audit
output and downstream consumers can cite the source摘录 instead
of just 'trust me, the loader says so'.
What's in the box:
- rules/_evidence/README.md: directory contract, evidence-file
template (4 required sections), coverage table, and a note on
RuleLoader's future strict_evidence toggle.
- rules/_evidence/hunan/<11 rule keys>.md: one Markdown
摘录 per source_evidence_id declared in hunan.yaml
(mode / batch / max_volunteers / max_majors_per_group /
has_adjustment / adjustment_scope / retrieval_rule /
collection_count / subject_mode / official_url /
exam_subject_total). Each file carries the official quote,
the machine-readable YAML form, key edge cases, and the
next-review date.
- tests/test_rules_evidence_layer.py: 4 invariants
* README exists and documents the contract
* every active hunan.yaml source_evidence_id has a matching
.md file
* 11 evidence files contain the keywords that prove they
actually carry the rule (parameterised, one test per file)
* every evidence file has all 4 required template sections
* no orphan evidence files (file exists but no rule
references it)
Verification:
- focused: 27 passed (15 evidence-layer + 12 cli doctor)
- dev-verify full gate: all checks passed (ruff / mypy /
coverage / pytest / benchmark)
Follow-up (not in this commit):
- Wire RuleLoader.from_truth_root(strict_evidence=True) so
callers can opt in to fail-loud on missing evidence
- Extend the same pattern to national.yaml + 2-3 more
provinces
- Add a 'last_verified_at' field to each rule and surface
>90-day-old evidence via 'gaokao-cli rules status'
2026-06-17 22:39:56 +08:00
Hermes Agent
f5e7098c50
fix(landing+pricing): A) consult form privacy note + B) pricing page copy sync
...
CI / pytest (Python 3.10) (push) Has been cancelled
CI / pytest (Python 3.11) (push) Has been cancelled
CI / pytest (Python 3.12) (push) Has been cancelled
A) 首页咨询表单加隐私说明 (admin/routes/web_public.py):
- 在表单标题下方加 .consult-privacy 框:
'🔒 这些输入只用于判断要不要复核你的方案, 不会留底、不会用于生成方案、不会发邮件推销。
如果你决定不进入付费方案, 提交的资料不会保存到我们的数据库。'
- 在表单下方加 .consult-privacy-tail:
'不会收到营销短信, 提交后你也可以随时要求删除已填资料。'
- 新增 CSS: .consult-privacy (薄荷绿底+边框) / .consult-privacy-tail (灰色脚注)
- 设计意图: 不抢眼但能看见, 用浅色背景与表单区分, 不影响主 CTA 视觉权重
B) 套餐页 /pricing 同步'复核免费 / 方案付费' 口径:
- lead 文案加 <strong>复核现有方案本身免费</strong> (放在最前面)
- consult-summary 内加 consult-reassure 框:
'💡 如果你还没决定, 先做一次免费复核, 再决定要不要进入付费方案。'
- summary 副卡加 summary-reassure:
'🔒 还没下单前, 提交的基本情况仅用于判断是否需要复核, 不会留底。'
- trust-proof 1 号卡: '先审计再决定' → '复核免费 / 方案付费'
- trust-band 3 号卡: '合规入口可见' → '复核免费 / 方案付费' (新增回流入口)
- 49元档 eyebrow: '快速校验' → '复核 / 风险' (强调只审不改)
- 99元档 eyebrow: '完整规划' → '生成 / 完整' (强调生成动作)
- 199元档 eyebrow: '深度辅导' → '生成 / 深度'
- 49元档 desc: 加'不会重新生成志愿表 (生成需选 99 元)' 边界
- 99元档 desc: 加'方案生成与详细报告在支付后启动' 边界
- 199元档 desc: 加'在 99 元完整方案基础上提供多轮修订和深度解释'
- 49元档 CTA: '先做快速审核' → '先做付费审核' (用'付费'反衬'免费复核')
- 99元档 CTA: '立即开始完整规划' → '支付并启动方案生成'
- 199元档 CTA: '了解深度辅导' (保持)
- 49元档 features: 加'不重新生成志愿表(生成需选 99 元)' 边界
- 199元档 features: 加'包含 99 元完整方案的所有交付'
- FAQ 加 '复核是免费的吗?包含什么?' (明确边界: 复核免费/审核报告 49/完整方案 99起)
- 99元 FAQ 加 '99 元是生成一份完整方案的价格, 不是查看价格' 避免误解
- notice 提示: '先做一次免费复核' 引导 + 保留 49/99 路径建议
新增测试断言:
- 首页: '不会留底' / '不会用于生成方案' / '不会发邮件推销' / '不会收到营销短信' (4 条)
- 套餐页: '复核现有方案本身免费' / '复核免费 / 方案付费' / 'href="/#consult-box"' /
'先做一次免费复核' / '先做付费审核' / '支付并启动方案生成' / '复核 / 风险' /
'生成 / 完整' / '生成 / 深度' / '不会重新生成志愿表' / '支付后启动' /
'复核是免费的吗?包含什么?' / '还没决定' (13 条)
- 套餐页反向断言: '先做快速审核' / '立即开始完整规划' / '先审计再决定' / '快速校验' (4 条)
验证:
- pytest 22 passed (test_web_public + test_order_status_page + test_web_public_alipay_sim_e2e)
- ruff check: All checks passed
- 真实 HTTP 端到端 17/17 断言 OK (A 6 条 + B 20 条旧移除+新命中)
- Playwright vision 验证:
A) 首页隐私说明: 上下双向布局, 浅色克制, 覆盖'用途/营销/删除'三要素 ✅
B) 套餐页: lead/eyebrow/CTA/FAQ 5 处引导回首页 全部对齐'复核免费/方案付费' ✅
2026-06-17 22:38:42 +08:00
Hermes
a57522b11e
feat(cli): delegate channel/delivery/retention/backup to gaokao-cli (phase 3 batch 3)
...
CI / pytest (Python 3.10) (push) Has been cancelled
CI / pytest (Python 3.11) (push) Has been cancelled
CI / pytest (Python 3.12) (push) Has been cancelled
Round 3 of the unified gaokao-cli rollout. Adds four more passthrough
markers so the unified entry point can drive the remaining ops scripts
without bringing new data models into data/.
- data/cli_compat_delivery_dispatch.py: runpy shim for
scripts/gaokao-delivery-dispatch.py (DispatchDeliveryEvents).
- data/cli_compat_delivery_watchdog.py: runpy shim for
scripts/gaokao-delivery-watchdog.py (WatchdogDeliveryEvents).
- data/cli_compat_retention_cleanup.py: runpy shim for
scripts/gaokao-retention-cleanup.py (OrderRetentionCleanup).
- data/cli_compat_channel_fallback.py: forwarder for
data.channel_sync.monitor.main (CheckChannelHealth /
ManualTemplate).
- data/cli_compat_backup.py: subprocess wrapper that dispatches
scripts/backup_snapshot.sh and scripts/backup_verify.sh.
- data/rules/cli.py main(): routes gaokao-cli {channel, delivery
{dispatch,watchdog}, retention, backup {snapshot,verify}} to the
shims; rejects unknown subcommands with a structured error.
- docs/CLI_API_MAPPING.md §2.1: now lists 12 top-level commands with
their real subcommands and fallback paths.
- tests/test_cli_doctor_phase3.py: +6 tests covering channel
delegation, delivery dispatch / unknown-subcommand, retention
routing, backup shell routing, and backup unknown-subcommand
rejection.
Verification:
- focused: 12 passed
- dev-verify full gate: all checks passed (ruff / mypy / coverage /
pytest / benchmark)
2026-06-17 22:18:57 +08:00
Hermes Agent
81dbaddaea
fix(landing): align copy to '复核免费 / 方案付费' (no 免费咨询 promise)
...
CI / pytest (Python 3.10) (push) Has been cancelled
CI / pytest (Python 3.11) (push) Has been cancelled
CI / pytest (Python 3.12) (push) Has been cancelled
用户最新反馈: 首页不应承诺'免费咨询'; 复核现有方案是免费的, 完整方案
生成和深度辅导需在支付后启动。咨询入口只用于快速问询, 不是承诺
免费生成方案。
文案改动 (admin/routes/web_public.py):
- hero-note: '咨询本身免费' → '复核现有方案本身免费; 新方案生成与深度辅导在支付后启动'
- 咨询表单标题: '先告诉我们你的基本情况' → '告诉我们你的基本情况'
- 咨询表单副标题: '判断 + 适合路径' → '判断 + 说明后续可走步骤, 复核本身免费; 新方案生成与深度辅导在支付后启动'
- 当前目标 placeholder: '先审计现有方案' → '先复核现有方案'
- 补充说明 placeholder: '想先看风险' → '想先看有没有明显风险'
- 主按钮: '获取推荐路径' → '获取复核与推荐'
- 次按钮: '直接看套餐' → '直接看付费套餐'
- hero-trust 1 号卡: '先审计后规划' → '复核免费 / 方案付费'
- hero-points lead: '先做审核' → '先做免费复核'; '再决定是否进入完整规划' → '再决定是否进入付费的完整规划'
- 服务流程 01 步: '选择服务深度' → '先判断入口' ('方案复核(免费) vs 完整方案/深度辅导(付费)')
- 服务流程 02 步: '避免在支付前被长表单劝退' → '选完整方案或深度辅导时, 先填最小信息后再支付'
- 服务流程导语: '比空泛地说智能系统已接入更重要' → '复核免费, 方案生成和深度辅导需付费'
- 底部 CTA 标题: '先看套餐, 再决定是否立即下单' → '已有方案? 先免费复核; 明确要做? 看付费套餐'
- 底部 CTA 副标题: '如果你已经明确要做完整方案, 可以直接进入 99 元方案页' → '如果已经拿到一版方案, 可先做一次免费复核; 明确要完整方案或深度辅导, 可直接进入套餐页'
测试更新 (admin/tests/test_web_public.py):
- 移除对'咨询本身免费' / '先审计后规划' / '先告诉我们你的基本情况' / '获取推荐路径' / '先看套餐' 的正向断言
- 改为反向断言 (确保旧文案已清除) + 新口径的正向断言
- 新增 9 条新口径断言: '复核现有方案本身免费' / '新方案生成与深度辅导在支付后启动' /
'复核免费 / 方案付费' / '获取复核与推荐' / '直接看付费套餐' / '方案复核(免费)' /
'深度辅导(付费)' / '已有方案? 先免费复核' / '告诉我们你的基本情况'
验证:
- pytest 22 passed (test_web_public + test_order_status_page + test_web_public_alipay_sim_e2e)
- 真实 HTTP 19/19 文案断言全部 OK (旧文案已清除, 新文案已上线)
- Playwright 截图 vision 验证: 5/5 触点对齐口径 (hero CTA / hero-note / 咨询表单 /
hero-trust 1 号卡 / 服务流程 + 底部 CTA)
2026-06-17 22:11:31 +08:00
Hermes Agent
f420301571
fix(plan-b): align landing CTAs to 立即咨询/查看套餐 + fix mobile sticky bottom
...
CI / pytest (Python 3.10) (push) Has been cancelled
CI / pytest (Python 3.11) (push) Has been cancelled
CI / pytest (Python 3.12) (push) Has been cancelled
A) 首页 hero CTAs 改成方案 B 原意:
- 旧: 立即咨询 (secondary) + 先做快速审核 (primary)
- 新: 立即咨询 (primary) + 查看套餐 (primary) — 两个并列主 CTA
- hero-note 从'适合已经拿到一版方案' 改为'咨询本身免费, 不必先付款'
B) 资料页移动端关键操作按钮改为 fixed 底部:
- 把 .wizard-actions 移出 <form>, 让它成为所有 step-panel 的同级元素
- 移动端 (max-width: 980px) 用 position: fixed 而非 sticky
- safe-area-inset-bottom 适配 iPhone 刘海/灵动岛
- 主面板 padding-bottom: 168px 防止按钮遮挡最后内容
- 桌面端 (desktop) 仍保留 sticky 行为, 不影响长内容阅读
测试覆盖:
- test_public_landing_page_served: 更新断言验证两个主 CTA 均为 btn-primary,
旧'先做快速审核' 已移除, 新'咨询本身免费' 文案已加入
- test_info_page_wizard_actions_outside_form_for_sticky_bottom: 验证
.wizard-actions 在 </form> 之后 (sibling 关系), 按钮文案齐全, safe-area 适配
Playwright 验证:
- scroll=0/800/1500 时, wizard-actions 始终在 viewport y=622-844 (固定底部)
- vision 验证: 顶部缺失项提示 + 底部 3 个主操作按钮 (上一步/下一步/保存草稿) 全部可见
测试结果: 22 passed (test_web_public + test_order_status_page + test_web_public_alipay_sim_e2e)
ruff: All checks passed
2026-06-17 21:50:06 +08:00
Hermes
77cde03f1d
feat(cli): delegate share/payment-doctor to gaokao-cli (phase 3 batch 2)
...
CI / pytest (Python 3.10) (push) Has been cancelled
CI / pytest (Python 3.11) (push) Has been cancelled
CI / pytest (Python 3.12) (push) Has been cancelled
Builds on 7d31d75 (order delegation + doctor self-check). The unified
gaokao-cli now also wraps the legacy shortlink and payment-doctor
scripts through thin runpy-based compat shims.
- data/cli_compat_gaokao_shortlink.py: loads scripts/gaokao-shortlink
via runpy.run_path; preserves argv routing for native subcommands
(create/list/resolve/revoke/...).
- data/cli_compat_payment_doctor.py: loads scripts/payment_provider_doctor.py;
strips the leading 'doctor' marker (the legacy script takes no args)
and rejects unrecognised tokens so silent flag drops are surfaced.
- data/rules/cli.py main(): routes gaokao-cli {share,payment} <...>
to the compat shims; gaokao-cli order remains delegated to
data.orders.cli.
- docs/CLI_API_MAPPING.md §2.1: records the actually-shipped command
surface (rules / majors / majors school-* / audit / order / share /
payment doctor / doctor) so the design doc matches runtime.
- tests/test_cli_doctor_phase3.py: covers share delegation, payment
doctor rejection, and the passthrough help flow.
Verification:
- focused: 6 passed
- dev-verify full gate: all checks passed (ruff / mypy / coverage / pytest / benchmark)
2026-06-17 19:16:44 +08:00
Hermes
38f74bd1f1
feat(portal): add payment-success intermediate page + status/info copy
...
CI / pytest (Python 3.10) (push) Has been cancelled
CI / pytest (Python 3.11) (push) Has been cancelled
CI / pytest (Python 3.12) (push) Has been cancelled
After successful payment, the gateway now lands users on an
intermediate 'payment-success' page that explains next steps
(continue intake, or jump to status) before they continue into
the live status view. This is a product-experience improvement
over the old direct /status redirect and was already staged in
uncommitted web_public work; this commit lands the matching test
assertions and copies.
Changes:
- admin/routes/web_public.py
* /portal/{token}/payment-success route + _render_payment_success_page
* payment_return_page now redirects to /payment-success (303)
* landing_page renders a 'consult' quick-intake card
- admin/tests/test_web_public.py
* test_payment_return_redirects_to_payment_success_page
* test_payment_success_page_served_after_paid_order
* landing/pricing/info/status copy assertions
- admin/tests/test_order_info_form.py
* assert the 'still need to fill' reminder renders
- admin/tests/test_order_status_page.py
* test_info_required_status_page_emphasizes_continue_intake
* assert '查看报告' / '查看当前进度' on delivered/processing status
- admin/tests/test_web_public_alipay_sim_e2e.py
* accept the new /payment-success intermediate page
- tests/test_cli_doctor_phase3.py
* drop unused pytest import (ruff F401)
Verification:
- focused alipay_sim E2E: 1 passed
- dev-verify full gate: all checks passed (ruff / mypy / pytest / coverage / benchmark)
2026-06-17 18:50:08 +08:00
Hermes
7d31d75145
feat(cli): add order delegation + doctor self-check (phase 3)
...
CI / pytest (Python 3.10) (push) Has been cancelled
CI / pytest (Python 3.11) (push) Has been cancelled
CI / pytest (Python 3.12) (push) Has been cancelled
docs-only + cli: extend scripts/gaokao-cli with two thin wrappers
without changing data/rules, data/majors_catalog, or rules/_truth.
- gaokao-cli order <subcommand> delegates argv to data.orders.cli.main
with the 'order' prefix stripped, so callers can use the unified
command face without changing the existing orders parser.
- gaokao-cli doctor <json?> returns a single self-check payload that
reuses RuleLoader + MajorsCatalogLoader (no new dependencies, no
gaokato/ scaffolding). Truth-root or catalog-root failures degrade
gracefully with structured {error, ok=false} sections instead of
raising.
- tests/test_cli_doctor_phase3.py covers: help text, order delegation
to list subcommand, doctor ok-path, doctor failure-path.
Also re-aligns docs/ACTIVE_EXECUTION_BOARD_2026-06-17.md (new) +
docs/CURRENT_STATE.md (single execution口径) + rules/majors source-
of-truth index files so design-phase numbering no longer drifts from
execution-phase numbering. Pre-existing 2026-06-16 optimization board
and 2026-06-17 phase2 plan are demoted to historical snapshots.
P0_P1_P2 remediation plan §4 historical cards get a red warning
banner so they are not re-read as current pending.
Verification:
- focused: 4 passed
- dev-verify: 770 passed, 1 failed
(alipay_sim E2E failure pre-existed this commit; caused by an
uncommitted upstream edit in admin/routes/web_public.py that
rewires payment_return -> /portal/{token}/payment-success while
the E2E still asserts /portal/{token}/status; out of scope for
this commit and intentionally not touched.)
2026-06-17 18:05:16 +08:00
Hermes Agent
edc5b11230
feat(audit): validate majors in structured audit flow
CI / pytest (Python 3.10) (push) Has been cancelled
CI / pytest (Python 3.11) (push) Has been cancelled
CI / pytest (Python 3.12) (push) Has been cancelled
2026-06-17 16:02:31 +08:00
Hermes Agent
6b1157fe19
feat(majors): add school catalog skeleton and verification
CI / pytest (Python 3.10) (push) Has been cancelled
CI / pytest (Python 3.11) (push) Has been cancelled
CI / pytest (Python 3.12) (push) Has been cancelled
2026-06-17 12:46:04 +08:00
Hermes Agent
36ad58a253
feat(majors): add phase2 national catalog mvp
CI / pytest (Python 3.10) (push) Has been cancelled
CI / pytest (Python 3.11) (push) Has been cancelled
CI / pytest (Python 3.12) (push) Has been cancelled
2026-06-17 12:06:46 +08:00
Hermes Agent
25a84c426b
feat(admin): add hidden dashboard seed-order tools
...
CI / pytest (Python 3.10) (push) Has been cancelled
CI / pytest (Python 3.11) (push) Has been cancelled
CI / pytest (Python 3.12) (push) Has been cancelled
- add hidden dev-only seed endpoint /api/admin/orders/dev-seed
- overdue_pending_once: create one 2-day-old pending order with draft intake
- cleanup_demo_seed: delete demo-tagged seeded orders
- restrict hidden seed route to non-prod env
- avoid decrypting all orders during cleanup; query ids/tags directly from SQL
- dashboard hidden entry:
- title id=dashboard-title
- dev-seed-panel hidden by default
- opens via 5 title clicks or ?seed-tools=1
- buttons: 补 1 笔超时待办 / 清理演示造数
- dashboard JS:
- postDevSeed()
- panel show/hide
- refresh dashboard after seed/cleanup
- tests:
- route auth + create/cleanup flow
- dashboard HTML/JS structure assertions
- admin UI page exposes hidden entry markup
- verification:
- pytest 69 passed
- browser: ?seed-tools=1 展开面板, 补造后 pending=8 overdue=1 missing=8, 清理后恢复 pending=7 overdue hidden
2026-06-17 10:42:14 +08:00
Hermes Agent
8a61b8fe4a
fix(rules): close phase15 verify and legacy checker migration
CI / pytest (Python 3.10) (push) Has been cancelled
CI / pytest (Python 3.11) (push) Has been cancelled
CI / pytest (Python 3.12) (push) Has been cancelled
2026-06-17 09:01:43 +08:00
Hermes Agent
fd7174a70e
feat(stats+dashboard): expand pending_orders into 3 actionable dimensions
...
CI / pytest (Python 3.10) (push) Has been cancelled
CI / pytest (Python 3.11) (push) Has been cancelled
CI / pytest (Python 3.12) (push) Has been cancelled
## 后端 admin/stats.py
- compute_summary 在单条聚合 SQL 中加两个新字段:
- pending_overdue_24h: status='pending' AND created_at < (now - 24h)
(超时未付,需主动催付)
- pending_missing_intake: status='pending' AND
(order_intakes 无记录 OR order_intakes.status='draft')
(资料待补,需主动跟进)
- LEFT JOIN order_intakes AS i ON i.order_id = orders.id
- 关键 bug 修复: SQL ? 顺序与参数顺序必须匹配,
(overdue_cutoff 在 IN 子句后) 之前误用 (overdue_cutoff, *_REVENUE_STATUSES)
导致 overdue_cutoff datetime 字符串误入 IN 子句,
'completed' 误入 created_at < ? 子句, 收入少算 30%。
已修正为 (*_REVENUE_STATUSES, overdue_cutoff)
- 列名全部限定为 orders.status / orders.created_at,避免与 i.status 歧义
## 前端 admin/static/dashboard.html
- KPI 4 待处理订单卡加 .pending-breakdown 区域
- 两个 pill 标签: pending-tag-overdue(红色,超时) + pending-tag-missing(橙色,资料待补)
- 仅在对应字段 > 0 时才显示
- CSS .pending-tag[hidden] { display: none; } 确保 hidden 属性生效
## 前端 admin/static/dashboard.js
- renderSummary 新增 pending_overdue_24h / pending_missing_intake 渲染
- 至少一个非零才展开 breakdown 区域
## 测试
- conftest.py orders_db fixture 同时建 order_intakes 表,避免 LEFT JOIN 缺表
- test_routes_stats_dashboard.py:
- test_dashboard_empty_db_shape 锁住 summary 必须含 12 字段
- test_dashboard_summary_pending_orders 更新 revenue 期望 (paid + serving 计入)
- 新增 test_dashboard_summary_pending_overdue_24h (2天前 vs 12h前)
- 新增 test_dashboard_summary_pending_intake (submitted/draft/无 intake 4 种组合)
- test_app.py 加 pending-breakdown 结构断言
- pytest 52 passed
## 真实环境验证
- admin/test-pass-123 登录后:
pending=7 overdue=0 missing_intake=7
- 视觉验证: KPI 4 显示 '7' 主值 + '资料待补 7' 橙色 pill
'超时' pill 因 overdue=0 自动隐藏
- 数据一致性: by_status.pending=7 与 summary.pending_orders=7 一致
2026-06-16 21:48:18 +08:00
Hermes Agent
ca80d7ba0e
feat(stats): add pending_orders to dashboard summary
...
CI / pytest (Python 3.10) (push) Has been cancelled
CI / pytest (Python 3.11) (push) Has been cancelled
CI / pytest (Python 3.12) (push) Has been cancelled
- admin/stats.py compute_summary 在单条聚合 SQL 中加 pending_orders 字段
(status = 'pending' 计数),与 total_orders / total_revenue_cents 共用一条 SQL
- 修复 dashboard '待处理订单' KPI 4 一直显示 0 的问题
- 前端 dashboard.js 已读 summary.pending_orders ?? 0,无需改动
- 测试:
- test_routes_stats_dashboard.py 加 test_dashboard_summary_pending_orders
(3 pending + 2 paid + 1 serving + 1 refunded 验证 pending=3、revenue=30000、
by_status.pending=3 与 summary.pending_orders 一致)
- test_routes_stats_dashboard.py test_dashboard_empty_db_shape 更新 key 集
- test_app.py test_create_app_bootstraps_orders_schema summary 等式加 pending_orders: 0
- 真实环境验证:admin/test-pass-123 登录后 11 orders / 7 pending 与 by_status 一致
2026-06-16 21:16:39 +08:00