Commit Graph

7 Commits

Author SHA1 Message Date
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
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 Agent
246f21c7f2 feat(review): land unified remediation and rules evidence closure
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
2026-06-18 10:21:38 +08:00
Hermes Agent
7fabc23715 fix(t12): close payment delivery and governance remediation
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
2026-06-15 11:39:31 +08:00
Hermes Agent
4b0390a255 feat: move delivery notification into dao transitions
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
2026-06-14 17:35:37 +08:00
Hermes Agent
3f46811e49 release: cut v2.1
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
2026-06-13 14:49:58 +08:00
coder
9168a10d75 feat(orders): T4.2 DAO 数据访问层 (CRUD + 事务 + 加密 + 状态机)
- data/orders/dao.py (530 lines): OrdersDAO class
  * CRUD: create / get / get_by_external_id / find_by_phone / list / count / stats_by_status / update / delete
  * 事务: transaction() 上下文 + 嵌套深度计数(外层事务中内层不重复 commit)
  * 加密透明化: API 入口 Order dataclass 走明文 PII,DAO 内部 to_db_row/from_db_row 转换
  * 状态机守护: transition_status() 单事务内 UPDATE orders + INSERT order_status_history
    + 时间戳联动 (paid_at/started_at/delivered_at/completed_at COALESCE 保留首次值)
  * 幂等 upsert_by_external_id: 4 种 action 与 data/channel_sync/dao_extension 对齐
  * 防御: update() 显式拒绝 status 字段; _row_factory_ctx() 不污染外部 row_factory
  * 异常: OrderNotFound(LookupError) / DuplicateOrder(ValueError)

- data/orders/tests/test_dao.py (51 cases): 加密透明化、状态机合法/非法路径、
  事务回滚、upsert 4 种 action、状态历史时间线、row_factory 隔离、删除 cascade、
  与 dao_extension 的契约对齐

- data/orders/__init__.py: 导出 OrdersDAO / UpsertResult / StatusChange /
  OrderNotFound / DuplicateOrder

- 验证: data/orders/tests/ 163/163, data/ 386/386, ruff 0 warning, py_compile clean
2026-06-12 16:36:51 +08:00