Files
gaokao-volunteer-system/CHANGELOG.md
Hermes Agent cad78940ef
Some checks failed
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(6/21-6/24): 系统复审 + 全升级规划 + TestClient 覆盖报告
新增文档:
- reports/STRICT_SYSTEM_REVIEW_2026-06-23.md (滚动严格复审过程稿)
- reports/STRICT_SYSTEM_REVIEW_2026-06-24.md (汇总版, 149 passed)
- reports/TEST_CLIENT_COVERAGE_2026-06-23.md (主链路真实 TestClient 覆盖收口)
- docs/plans/2026-06-23-full-upgrade-optimization-plan.md (全升级优化计划)
- docs/COMPETITOR_SCREEN_ANALYSIS_WENXIN_QIANWEN_2026-06-21.md (竞品分析)
- docs/FIELD_MAPPING_AUDIT_FIRST_PROFILE_2026-06-21.md (首版字段映射审计)
- docs/PAGE_REDESIGN_CHECKLIST_2026-06-21.md (页面重设计清单)
- docs/REPORT_PROFILE_VERSION_RELATION_2026-06-22.md (报告版本关系)
- docs/P0_EXECUTION_TASK_BREAKDOWN_2026-06-22.md (P0 任务拆解)
- docs/P0_MINIMAL_API_CHANGES_2026-06-22.md (P0 最小 API 改动)
- docs/UPGRADE_EXECUTION_BOARD_2026-06-22.md (升级执行板)
- product/PRD_UPGRADE_2026-06-21.md (PRD 升级版)

CHANGELOG.md 同步本轮 commits
2026-06-25 09:28:23 +08:00

48 KiB
Raw Blame History

变更日志

记录高考志愿填报智能系统的所有变更。


v2.1.8 (2026-06-24) — 测试弃用 warning 清零

🧪 测试依赖

  • requirements-dev.txt 新增 httpx2>=2.0.0
  • starlette.testclienthttpx2 的弃用 warning 已清除

验证

  • ./.venv/bin/python -m pytest -q admin/tests/test_order_status_page.py admin/tests/test_web_public.py admin/tests/test_web_public_content_pages.py admin/tests/test_web_public_review_flow.py admin/tests/test_web_public_portal_info.py admin/tests/test_order_deletion.py admin/tests/test_routes_cases.py admin/tests/test_routes_stats_dashboard.py admin/tests/test_admin_ui_pages.py admin/tests/test_order_info_form.py data/orders/tests/test_schema.py data/orders/tests/test_public_flow.py tests/test_backup_restore_service_level.py149 passed

v2.1.7 (2026-06-24) — 严格审查汇总版与最新入口切换

📄 审查与文档

  • 新增 reports/STRICT_SYSTEM_REVIEW_2026-06-24.md
    • 以当前仓库状态重写严格审查汇总版,不再继续在 6/23 过程稿上叠加历史结论
    • 明确当前结论:前台主链路、后台安全边界、恢复演练口径、后台录单契约、第五轮补充问题均已修复
  • docs/CURRENT_STATE.md 已切换为以 STRICT_SYSTEM_REVIEW_2026-06-24.md 作为最新严格审查结论
  • docs/NAVIGATION.md 已新增 6/24 汇总版入口,同时保留 6/23 过程稿作为历史轨迹参考

验证

  • ./.venv/bin/python -m pytest -q admin/tests/test_order_status_page.py admin/tests/test_web_public.py admin/tests/test_web_public_content_pages.py admin/tests/test_web_public_review_flow.py admin/tests/test_web_public_portal_info.py admin/tests/test_order_deletion.py admin/tests/test_routes_cases.py admin/tests/test_routes_stats_dashboard.py admin/tests/test_admin_ui_pages.py admin/tests/test_order_info_form.py data/orders/tests/test_schema.py data/orders/tests/test_public_flow.py tests/test_backup_restore_service_level.py149 passed, 1 warning

v2.1.6 (2026-06-23) — 主链路真实 TestClient 覆盖收口

🧪 测试可信度收口

  • 用户端主链路不再依赖 RouteClient 自证
    • 公开页、内容页、资料页、状态页、报告页、CWB、full-plan、payment-success 的关键页面访问已迁到真实 TestClient
    • POST /api/public/ordersPOST /review/action(真实 form + 303POST /pay/mock/{payment_id}/complete 的主链路已迁到真实 client
  • 前台关键测试文件已清零 RouteClient
    • admin/tests/test_web_public.py
    • admin/tests/test_web_public_content_pages.py
    • admin/tests/test_web_public_review_flow.py
    • admin/tests/test_web_public_portal_info.py
    • admin/tests/test_order_status_page.py
  • 剩余 RouteClient 已降级为非前台主证据
    • 仅作为仓库中的轻量辅助夹具保留,不再用于这批关键前台测试文件

📄 文档

  • 新增 reports/TEST_CLIENT_COVERAGE_2026-06-23.md
  • reports/STRICT_SYSTEM_REVIEW_2026-06-23.md 与覆盖报告已互链
  • docs/CURRENT_STATE.md 已将两份 6/23 报告纳入真相源优先级前部

验证

  • ./.venv/bin/python -m pytest -q admin/tests/test_web_public.py admin/tests/test_web_public_review_flow.py admin/tests/test_web_public_portal_info.py54 passed, 1 warning
  • ./.venv/bin/python -m pytest -q admin/tests/test_order_status_page.py admin/tests/test_web_public.py admin/tests/test_web_public_content_pages.py admin/tests/test_web_public_review_flow.py admin/tests/test_web_public_portal_info.py data/orders/tests/test_schema.py89 passed, 1 warning

v2.1.5 (2026-06-23) — P1/P2 页面升级与轻量版本管理

新增

  • Step 2-4 / P2 偏好收口
    • Portal Step 2 新增 target_cities 输入控件
    • submit_order_info 现在保留 profile_versions[]latest_profile_version_id,相同快照不重复记版本
  • 报告页 / 冲稳保页辅助能力升级
    • 报告页新增“基于最新档案生成 / 基于历史档案版本生成,建议刷新”判断
    • 报告页与冲稳保页新增政策中心、同分段参考入口与辅助判断因子区块
    • 完整规划入口页新增版本历史与辅助判断因子区块
  • 统一信任条
    • 政策中心与同分段参考页改为共用统一信任条:来源、更新时间、适用范围、适用省份、置信等级、边界文案
    • 同分段页继续保留“非高置信数据不得作为强推荐依据”约束
  • 轻量报告版本元数据
    • order_intakes.payload_json 新增 report_versions[] / latest_report_version_id
    • 报告页外显与 profile_versions[] / review_results{} 形成最小版本关系

🧪 测试

  • admin/tests/test_web_public_portal_info.py
    • test_portal_info_page_renders_target_cities_field
    • test_submit_order_info_creates_profile_version_history_without_duplicate_snapshots
  • admin/tests/test_web_public_review_flow.py
    • test_cwb_page_links_policy_same_score_and_auxiliary_factors
    • test_report_page_shows_latest_profile_state_and_helper_links
    • test_report_page_warns_when_based_on_historical_profile_version
    • test_full_plan_page_shows_profile_versions_and_assessment_context
  • admin/tests/test_web_public_content_pages.py
    • test_policy_and_same_score_pages_expose_helper_navigation
  • 回归:./.venv/bin/python -m pytest -q admin/tests/test_web_public_content_pages.py admin/tests/test_web_public_portal_info.py admin/tests/test_web_public_review_flow.py data/orders/tests/test_schema.py60 passed

v2.1.4 (2026-06-23) — 审核优先主线第三轮质量收敛

新增

  • 审核页最小输入 / 约束 / 输出 / 分流四区块收口
    • admin/routes/web_public.pyReviewResultContract 新增 review_input_summary / review_input_attachments / review_constraints
    • /review/start 现在支持承接首页 province / score / goal / consult 查询参数,并把最小约束与现有方案说明写入轻量 review result
    • 审核结果页不再只展示 JSON占位页已补齐“审核输入 / 最小约束 / 审核输出摘要 / 下一步分流”四区块
  • 首页咨询卡回到审核主线
    • 首页咨询表单由 /pricing 改为 /review/start
    • 增加隐藏字段 source=home,保持 review_entry_source 可追踪
  • 工作台主动作按资料完整度收口
    • 当 Step 1 已完成且还没有最近一次复核结果时,首页工作台默认动作改为“开始方案复核”
    • 仍保留“继续补充 Step 1”与“继续查看最近一次复核”两种路径

🐛 修复

  • 第三轮质量收敛残留:首页咨询卡此前仍把用户导向 /pricing,与 P0“先审核再规划”主线不一致
  • 第三轮质量收敛残留:审核页此前只有轻量 JSON 占位,未满足“输入区 / 最小约束区 / 结果区 / 分流区”结构验收
  • 第三轮质量收敛残留Step 1 已完整但无复核结果时,首页工作台仍默认指向补资料,造成主动作偏移

🧪 测试

  • admin/tests/test_web_public_review_flow.py
    • test_landing_page_review_consult_form_targets_review_start
    • test_landing_page_uses_review_as_workspace_primary_action_when_step1_complete
    • test_review_start_page_renders_input_constraints_result_and_diversion
  • 回归:./.venv/bin/python -m pytest -q admin/tests/test_web_public.py admin/tests/test_web_public_content_pages.py admin/tests/test_web_public_portal_info.py admin/tests/test_web_public_review_flow.py data/orders/tests/test_schema.py70 passed

v2.1.3 (2026-06-20) — 生产加固 + L-A 送审前修复 + crowd_db 质量契约

新增

  • admin /health 端点增强 (6/20 加固)
    • 主键契约: status: "ok" (PRODUCTION_DEPLOYMENT_CHECKLIST §4 liveness probe)
    • 新增 checks 子对象: db_writable / disk_writable / settings_valid
    • DB 可写: connect + CREATE TEMP TABLE + INSERT + SELECT + DROP
    • 磁盘可写: 在 ops_alert_log_path 目录创建临时文件 + 删除
    • settings_valid: 复用 is_jwt_secret_secure 判断配置就绪
    • 仍不暴露环境/路径/版本细节
  • _enforce_jwt_secret_policy (P2-4 同级, 6/20 加固)
    • GAOKAO_ENV=prod + dev 默认 JWT secret → RuntimeError fail-closed
    • GAOKAO_ENV=prod + JWT secret 长度 < 32 → RuntimeError fail-closed
  • _enforce_default_admin_password_policy (6/20 加固)
    • GAOKAO_ENV=prod + GAOKAO_ADMIN_PASS=admin123 → RuntimeError fail-closed
    • GAOKAO_ENV=prod + 密码 < 10 字符 / 字符类 < 3 → RuntimeError fail-closed
  • tests/test_crowd_db_data_quality.py (Q-A 闭环, CROWD_DB_DATA_QUALITY §7 承诺的锁死文件)
    • 锁住 27 省总数 + 仅湖南 high + 其它 26 省 ≤ usable + 高考生源大省不在 high 集合
    • 锁住 data_year=2025 (6/25 后需显式更新)
    • 防止"27 省高置信"合规假象回归
  • admin 后台 footer 隐私政策链接 (L-A R7)
    • admin/static/dashboard.html (592 行) 加 <footer> 块, 链接 /privacy + /deletion-policy + /service-terms
    • admin/routes/ui.py 内联 admin/orders/new 模板 (line 182 闭包) 同步加 footer
    • 与 portal 前台 _render_footer_links() 同口径

🐛 修复

  • L-A R1: docs/LEGAL_PRIVACY_BASELINE.md §6 consent_channel 列表移除孤儿 admin 渠道值 (代码侧从未实际产生)
  • L-A R4: docs/LEGAL_PRIVACY_BASELINE.md §7 "已具备/尚缺" 同步 6/20 A-2 + T12-D 进展 (后台/外部渠道补录同意审计 + 数据删除 SOP 脚本化)

📝 文档

  • docs/LEGAL_PRIVACY_BASELINE.md §6 增注释说明 admin 渠道值移除原因
  • docs/LEGAL_PRIVACY_BASELINE.md §7 重写"已具备/尚缺"分区, 显式归到 6/20 增量
  • docs/CURRENT_STATE.md 状态词段升级 (见下)
  • docs/ACTIVE_REMEDIATION_2026-06-20.md 加固项标记 completed
  • reports/PRODUCTION_HARDENING_AUDIT_2026-06-20.md (子代理失信, 主代理自跑)
  • reports/LA_LEGAL_PRIVACY_PRE_AUDIT_2026-06-20.md (子代理 363 行交付)
  • reports/QA_CROWD_DB_NON_HUNAN_DENSITY_AUDIT.md (子代理 45 行交付)

🧪 测试

  • admin/tests/test_health.py:
    • test_health_endpoint_returns_minimal_readiness_only (升级: 断言 checks 子对象)
    • test_load_settings_prod_rejects_dev_jwt_secret (新)
    • test_load_settings_prod_rejects_short_jwt_secret (新)
    • test_load_settings_prod_rejects_default_admin_password (新)
  • data/crowd_db/tests/test_crowd_db_data_quality.py (新, 8 个测试):
    • test_total_provinces_is_27
    • test_hunan_is_the_only_high_quality_province
    • test_hunan_confidence_meets_high_threshold
    • test_non_hunan_provinces_not_high
    • test_high_population_provinces_acknowledged_as_skeleton_or_lower
    • test_quality_levels_are_valid_enum
    • test_confidence_values_in_valid_range
    • test_data_year_is_2025_until_2026_published

v2.1.2 (2026-06-20) — A-2 后台/外部渠道补录同意审计统一化

新增

  • admin POST /api/orders 强制要求 consentA-2 落地)
    • CreateOrderRequest 新增必填字段 consent: ConsentInfo
    • ConsentInfo.consent_method 白名单: verbal_chat / phone_recording / screenshot / written_form / self_declared
    • ConsentInfo.consent_note 可选, 表示"已确认但无备注"
    • 缺失或非法 → HTTP 422
    • 4 个 source (xianyu / wechat / web / school) 一致处理
  • Order 冗余字段: consent_method + consent_given_at
    • 落 orders 表, 避免每次列表 join order_intakes
    • schema 增量升级: ALTER TABLE orders ADD COLUMN consent_method TEXT (幂等)
    • schema 增量升级: ALTER TABLE orders ADD COLUMN consent_given_at TEXT (幂等)
    • DAO _WRITABLE_COLUMNS 加新字段
  • 创建订单后同步写 order_intakes 记录
    • 与 portal 路径同口径: consent_version / consent_scope / consent_channel / consent_operator / consent_method / consent_given_at / consent_note
    • consent_channel = 渠道 source (xianyu / wechat / school / web)
    • consent_operator 严格按 LEGAL_PRIVACY_BASELINE §4 白名单 self / guardian / admin_import:
      • web 渠道: guardian (用户本人或监护人自助 portal, 与 intake_store.save 默认值一致)
      • 其他渠道 (xianyu / wechat / school): admin_import (后台代录, 同意来源是渠道商)

🐛 修复

  • 后台代录合规盲区: 6/20 之前 admin create_order 路径完全不入任何 consent 字段 (consent 字段在 admin/routes/orders.py grep 0 命中), 直接违反 LEGAL_PRIVACY_BASELINE §6。现已统一审计口径。

📝 文档

  • docs/LEGAL_PRIVACY_BASELINE.md §6 已隐含 admin 补录需 consent 字段, 本次落地后真正闭环
  • docs/ACTIVE_REMEDIATION_2026-06-20.md A-2 状态从 pending 升级为 completed
  • CHANGELOG.md 顶部加 v2.1.2 段

🧪 测试

  • 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 块)

v2.1.1 (2026-06-20) — T12-D retention cleanup 生产化部署验收

🐛 修复

  • retention cleanup 多订单 anonymize 崩溃P0 — T12-D 端到端 acceptance 必现)
    • 现象: retention_cleanup.run_cleanup(apply=True) 在一次命中 ≥ 2 笔终端态订单时, 第二笔开始全部 sqlite3.ProgrammingError: Cannot operate on a closed database
    • 根因: OrdersDAO.__exit__ 不区分连接所有权,对外部 service 传入的 self._connclose()deletion_service.anonymize_order 把 service 持有的 连接包成 OrdersDAO(self._conn) 走 with-block第一笔执行完就把连接关掉
    • 触发条件: 生产 retention_days=180 + 周日 03:30 timer 触发时极易命中
    • 修复: OrdersDAO.__init__ 新增 owns_conn: bool = False 参数; __exit__ 仅在 owns_conn=True 时 closeconnect() classmethod 创建的连接自动设 owns_conn=True(保持原行为)
    • 回归测试: tests/test_retention_cleanup.py::test_retention_cleanup_apply_anonymizes_multiple_old_orders_in_sequence 锁住多订单连续 anonymize 契约

📝 文档

  • docs/DELIVERY_RETENTION_OPS_RUNBOOK.md §8 新增 T12-D 本地端到端 acceptance 步骤
    • 验收通过判定表6 项全过)+ 部署前 checklist
  • 历史 bug 背景已写入 runbook §8.4,避免后续误判为"运行环境问题"

v2.1 (2026-06-13)

🚧 进行中

新增T5.3 已完成)

  • 📝 T5 集成测试与文档收口
    • T5.1 端到端主链已固化到 tests/test_t5_e2e_workflows.py:覆盖“咨询→方案生成 / 审核→报告 / 订单→交付 / 升级流程 / 数据溯源展示”5 条主链
    • T5.2 性能与并发门禁已固化到 tests/test_t5_performance.py
      • gaokao-quick-3min.py 的真实 parse_quick_response + generate_quick_summary + generate_quick_recommendation 链路 100 次执行断言 < 5s
      • locustfile.pyadmin.app 做 10 并发、15 秒 headless 压测,断言聚合成功率 >95%
    • T5.3 文档同步:重写 docs/API.mddocs/ARCHITECTURE.md 以匹配当前已落地真相,并补充 T5 验证入口与当前系统边界说明
    • 定向验证python3 -m pytest tests/test_t5_e2e_workflows.py tests/test_t5_performance.py -q 通过;其中性能基准覆盖 100 次方案生成与 10 并发后台访问两条验收路径
    • 当前定位修正:项目应描述为“管理后台 + 订单/分享/渠道同步 + AI 审核链路”的可运行系统;用户端 Web 自助闭环仍未落地

新增T6.4 已完成)

  • 管理后台订单管理 admin/routes/orders.py
    • 端点落地GET /api/orders(真实列表)/ GET /api/orders/{id}(详情 + 状态历史)/ GET /api/orders/exportCSV 导出)/ POST /api/orders(手工录单)/ PATCH /api/orders/{id}(业务字段更新 + 状态流转 + 退款)
    • 状态机守护:写路径复用 OrdersDAO.update()transition_status(),非法流转统一映射到 E02301,不允许绕过 6 态状态机直接写库
    • 默认脱敏:列表、详情和 CSV 导出均走 Order.to_dict(decrypt_sensitive="mask"),避免管理后台直接导出完整手机号/身份证号
    • 手工兜底:支持 external_id 留空的人工补录路径,与 docs/CHANNEL_INTEGRATION.md 约定一致;退款仅更新本地订单状态,不主动触发第三方退款 API
    • 测试 6 个全部通过admin/tests/test_routes_orders.py):创建、列表/详情、PATCH 更新+付款、退款、非法状态冲突、CSV 导出
    • 定向验证python3 -m pytest admin/tests/test_routes_orders.py admin/tests/test_routes.py -q → 20 passedruff check admin/routes/orders.py admin/tests/test_routes_orders.py admin/tests/test_routes.py 通过
    • 文档同步README.md 新增 T6.4 章节;docs/plans/T6-admin-mvp.md 标记 T6.4 已落地并更新路由清单

新增T6.2 已完成)

  • 管理后台仪表盘 — 真实 SQL 聚合层 admin/stats.py434 行)
    • 端点落地GET /api/stats/dashboard(一站式仪表盘)+ GET /api/stats/orders(沿用 T6.1 stub 字段名,去掉 _stub 标记)
    • 纯函数聚合层build_dashboard_payload / compute_summary / compute_by_status / compute_by_source / compute_by_service_version / compute_trends / generate_day_series
    • 响应契约summary(订单/用户/收入 + 今日/7d/30d 切片 9 字段) + by_status / by_source / by_service_version (完整 0 填充) + trends (today=1, 7d=7, 30d=30 个点, 日粒度, 0 填充) + generated_at
    • 关键口径
      • 收入 = paid / serving / delivered / completed 四态订单的 amount_cents 累计值;pending(未付款)与 refunded(已退款)排除
      • 趋势桶粒度 = 日UTCYYYY-MM-DD),用 substr(created_at, 1, 10) 切片
      • 0 填充 = 窗口内的"无订单日"也返回 0 点,前端拿到稠密序列
      • 数据源隔离 = ordersGAOKAO_ORDERS_DB_PATH(默认 data/orders.dbadmin_usersGAOKAO_DB_PATH(默认 data/orders/admin.db
      • 不读 PII统计路径只触碰 amount_cents / status / source / service_version / created_at
    • 配置新增Settings.orders_db_pathGAOKAO_ORDERS_DB_PATH 环境变量,默认 data/orders.db),与 data.channel_sync.webhook_server 已有的同名变量对齐
    • 测试 12 个全部通过admin/tests/test_routes_stats_dashboard.py
      • 鉴权(无 token 401 / 有 token 200
      • 空库形状契约summary / by_* / trends 三层结构稳定
      • 趋势序列1 / 7 / 30 个点,按日期严格升序
      • 0 填充点:包含完整三字段(date / orders / revenue_cents
      • 真实数据窗口边界45 天前的订单被 30d 窗口排除,但计入 total
      • 收入口径pending / refunded 不计入 revenue
      • 0 填充:范围内无订单的日也返回 0 点
      • 兼容层:/api/stats/orders 字段名不变,_stub 标记已移除
    • T9.3 已知缺口已闭环admin/tests/conftest.py 新增 orders_db autouse fixtureT6.2 起,所有测试默认带空 orders DBpytest -q admin/tests 87/87 通过
    • 测试套件pytest -q admin/tests 87/87 passedpytest -q 仓库全量 392/392 passedruff check admin/stats.py admin/routes/stats.py admin/tests/test_routes_stats_dashboard.py admin/tests/conftest.py admin/config.py admin/tests/test_routes.py All checks passed
    • 文档同步docs/plans/T6-admin-mvp.md 新增 §10T6.2 设计与 DoD§12 后续任务衔接标 [x]README.md 新增 T6.2 章节;CHANGELOG.md 本条

新增T9.3 已完成)

  • 结构化 JSON 日志 admin/logging_utils.py
    • 新增 JsonLogFormatter:单行 JSON 输出 ts / level / logger / msg / ctx / exc
    • 新增 log_event() / log_event_exc():业务侧一行写结构化事件,避免散落字符串拼接
    • 新增 contextvars 请求上下文:自动注入 request_id / path / method,并在请求结束后清理,避免串请求污染
    • admin/app.py 新增 request_context_middleware--log-format json|plain 启动参数CLI 默认输出 JSON保留 plain 便于本地调试
    • admin/errors/exceptions.pyBusinessError / HTTPException / RequestValidationError / 兜底异常日志全部升级为结构化事件
    • 新增 admin/tests/test_logging.py 8 个测试,覆盖 formatter、上下文绑定、异常 traceback、FastAPI 端到端 JSON 日志
    • 定向验证通过:pytest -q admin/tests/test_logging.py admin/tests/test_errors.py = 34/34 passedruff check admin/app.py admin/errors/exceptions.py admin/logging_utils.py admin/tests/test_logging.py admin/tests/test_errors.py 通过
    • 已知缺口T6.2 已闭环):pytest -q admin/tests 之前有 1 个非 T9.3 失败(test_stats_orders_real_shapesqlite3.OperationalError: no such table: orders)— 根因是 stats 端点读 orders 表,但 T6.1 阶段 conftest 没建 orders DBT6.2 在 conftest 加 orders_db autouse fixture 闭环,当前 pytest -q admin/tests 87/87 通过

新增T4.3 已完成)

  • 订单管理 CLI scripts/gaokao-order-manager + data/orders/cli.py
    • 子命令落地:create / list / show / update / pay / deliver / stats
    • 默认 JSON 输出,订单详情默认走 Order.to_dict() 遮罩模式,避免 CLI 直接泄露完整手机号/身份证
    • create 直接复用 OrdersDAO.create()show 返回订单详情 + order_status_history
    • update 只允许业务字段,空更新返回 exit code 2继续强制 status 变更走 DAO 状态机
    • pay 推进 pending -> paiddeliverpaid 时自动串联 serving -> delivered,兼容已在 serving 的最后一步交付
    • stats 输出 total_orders / by_status / by_source / by_service_version
    • 新增 data/orders/tests/test_cli.py 5 个 pytest 用例:
      • 脚本级端到端主链路create/list/show/update/pay/deliver/stats
      • 缺失订单错误码
      • 空更新防御
      • 模块内 direct-main 覆盖,data.orders.cli 覆盖率 90%
    • 定向验证:pytest -q data/orders/tests/test_cli.py 5/5 passedpytest -q data/orders/tests 166/166 passedruff check data/orders/cli.py data/orders/tests/test_cli.py scripts/gaokao-order-manager 通过;py_compile 通过
  • 📝 data/orders/README.md 新增 T4.3 CLI 使用示例与子命令语义

新增T4.2 已完成)

  • 订单 DAO 数据访问层 data/orders/dao.py530 行,OrdersDAO 类)
    • CRUD 完整create() / get() / get_by_external_id() / find_by_phone() / list() / count() / stats_by_status() / update() / delete()
    • 事务守护dao.transaction() 上下文管理器;嵌套语义(外层在事务中时内层不重复 commit异常统一回滚外层
    • 加密透明化API 入口接收 Order dataclass明文 PIIDAO 内部用 to_db_row() 加密落盘 / from_db_row() 解密读回;调用方无需接触 *_enc 字段
    • 状态机守护transition_status()assert_valid_transition() 单事务内 UPDATE orders + INSERT order_status_history;非法抛 InvalidStateTransition 并回滚
    • 时间戳联动paid → paid_at / serving → started_at / delivered → delivered_at / completed → completed_at 由状态自动置位(COALESCE 保留首次值)
    • 幂等 upsertupsert_by_external_id() 接管 T8.1 闲鱼 Webhook 路径4 种 actiondata/channel_sync/dao_extension.py 完全对齐(inserted / updated / unchanged / illegal_transition
    • 防御设计_row_factory_ctx() 临时切 sqlite3.Row、退出后恢复外部 row_factoryupdate() 显式拒绝 status 字段(强制走 transition_status()
    • 51 个 pytest 用例全绿(覆盖加密透明化、状态机合法/非法路径、事务回滚、upsert 4 种 action、状态历史时间线、row_factory 不污染、删除 cascade
    • data/orders 模块总测试 163/163 通过(含 T4.1 既有 112 + T4.2 新增 51data/ 全模块 386/386 通过ruff 0 warning
  • 🔧 data/orders/__init__.py 导出 DAO 公共 APIOrdersDAO / UpsertResult / StatusChange / OrderNotFound / DuplicateOrder 一行 import
  • 📝 data/orders/README.md 更新 T4.2 DAO 一览表、加密透明化边界表、DoD 勾选、API 下游衔接

新增T2.4 已完成)

  • 扎堆报告生成器 risk_report.pydata/crowd_db/risk_report.py183 行)
    • build_crowd_risks(plan, user_score, province, loader=None) — 把 crowd_detector.detect_crowd_riskRiskFinding 列表转换为 templates/audit_report.html 模板所需的 crowd_risks 字典格式
    • 三色 emoji 标识high → 🔴、medium → 🟡、low → 🟢(随 RISK_LEVEL_META 自动匹配)
    • 模板字段完整:school / major / frequency / predicted_increase / risk_level / risk_level_label / risk_emoji / platforms / alternatives
    • alternatives 字段重映射:nameschoolscore 强制 int(防御非数字字符串)
    • 辅助能力:
      • group_by_risk() — 按风险等级分组(永远返回 high/medium/low 三个 key
      • format_risk_summary() — 单行汇总(如 "🔴 1 个高风险、🟡 2 个中风险"),给报告顶部用
      • render_risk_table() — CLI / 微信消息场景的纯文本表格(含替代院校行)
    • 类型设计:用 Protocol 定义 _LoaderProtocol,避免对 CrowdDBLoader 强依赖(支持 mock 注入与未来的不同实现)
    • 22 个 pytest 单元测试全部通过(三色 emoji / 字段完整性 / 替代项重映射 / 防御性 fallback / 空方案 / 不存在省份 / 自定义 loader 注入)
  • 端到端集成验证脚本 scripts/verify_t2_4_e2e.py95 行)
    • 用真实湖南 575 分数据 + audit_report.html 模板渲染一遍
    • 断言:模板必需字段全部存在 / alternatives 重映射正确 / 三色 emoji 在渲染输出可见
    • 跑法:python3 scripts/verify_t2_4_e2e.py
    • 6/6 集成断言通过
  • 质量门禁
    • data/crowd_db/tests/ 105/105 通过(含本次新增 22 + 历史 83
    • 仓库全量 pytest392 passed
    • ruff check data/crowd_db/ scripts/verify_t2_4_e2e.py — All checks passed
    • validate_template.py 仍 PASS模板字段契约未破坏

新增T2.5 已完成)

  • 扎堆检测单元测试 T2.5data/crowd_db/tests/test_crowd_detector.py 由 35 增至 55 个测试(新增 20 个)
    • 用例 1 高风险识别test_high_risk_use_case_frequency_4_full_payloadfreq=4 全平台 + predicted_increase + alternatives/ test_high_risk_boundary_frequency_exactly_4>=4 闭合区间边界)/ test_high_risk_distinct_from_medium_and_lowhigh/medium 互不混淆)
    • 用例 2 替代方案test_alternatives_use_case_contains_required_keys(每个 alt 必须含 name/major/score, 0-100 区间)/ test_alternatives_use_case_sortable_by_scoredetector 透传 alternatives 字段不丢)/ test_alternatives_use_case_empty_list_is_valid(空列表合法)
    • 用例 3 跨省份test_cross_province_hunan_hit_guangdong_miss(湖南 575 命中 vs 广东 575 无数据隔离)/ test_cross_province_beijing_at_690(同校不同省命中不同记录 — 清华 工科试验班)/ test_cross_province_loader_called_with_correct_provinceprovince 透传给 loader, 不做全局查询)
    • 用例 4 异常处理test_exception_use_case_loader_returns_none_fieldname=None 不崩)/ test_exception_use_case_loader_returns_non_dict(混入 None/str/int 时优雅过滤)/ test_exception_use_case_loader_raises_propagatesloader 抛错向上传播)/ test_exception_use_case_unrecognized_entry_typeint/float/object 走 str 兜底)/ test_exception_use_case_entry_with_int_school_dictschool=0 falsy 跳过)/ test_exception_use_case_province_is_noneprovince=None 不抛)/ test_exception_use_case_tuple_with_non_string_schooltuple 元组非 str school 走 str() 兜底)/ test_exception_use_case_dict_with_truthy_non_string_school0.5 这种 truthy 非 str school 走 str() 兜底)/ test_exception_use_case_dict_with_name_truthy_non_stringname 字段 truthy 非 str 同样兜底)/ test_exception_use_case_single_element_tuple_non_string(单元素 tuple 非 str 兜底)/ test_exception_use_case_malformed_frequency_in_recordfrequency="not a number"/None 时 try/except 按 0 处理)
  • 🛡️ crowd_detector.py 根因加固 — 与测试同步detector 主循环加入三层防御:
    • if not isinstance(rec, dict): continue — 防止 loader 混入非 dict 元素时 rec["name"] 抛 TypeError
    • if not isinstance(rec_name, str) or not rec_name.strip(): continue — 防止 name 缺失/非 str 时 .strip() 抛 AttributeError
    • try/except (TypeError, ValueError): freq = 0 — 防止 frequency 字段异常时 int(...) 崩溃
    • _normalize_entry 增加 truthy 非 str school 的 str() 兜底dict / tuple / list 三分支)
    • 取值统一用 or 兜底空值:rec.get("platforms") or [] / rec.get("predicted_increase") or 0 / rec.get("alternatives") or []
  • 质量门禁
    • crowd_detector.py 单模块覆盖率:93%101 statements / 7 missed 仅 __main__ CLI demo 块)
    • 远高于 T2.5 PRD 阈值 ≥80%
    • data/crowd_db/tests/test_crowd_detector.py 55/55 passed
    • data/crowd_db/tests/ 全量 125/125 passed不动 T2.1/T2.2/T2.4 既有测试)
    • pytest -q --ignore=data/orders 仓库全量 249 passed
    • ruff check data/crowd_db/ — All checks passed

新增T1.3 已完成)

  • 方案解析器 plan_parser.pyskills/gaokao-audit/scripts/plan_parser.py295 行)
    • 解析大厂AI志愿方案文本纯文本/PDF提取/截图OCRParsedPlan dataclass
    • 字段提取省份27 省 + 别名)、分数、位次、选科、来源(千问/元宝/百度/豆包)、志愿列表
    • 志愿行识别支持 4 种行首编号格式:1. xxx / 1、xxx / 1) xxx / 1 xxxPDF 提取常见)
    • 学校/专业分隔支持 4 种风格:学校 - 专业 / 学校:专业 / 学校(专业组) / 学校 专业(按大学/学院关键字兜底)
    • 健壮边界:空文本/无志愿/编号异常均返回 ParsedPlan 默认值,不抛异常
    • CLIpython3 -m skills.gaokao-audit.scripts.plan_parser <file> 输出 JSON
    • 10 个 pytest 单元测试全部通过(基础解析/志愿列表/省份别名/选科/PDF 格式/空文本/无志愿/编号多样性/序列化/真实样本回归)
    • 真实样本回归 fixturetests/fixtures/sample_xianyu.txt百度AI方案
  • 🔒 T1.2 review 闭环修复skills/gaokao-audit/scripts/validate_template.py
    • 模板渲染 Environment(autoescape=False)autoescape=True——修复用户派生字段policy_errors/crowd_risks/data_issuesXSS 注入风险
    • 标签平衡检查:原 "(HTML5 void elements ignored)" 注释与实际行为不符regex 未排除 void 元素),改为显式 VOID_ELEMENTS 集合减去空元素计数103=1037 void 元素正确排除)
    • T1.2 验证脚本仍 PASSmock payload 全部 7 个 must_contain 字符串命中)
  • 📝 docs/plans/T1-2-audit-skill-and-parser.md 实施记录10/10 测试 ✓ · 真实样本解析正确 ✓ · 省份别名 27 省 ✓ · 编号格式 4 种 ✓

新增T1.2 已完成)

  • AI方案审核服务 Skillskills/gaokao-audit/
    • SKILL.md143 行)— 角色边界 + 49 元服务定价 + 四维审核框架 + 合规红线 + DoD
    • templates/audit_report.html262 行Jinja2— 报告模板,含政策合规/扎堆风险/数据存疑/改进建议 4 区块 + 升级到 99 元完整方案卡片
    • examples/sample_audit.md144 行)— 输入样例大厂AI方案文本/PDF/截图)+ 输出报告样例 + 渲染数据契约表
    • scripts/validate_template.py137 行)— 模板渲染校验器16 个占位符 + 7 个渲染输出字符串断言
    • tests/test_validate_template.py33 行)— pytest 入口1 用例通过
    • 关键设计T1.1 review 暴露的 4 个反模式(吞错、模糊 substring、vacuous 测试、缺失档位)已显式列入"对齐 T1.1 review 教训"表,由 T1.3 实施时强制规避
    • T1.2 测试套件:1/1 通过(含项目原有 6 个 spec_checker 测试 → 7/7 通过)

新增T7.1 已完成)

  • 短链接生成data/share/short_link.py + scripts/gaokao-shortlink
    • base62 短码生成(默认 6 位4-16 位可配,加密随机 + 冲突重试)
    • SQLite 映射表 share_linksWAL 模式code 主键 + report/owner/expires 三索引)
    • ShortLinkService 完整 APIcreate / get / resolve / revoke / list_by_report / list_by_owner / get_stats / purge_expired
    • 访问控制:permissionread/comment/edit/admin+ 密码PBKDF2-HMAC-SHA256兼容历史 sha256 读时迁移)+ expires_at + revoked
    • route_short_link(code, password, base_url) 路由辅助,可挂载任意 Web 框架的 /s/<code>
    • CLIcreate / resolve / revoke / list / stats / purge,全部子命令 JSON 输出
    • 25 个 pytest 用例全部通过base62 编解码、碰撞重试、TTL、密码、撤销、列表、统计、清理、路由

新增T7.3 已完成)

  • 分享权限策略data/share/permission.py
    • 新增 PermissionPolicy.for_permission(permission):把 read/comment/edit/admin 归一化成分享页能力策略
    • 能力判断:can_view / can_comment / can_edit / allows_field / can("...")
    • 安全兜底:未知 permission 一律回退到最严格的 read 策略,防止越权
  • 姓名脱敏策略复用
    • 复用 data/orders/masking.py::mask_name,避免在分享链路重复实现脱敏算法
    • read/comment 默认回传脱敏姓名公开分享场景额外收紧为3 字及以上中文名统一 姓+**,非中文名统一 **
    • edit(以及历史兼容 admin)下姓名原样展示,但 password_hash / internal_note / note / debug_info / raw_payload 等内部字段仍强制隐藏
  • 权限感知路由辅助data.share.short_link.route_short_link_with_report
    • route_short_link() 之上叠加报告 payload 渲染,支持 report= 直接注入或 report_loader(report_id) 懒加载
    • resolve 失败not_found / revoked / expired / password_required / password_wrong时不下发 rendered payload避免泄露报告元数据
    • render_report_payload(permission, report, share_url=...) 输出统一结构:policy + visible_fields + payload + masked_fields
  • 测试验证
    • 新增 data/share/tests/test_permission.py34 个 pytest 用例覆盖三档权限、admin alias、未知 permission fallback、字段裁剪、姓名脱敏、公开分享收敛规则、route + report_loader 端到端
    • python3 -m pytest data/share/tests/test_permission.py -q34 passed
    • python3 -m pytest data/share/tests/ -q61 passed
    • python3 -m pytest data/share/ data/orders/ -q231 passed
    • python3 -m ruff check data/share/permission.py data/share/tests/test_permission.py data/share/short_link.pyAll checks passed

新增T10.1 已完成)

  • GitHub Actions CI 流水线
    • 自动化测试push / pull_request 触发)
    • 多 Python 版本矩阵3.10 / 3.11 / 3.12
    • pytest + pytest-cov 覆盖率报告XML 产物供 T10.2 codecov 集成)
    • pip 依赖缓存(加速运行)
  • requirements-dev.txt — 测试依赖pytest / pytest-cov / pytest-timeout / pytest-xdist
  • pytest.ini — 统一本地与 CI 测试发现配置
  • README 顶部 CI 状态徽章

新增T10.2 已完成)

  • Codecov 覆盖率报告与徽章
    • .github/workflows/ci.yml 集成 codecov/codecov-action@v43.11 单点上传 coverage.xml
    • codecov.yml 定义 project 目标 80% / 核心 skills 目标 100% / patch 目标 70%,与 T5.5 硬门槛对齐
    • fail_ci_if_error: falsecodecov 不可达时不影响 CI 通过(适配多镜像仓库场景)
    • README 顶部新增 codecov 覆盖率徽章
  • PR 浮动容忍 1%project/ 2%core避免噪声红灯

新增T11.2 已完成)

  • 敏感字段展示脱敏工具 data/orders/masking.py127 行)
    • mask_phone / mask_id_card / mask_name / mask_sensitive_dict 四个纯函数
    • 手机号11 位 → 138****1234;支持 +86 / 86 国家码剥离、常见分隔符(空格 / 横杠)
    • 身份证18 位 → 430102********1234(保留前 6 行政区划 + 末 4 位15 位老版兼容;非 18/15 位且 ≥13 位的非标准输入也走"前 6 后 4"遮罩
    • 姓名1 字原样 / 2 字 张* / 3 字 张*丰 / 4+ 字 张**;非中日韩字符全遮 *****
    • 默认安全None / 空串 / 非字符串均不抛错,统一返回 None / ""
    • mask_sensitive_dict 一键遮罩订单字典中所有已知 PII 字段(不动 _enc / _hash 等索引/密文字段)
  • Order.to_dict 扩展 decrypt_sensitive 三态策略
    • True : 完整明文(权限内接口使用,如后台人工核对)
    • False: 完全移除明文(对外公开统计 / 审计日志)
    • "mask" (默认): 部分遮罩(列表 / 详情默认 — 推荐且默认安全)
    • 未知字符串策略值回退为 mask防误传"plaintext"导致明文泄露)
  • data/orders/tests/test_masking.py — 32 个 pytest 用例覆盖:手机号 11/12/带 +86 / 短串 / 非法输入、身份证 18/15/X 校验位 / 短串 / 13 位非标准、姓名 1/2/3/4+ 字 / 英文 / 混合、mask_sensitive_dict 不变性、Order.to_dict 三态与默认 mask
  • 测试验证data/orders/tests 全套 112 用例通过(含原有 80 + 新增 32全仓 344/344 通过;ruff check 0 warningruff format --check 3 文件已规范
  • 🔒 与 T4.1 落盘加密的关系crypto.py 负责"落盘形态"(密文 + hashmasking.py 负责"展示形态"(部分遮罩),两者正交 — 落盘加密是底层保险,脱敏展示是上层最小特权

新增T8.3 已完成)

  • 企业微信最小客户端data/channel_sync/wecom_adapter.py
    • WeComBotClient.from_env():从 GAOKAO_WECOM_BOT_KEY / GAOKAO_WECOM_API_BASE / GAOKAO_WECOM_TIMEOUT_SECONDS 读取机器人 webhook 配置,缺失时 fail-fast
    • WeComAppClient.from_env():从 GAOKAO_WECOM_CORP_ID / GAOKAO_WECOM_CORP_SECRET / GAOKAO_WECOM_AGENT_ID / GAOKAO_WECOM_API_BASE / GAOKAO_WECOM_TIMEOUT_SECONDS 读取应用消息配置
    • 机器人消息:send_text(...) 覆盖文本通知,支持 mentioned_list / mentioned_mobile_list
    • 应用消息:send_text(...) 覆盖 touser / toparty / totag 文本推送,支持 safe 与重复消息检查参数
    • access_token 自动缓存 + 提前刷新窗口:避免每次应用推送都重新拉 token
    • 错误模型统一HTTP 非 2xx、上游 errcode != 0、transport 异常、非 JSON 响应统一包装为 WeComAPIError
  • 企业微信集成测试data/channel_sync/tests/test_wecom_adapter.py
    • 覆盖机器人 webhook payload、应用 token 缓存/消息 payload、上游 errcode、transport 异常、环境变量缺失 fail-fast
    • 同时补上 WeChatClient transport 异常包装回归,避免标准库 transport 网络错误直接泄漏原始异常

新增T8.2 已完成)

  • 微信 SDK 最小客户端data/channel_sync/wechat_adapter.py
    • WeChatClient.from_env():从 GAOKAO_WECHAT_APP_ID / GAOKAO_WECHAT_APP_SECRET / GAOKAO_WECHAT_API_BASE / GAOKAO_WECHAT_TIMEOUT_SECONDS 读取配置,缺失时 fail-fast
    • access_token 自动缓存 + 提前刷新窗口:避免每次发送都重新拉 token也避免临近过期 token 被继续复用
    • 订阅消息:send_subscribe_message(...) 自动规范化 data{key: {value: ...}} 形状,并透传 page / miniprogram_state / lang
    • 客服消息:send_custom_message(...) / send_custom_text(...) 覆盖文本客服场景,支持可选 kf_account
    • 纯标准库 HTTPUrllibTransport + 可注入 Transport 协议,便于测试 fake transport 与后续 T8.3 复用
    • 错误模型统一HTTP 非 2xx、上游 errcode != 0、非 JSON 响应全部包装为 WeChatAPIError
  • 微信集成测试data/channel_sync/tests/test_wechat_adapter.py
    • 覆盖 token 缓存/刷新、订阅消息 payload、客服文本消息 payload、上游 errcode、HTTP 500、环境变量缺失 fail-fast
    • pytest --cov=data.channel_sync.wechat_adapter 覆盖率 90%8/8 通过)
    • pytest -q data/channel_sync/tests75 passedruff check data/channel_sync/wechat_adapter.py data/channel_sync/tests/test_wechat_adapter.py data/channel_sync/__init__.pyAll checks passed

新增T8.1 已完成)

  • 闲鱼 Webhook + poller 兜底同步data/channel_sync/

  • webhook_server.pyPOST /webhook/xianyu + /healthz,覆盖签名校验、时间戳过期、重复 event、非法状态迁移、审计落库、单 IP 限流

  • poller.py:共享 upsert_by_external_id 幂等链路,支持 cursor 推进与 poller_state / poller_run 运行记录

  • audit.py + dao_extension.py + xianyu_adapter.py + signature.py:补齐渠道同步所需审计、适配、验签与订单写库能力

  • data/channel_sync/tests/test_xianyu_channel.py129 个 data/orders + data/channel_sync 测试通过;data.channel_sync 覆盖率 90%ruff check data/channel_sync 0 warning

  • 修复关键缺陷Webhook server 预热 SQLite 连接原先在主线程创建server 线程复用时触发 sqlite3.ProgrammingError,导致 accepted/duplicate/illegal-transition 路径误报 500 且拒绝审计落库失败;现改为 schema bootstrap 后以 check_same_thread=False 重新打开连接

新增T2.3 已完成)

  • 扎堆检测算法data/crowd_db/crowd_detector.py
    • detect_crowd_risk(plan, user_score, province) → list[RiskFinding]:遍历方案每条志愿,匹配该分数段内的 crowd_db 记录,返回风险列表 + 替代方案
    • 风险等级映射frequency ≥4 high / 2-3 medium / 1 low / 0 跳过
    • 院校模糊匹配(互相包含),专业可选(计划未指定专业时按院校命中)

新增T3.1 已完成)

  • 27 省院校数据模型扩展溯源字段data/crowd_db/{province}.json + loader.py
    • 27 省 JSON 顶层新增 6 字段:source / source_url / source_type / data_year / confidence / last_updated
    • 现有 26 省骨架数据confidence=0.45source_type=manual_summarydata_year=2025
    • 湖南数据confidence=0.85,含 68 条推荐专科批→省外顶尖10 段连续 440-690 覆盖)
    • CrowdDBLoader 扩展 warn_low_confidence / load_metadata(province) → 8 字段 / list_supported_provinces() / list_provinces() / load_province 对 confidence<0.5 发 UserWarning
    • 新增 data/crowd_db/SCHEMA.md:顶层/分数段/推荐条目三表 schema + source_type 枚举(manual_summary / official_release / platform_scrape / derived+ 骨架文件约定
    • 测试:data/crowd_db/tests/test_provenance.py 9 用例27 存在性、顶层字段、score_range schema、confidence 区间、loader 27 报告、metadata 8 字段、低 confidence 警告、端到端匹配T2.1/T2.2/T2.3 46 用例无回归
    • 与 T2.3 协同:crowd_detector._risk_level_from_frequencyCrowdRecommendation.risk_level 在 frequency 0-5 边界完全一致

新增T3.2 已完成)

  • 溯源字段查询 + 验证 APIdata/crowd_db/loader.py + tests/test_provenance_query.py
    • 新增 dataclass ProvenanceValidation:含 ok / errors / warnings / is_usable / summary 5 字段 + to_dict()
    • 类常量:USABLE_CONFIDENCE_THRESHOLD = 0.5 / VALID_SOURCE_TYPES4 枚举)/ ISO_DATE_PATTERN / REQUIRED_PROVENANCE_FIELDS7 字段)
    • validate_provenance(data, province) → ProvenanceValidation@classmethod不需 loader 实例):校验字段类型/范围/枚举/日期格式,区分硬错误与软警告
    • validate_province(province) → ProvenanceValidation:加载 + 校验一体化
    • validate_all() → dict[province, ProvenanceValidation]27 省一次性扫描
    • filter_provinces(*, source_type, min_confidence, max_confidence, data_year, updated_since, updated_before, only_usable) → list[province]:多维溯源过滤,按 PROVINCE_FILE_MAP 顺序返回
    • get_provenance_report(*, only_usable, source_type) → dict:汇总 total / usable_count / failed_count / by_source_type / items
    • 27 省现状:全部 schema 校验通过(failed=0),仅湖南 1 省 is_usable=Trueconfidence=0.8526 省 low_confidence warning
    • 测试:data/crowd_db/tests/test_provenance_query.py 33 用例全通过,覆盖 validate_all/27、validate_province 单省、validate_provenance 边界None/空 dict/confidence 越界/source_type 非法/data_year 类型错/date 格式错/empty source warning、filter_provinces 9 维 + 组合、get_provenance_report 5 统计项、未知省份 load_failed、ProvenanceValidation.to_dict、load_metadata 兼容性、validate_provenance 不可变性
    • 不破坏既有 APIload_province / find_recommendations / find_recommendation_by_school / load_metadata 行为与契约完全不变T2.x 46 用例 + T3.1 9 用例 + T3.2 33 用例 = 88/88 通过
    • 多种 plan 形态dict / CrowdRecommendation / tuple / list
    • 支持注入 loader 便于测试,频率降序排序
    • 20 个单元测试覆盖:高/中风险识别、替代方案、分数段边界、模糊匹配、专业匹配、空/异常输入、部分命中、排序
  • data/crowd_db/tests/test_crowd_detector.py — 20 个测试覆盖算法各分支

📅 计划中

  • T5.5 覆盖率硬门槛(全局 ≥80% / 核心 =100% / E2E模拟通过

v2.0 (2026-06-11)

🎉 重大变化

新增

  • 规范检查Skill V2支持27个省份自动适配
    • 院校专业组模式14省
    • 专业+学校模式8省
    • 传统模式5省
  • 省份规则库(rules/provinces/
  • 错误模式库(rules/errors/
  • 真实案例库(docs/case-studies/
  • 优化日志(docs/optimization-log/
  • 完整项目目录结构

修复

  • 🐛 修正"院校专业组"概念(原错误为"45个学校"
  • 🐛 修正调剂规则(原错误为"全校调剂"
  • 🐛 修正投档后规则(原错误为"退到下个志愿"
  • 🐛 移除主观概率(原错误为"35%、80%"
  • 🐛 修正选科一刀切(原错误为"所有会计都要求物+化+生"

改进

  • 院校数据从2025年位次精确化
  • 风险提示前置
  • 数据来源明确标注
  • 强调"以官方为准"

📝 起源事故

  • 真实用户咨询湖南578分/物化生
  • 原方案出现致命错误(院校专业组概念错误)
  • 用户质疑"是否符合规范"触发自查
  • 创建本检查Skill防止错误复发

v1.0 (2026-06-10 → 2026-06-11)

初始版本

  • gaokao-college-advisor Skill
  • 可视化报告脚本
  • 1分钟/3分钟/7步三套问卷
  • 邮件发送功能

已知问题

  • 政策理解停留在2024年水平
  • 数据主观化严重
  • 缺乏方案检查机制
  • 部分细节不符合本省规范

用户反馈

  • "符合今年对应区域志愿填报规范吗?" ← 触发v2.0创建

📊 版本对比

维度 v1.0 v2.0
省份支持 湖南 27个
检查机制 规范检查Skill
错误模式库 8+种错误
数据精度 主观 基于2025位次
风险提示 后置 前置
项目结构 散落 集中
文档体系 简单 完善

🎯 下一步

  • 添加更多省份覆盖完整30+省)
  • 完善数据自动化对接
  • 增强算法精度
  • 完善UI/UX

详见 docs/optimization-log/future-plan.md