4.1 KiB
P6 hosted 投稿(方案 A)· 实施计划
依据:docs/specs/2026-09-30-hosted-submission-design.md(D-A…D-F 定稿)。分支名统一 feat/p6-hosted,各仓各自实现者自拉自提交,不 push;合主由控制者 --no-ff。
Task 1 · server 校验收紧(crearte-server)
基线 master(ca24805 起)。改动点:
src/internal/service/content.goValidateSubmission(约 :327 起的 switch):metadata_change分支:取现有 work 后新增不可变校验——RuntimeOrDefault(p) != work.Runtime→ValidationError{Fields: []string{"runtime: immutable on metadata_change"}}(D-B)。- 通用(new_work 与 metadata_change 都过):
runtime == hosted && bundleUploadID != ""→ValidationError{Fields: []string{"bundle_upload_id: hosted works cannot carry a bundle"}}(D-C)。 new_version分支已 virtual-only,不动。
- 单测(同文件所在包 service):
- hosted+bundle → 校验失败且字段名精确;
- metadata_change 改 runtime(hosted↔external/virtual 双向至少各一)→ 失败;runtime 相同 → 通过既有路径;
- 回归确认:hosted new_work 无 bundle、带合法 https hostedUrl 仍通过(validate.go:140 既有)。
- 集成测试(带
TEST_DATABASE_URL的既有风格,参考 admin 面集成六场景文件):hosted 草稿→submit-review→approve→works行hosted_url/play_origin/fallback读回一致;GET /api/games/<user/slug>载荷含runtime:"hosted"与hostedUrl。 CHANGELOG.md中英成对,版本 0.13.0(Added=校验护栏+集成覆盖;Changed 若有措辞按实际)。
红线:零迁移、零新依赖、不动 handler 响应形状、不动 audit/admin 面、Approve 落库路径(PayloadToWork 映射已全,见 spec §1)不改。
验证(容器内,goproxy.cn 姿势同 AGENTS.md):gofmt -l 空、go vet ./...、go build ./...、go test -p 1 ./internal/...;带 db 的集成腿控制者跑,实现者确保无 TEST_DATABASE_URL 时 skip 语义与既有一致。
Task 2 · crearte 前端表单打通
基线 master(900f13a 起),源码根 crearte/src。改动点:
- 内容层类型:提交 payload runtime 联合扩为三档,
hostedUrl、fallback字段落位(对齐 serverWorkPayloadjson 名hostedUrl/fallback/runtime)。 app/views/SubmitFormView.vue::33表单 runtime 加'hosted';:408-415radio 组加第三项「自托管内嵌」(data-testid="runtime-hosted")。- hosted 档字段:
hostedUrl(必填 https)、fallback选择(external|hosted|none,默认external);fallback=external 时url必填(前端校验镜像 server)。 - 提交形状:hosted 时 payload 带
runtime:'hosted'+hostedUrl+fallback,不带 bundle/version/entry/features;kind仅 new_work / metadata_change(new_version radio 保持 virtual-only 逻辑)。 - 删除
:144-147hosted 预填拒绝;预填回填 hostedUrl/fallback(注意 server GET 载荷字段名)。 - hosted 档下 cover 上传照常。
- vitest(SubmitFormView.test.ts 等):hosted 提交形状、必填校验失败面、预填回填、new_version 禁入 hosted。
- e2e:
admin-flow.spec.ts或提交流既有夹具内加 hosted 提交流(表单→draft payload 断言);不动full-loop.spec.ts/playwright.stack.config.ts。 docs/CHANGELOG.md中英成对,版本 0.19.0。
红线:不动运行时三件套(sw/agent/bootstrap/GameHost/useGameFrame——播放端零改动是 spec 决策);不动管理面;apiRepo 无新端点。
验证(crearte/src):npx vitest run、npm run typecheck、npx playwright test e2e/admin-flow.spec.ts、npm run e2e 全 RC=0。
Task 3 · deploy 核证(控制者,非实现者任务)
生产/dev 主站响应头无 frame-src 限制即记录在案;若有则模板补丁+复验。
合主与验收(控制者)
双路独立审查(spec→代码逐条,PASS with notes 起)→ 六腿验收(spec §5)→ --no-ff 合主推送 → wrapper 记账(ROADMAP P6 行 + spec/plan 索引行 + CHANGELOG 0.2.7)→ 删分支。