fix(billing): 删任务/删项目级联吞 ACTIVE 预留致 reserved_balance 永久冻结(审计 I2)

- 根因: CreditReservation.task 是 OneToOneField(CASCADE), AITask.project 也是 CASCADE
  —— 删项目→级联删任务→ACTIVE 预留行被吞, 账户冻结份额永不归还(实测 4 账户漂移共 ¥42,
  且随删项目持续增长)
- 修法: billing/signals.py 挂 AITask pre_delete, 删除前先 release_credit 释放(级联同样
  触发, release 自带行锁+幂等); apps.py ready() 接线
- 回归测试 x3: 直删任务/删项目级联/已扣费不重复释放
- qa/repair_reserved_drift.py: 存量漂移回填脚本(dry-run 默认, --apply 落 RELEASE 流水),
  已对线上 4 账户执行并复验清零
- qa/function-audit/output: 本轮 18 页模拟点击审计报告(0 真死按钮 0 JS 报错)

验证: 后端测试 213/213 通过, django check 无警告
补齐 aab4d7e: 该提交带走了 signals.py 之外的测试轮改动, 信号挂载点与回归测试在本提交收口

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
zyc
2026-07-02 13:07:09 +08:00
co-authored by Claude Fable 5
parent aab4d7ea4c
commit dcc5d7fe50
43 changed files with 4860 additions and 3143 deletions
@@ -1,21 +1,19 @@
# 功能审计 · image-optimize
路由:`/image-optimize` · 模式:quick
合计 24 · ✅ works 21 · ❌ **dead 2** · 🛑 error 0 · ⏭ skipped(破坏性)0 · ◷ noop-active 1 · ⚪ disabled 0
合计 37 · ✅ works 34 · ❌ **dead 1** · 🛑 error 0 · ⏭ skipped(破坏性)0 · ◷ noop-active 2 · ⚪ disabled 0
## ❌ 点了没反应(DEAD —— 重点修)
| # | 文字 | 标签 | 类名 |
|---|---|---|---|
| 22 | 3:4 | `button` | `mi.` |
| 23 | 4:5 | `button` | `mi.` |
| 29 | 下载 | `button` | `gen-img-btn` |
## 🔍 设计稿里有、React 没渲染出来的控件(MISSING · 启发式)
> 按控件文字与设计稿 `/exact` 对比,可能含装饰/动态文案误报,人工过一眼。
- 搜索
- E E2E 桥接测试团队 20260529
- 余额 ¥14,907.00
- 账户
- 余额 ¥14,072.00
- 折叠侧栏
- 时间
- 生成模式
@@ -24,4 +22,5 @@
- 极简北欧风格的茶杯,白底,自然柔光,产品摄影
- 国风水墨海报,主体一只白鹤立于水边,留白构图
- 电影感都市夜景,街道湿漉漉反射霓虹,4K 高清
- 上传参考图