Files
dealerhub/PROGRESS_AGI_ITERATION_6.md
T

4.5 KiB
Raw Blame History

PROGRESS_AGI_ITERATION_6 · P0 收口 + 财务闭环 + PG 并发复跑

实跑基线(2026-09-12,pytest 全量口径):

  • SQLite:509 passed / 4 skipped(4 skipped 均为 tests/test_concurrency.py 的 PG 专用用例)
  • PostgreSQL(127.0.0.1:5433,config.settings.pgtest):499 passed / 0 skipped(含 -m postgres 4 并发用例全绿)
  • 前端:npm run build ✅ 6.32s;npm test ✅ 11/11 manage.py check 0 issues;makemigrations --check No changes。

本轮做了什么

P0-1(交接计划 NEXT_PLAN.md §P0-1)收口。接管时工作区已有未提交的半成品 (permissions 超管放行 + 未知租户 400 分层、viewset 未知租户显式 400、 seed_demo/demo 幂等兜底、两个测试侧 membership 修补、exceptions 去 exc_type

  • 补 _with_error_code),本轮在其上完成最后闭环:
  1. tests/test_membership.py(新建,8 用例):无 membership→403+code、 跨租户→403、inactive membership→403、未知租户→400、超管放行、 API Key 分支(单元级)+ 集成接线现实、demo token 只读可读、 seed_initial_data membership 幂等。
  2. tests/test_exception_handler.py::test_handler_returns_structured_500_for_unknown: 期望从 exc_type == "RuntimeError" 改为 "exc_type" not in resp.data, 对齐 P0-4 已落地的去泄露修复(实现先于测试更新)。

语义决策(理由)

  • 未知租户 → 400 而非 403:参数错误与授权失败分离,未知 code 走视图层 ValidationError({"tenant": "无法识别租户"}),不泄露租户存在性判断给授权层。
  • 超管直通:与 seed_initial_data 的 bootstrap 契约一致 ("existing superusers are operators for every seeded tenant")。
  • demo 幂等兜底:demo token 流 bypass 正常登录路径,enter_demo 内 get_or_create 保证手工建的 demo 租户也能进。
  • API Key 分支的接线现实(实测,非假设): TenantMembershipPermission 的 APIKey 分支目前没有视图同时接线—— BaseTenantViewSet 系用 JWT/Session,Open* 系用 require_scope。 所以用例 6 按"单元级分支验证 + 集成级现实记录"写,不伪造 403。 若后续要把 APIKey 接进租户系视图,再把该用例升级为端到端。

踩坑

  • test_demo.py、test_printing.py 的 membership 修补在接管时已在工作区, 本轮只验证了它们变绿,没有重写。
  • pytest -q 不打印 passed 汇总行(只有 dots + warnings + FAILED/SKIPPED), 用例数用 --collect-only | grep -c "::" 拿:全量 490(tests/ 476 + core 14)。
  • 交接计划写的"482 全量 / 477 passed"是旧基线数字,本轮实测已是 490, 差异来自期间新增用例;文档数字以本轮实跑为准。

本轮新增(2026-09-12 续)

  1. P0 级阻塞修复:BaseTenantViewSet.acreate() 在 async 上下文同步跑 serializer.is_valid(),凡带 FK 的创建(收款/付款单等)全 500 SynchronousOnlyOperation。修法:包进 sync_to_async(与 printing 已有写法对齐)。 验证:收款单 201 / 付款单 201 / 重复编码 400。 落点:backend/apps/core/viewset.py(+3 行注释)。
  2. 前端财务入口闭环(NEXT_PLAN.md §附录 A #1#2 + f7eb4325"补前端财务入口与错误状态"):
    • Receivables.vue:"+登记收款"按钮 → 收款单创建 dialog(客户下拉/单号留空自生成/日期/金额>0/方式/备注)
      • 每行"核销"按钮 → 收款单选择 + 金额 dialog(默认未结余额,超额后端 400 透出)。
    • Payables.vue:镜像实现(登记付款 + 核销应付)。
    • 后端字段级错误(customer/bill_no/amount/allocations/detail)本地透出 ElMessage.error, 全局拦截器兜底其余状态。
    • 验证:npm run build ✅ 6.32s;后端 finance 22 用例绿;全量 509 绿无带崩。
  3. P1-1 PG 并发复跑:python scripts/setup_pg.py 连通 127.0.0.1:5433; -m postgres 4/4 绿;PG 全量 499 绿。
  4. 日志清理:删 backend/g8060/g8070/g8080/g8090.log(P0-4 现场 g8070 已无保留价值, *.log 已在 .gitignore)。

遗留(诚实记录)

  • §附录 A #4–#10(库存流水/预警规则/打印模板/自定义报表/库存大盘/科目管理/价格等级页) 仍是后端有、前端无——超出本轮 27 条真源范围,未动。
  • P2-2 部署 readiness gate + 上线 192.168.5.7:需 Docker/服务器凭证,未动。
  • P2-3/D2 移动开单、P3-1 行业专版:按客户驱动,未动。