WIP-328 品牌配置页 · 验收矩阵(一号 / coze1)

白标化 L1 零代码换皮:admin-console 品牌配置页(表单 + 校验 + fixture 自测,零后端等待)。
日期:2026-09-14。闸门:admin-console/src 🔒一号(可直推)。

1. 契约核验(后端端点已在位,非缺失)

项冻结值核验来源结果
读GET /api/miniapp/config/site → {code:0,data:{...品牌5字段在顶层...}}backend/app/routers/miniapp_site.py L50-84✅
写PUT /api/miniapp/config/site/brand body {value:{brandName,slogan,tibetanText,logoUrl,heroBgUrl}}同文件 L86-118✅
写响应{code:0,data:{key:'brand',updated_by:<uid>,name:'品牌信息'}}同上✅
403非 staff/admin → 403「需要员工权限」L101-106✅ 前端显式提示
422validate_config('brand', value),brand 必须是对象site_config_registry.py L114-119✅ 前端更严先拦+422兜底提示
读打平/写嵌套GET 把 site_config.brand 子对象打平到顶层;PUT 整对象写 brand 单 keyminiapp_site.py L57-61 / L110-114✅ service 层收口不对称
生产实证GET 生产返回 brandName/slogan/tibetanText/logoUrl/heroBgUrl 全 5 字段顶层curl https://api.kailashi.cn/api/miniapp/config/site 2026-09-14✅ 实测

生产 GET 实测片段:

{"code":0,"data":{"brandName":"神山秘境","slogan":"在世界的屋脊,遇见真正的自己","tibetanText":"གངས་རིན་པོ་ཆེ","logoUrl":"https://doc.kailashi.cn/assets/miniprogram/kailash-logo-horiz-376.png","heroBgUrl":"https://doc.kailashi.cn/assets/miniprogram/kailash-bg.jpg",...}}

2. 交付物

文件说明
admin-console/src/services/brand.ts品牌 service:BrandDraft 类型 + 字段元数据单一来源 BRAND_FIELDS + validateBrand 纯函数 + isHttpUrl + siteViewToDraft(打平→表单)+ fetchBrand/saveBrand(读/写)
admin-console/src/services/brand.fixture.tsfixture:GET 视图/期望 draft/PUT body/PUT 响应/最小集/边界集 + 11 条非法样例
admin-console/scripts/selftest-brand.mjs零后端零网络自测(ts.transpileModule 加载源 + data:URL),47 断言
admin-console/src/pages/BrandConfig.tsx页面:5 字段表单 + 逐字段校验/红框/字数计数 + 保存/撤销/dirty 态 + 加载失败诚实重试 + 403/422 区分提示 + C 端手机实时预览(home 顶栏+分享卡,logo/hero 缺省降级)
admin-console/src/pages/BrandConfig.css沿用后台暖米/墨绿体系,响应式(≤980px 单栏)
src/App.tsx / src/components/menu.ts路由 /brand-config + 菜单项「品牌配置 B」

3. 校验规则(前端,比后端「brand 必须是对象」更严)

字段必填上限规则
brandName✅20trim 后非空
slogan—40—
tibetanText—40—
logoUrl—500非空时必须 http(s) 绝对地址
heroBgUrl—500同上

非字符串(number/object 污染)逐字段拦截;提交即 trim 归一。

4. fixture 自测结果

node admin-console/scripts/selftest-brand.mjs → 47 通过 / 0 失败,exit 0(输出见 selftest-output.txt)

覆盖:①GET 打平映射(含空/脏值归一)②合法/最小/边界集 ③11 条非法样例逐字段命中且无误伤 ④URL 判定 ⑤PUT 写契约 shape(仅 value 键、恰 5 字段、响应 key=brand)⑥字段元数据完整性。

5. 工程验证

6. 未覆盖与后续(诚实项)

本包交付的是「契约对齐 + 422/403 错误面 + fixture 全绿」,写链路端到端待小冈 323 后端插点后/staging 机位代跑验收(328 验收标准中的 L3 半句)。