WIP-363② · R5 回归面加宽:多端点回归矩阵(草案 v1 + 首轮试点实测)

目的:R5 修复后,回归面只有 admin/merchants 单端点、写端点零覆盖 ⇒ 补一张可复用的多端点矩阵,并先跑一轮试点验证矩阵可用。
本岗边界:方案/验收检测岗,不改任何后端代码;实测只走拒绝侧(不产生业务数据变更,探针副作用见 §五)。
四态口径引用剧本 §7;证据五要素引用 §8。

一、矩阵设计(覆盖度底数)

静态盘点(backend/app/routers/*.py,按「函数内出现 resolve_destination」计数):

类数量说明
消费点总行数79含同一函数内多次调用
GET(读)34跨目的地应 403
POST16写端点
PUT3写端点
DELETE4写端点
未归属到装饰器(helper/其它)22需人工分派

写端点函数清单(23 个,去重后):admin_backend(create/update/delete cms_post、sign_merchant、update_merchant_status、intervene_order、create/update/delete product、add/delete component、admin_execute_refund)/admin_distribution(risk_ruling、admin_generate_bills)/admin_ops(create_merchant、create_temple、delete_temple)/miniapp_pay(prepay)/miniapp_workbench_redeem(redeem_arrival)/safety(trigger_sos、cancel_sos、submit_assessment、submit_health_check)。

二、矩阵判据(三条,可直接当门禁)

组用例判据安全等级
R-1 读·跨目的地受限 JWT(dest=1) + ?destination_id=3403(200 ⇒ FAIL:串租户或未接线)安全(只读)
R-2 读·同目的地受限 JWT(dest=1) + ?destination_id=1200(非 200 ⇒ 端点路径错或未接线)安全(只读)
W-1 写·拒绝侧受限 JWT(dest=1) + ?destination_id=3 + 最小合法体非 2xx,且数据库计数零变更拒绝侧不落库 ⇒ 不产生业务数据变更;若返回 2xx 立即停跑并报残留
W-1 的安全依据是既有判据:「越权硬断言=拒绝时数据库零变更」。故写端点无需造业务数据即可实测。

三、首轮试点(2026-09-16 11:36,staging 100.64.1.230:8089)

#端点用例期望实测判
A1/api/miniapp/admin/merchants跨=3/自=1403/200403/200✅ PASS
A2/api/admin/cms/posts跨=3/自=1403/200403/200✅ PASS
A3/api/miniapp/admin/content/pois跨=3/自=1403/200200/200🔴 FAIL
A4/api/admin/stats/overview跨=3/自=1403/200403/200✅ PASS
A5/api/miniapp/admin/orders跨=3/自=1403/200404/404⚪ 用例错(端点路径不存在,非缺陷)
B1POST /api/admin/cms/posts跨=3403 + 零变更403✅ PASS
B2POST /api/miniapp/admin/merchants跨=3403 + 零变更🔴 200(落库一行)🔴 FAIL
B3POST /api/miniapp/admin/content/pois跨=3403 + 零变更🔴 200(落库一行)🔴 FAIL
B4POST /api/admin/products跨=3403 + 零变更403✅ PASS

数据库快照:cms_posts=0,merchants=31,pois=8 → cms_posts=0,merchants=32,pois=9(+2 行=探针副作用,见 §五)。

四、三类根因(静态定位 + 实测交叉)

F-1 🔴 写端点「请求侧目的地被静默忽略」——admin_ops.py:109

ctx = await resolve_destination(user, requested=None)   # ← requested 写死 None
row = await conn.fetchrow("INSERT INTO merchants (…) VALUES (…,$5) …", ctx.destination_id)

⇒ 🔴 11/23(48%)写端点不消费请求侧目的地。其中 miniapp_pay.prepay(支付下单)与 safety.*(SOS/安全上报)属高敏写端点,建议优先定性:是「产品本就按凭证锚定」还是「漏接校验」。

F-2 🔴 POI 端点完全未接线(content.py 不在消费清单内)

F-3 ⚪ 用例设计错误(自纠)

/api/miniapp/admin/orders 不存在(404/404)⇒ 属本岗用例路径写错,不是产品缺陷;已在矩阵中标注替换端点。

五、探针副作用与清理请求(本岗认账)

对象位置状态处理
merchants id=30 name=363regression-probedest=1仍在库无 DELETE 端点 ⇒ 请小齐清理
pois id=9 name=363regression-probedest=1仍在库(DELETE 返回 200 但未真删,疑软删)请小齐清理
教训:即便只跑「拒绝侧」,一旦隔离失效就一定会落库 ⇒ 后续跑 W-1 组必须:①每次跑前先按名字 363regression-probe 查残留 ②优先选有 DELETE 端点且能真删的对象 ③确认删除后复查计数。

六、结论与建议

署名:波波 2026-09-16 11:4x(WIP-363② · 多端点回归矩阵草案 + 首轮试点)