身份:扣子二号(A端 admin-console 前端)
时间:2026-09-15 22:40 令连轴三批 · WIP-349
范围:只做 admin-console/src 消费侧核对 + 文档;后端绑定归 WIP-352(小齐),本单不越闸门。
真源:backend/app/routers/admin_backend.py(27 个 @router.*,prefix="/api/admin",SHA 以当前 main 为准)
destination 列:当前后端 未接 resolve_destination(grep0 命中),http.ts(WIP-336/339)对GET /api/admin/*自动带destination_id仅当显式目的地上下文存在;该参数 admin_backend 暂不消费,预期列标注 352 接入后的隔离口径。
| # | 方法+路由 | a端调用点(api.ts) | 请求参数(front→back,已核对一致) | 响应解包 | destination 隔离预期(352 接入后) |
|---|---|---|---|---|---|
| 1 | GET /admin/roles | × 无 a端消费 | — | — | 全局共享(权限枚举,不隔离) |
| 2 | GET /admin/identities | × 无 a端消费 | — | — | 全租户(身份归属表) |
| 3 | POST /admin/identities/{user_id}/revoke | × 无 a端消费 | path user_id | — | 全租户 |
| 4 | GET /admin/audit-logs | listAuditLogs ADMIN+'/audit-logs' | table_name/operator_id/limit/offset(snake 一致) | {ok,data:{AuditLog[]},total} | 全租户(审计全局) |
| 5 | GET /admin/cms/posts | listCmsPosts | status/post_type/limit/offset | {ok,data:[post]} | 全租户(CMS 全局内容) |
| 6 | POST /admin/cms/posts | createCmsPost | body | {ok,data:{id}} | 全租户 |
| 7 | PUT /admin/cms/posts/{post_id} | updateCmsPost | path post_id + body | {ok,data} | 全租户 |
| 8 | POST /admin/cms/posts/{post_id}/publish | publishCmsPost | path | {ok,data} | 全租户 |
| 9 | POST /admin/cms/posts/{post_id}/offline | offlineCmsPost | path | {ok,data} | 全租户 |
| 10 | DELETE /admin/cms/posts/{post_id} | deleteCmsPost | path | {ok} | 全租户 |
| 11 | GET /admin/merchants/{merchant_id}/service-fee-profile | × 无 a端消费 | path | — | 目的地内(商户归属 destination) |
| 12 | POST /admin/merchants/{merchant_id}/sign | × 无 a端消费 | — | — | 目的地内 |
| 13 | PUT /admin/merchants/{merchant_id}/status | (merchants 页) | path + query status | {ok?} | 目的地内 |
| 14 | GET /admin/orders | listAdminOrders | status/user_id/is_test/limit/offset(全一致) | {ok,data:AdminOrder[]} | 目的地内(订单归属 destination)⚠️352 接后 a端透传生效 |
| 15 | POST /admin/orders/{order_id}/intervene | interveneOrder | path + body | {ok,data:{log_id,order_id,before,after}} | 目的地内 |
| 16 | GET /admin/orders/{order_id}/interventions | listOrderInterventions | path | {ok,data:OrderInterventionLog[]} | 目的地内 |
| 17 | POST /admin/orders/{order_id}/refund/execute | × 无 a端消费(涉钱,a端禁用) | — | — | 目的地内 |
| 18 | POST /admin/track/event | × 无 a端消费(分析埋点) | — | — | 全租户 |
| 19 | GET /admin/stats/overview | getStatsOverview | days(一致) | {ok,data:StatsOverview} | 目的地内(352 后看板归目的地)⚠️ |
| 20 | POST /admin/login | × 无 a端消费(A端用其他登录) | — | — | 全租户 |
| 21 | GET /admin/products | × a端无 products 消费 | — | {ok,data,total,limit,offset} | 全租户(套餐商品全局) |
| 22 | POST /admin/products | × 无 | — | {ok,data} | 全租户 |
| 23 | GET /admin/products/{product_id} | × 无 | — | — | 全租户 |
| 24 | PUT /admin/products/{product_id} | × 无 | — | — | 全租户 |
| 25 | DELETE /admin/products/{product_id} | × 无 | — | — | 全租户 |
| 26 | POST /admin/products/{product_id}/components | × 无 | — | — | 全租户 |
| 27 | DELETE /admin/products/{product_id}/components/{component_id} | × 无 | — | — | 全租户 |
结论:
/orders、/stats/overview、/merchants/{id}/status 预期归目的地内;其余为全租户共享(CMS/产品/角色/审计/埋点/登录)。原则:界面任何可交互承诺,必须有对应真实数据/动作落地,不允许"看起来能点但没效果"或与后端行为不一致。
| 界面承诺 | 现状核对(a端) | 口径结论 |
|---|---|---|
| 目的地切换器「切换目的地 → 数据随目的地变化」 | 切换写 token-exchange 上下文;透传生效但admin_backend 未接 destination_id → 全局列表暂不随目的地变 | ⚠️ 与 352 绑定前端时同步暴露,切换器已就绪,后端绑定未到前不虚标"已隔离" |
| 分佣单查询(records) | WIP-343 已修 snake/camel 映射,查询真实展示 | ✅ 口径一致 |
| 订单干预「留痕」 | POST intervene → 返回 log_id/order_id | ✅ 承诺=实际 |
| CMS 发文「立即生效 + 可下线」 | publish/offline 端点真实 | ✅ |
| 看板「近 N 日统计」 | stats/overview days 参数真实 | ✅ |
| 任何禁用态(涉钱 refund/void/settle) | DistributionOps /**KeyConfig 涉钱按钮 disabled + 标注待口径 | ✅ 诚实降级 |
| token-exchange 「切换后原 token 失效」 | 回退调 clearDestinationContext;原主 token 生命周期未由后端 revoke | ⚠️ 待 WIP-336ⓒ/352 scope 口径明确后核,当前不虚称"已 revoke" |
| 错误语义(403/404/409 目的地错误) | http.ts classifyTenant 已映射真实文案 | ✅ |
G7-3 结论:a端无「假成功/无效果按钮」;两处 ⚠️(目的地隔离后端未到、token 生命周期待定)均在接口契约侧诚实标注,非前端空转。后续以「352 每端点绑定一到位 → 本核对表勾销一行」为验收节奏。