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:
@@ -4,12 +4,12 @@
|
||||
"url": "http://127.0.0.1:5173/dashboard",
|
||||
"mode": "quick",
|
||||
"tally": {
|
||||
"total": 25,
|
||||
"works": 20,
|
||||
"total": 31,
|
||||
"works": 28,
|
||||
"dead": 0,
|
||||
"error": 0,
|
||||
"disabled": 0,
|
||||
"skipped": 5,
|
||||
"skipped": 3,
|
||||
"noop": 0,
|
||||
"blocked": 0
|
||||
},
|
||||
@@ -28,7 +28,7 @@
|
||||
"url": false,
|
||||
"overlay": false,
|
||||
"self": false,
|
||||
"mutations": 19,
|
||||
"mutations": 30,
|
||||
"api": 0
|
||||
}
|
||||
},
|
||||
@@ -46,7 +46,7 @@
|
||||
"url": false,
|
||||
"overlay": false,
|
||||
"self": false,
|
||||
"mutations": 17,
|
||||
"mutations": 19,
|
||||
"api": 0
|
||||
}
|
||||
},
|
||||
@@ -64,7 +64,7 @@
|
||||
"url": false,
|
||||
"overlay": true,
|
||||
"self": false,
|
||||
"mutations": 14,
|
||||
"mutations": 17,
|
||||
"api": 0
|
||||
}
|
||||
},
|
||||
@@ -82,7 +82,7 @@
|
||||
"url": false,
|
||||
"overlay": false,
|
||||
"self": false,
|
||||
"mutations": 19,
|
||||
"mutations": 30,
|
||||
"api": 0
|
||||
}
|
||||
},
|
||||
@@ -100,7 +100,7 @@
|
||||
"url": true,
|
||||
"overlay": false,
|
||||
"self": true,
|
||||
"mutations": 30,
|
||||
"mutations": 41,
|
||||
"api": 0
|
||||
}
|
||||
},
|
||||
@@ -109,6 +109,24 @@
|
||||
"tag": "a",
|
||||
"role": "",
|
||||
"cls": "",
|
||||
"label": "模特库",
|
||||
"href": "/models",
|
||||
"disabled": false,
|
||||
"active": false,
|
||||
"verdict": "works",
|
||||
"signals": {
|
||||
"url": true,
|
||||
"overlay": false,
|
||||
"self": true,
|
||||
"mutations": 29,
|
||||
"api": 1
|
||||
}
|
||||
},
|
||||
{
|
||||
"idx": 6,
|
||||
"tag": "a",
|
||||
"role": "",
|
||||
"cls": "",
|
||||
"label": "视频项目",
|
||||
"href": "/projects",
|
||||
"disabled": false,
|
||||
@@ -118,12 +136,12 @@
|
||||
"url": true,
|
||||
"overlay": false,
|
||||
"self": true,
|
||||
"mutations": 25,
|
||||
"mutations": 31,
|
||||
"api": 0
|
||||
}
|
||||
},
|
||||
{
|
||||
"idx": 6,
|
||||
"idx": 7,
|
||||
"tag": "a",
|
||||
"role": "",
|
||||
"cls": "",
|
||||
@@ -136,12 +154,12 @@
|
||||
"url": true,
|
||||
"overlay": false,
|
||||
"self": true,
|
||||
"mutations": 29,
|
||||
"api": 0
|
||||
"mutations": 49,
|
||||
"api": 3
|
||||
}
|
||||
},
|
||||
{
|
||||
"idx": 7,
|
||||
"idx": 8,
|
||||
"tag": "a",
|
||||
"role": "",
|
||||
"cls": "",
|
||||
@@ -154,12 +172,12 @@
|
||||
"url": true,
|
||||
"overlay": false,
|
||||
"self": true,
|
||||
"mutations": 42,
|
||||
"api": 0
|
||||
"mutations": 45,
|
||||
"api": 5
|
||||
}
|
||||
},
|
||||
{
|
||||
"idx": 8,
|
||||
"idx": 9,
|
||||
"tag": "a",
|
||||
"role": "",
|
||||
"cls": "",
|
||||
@@ -172,12 +190,12 @@
|
||||
"url": true,
|
||||
"overlay": false,
|
||||
"self": true,
|
||||
"mutations": 25,
|
||||
"api": 0
|
||||
"mutations": 29,
|
||||
"api": 3
|
||||
}
|
||||
},
|
||||
{
|
||||
"idx": 9,
|
||||
"idx": 10,
|
||||
"tag": "a",
|
||||
"role": "",
|
||||
"cls": "",
|
||||
@@ -190,12 +208,30 @@
|
||||
"url": true,
|
||||
"overlay": false,
|
||||
"self": true,
|
||||
"mutations": 27,
|
||||
"mutations": 109,
|
||||
"api": 4
|
||||
}
|
||||
},
|
||||
{
|
||||
"idx": 11,
|
||||
"tag": "a",
|
||||
"role": "",
|
||||
"cls": "",
|
||||
"label": "垃圾桶",
|
||||
"href": "/trash",
|
||||
"disabled": false,
|
||||
"active": false,
|
||||
"verdict": "works",
|
||||
"signals": {
|
||||
"url": true,
|
||||
"overlay": false,
|
||||
"self": false,
|
||||
"mutations": 31,
|
||||
"api": 1
|
||||
}
|
||||
},
|
||||
{
|
||||
"idx": 10,
|
||||
"idx": 12,
|
||||
"tag": "a",
|
||||
"role": "",
|
||||
"cls": "",
|
||||
@@ -208,12 +244,30 @@
|
||||
"url": true,
|
||||
"overlay": false,
|
||||
"self": true,
|
||||
"mutations": 54,
|
||||
"mutations": 29,
|
||||
"api": 2
|
||||
}
|
||||
},
|
||||
{
|
||||
"idx": 11,
|
||||
"idx": 13,
|
||||
"tag": "div",
|
||||
"role": "button",
|
||||
"cls": "user",
|
||||
"label": "账户",
|
||||
"href": "",
|
||||
"disabled": false,
|
||||
"active": false,
|
||||
"verdict": "works",
|
||||
"signals": {
|
||||
"url": false,
|
||||
"overlay": false,
|
||||
"self": true,
|
||||
"mutations": 21,
|
||||
"api": 0
|
||||
}
|
||||
},
|
||||
{
|
||||
"idx": 14,
|
||||
"tag": "button",
|
||||
"role": "",
|
||||
"cls": "icon-btn",
|
||||
@@ -226,12 +280,12 @@
|
||||
"url": true,
|
||||
"overlay": false,
|
||||
"self": false,
|
||||
"mutations": 28,
|
||||
"mutations": 33,
|
||||
"api": 1
|
||||
}
|
||||
},
|
||||
{
|
||||
"idx": 12,
|
||||
"idx": 15,
|
||||
"tag": "button",
|
||||
"role": "",
|
||||
"cls": "btn",
|
||||
@@ -241,15 +295,15 @@
|
||||
"active": false,
|
||||
"verdict": "works",
|
||||
"signals": {
|
||||
"url": true,
|
||||
"overlay": false,
|
||||
"url": false,
|
||||
"overlay": true,
|
||||
"self": false,
|
||||
"mutations": 30,
|
||||
"mutations": 24,
|
||||
"api": 0
|
||||
}
|
||||
},
|
||||
{
|
||||
"idx": 13,
|
||||
"idx": 16,
|
||||
"tag": "button",
|
||||
"role": "",
|
||||
"cls": "btn.btn-primary.btn-lg",
|
||||
@@ -260,109 +314,18 @@
|
||||
"verdict": "works",
|
||||
"signals": {
|
||||
"url": true,
|
||||
"overlay": false,
|
||||
"overlay": true,
|
||||
"self": false,
|
||||
"mutations": 25,
|
||||
"mutations": 60,
|
||||
"api": 0
|
||||
}
|
||||
},
|
||||
{
|
||||
"idx": 14,
|
||||
"tag": "button",
|
||||
"role": "",
|
||||
"cls": "stat",
|
||||
"label": "余额 ¥¥14908.00已冻结 ¥0.00",
|
||||
"href": "",
|
||||
"disabled": false,
|
||||
"active": false,
|
||||
"verdict": "works",
|
||||
"signals": {
|
||||
"url": true,
|
||||
"overlay": false,
|
||||
"self": false,
|
||||
"mutations": 27,
|
||||
"api": 1
|
||||
}
|
||||
},
|
||||
{
|
||||
"idx": 15,
|
||||
"tag": "button",
|
||||
"role": "",
|
||||
"cls": "more",
|
||||
"label": "[ ALL · 6 ] →",
|
||||
"href": "",
|
||||
"disabled": false,
|
||||
"active": false,
|
||||
"verdict": "works",
|
||||
"signals": {
|
||||
"url": true,
|
||||
"overlay": false,
|
||||
"self": false,
|
||||
"mutations": 25,
|
||||
"api": 0
|
||||
}
|
||||
},
|
||||
{
|
||||
"idx": 16,
|
||||
"tag": "button",
|
||||
"role": "",
|
||||
"cls": "recent-row",
|
||||
"label": "9:16真应用验证项目 · 补水面膜种草透真玻尿酸补水面膜 / AI 全生 / 4 镜基础资产继",
|
||||
"href": "",
|
||||
"disabled": false,
|
||||
"active": false,
|
||||
"verdict": "skipped-destructive"
|
||||
},
|
||||
{
|
||||
"idx": 17,
|
||||
"tag": "button",
|
||||
"role": "",
|
||||
"cls": "recent-row",
|
||||
"label": "9:16端到端播放器验证南卡 Lite Pro 蓝牙耳机 / AI 全生 / 4 镜拼接导出继续",
|
||||
"href": "",
|
||||
"disabled": false,
|
||||
"active": false,
|
||||
"verdict": "skipped-destructive"
|
||||
},
|
||||
{
|
||||
"idx": 18,
|
||||
"tag": "button",
|
||||
"role": "",
|
||||
"cls": "recent-row",
|
||||
"label": "9:16南卡 · 痛点种草 · v1南卡 Lite Pro 蓝牙耳机 / AI 全生 / 4 镜",
|
||||
"href": "",
|
||||
"disabled": false,
|
||||
"active": false,
|
||||
"verdict": "skipped-destructive"
|
||||
},
|
||||
{
|
||||
"idx": 19,
|
||||
"tag": "button",
|
||||
"role": "",
|
||||
"cls": "recent-row",
|
||||
"label": "9:16桥接测试项目 20260529透真玻尿酸补水面膜 / AI 全生 / 4 镜脚本继续",
|
||||
"href": "",
|
||||
"disabled": false,
|
||||
"active": false,
|
||||
"verdict": "skipped-destructive"
|
||||
},
|
||||
{
|
||||
"idx": 20,
|
||||
"tag": "button",
|
||||
"role": "",
|
||||
"cls": "recent-row",
|
||||
"label": "9:16南卡 · 痛点种草 · v1南卡 Lite Pro 蓝牙耳机 / AI 全生 / 4 镜",
|
||||
"href": "",
|
||||
"disabled": false,
|
||||
"active": false,
|
||||
"verdict": "skipped-destructive"
|
||||
},
|
||||
{
|
||||
"idx": 21,
|
||||
"tag": "a",
|
||||
"role": "",
|
||||
"cls": "shortcut",
|
||||
"label": "商品库8 SKU",
|
||||
"cls": "stat",
|
||||
"label": "总项目 ALL39",
|
||||
"href": "",
|
||||
"disabled": false,
|
||||
"active": false,
|
||||
@@ -371,16 +334,16 @@
|
||||
"url": true,
|
||||
"overlay": false,
|
||||
"self": false,
|
||||
"mutations": 30,
|
||||
"mutations": 31,
|
||||
"api": 0
|
||||
}
|
||||
},
|
||||
{
|
||||
"idx": 22,
|
||||
"tag": "a",
|
||||
"idx": 18,
|
||||
"tag": "button",
|
||||
"role": "",
|
||||
"cls": "shortcut",
|
||||
"label": "资产库101 资产",
|
||||
"cls": "stat",
|
||||
"label": "进行中 WIP16",
|
||||
"href": "",
|
||||
"disabled": false,
|
||||
"active": false,
|
||||
@@ -394,11 +357,11 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"idx": 23,
|
||||
"tag": "a",
|
||||
"idx": 19,
|
||||
"tag": "button",
|
||||
"role": "",
|
||||
"cls": "shortcut",
|
||||
"label": "充值¥14908.00",
|
||||
"cls": "stat",
|
||||
"label": "成片 DONE4",
|
||||
"href": "",
|
||||
"disabled": false,
|
||||
"active": false,
|
||||
@@ -407,16 +370,103 @@
|
||||
"url": true,
|
||||
"overlay": false,
|
||||
"self": false,
|
||||
"mutations": 27,
|
||||
"mutations": 45,
|
||||
"api": 0
|
||||
}
|
||||
},
|
||||
{
|
||||
"idx": 20,
|
||||
"tag": "button",
|
||||
"role": "",
|
||||
"cls": "stat",
|
||||
"label": "余额 ¥¥14074.00冻结 ¥4.00 / 共 ¥14078.00",
|
||||
"href": "",
|
||||
"disabled": false,
|
||||
"active": false,
|
||||
"verdict": "works",
|
||||
"signals": {
|
||||
"url": true,
|
||||
"overlay": false,
|
||||
"self": false,
|
||||
"mutations": 112,
|
||||
"api": 4
|
||||
}
|
||||
},
|
||||
{
|
||||
"idx": 21,
|
||||
"tag": "button",
|
||||
"role": "",
|
||||
"cls": "more",
|
||||
"label": "[ ALL · 39 ] →",
|
||||
"href": "",
|
||||
"disabled": false,
|
||||
"active": false,
|
||||
"verdict": "works",
|
||||
"signals": {
|
||||
"url": true,
|
||||
"overlay": false,
|
||||
"self": false,
|
||||
"mutations": 31,
|
||||
"api": 0
|
||||
}
|
||||
},
|
||||
{
|
||||
"idx": 22,
|
||||
"tag": "button",
|
||||
"role": "",
|
||||
"cls": "recent-row",
|
||||
"label": "9:16南卡 · 短视频 · v4南卡 Lite Pro 蓝牙耳机 / AI 全生 / 1 镜基",
|
||||
"href": "",
|
||||
"disabled": false,
|
||||
"active": false,
|
||||
"verdict": "skipped-destructive"
|
||||
},
|
||||
{
|
||||
"idx": 23,
|
||||
"tag": "button",
|
||||
"role": "",
|
||||
"cls": "recent-row",
|
||||
"label": "9:16Apple/苹果 · 短视频 · v3Apple/苹果 iPhone 17 Pro / ",
|
||||
"href": "",
|
||||
"disabled": false,
|
||||
"active": false,
|
||||
"verdict": "works",
|
||||
"signals": {
|
||||
"url": true,
|
||||
"overlay": false,
|
||||
"self": false,
|
||||
"mutations": 7,
|
||||
"api": 1
|
||||
}
|
||||
},
|
||||
{
|
||||
"idx": 24,
|
||||
"tag": "a",
|
||||
"tag": "button",
|
||||
"role": "",
|
||||
"cls": "shortcut",
|
||||
"label": "所有项目6 个",
|
||||
"cls": "recent-row",
|
||||
"label": "9:16南卡 · 短视频 · v12南卡 Lite Pro 蓝牙耳机 / AI 全生 / 1 镜",
|
||||
"href": "",
|
||||
"disabled": false,
|
||||
"active": false,
|
||||
"verdict": "skipped-destructive"
|
||||
},
|
||||
{
|
||||
"idx": 25,
|
||||
"tag": "button",
|
||||
"role": "",
|
||||
"cls": "recent-row",
|
||||
"label": "9:16内衣-文胸 · 短视频 · v2内衣-文胸 / AI 全生 / 1 镜视频片段继续",
|
||||
"href": "",
|
||||
"disabled": false,
|
||||
"active": false,
|
||||
"verdict": "skipped-destructive"
|
||||
},
|
||||
{
|
||||
"idx": 26,
|
||||
"tag": "button",
|
||||
"role": "",
|
||||
"cls": "recent-row",
|
||||
"label": "9:16Apple/苹果 · 短视频 · v2Apple/苹果 iPhone 17 Pro / ",
|
||||
"href": "",
|
||||
"disabled": false,
|
||||
"active": false,
|
||||
@@ -425,7 +475,79 @@
|
||||
"url": true,
|
||||
"overlay": false,
|
||||
"self": false,
|
||||
"mutations": 25,
|
||||
"mutations": 7,
|
||||
"api": 1
|
||||
}
|
||||
},
|
||||
{
|
||||
"idx": 27,
|
||||
"tag": "a",
|
||||
"role": "",
|
||||
"cls": "shortcut",
|
||||
"label": "商品库17 SKU",
|
||||
"href": "",
|
||||
"disabled": false,
|
||||
"active": false,
|
||||
"verdict": "works",
|
||||
"signals": {
|
||||
"url": true,
|
||||
"overlay": false,
|
||||
"self": false,
|
||||
"mutations": 41,
|
||||
"api": 0
|
||||
}
|
||||
},
|
||||
{
|
||||
"idx": 28,
|
||||
"tag": "a",
|
||||
"role": "",
|
||||
"cls": "shortcut",
|
||||
"label": "资产库53 资产",
|
||||
"href": "",
|
||||
"disabled": false,
|
||||
"active": false,
|
||||
"verdict": "works",
|
||||
"signals": {
|
||||
"url": true,
|
||||
"overlay": false,
|
||||
"self": false,
|
||||
"mutations": 41,
|
||||
"api": 5
|
||||
}
|
||||
},
|
||||
{
|
||||
"idx": 29,
|
||||
"tag": "a",
|
||||
"role": "",
|
||||
"cls": "shortcut",
|
||||
"label": "充值¥14074.00",
|
||||
"href": "",
|
||||
"disabled": false,
|
||||
"active": false,
|
||||
"verdict": "works",
|
||||
"signals": {
|
||||
"url": true,
|
||||
"overlay": false,
|
||||
"self": false,
|
||||
"mutations": 31,
|
||||
"api": 4
|
||||
}
|
||||
},
|
||||
{
|
||||
"idx": 30,
|
||||
"tag": "a",
|
||||
"role": "",
|
||||
"cls": "shortcut",
|
||||
"label": "所有项目39 个",
|
||||
"href": "",
|
||||
"disabled": false,
|
||||
"active": false,
|
||||
"verdict": "works",
|
||||
"signals": {
|
||||
"url": true,
|
||||
"overlay": false,
|
||||
"self": false,
|
||||
"mutations": 31,
|
||||
"api": 0
|
||||
}
|
||||
}
|
||||
@@ -433,21 +555,16 @@
|
||||
"missing": [
|
||||
"搜索",
|
||||
"E E2E 桥接测试团队 20260529",
|
||||
"余额 ¥14,908.00",
|
||||
"账户",
|
||||
"总项目 ALL 6 本月完成 2",
|
||||
"进行中 WIP 4 全部正常推进",
|
||||
"本月成片 DONE 2 累计完成 2",
|
||||
"余额 ¥ ¥14,908.00 已用 ¥113.00 / ¥15,021.00",
|
||||
"[ ALL · 6 ]",
|
||||
"9:16真应用验证项目 · 补水面膜种草透真玻尿酸补水面膜 / AI 全生 / 4 镜基础资产生",
|
||||
"9:16端到端播放器验证南卡 Lite Pro 蓝牙耳机 / AI 全生 / 4 镜已完成打开",
|
||||
"9:16桥接测试项目 20260529透真玻尿酸补水面膜 / AI 全生 / 4 镜脚本待生成继",
|
||||
"余额 ¥14,074.00",
|
||||
"总项目 ALL 20 本月完成 0",
|
||||
"进行中 WIP 16 全部正常推进",
|
||||
"本月成片 DONE 4 累计完成 4",
|
||||
"余额 ¥ ¥14,074.00 已用 ¥947.00 / ¥15,021.00",
|
||||
"[ ALL · 20 ]",
|
||||
"9:16内衣-文胸 · 短视频 · v2内衣-文胸 / AI 全生 / 4 镜已完成打开",
|
||||
"资产库资产 20 个",
|
||||
"充值¥14,908.00",
|
||||
"充值¥14,074.00",
|
||||
"基础资产生成中",
|
||||
"已完成",
|
||||
"脚本待生成",
|
||||
"故事板生成中"
|
||||
"已完成"
|
||||
]
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user