# crearte 路线图 / Roadmap 跨三个仓库(`crearte` 前端 / `crearte-server` 后端 / `crearte-deploy` 编排)的子项目路线图与索引,维护在 monorepo wrapper(本仓库)。 - **版本 v0**:2026-09-29 与维护者确认的分解与顺序。 - **现状基线**:crearte 0.13.0 / crearte-server 0.11.0 / crearte-deploy 0.3.1。 ## 分解原则 - 按「依赖关系 + 是否阻塞上线」排序;每个子项目的规模控制在一份 spec 能装下。 - 每个子项目独立走 **spec → 实现计划 → 实现 → 验证** 的循环。 - 隐藏复杂度出现时升级路径(拆出新子项目),不硬塞进当前子项目。 ## 第一波:上线底座(运维 / 可靠性,顺序敏感) | # | 子项目 | 内容 | 涉及仓库 | 依赖 | 状态 | |---|--------|------|----------|------|------| | P0 | 已知缺陷清理 | ① CORS `Access-Control-Allow-Headers` 补 `If-None-Match`(解锁 e2e:stack Step5:revoke 410 + 降级)② 清理 compose 配置漂移(`BUNDLE_KEY_STORE` 环境变量、`bundle-keys-*` 卷——密钥自 server 0.6.0 起在 Postgres)③ `crearte-deploy` CHANGELOG 补账 | server, deploy | 无 | **完成**(server `a8ea755` / deploy `27044be`,2026-09-29 合并推送) | | P1 | prod 写侧可用 | prod 栈补对象存储(prod MinIO 或外部 S3)+ `api-prod` 配 `STORAGE_S3_*` / `GAMES_BASE_DOMAIN` / `CORS_ALLOWED_ORIGINS`;密码默认值、TLS 起步。现状:prod 无对象存储时写侧路由(上传/投稿/审核/预览)不注册,生产只读 | deploy(少量 server) | P0 | **完成**(crearte `63bb96d` / deploy `4d53d58`,2026-09-29 合并推送;TLS 与真域名留清单,见 spec §6) | | P2 | CI + 测试基线 | 后端 / 部署仓建 CI(gofmt/vet/test + `TEST_DATABASE_URL` 集成层 + e2e:stack 全链路);与前端已有 `validate.yml` 对齐。现状:后端/部署仓无 CI,Postgres 集成测试无 `TEST_DATABASE_URL` 时静默 skip | 三仓 | P0(e2e 依赖其修复) | **完成**(server `7b97108` / crearte `711b6de` / deploy `522545d`,2026-09-30 合并推送;e2e-stack 宿主仓修订见 spec §2.2;首跑拓出 serve-runtime 子域缺陷已修(`5e0fb2e`);Actions 启用与分支保护为 owner 手动尾巴,见 spec §2.4) | | P3 | 备份 + 可观测 | `pg_dump` 定时备份 + MinIO 数据保护 + 恢复演练 runbook;结构化 / 请求日志 + `/metrics`;限流器单实例问题记录权衡 | server, deploy | P1(拓扑定型) | **完成**(2026-10-01 历史重放合并推送:deploy `12f7c10` 0.6.0(backup.sh/restore-drill.sh/BACKUP-RUNBOOK/CI dry-run 腿/LOG_FORMAT-LOG_LEVEL 透传)+ server `d627e12` 0.16.0(slog 机械迁移 30 处含 P7/P8b2 新面、RequestLogger 中间件、手写 /metrics http+go+pgpool 三族、限流单实例权衡文档)。P3M 合流后终验全绿:容器四连+真库 `-p 1 -count=1`(skip 守卫 0,含注销链集成)+实栈 metrics 冒烟(计数族/nomatch/双跳过/slog JSON/pgpool 族/go 族全中)。原 P3 提交 `7fcfe0e`/`6ffd1ee`/`93a3c70` 在回滚窗口脱离 master,经 cherry-pick 重放字节级回归,P7/P8b2 新面补入同规则迁移。本机实栈备份演练腿未跑(prod 栈未起),留 owner 按 runbook 执行) | ## 第二波:产品价值(可与第一波部分并行) | # | 子项目 | 内容 | 涉及仓库 | 依赖 | 状态 | |---|--------|------|----------|------|------| | P4 | 作者主页 | `/users/:user` 聚合页(该作者全部已上架作品,前端按命名空间过滤,**零后端改动**),按最新上架排序;顺带 `/games/:user/:slug` 面包屑与作者名互链。spec:`docs/specs/2026-09-29-author-page-design.md` | crearte(前端) | 无强依赖,可提前并行 | **完成**(crearte `f12cbf1`,2026-09-29 合并推送) | | P5 | 收藏 / 评分 | 新数据表 + 用户态 API + 目录/详情页 UI;产品线里最大的一块 | 三仓 | 建议 P2 先落地 | **完成**(server `e3da246` / crearte `eb5fbed`,2026-09-30 合并推送;范围修订 deploy 零改动,见 spec) | | P6 | hosted 作品投稿(方案 A 自托管内嵌) | 作者把游戏部署在别处,投稿填 https URL,站内沙箱 iframe 播放;播放端机件已全存在,打通的是入口:后端 D-B runtime 不可变 + D-C hosted 禁 bundle 两护栏,前端表单第三档+预填解锁 | 三仓 | owner 已拍 A | **完成**(owner 拍板方案 A:只存 URL、站内沙箱 iframe 播;server `3e11446` 0.13.0 / crearte `fee5f3b` 0.19.0,2026-09-30 合并推送。勘查正误:Approve 落库映射本就全(PayloadToWork import.go:39),无需动;真实缺口只在校验两处——D-B metadata_change 禁改 runtime(根治前端拒预填的降级风险)+ D-C hosted 禁带 bundle。前端:类型三档/表单第三 radio「自托管内嵌」/hostedUrl https+fallback 默认 external 镜像校验/预填解锁;播放端零改动(GameHost/useGameFrame 既有)。双路审查 PASS with notes;六腿全绿:容器四连、空库 -count=1 集成 151 PASS 零 FAIL(含 TestHostedPublishChainOnPostgres 真 HTTP 全链)、真栈 full-loop 分支后端 1 passed、vitest 492/typecheck/admin-flow 6(首轮 1 passed 系栈腿争用假警报,复跑坐实)/主套件 69。T5:deploy 模板层无主站 frame-src 下发(仅两处属运行时子域页 CSP),零改动记录在案。遗留仅剩:new_version 对 hosted 仅 server 拦(前端无硬校验,spec 决策)。D-D(审核面 hostedUrl/fallback 展示行)当日补交:控制者直改维护者小补丁,分支 feat/p6-dd-adminrow(Task 2 任务书漏列该条;审查按任务书对照未扯出——教训:审查依据应是 spec §3 全量),纯文本无锚点+降级中文标签,四腿复跑 vitest 492/typecheck/admin-flow 7/主套件 70 全 RC=0,crearte 合主 `9bd9372`(0.19.1) | ## 第三波:治理与长尾(随时可插队) | # | 子项目 | 内容 | 状态 | |---|--------|------|------| | P7 | 管理后台增强 | 用户列表 / 角色管理 UI(替代 CLI `user set-role`)+ 审计日志 | **完成**(server `ca24805` 0.12.0 / crearte `900f13a` 0.18.0,2026-09-30 合并推送。audit_log 表 0010 + 组中间件统一记录(owner 定稿:admin 路由收敛为组,Full-Path 模板入史,GET 也记,失败尝试照记,未遂 401/403 不记);用户列表/PATCH 角色/审计查询三端点;唯一 admin 降级 409 护栏 CLI/API 双覆盖;前端 /admin/users + /admin/audit 两页,降级确认双要点文案;本机六腿验收全绿:容器四连+fresh-DB `-count=1` 10 ok 零 FAIL 零 skip、废 token 端到端 401、护栏矩阵(非唯一降 OK/唯一降 CLI 拒+API 409)、审计流水含 409 失败尝试、真栈 full-loop 分支后端 1 passed×2、vitest 488/typecheck/admin-flow 6/主套件 68) | | P8 | 长尾打包 | 权限开关 UI 全量(`inlineStyle/wasm/coop/fullscreen/gamepad`)、后端 triage 小项(`games.Detail` 400 细分、admin 路由 slug 校验、approve 同名竞态测试)、账号注销、静态兜底目录、CHANGELOG 模板文案 | **第一批完成**(②⑤①,2026-10-01 合并推送:server `921443a` 0.14.0 / crearte `70ba10c` 0.20.0。容器四连+空库 `-count=1` 集成全绿(新竞态测试含,skip 守卫 0)+`-race` 竞态腿 PASS;curl 冒烟全中:detail 400 细分 user:/slug: 且双非法 user 优先、admin 四路非法 400 `invalid work id`、合法格式不存在仍 404;FE vitest 499/typecheck/admin-flow 7/主套件 70+1skip;双审 PASS(server PASS with notes—唯一 note 双非法优先级缺钉桩,已以 `ee5b960` 测试断言补上);deploy 零改动。**第二批完成(③账号注销+④静态兜底目录)**(2026-10-01 合并推送:server `12b8ffb` 0.15.0(迁移 0011 墓碑化删行、DELETE /api/auth/account 对密码注销、唯一 admin 409、user delete CLI、catalog export 出 schemaVersion=2 目录)+ crearte `7d5f338` 0.21.0(/account 危险区+deleteAccount 客户端+AdminUsersView 三码中文化钉桩)+。真库注销链集成+分支真产物 curl 冒烟 14 项全 PASS(墓碑行/邮箱复用/409/旧 token 作废/CLI delete/export schema);FE vitest 512/typecheck/主套件 71+1skip/noauth 4,双审 PASS with notes(前端 2 条次要已钉桩 `7a54152`,server 裁决项:LOG_LEVEL 大小写不一致—deferred)。余 ④的 render 消费端接入按需(feed 已交付)**,CHANGELOG 头部去模板腔两仓已随第一批完成、wrapper 头部不在 spec 范围 | | P9 | UX 增强(第一批:浏览器反馈包) | 路由级 `document.title` 两段式(router `afterEach` 按 19 个 name 全表设静态基线 + 四个数据页 watch 数据后精化)+ 作品页 `meta description`(截 120 码点、默认回落)+ `StatePanel` 骨架对齐(cards 3→6 张、新增 `lines` 变体六页八实例)。零后端/部署改动 | **第一批完成**(2026-10-01 合并推送:crearte `26cd625` 0.22.0(`a196603`+`3f1de38`+审查补钉 `e9e4c56`)。五腿全绿:vitest **551**(基线 512+新增 39)/ vue-tsc 零错 / build OK / 主套件 72+1skip(含新增标题 e2e 腿,`landing.spec.ts` 首条兼容钉一字未动)/ noauth 4。独立审查 PASS with notes:ISSUE-1(离开作品页 description 未回落默认,spec D-C 子项)与 ISSUE-2(「七页」实为六页文案)均已在合主前补钉+补测。B 效率可访问(已于 P9-B 交付)/ C 暗色模式(已于 P13 交付)两批挂账已清偿) | | P10 | UX 增强(第一批:日常交互包) | toast 体系(useToast 单例 store + ToastHost 挂 App.vue)+ 投稿表单脏数据离开守卫(onBeforeRouteLeave confirm + beforeunload)+ 作品标签可点(GameView/GameCard tags → /games?tag= RouterLink)+ 作品页复制链接分享(clipboard + toast)+ 最近玩过条带(recent.ts localStorage + GameHost ready 记录 + LandingView 条带)+ 页头下拉外点/Esc 关闭。零后端/部署改动 | **第一批完成**(2026-10-01 合并推送:crearte `ee4edf7` 0.23.0,merge-base `26cd625`。六任务各经实现→任务级审查→裁定,另加全分支终审(spec §3/§4/§5 全量对照)。五腿全绿:vitest **601**(基线 551+新增 50)/ vue-tsc 零错 / build OK / 主套件 **77+1skip**(基线 72+1skip)/ noauth 4。审查补钉四处:`fc0270e`(AppHeader 卸载清理 spy)、`dbf4bf0`(hosted 重开 sync-flush 再记,spec D-H re-pin)、`bb9bb35`(e2e 夹具修正——spec 测试计划自身误选 external-runtime 夹具 2048/a-dark-room,换 abs-paths/storage)、`836b2fb`(AppHeader 路由收起回归,spec §5 明列项)。终审裁定「需修复后合并」两条件均已闭合。B 效率可访问(已于 P9-B)/ C 暗色模式(已于 P13)已清偿;OG 卡片 / 播放计数等后续批挂账待启动) | | P9-B | UX 增强(第二批:可访问与键盘效率包) | WCAG AA 色彩对比达标(`--color-success` 加深 + error toast 换 `bg-accent-ink`)+ toast 播报区重构(常驻 sr-only 播报层与视觉层解耦,收口 P10 终审转办项 T1(d)「实时区嵌交互按钮」)+ skip-link(`App.vue` 根首子,`focus:z-[80]`)+ SPA 导航后焦点管理(`focusMain()`,仅路径变化触发、`preventScroll`)+ 管理端表格 24 个 `` 补 `scope="col"`(两处空表头补 sr-only「操作」)+ 五星评分可访问名(逐星「评 N 星」+ 分组 `role="group"` 动态标签 + 字形 `aria-hidden`)。另加两个源码级守卫(`contrast.test.ts` 十一配对对比度、`tableScope.test.ts` 全仓 ` 3**,50653 采样暴力验证),故把亮色 scrim 改纯白(正是该令牌要防的泛白)时填充侧 1.1165 而 max() 读 18.42、守卫仍绿(任务级审查 M1 抓到);交付形态改为**按主题钉实际分离侧**(亮=填充侧 paper、暗=边框侧 ink),mutation 现能变红。**两条教训入 spec**:① `max(a,b) ≥ k` 是恒真断言高发区(互补时下界非平凡),且**修守卫必须两方向都验**(对合法值不误红 + mutation 下不误绿)——同一错误在 alpha 兜底分支重演(只对当前 Chromium 输出验,漏了 CSS Color 4 百分比/指数 alpha 被解析成 80/1);② **Tailwind v4 扫描全部源文件含 `.test.ts`/`.spec.ts`**——测试注释里的类名字面量会被当候选、烧死 utility 进产物(实现者用拼接修对一处,控制者八分钟后在自己裁定 commit 里重新引入,靠重建抓出 → spec §8-5b)。**终审另暴露一处 pre-existing 缺陷并延后不忽视**:`runtime/host/GameHost.vue:39` 降级外链徽标(`bg-accent text-paper`,11px bold)实测**亮色 `paper on accent` = 3.2590 < 4.5 FAIL**(暗色 7.1218 过),根因是 spike-0 的 grep 与 `noHardcodedColor` 守卫都只覆盖 `app/`、**漏了与 `app` 同级的 `runtime/`**;该违规自 P9-B 就在、P13 未使其变差且不属 P13 范围 → 三方面处置(守卫扫描根已含 `runtime/`、spec §3.2「accent 全仓唯一/纯非文本令牌」的假声明已纠正、违规本身登记可访问性打磨批)。守卫体系:`contrast.test.ts` **重构为按主题分块解析**(旧单 Map 解析器逐字保留为 `legacySingleMapParse` **反面钉桩**,防后人「简化」回去——旧解析器在暗色块存在后会把九个旧键静默解析成暗色值而断言标签仍写 light palette = 守卫悄悄变只守暗色)+ 新增 `noHardcodedColor.test.ts`(沿用 P12 `tableOverflow` 屏蔽范式,扫 `app/`+`runtime/`,含 2 positive + 1 negative control 防「扫 0 文件也报 0 违规」的假信心)+ `themeBootstrap.test.ts`(钉双写:同键名、两侧 stored 白名单、判定序、IIFE+var、theme-color、color-scheme meta)+ `dark.spec.ts` **10 腿**(含 pre-paint 归因腿:拦 JS 包后 `data-theme` 仍 dark,证明是内联脚本而非挂载后设置;反方向 stored 压过 system 腿;垃圾 stored 被忽略腿——后两条是 finding #2/N2 的行为解药,因文本位置守卫不鉴别语义重排)。验收:crearte vitest **688/79**(基线 635/74)/ vue-tsc 零错 / build+build-runtime OK / 主 e2e **102+1skip**(基线 92+1skip,P12 的 12 条 responsive 腿未动全绿)/ noauth 4——控制者与两位审查者各自独立复跑;产物 `main-C7966Gm-.css`:`var(--color-*)`=75、内联 `#141414`=2、暗色块在位、死 utility 双双归零、`--tw-shadow` 含 `var(--color-ink)`。挂账新增:第三态「恢复跟随系统」(spike 3 证明 header 在 @320px 最坏格无像素容纳带标签控件)、CSP 落地时内联 pre-paint 脚本需 `nonce`、死令牌 `--color-info`(`bg-info`/`text-info` 零实例)、SFC `