Files
yingqing/core/qa/function-audit/output/perf-report.json
T
zycandClaude Fable 5 dcc5d7fe50 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>
2026-07-02 13:07:09 +08:00

284 lines
7.8 KiB
JSON
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
{
"ts": "2026-07-02T03:02:30.918Z",
"base": "http://127.0.0.1:5174",
"apiChecks": [
{
"name": "page_size 生效 /api/assets/",
"pass": true,
"detail": "count=428 返回=200 next=有"
},
{
"name": "page_size 生效 /api/products/",
"pass": true,
"detail": "count=17 返回=17 next=无"
},
{
"name": "page_size 生效 /api/projects/",
"pass": true,
"detail": "count=39 返回=39 next=无"
},
{
"name": "延迟 /api/assets/?page_size=200",
"pass": true,
"soft": true,
"detail": "754ms / 参考 1200ms (HTTP 200)"
},
{
"name": "延迟 /api/products/?page_size=200",
"pass": true,
"soft": true,
"detail": "569ms / 参考 1200ms (HTTP 200)"
},
{
"name": "延迟 /api/projects/?page_size=200",
"pass": true,
"soft": true,
"detail": "580ms / 参考 1200ms (HTTP 200)"
},
{
"name": "延迟 /api/ops/notifications/?page_size=100",
"pass": false,
"soft": true,
"detail": "1474ms / 参考 1200ms (HTTP 200)"
}
],
"pageFailed": 0,
"results": [
{
"name": "dashboard",
"route": "http://127.0.0.1:5174/dashboard",
"unique": 6,
"budget": 7,
"rawRequests": 8,
"waterfall": 0,
"duplicates": [],
"failed": [],
"breakdown": [
"GET /api/auth/me/",
"GET /api/products/",
"GET /api/projects/",
"GET /api/billing/summary/",
"GET /api/ai/models/",
"GET /api/ops/notifications/?page_size=1",
"GET /api/assets/summary/",
"GET /api/ai/tasks/unread/"
],
"elapsedMs": 3773,
"problems": [],
"warnings": [],
"pass": true
},
{
"name": "products",
"route": "http://127.0.0.1:5174/products",
"unique": 5,
"budget": 6,
"rawRequests": 7,
"waterfall": 0,
"duplicates": [],
"failed": [],
"breakdown": [
"GET /api/auth/me/",
"GET /api/products/",
"GET /api/projects/",
"GET /api/billing/summary/",
"GET /api/ai/models/",
"GET /api/ops/notifications/?page_size=1",
"GET /api/ai/tasks/unread/"
],
"elapsedMs": 3714,
"problems": [],
"warnings": [],
"pass": true
},
{
"name": "projects",
"route": "http://127.0.0.1:5174/projects",
"unique": 5,
"budget": 6,
"rawRequests": 7,
"waterfall": 0,
"duplicates": [],
"failed": [],
"breakdown": [
"GET /api/auth/me/",
"GET /api/products/",
"GET /api/projects/",
"GET /api/billing/summary/",
"GET /api/ai/models/",
"GET /api/ops/notifications/?page_size=1",
"GET /api/ai/tasks/unread/"
],
"elapsedMs": 4631,
"problems": [],
"warnings": [],
"pass": true
},
{
"name": "library",
"route": "http://127.0.0.1:5174/library",
"unique": 9,
"budget": 9,
"rawRequests": 12,
"waterfall": 0,
"duplicates": [
{
"key": "GET /api/assets/batches/?ordering=-created_at&page=1&page_size=10&tab=tryon",
"n": 2
}
],
"failed": [],
"breakdown": [
"GET /api/assets/batches/?ordering=-created_at&page=1&page_size=10&tab=tryon ×2",
"GET /api/auth/me/",
"GET /api/products/",
"GET /api/projects/",
"GET /api/billing/summary/",
"GET /api/ai/models/",
"GET /api/ops/notifications/?page_size=1",
"GET /api/assets/summary/",
"GET /api/assets/video-packs/",
"GET /api/assets/facets/?meta_keys=product&tab=tryon",
"GET /api/ai/tasks/unread/"
],
"elapsedMs": 3738,
"problems": [],
"warnings": [],
"pass": true
},
{
"name": "account",
"route": "http://127.0.0.1:5174/account",
"unique": 9,
"budget": 9,
"rawRequests": 11,
"waterfall": 0,
"duplicates": [],
"failed": [],
"breakdown": [
"GET /api/auth/me/",
"GET /api/products/",
"GET /api/projects/",
"GET /api/billing/summary/",
"GET /api/ai/models/",
"GET /api/ops/notifications/?page_size=1",
"GET /api/billing/trend/",
"GET /api/auth/team/members/",
"GET /api/auth/team/settings/",
"GET /api/billing/ledgers/?page=1&page_size=10",
"GET /api/ai/tasks/unread/"
],
"elapsedMs": 3917,
"problems": [],
"warnings": [],
"pass": true
},
{
"name": "team",
"route": "http://127.0.0.1:5174/team",
"unique": 7,
"budget": 7,
"rawRequests": 10,
"waterfall": 0,
"duplicates": [],
"failed": [],
"breakdown": [
"GET /api/auth/me/",
"GET /api/products/",
"GET /api/projects/",
"GET /api/billing/summary/",
"GET /api/ai/models/",
"GET /api/ops/notifications/?page_size=1",
"GET /api/auth/team/members/",
"GET /api/ops/notifications/?page_size=100",
"GET /api/auth/team/settings/",
"GET /api/ai/tasks/unread/"
],
"elapsedMs": 3706,
"problems": [],
"warnings": [],
"pass": true
},
{
"name": "messages",
"route": "http://127.0.0.1:5174/messages",
"unique": 5,
"budget": 6,
"rawRequests": 8,
"waterfall": 0,
"duplicates": [],
"failed": [],
"breakdown": [
"GET /api/auth/me/",
"GET /api/products/",
"GET /api/projects/",
"GET /api/billing/summary/",
"GET /api/ai/models/",
"GET /api/ops/notifications/?page_size=1",
"GET /api/ops/notifications/?page=1&page_size=10",
"GET /api/ai/tasks/unread/"
],
"elapsedMs": 4048,
"problems": [],
"warnings": [],
"pass": true
},
{
"name": "productDetail",
"route": "http://127.0.0.1:5174/products/045ad8d6-8b15-486b-a4a9-f6968eb1555f",
"unique": 8,
"budget": 7,
"rawRequests": 10,
"waterfall": 0,
"duplicates": [],
"failed": [],
"breakdown": [
"GET /api/auth/me/",
"GET /api/products/",
"GET /api/projects/",
"GET /api/billing/summary/",
"GET /api/ai/models/",
"GET /api/ops/notifications/?page_size=1",
"GET /api/ai/tasks/unread/",
"GET /api/assets/?page_size=200&product=045ad8d6-8b15-486b-a4a9-f6968eb1555f",
"GET /api/products/045ad8d6-8b15-486b-a4a9-f6968eb1555f/materials/",
"GET /api/assets/?asset_type=image&in_library=all&page_size=200&product=045ad8d6-8b15-486b-a4a9-f6968eb1555f"
],
"elapsedMs": 4447,
"problems": [],
"warnings": [
"首屏接口数 8 > 预算 7(架构性过量拉取,待决策)"
],
"pass": true
},
{
"name": "pipeline",
"route": "http://127.0.0.1:5174/pipeline/cb82b6ee-c106-4380-b7d5-979c4b9c19a0",
"unique": 9,
"budget": 8,
"rawRequests": 11,
"waterfall": 0,
"duplicates": [],
"failed": [],
"breakdown": [
"GET /api/auth/me/",
"GET /api/projects/cb82b6ee-c106-4380-b7d5-979c4b9c19a0/",
"GET /api/products/",
"GET /api/projects/",
"GET /api/billing/summary/",
"GET /api/ai/models/",
"GET /api/ops/notifications/?page_size=1",
"GET /api/ai/tasks/unread/",
"POST /api/projects/cb82b6ee-c106-4380-b7d5-979c4b9c19a0/poll-reviews/",
"GET /api/projects/cb82b6ee-c106-4380-b7d5-979c4b9c19a0/pending-assets/",
"GET /api/projects/cb82b6ee-c106-4380-b7d5-979c4b9c19a0/extract-status/"
],
"elapsedMs": 5214,
"problems": [],
"warnings": [
"首屏接口数 9 > 预算 8(架构性过量拉取,待决策)"
],
"pass": true
}
]
}