games-development-ai/docs/superpowers/specs/2026-06-09-王蓝莓小卖部黄金闭环-design.md
zizi 6add6c771a docs(design): 王蓝莓小卖部黄金垂直闭环实现设计(brainstorming 产出)
- B 轨黄金闭环具体化:创作→确定性模板填充→落包→发布→审核→feed→试玩→遥测→quality_score→排序
- 经只读代码可行性勘察:前端 Runtime 只会 clicker、后端数据链全桩+结构缺口(无FeedApi/包不落库/不算分)
- 方案=后端数据链全建+前端轻经营(点击售卖,主题王蓝莓);8 组件/数据流/错误/测试/A-B验收
- 转 writing-plans 前的设计层

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-09 08:31:01 +00:00

13 KiB
Raw Blame History

设计:王蓝莓的小卖部 · 黄金垂直闭环B 轨实现设计)

文档号HJ-DESIGN-006 日期2026-06-09 分支dev/2.0.0 上游:docs/agent-specs/2026-06-09-下一阶段路线-plan.mdautoplan 三轨定稿)的 B 轨黄金闭环实现设计。 进度底账:docs/mvp/MVP进度总账.md。本文经 /superpowers:brainstorming 协作打磨 + 只读代码可行性勘察。 下一步:转 writing-plans 出实现计划。


1. 背景与动机

autoplan 双模型评审定稿"三轨并行",其中 B 轨 = 把 1 条完整垂直闭环做到真实可演示、可采数据,核心是 最小数据回路遥测→quality_score→feed 排序)= 护城河种子。本设计把 B 轨具体化为一条端到端真链路,主题 「王蓝莓的小卖部」(经营模板,轻经营玩法)

为什么是"轻经营 + 后端数据链全建"(方案 1只读代码勘察实证

  • 前端 Canvas Runtime 只会跑写死的 clickergame-studio/src/host/runtime/index.ts:状态仅 score/running/targetmanifest.entry 代码加载链路未接)。跑完整经营要扩 Runtime中→大撞 <15KB 红线)。→ 故前端做轻经营clicker 小扩成"点击售卖+极简库存"),不做完整经营状态机。
  • 后端整条数据生产链是桩 + 结构缺口aigc 不产 GamePackage、runtime 包从不 insert、telemetry 只 dispatchToMqdebug TODOfeed-api 连 FeedApi 都没有、publish 不写 feed。→ 这条链是大而不可避免的工作,也正是护城河,本设计全建。

2. 目标 / 非目标

目标:

  • 一条真实垂直闭环创作→确定性模板填充生成→落包→发布→审核→feed 可见→试玩→遥测→quality_score→feed 排序,全程真实(非 mock、非 demo 兜底)。
  • 最小数据回路真实产出play 事件真落库、quality_score 真计算、feed 排序真读它A/B 可证)。
  • 「王蓝莓的小卖部」在玩法上真有"卖货赚钱"手感(点击售卖 + 极简库存),不只换文案。

非目标YAGNI本阶段明确不做

  • 不接真实 LLM/Dify生成走确定性模板填充真实生成是 C 轨 Spike
  • 不做完整经营状态机(顾客 AI/进货循环/价格博弈 留后续)。
  • 不接 MinIO/OSSmanifestUrl 走后端端点GamePackage 存 DB
  • 不接 MQtelemetry 同步落库MQ 只留契约 + TODO
  • 不做 runtime 真实编译引擎(最小直接落包)。
  • 不做真实鉴权/多租户mock token账号/权限是 P0留下一步
  • 其余 4 条链路只烟测登记(本设计只详化黄金闭环这一条)。

3. 架构总览

[创作] studio.createDraft → project.createProject                         ✅已有真实
        ↓ 用户选「经营」模板 + 填王蓝莓商品/价格
[生成] aigc.generate(经营模板,参数) → 确定性模板填充 → 合法 GamePackage   🔨桩→真(无LLM)
        ↓
[落包] runtime 最小直接落包 → game_runtime_package(READY)                🔨新建(跳过真编译)
        ↓                       manifestUrl = 后端端点(不接OSS)
[发布] project.submitPublish 门禁 → REVIEWING                            ✅门禁已真
[审核] admin reviewProject(APPROVE) → PUBLISHED ──钩子──→ 写 feed rank    🔨新建 FeedApi.upsertRank
        ↓
[feed可见] feed.stream 读 game_feed_rank(按 sort_score 降序)             ✅已有真实
        ↓
[试玩] 前端 getRuntimePackage→manifestUrl→Canvas Runtime「轻经营」        🔨前端小扩(点击售卖+极简库存)
        ↓
[遥测] game_play_start/end(duration_ms,completed)/like/share              🔨桩→真(同步落库,不接MQ)
        → /events/batch 同步写 event → upsert game_telemetry_game_stat
        → 算极简 quality_score → 窄seam 写 game_feed_rank.quality_score/sort_score
        ↓
[排序] feed.stream 重查 → 排序反映新 quality_score                       ✅已有(读端真实)

新建/改动单元8 个):见 §4。 3 个关键架构决策(已确认)

  1. feed 写入时机 = 审核通过PUBLISHED那一刻(非提交发布 REVIEWING 时)——游戏 PUBLISHED 才该可见A/B 验收需 2 个 PUBLISHED 游戏。
  2. manifestUrl = 后端端点/app-api/runtime/manifest/{versionId}绕开 MinIO/OSSGamePackage JSON 暂存 DB。
  3. quality_score 极简公式(给定具体默认,实现可调权重)quality_score = clamp(60×完玩率 + 20×like率 + 20×share率, 0, 100)(完玩率=completed/play_startlike率/share率=like 或 share 数 / play_start各截断至 1.0sort_score = quality_score + boost

4. 组件设计(职责 / 接口 / 依赖)

# 单元 职责 接口 依赖
1 经营 GameConfig schema(契约新建) 约束 templateId=business 的 gameConfig 结构 contracts/templates/business.schema.json{shopName, goods:[{id,name,cost,price,stock}], durationSec, goalMoney, customerIntervalMs} game-package.schema.json
2 aigc 模板填充器(桩→真) 给 templateId+参数 → 确定性产合法 GamePackage无 LLM getTemplateList() 返真模板;generate task DONE 时产物=经营骨架代入参数→校验 business+package schema #1、project(gameId/versionId)
3 runtime 最小落包(新建) 跳过真编译,把 GamePackage 写 game_runtime_package(READY) 存 DB persistPackage(versionId, pkg)GET /app-api/runtime/manifest/{versionId} 返 manifest JSON game_runtime_package 表(已有)
4 FeedApi.upsertRank(新建·填结构缺口) feed-api 新增 FeedApiupsert game_feed_ranksort_score=quality_score+boost upsertRank(gameId, versionId, zoneId, qualityScore, boost)两个调用方语义明确project 钩子=建行写基线分(不下调已有 quality_scoretelemetry=更新 quality_score。两者均重算 sort_score。因"发布先于试玩",正常无竞争;该规则是再发布/并发的安全网 game_feed_rank 表(已有)
5 project 发布钩子(改) reviewProject(APPROVE)→PUBLISHED 后调 FeedApi.upsertRank 写 feed初始基线分 现有 APPROVE 分支后加 seam 调用,不动门禁/状态机D2 锚点) #4
6 telemetry 同步落库+算分(桩→真) /events/batch 同步:写 event→upsert stat→算 quality_score→调 #4 更 rank 替换 dispatchToMq 桩;同 traceId 批次幂等去重MQ 只留契约+TODO event/stat 表(已有)、#4
7 Canvas Runtime 轻经营(前端小扩) clicker→点击售卖读 gameConfig 商品/价/库存/时长;顾客按 interval 到;点击=卖money+=pricestock--);时长尽/达 goal→结束。主题王蓝莓 startRuntime;上报 game_play_start/game_play_end(duration_ms,completed)/like/share,带有效 traceId保持 <15KB gameConfig(#1)、SDK postMessage已有
8 6 开工前置项前端autoplan 已定) VITE_API_BASE 真名 / mock 门控 / token=test1+tenant-id / sendBeacon 走 baseURL / 种子 tenant_id=1 / vite dev 连 staging

契约新增contracts/templates/business.schema.jsonfeed.yamlFeedApi.upsertRank、runtime manifest 端点GAP-2 manifestUrl 给真实现)。

单元边界自检:每个单元独立可测;改动严守——不动 project 门禁/状态机、不动 feed 读端排序逻辑、不接 MQ/OSS。


5. 数据流

主链路(一次完整跑通):

  1. 创作studio.createDraft(creatorId, "王蓝莓的小卖部", templateId=business) → project.createProject 返 gameId/versionId真)。
  2. 生成studio.generate → aigc.generate(templateId, params={goods:[辣条/汽水/冰棍…], 价/成本/库存, durationSec, goalMoney}) → 填充器取经营骨架代入参数 → 校验 business+package schema → 产合法 GamePackagetask DONE
  3. 落包runtime.persistPackage(versionId, pkg) → 写 game_runtime_package(READY)package JSON 存 DBmanifestUrl=/app-api/runtime/manifest/{versionId}
  4. 发布→审核project.submitPublish 门禁(→REVIEWINGadmin reviewProject(APPROVE)→PUBLISHED →钩子 FeedApi.upsertRank(gameId, versionId, defaultZone, qualityScore=基线 0, boost=0) → 写 game_feed_rank
  5. feed 可见GET /app-api/feed/stream → 读 rank 按 sort_score 降序(真),含本游戏。
  6. 试玩:前端 getRuntimePackage→manifestUrl→fetch+sha256 校验→Canvas Runtime 轻经营跑王蓝莓小卖部(点击售卖)。
  7. 遥测:开局 game_play_start、结束 game_play_end(props.duration_ms, completed)、点 like/share → /events/batch带 traceId→ 同步写 event → upsert stat → 算 quality_score → FeedApi.upsertRank 更新 quality_score/sort_score。
  8. 排序:重查 feed/stream → 顺序反映新分。

A/B 验收(证 quality_score 真驱动排序Codex critical:备同 zone 同 boost 的 A/B 两个 PUBLISHED 王蓝莓游戏 → 记初始 feed 顺序 → 只向 B 上报有效 game_play_start+game_play_end(completed=true)+like+share → 断言 game_telemetry_event 有原始行、game_telemetry_game_stat.quality_score 变大、game_feed_rank.sort_score 变大 → 重查 feed B 排到 A 前 → 同 traceId 重发不重复计数 → 关 mock 仍通过。


6. 错误处理(失败路径)

失败点 处理
aigc 填充产物 schema 不合法 task FAILED不落包studio 链态 FAILED前端提示不污染下游
runtime 包不存在NOT_READY 前端现有逻辑走 demo 兜底——但黄金闭环要真包,故落包失败=闭环断,登记缺口(不靠兜底掩盖)
审核 REJECT 只 APPROVE 写 feedREJECT 不写,游戏不可见
feed rank 并发写(审核钩子 vs telemetry 算分抢同一行 uk_game_zone 职责分离project 钩子只在行不存在时写基线(不覆盖 quality_scoretelemetry 权威更新 quality_score/sort_score。避免互相覆盖
telemetry traceId 空/无效 后端拒(已有校验);前端必须生成有效 traceId(前置项)
telemetry 同 traceId 批次重发 幂等去重,不重复计数
前端 manifest fetch/sha256 失败 现有 fetchAndVerifyManifest 失败走兜底;黄金闭环须保证 manifest 端点返合法包(否则登记)
mock token 401 / 加密 / 跨域 autoplan 已覆盖token=test1+tenant-id、admin 关加密、CORS 已放行)

7. 测试与验收

  • A/B 验收协议§5已落 ~/.gstack/projects/.../test-plan-20260609.md):端到端证 quality_score 驱动排序。
  • 单元测试(各单元独立可测):① aigc 填充器(合法/非法参数各验产物 schema② FeedApi.upsertRank给分验 sort_score + 幂等)③ telemetry 同步(灌 play_start/end 验 stat 累加 + quality_score 公式 + 调 feed④ project 钩子APPROVE→FeedApi 被调REJECT→不调⑤ Runtime 轻经营(给 config 验售卖 money/stock/结束判定)。
  • 前端 6 前置项验证beacon 走 baseURL、token=test1+tenant-id、mock 门控。
  • 主 agent 独立复跑(铁律,不采信子代理自报)。

完成判据A/B 验收全绿 + 5 单元测试绿 + 黄金闭环浏览器肉眼可演示创作→生成→发布→审核→feed→试玩→排序变化


8. 边界 / 回滚 / 风险

  • 改动边界:不动 project 门禁/状态机D2 锚点)、不动 feed 读端排序逻辑、不接 MQ/OSS/真实编译/真实 LLM。
  • 回滚单元(各自独立 commit:① 前端联调开关+轻经营 ② aigc 填充器 ③ runtime 落包+manifest 端点 ④ FeedApi+project 钩子 ⑤ telemetry 同步落库。后端非零改动,回滚=按单元 revert + cleanup SQL。
  • 数据污染清理:测试数据用固定 traceId 前缀 + 固定 gameId 清单 + cleanup SQL验证前后表快照。
  • 风险:① Runtime 轻经营撞 <15KB缓解状态机最小化② 模板填充骨架与 Canvas Runtime gameConfig 解析口径需对齐缓解business.schema 为单一事实源,两侧都校验)③ DDL 是否需新增game_runtime_package 存 package JSON——若现有列不够需 V10 迁移,实现时确认)。

9. 开放项 / 依赖

  • DDL 确认game_runtime_package 是否有列存完整 GamePackage JSONmanifest 端点要返它feed/telemetry 现有表列已足够(勘察确认 stat 有 quality_score 列)。若 runtime 需加列 → V10 迁移。
  • defaultZonefeed 默认专区 zoneId 取值(读 project game_zone 或约定常量)——实现时定。
  • 经营骨架内容:王蓝莓商品清单/封面/文案——种子数据,实现时填(注意 IPstaging demo 可用,公开上线需换皮,撞 ip/compliance 锁风门)。