Commit Graph

6341 Commits

Author SHA1 Message Date
k88936 009a772ebd 媒体验证 E2E 去掉对服务端存储前缀的硬编码断言
- 「公开投影只暴露服务端派生的媒体 objectKey」改为结构断言:非空去空白、含路径分隔符、不是客户端 part 文件名
- 不再断言 agc/project-snapshots/v1/game-distribution/media/ 这一内部布局常量
- 与服务端返回键的一致性仍由相邻的 owner/公开投影相等断言覆盖
2026-10-07 11:43:17 +08:00
k88936 1f239a96ce 游戏分发 E2E 抽出共享 multipart 发布 helper
- 新增 scripts/game-distribution-e2e-helpers.mjs:COVER_PNG、imagePart、coverImagePart、publishFormData、resolveApiRequest
- 11 个 E2E 脚本删除各自的重复实现,改为 import;api() 的 body 分支收敛到 resolveApiRequest
- 各脚本的封面文件名前缀、envelope 与鉴权头合并顺序、返回形状保持不变
2026-10-07 11:42:45 +08:00
k88936 ab2af60d30 发布用 packageAll 落定的权威表单合成 metadata
- useTaonierExport 维护 effectiveFormRef,refresh 采纳新表单与打包前 flush 成功时同步
- 暴露 getEffectiveForm;publishGame 在 await packageAll() 之后用它,避免旧快照与宿主读盘不一致
- 补两条单测:采纳新表单后权威表单更新、未保存输入先落盘再作为权威表单
2026-10-07 11:41:27 +08:00
k88936 800c456804 回读版本冻结资料时透传 objectKey 并接受字符串截图数组
- GameDistributionPublicationImageDraft 增加 objectKey,封面/截图回读时带上沿用键
- FrozenPublicationMetadata.screenshots 改按字符串数组解析,删除只认 {assetId,objectKey} 的旧结构
- 前端草稿类型补 objectKey;补字符串数组解析的 Rust 单测
2026-10-07 11:39:34 +08:00
k88936 aa946a9304 发布命令删掉已失效的 package_relative_path 形参
- Rust 命令与 stage_publish_package 去掉该形参,整包固定读 .export/taonier.zip
- 前端服务类型、invoke 载荷与 useTaonierTab 调用同步删除
- 更新单测与 live 测试,去掉对已忽略形参的断言
2026-10-07 11:34:54 +08:00
k88936 12d4e8477a 发布图片加稳定 id,截图列表不再按 name-index 做 key
- GamePublishImage 新增 id,本地新选图与线上沿用图各自铸一次
- 截图列表 key 改用 image.id,删除/重排时不再因 index 位移重建节点,同名文件也能区分
- 补同名本地图 id 互异的单测
2026-10-07 11:13:45 +08:00
k88936 9184e92774 运维回滚 E2E:封禁态建游请求去掉歧义的沿用封面键
- 带二进制 cover part 时把 metadata.coverObjectKey 显式置 null,与套件其余「新图」语义一致
- 避免同一请求同时携带 objectKey 与 cover 字节,在网关检查顺序变化时结论漂移
2026-10-07 11:12:20 +08:00
k88936 152cdc6177 可达性 E2E:创建游戏失败时先退出再解引用封面键
- 在 gameId 取值后补 if (!gameId) process.exit(1)
- 创建失败时 created.data 为空,提前取 coverObjectKey 会抛未捕获 TypeError 打崩脚本
2026-10-07 11:12:08 +08:00
k88936 9c822c098d 重启校验 E2E 续跑兼容旧 STATE_FILE 的 coverAssetId
- runResume 读封面键时回退 state.coverAssetId
- 旧版状态文件没有 coverObjectKey,直接读会得到 undefined 且被 JSON.stringify 丢掉,v3 会缺封面
2026-10-07 11:11:58 +08:00
k88936 8e59e11f0d 重启校验 E2E:创建游戏失败时先退出再解引用
- 在 check('创建游戏成功') 后补 if (!gameId) process.exit(1)
- check 只记失败不中断,created.data 为空时继续取 coverObjectKey 会抛未捕获 TypeError 打崩脚本
2026-10-07 11:11:41 +08:00
k88936 067f02c855 作者视角的游戏详情媒体换签走 owner 作用域
- GameDetailResolvedAsset 新增 gameId 入参,ownerView 时传 game.id
- 公开读只服务已发布 + active 作品,未公开/待审/驳回的作者预览此前只会静默回占位
- 测试替身记录换签选项,补作者视角带 gameId 的定向断言
2026-10-07 11:10:44 +08:00
k88936 42c742df5c 发布预检的标题/简介长度改按码点计数
- normalizeMetadata 用 Array.from(...).length,与面板校验及服务端 chars().count() 同口径
- 含 emoji 的压线标题/简介不再因 UTF-16 码元长度被发布预检误拒
- 补 40 个 emoji 标题 + 120 个 emoji 简介的定向测试
2026-10-07 11:09:08 +08:00
k88936 075078f358 保存遇宿主不可用保持 dirty,避免陈旧注册表覆盖未落盘输入
- 保存失败分流后不再无条件 setDirty(false):exportUnavailable 分支保留 dirty
- dirty 为真时 adoptable 保持 false,宿主恢复后的重读不会用旧注册表表单覆盖用户输入
- 冲突/未知失败仍归零 dirty,维持「同一份输入不反复打宿主」
2026-10-07 11:08:13 +08:00
k88936 00448e0b26 重读采纳新表单不再清掉构建失败现场
- 采纳路径去掉无条件 setFailure(null),只保留上方「读来源失败」的函数式清理
- 面板后台注册表被改写时,构建失败弹窗不再被下一次成功重读顺手抹掉
- 补「构建失败 + 重读采纳新表单」定向测试
2026-10-07 11:08:09 +08:00
k88936 fede8cc161 作品资料更新的幂等摘要纳入 game_id
- update_owner_game_metadata 的 request_digest 与 create_version 同口径,带上 game_id 作用域
- 幂等账本按 (owner, action, key) 归档不含 game_id,摘要不带作用域会把另一部作品的同资料更新当成重放
- 补跨作品摘要区分断言
2026-10-07 11:05:45 +08:00
k88936 d24a16ad02 发布资料 multipart 路由显式放行请求体上限
- create_game / create_version / update_owner_game_metadata 三条 multipart 路由补 DefaultBodyLimit
- 放行封面 + 最多 6 张截图 + metadata/boundary 余量,否则 Axum 默认 2 MiB 会在抽取前 413
- MAX_SINGLE_MEDIA_BYTES 提升为 pub(crate),补口径断言
2026-10-07 11:04:15 +08:00
k88936 057b56b24a 截图导入按剩余名额逐张写入,不再只取最后一张
- AssetImporter 是多选(上限 100),onImport 改为遍历 assets 按 6 张上限截断
- 一次选多张时不再静默丢弃除最后一张外的截图
- 补多选导入定向测试
2026-10-07 11:02:29 +08:00
k88936 bb7097ce5c FormCard 截图数量文案摊平嵌套三元
- 本地张数 / 整组沿用线上 / 还没有截图三态先算成 screenshotSummary
- 行为不变,去掉嵌套三元
2026-10-07 11:01:04 +08:00
k88936 e4d46609cf FormCard 字段控件摊平嵌套三元
- options/multiline/input 三态改为 if/else 生成 inputSlot
- 复用一个 fieldClassName,去掉三份重复的边框/错误态样式与嵌套三元
2026-10-07 11:00:34 +08:00
k88936 8d74fa9aba 发布打包 reject 时收尾进度,避免面板卡死
- packageAll 在宿主不可用/读失败时会直接抛,await 包一层 try/catch
- 失败时把进度置为 failed 并带上原因,不再停在 running(运行中对话框没有关闭入口)
2026-10-07 10:59:50 +08:00
k88936 7b521f6f29 useTaonierTab 发布版本号判空改用严格相等
- `online.nextVersionNumber == null` 改为 `=== null`,去掉宽松相等
- online 为空已由 `!online` 显式挡掉,语义不变
2026-10-07 10:59:14 +08:00
k88936 4acb0e7124 陶泥儿产物读取按已知体积预分配
- read_package_bytes 接收调用方已验证的 expected_bytes,用 Vec::with_capacity
- 接近 200 MiB 的包不再因反复扩容多复制约一倍数据
2026-10-07 10:58:46 +08:00
k88936 d3d7e5a8ca 陶泥儿构建收尾:体积超线不整包读入内存
- conclude 仅在 produced(普通文件、非链接、非空)时才读取产物
- 读取前先看 metadata.len(),超过 ARTIFACT_PACKAGE_READ_MAX_BYTES 直接判不合格
- 避免构建脚本写出超大 zip 时先把宿主内存读满,也堵住符号链接被整包读取
2026-10-07 10:57:00 +08:00
k88936 500c3fda6b ConflictCard 按字段类型分开赋值,去掉 as never
- 截图字段走数组分支,文本字段走字符串分支,不再用 as never 关掉类型检查
- 表单将来加入非 string/string[] 字段时这里会当场编译失败
2026-10-07 10:55:25 +08:00
k88936 4d72a77aeb OnlineValuesCard 线上状态文案摊平嵌套三元
- 模板字符串里的版本号后缀与已发布/未发布两态改为先算 onlineSummary 变量
- 行为不变,去掉嵌套三元
2026-10-07 10:54:32 +08:00
k88936 7db1fc4ff4 发布按钮禁用条件纳入 taonier.running
- 「打包并发布」与「打包」共用禁用判据,构建进行中不能再并发触发 packageAll
- 避免两次构建争抢同一个 .export/taonier.zip 并互相覆盖结果
2026-10-07 10:53:56 +08:00
k88936 229f0580fa ArtifactsPane 发布禁用条件改用严格判空
- `online?.nextVersionNumber == null` 改为 `!online || online.nextVersionNumber === null`
- 去掉宽松相等,同时显式挡掉 online 为空的形态
2026-10-07 10:53:28 +08:00
k88936 30b129fcfe ArtifactsPane 发布按钮文案摊平嵌套三元
- publishLabel 改为 if/else 三态赋值,去掉「正在发布/更新/首次发布」的嵌套三元
- 行为不变,仅满足项目禁止嵌套三元的约定
2026-10-07 10:53:18 +08:00
k88936 3d6795978c multipart 图片文件名按真实内容类型给扩展名
- 新增 multipart_image_file_name,JPEG/WebP/GIF/AVIF 不再统一叫 .png
- 服务端仍按 MIME part 判定,文件名只作为未来消费者可依赖的事实保持一致
- 补扩展名映射单测
2026-10-07 10:52:58 +08:00
k88936 3ecd4efcbb 读取发布图片前先按体积上限失败关闭
- read_draft_image 先看 metadata.len(),超过 8MB(对齐服务端单图上限)直接返回错误
- 避免草稿指向超大本地文件时先把宿主内存读满,再由服务端事后拒绝
- 补稀疏大文件定向测试
2026-10-07 10:51:01 +08:00
k88936 3832ca4fab 发布资料摘要给图片字节加长度前缀
- metadata_digest 逐张先写 u64 长度再写字节,分片边界进入摘要
- 否则「封面 [1,2]+截图 [3]」与「封面 [1]+截图 [2,3]」摘要相同,本地幂等账本会误判重放
- 补分片不变性断言
2026-10-07 10:48:16 +08:00
k88936 ab9789d11a 截图槽位空串归一成 null 保留顺序
- normalizeMetadata 不再 filter 掉空串槽位,改为归一成 null(消费草稿本地图)
- 否则后续槽位整体前移,与 .export/taonier.json 的截图顺序错位
- 更新定向测试:空串槽位保留为 null
2026-10-07 10:47:10 +08:00
k88936 99d5fd1eaa 抽取 jsdom 用例共享的内存 Storage
- 新增 tests/memoryStorage.ts 导出 createMemoryStorage,统一 length/key 语义
- jsdomLocalStorageSetup 全局兜底、appSurface/harness、chatPromptPolish 改为导入同一实现
- chatPromptPolish 断言由 Map.size 改为 Storage.length,语义不变
2026-10-07 10:46:21 +08:00
k88936 3cd5928fc5 标注陶泥儿计划与里程碑文档为已实施并保留
- 两份文档 Status 由「待评审」改为「已实施(M1–M4 已落地)」
- 实施计划头部注明长期保留,原 §5.4「收尾删除计划文档」不再执行
2026-10-07 10:27:47 +08:00
k88936 5142c26011 文档同步游戏分发 owner 媒体读
- 后端契约/玩法链路/AGC 实施计划补 owner 作用域读路由与作者预览口径(软删仍 404)
- decision-log 2026-10-06 条目记录 owner 读决策,并改「临时计划已删除」为保留计划与里程碑文档
- pitfalls 新增作者预览必须走 owner 读、不能回退素材库 ACL 的排障口径
2026-10-07 10:27:19 +08:00
k88936 89567d94a9 平台 web 作者预览切到 owner 媒体读
- gameDistributionClient 新增 getOwnerGameDistributionMediaReadUrl,参数与换签解析与公开读共用
- useGameDistributionMediaReadUrl 支持 gameId;GameCover 增 owner 开关,MyGamesPage 封面走 owner
- resolveGamePublishImagePreview 接 gameId,发布/编辑回填未发布作品的封面与截图也能换签
- 补 client 路由/鉴权测试与 MyGamesPage owner 换签测试
2026-10-07 10:27:14 +08:00
k88936 4cd7843134 AGC 作者预览切到 owner 媒体读路由
- resolve_preview_url 改走 /api/game-distribution/my-games/{gameId}/media/read-url,不再走素材库 /api/assets/read-url
- 新增 owner_media_read_url,复用 endpoint 的路径段转义并编码 objectKey
- 新增路由与编码单测,钉住不再回退素材库 ACL
2026-10-07 10:27:03 +08:00
k88936 069df704fd 真实链路脚本补 owner 媒体读检查
- 待审期间断言作者本人可经 owner 路由预览自己的封面
- 断言匿名走 owner 路由被拒(401)、非本作品媒体的 objectKey 换不出来(404)
2026-10-07 10:26:50 +08:00
k88936 9cd6357946 游戏分发媒体读新增 owner 作用域路由
- 新增 GET /api/game-distribution/my-games/{gameId}/media/read-url 与 .../media/read-bytes,需 bearer
- 判定 = gameId 属于当前登录主体且 objectKey 命中该作品当前行 cover_object_key/screenshots_json
- 抽出 game_media_object_keys 与换签/字节中转共用函数,公开读判定与响应形状不变
- 新增媒体键提取单测与 owner 路由挂载/鉴权断言
2026-10-07 10:26:37 +08:00
k88936 bd4801ef80 恢复陶泥儿实施计划与里程碑文档
- 从 5e8ecaa35^ 取回被 M4 删除的【实施计划】与【里程碑】陶泥儿导出文件草稿化与发布媒体直传-2026-10-06.md
- 本次起不再按计划 §5.4 在收尾删除计划文档,保留理由记录在 decision-log
2026-10-07 10:26:29 +08:00
k88936 5e8ecaa35b 回写陶泥儿导出与发布媒体直传文档并删除临时计划
Project CI / AI game creator shell Rust crates (pull_request) Failing after 57s
Project CI / Backend tests (pull_request) Failing after 16s
Project CI / AI game creator shell Rust lane 1/2 (pull_request) Successful in 6m27s
Project CI / Repository checks (pull_request) Failing after 13s
Project CI / Frontend tests (pull_request) Successful in 2m5s
Project CI / AI game creator shell Rust lane 2/2 (pull_request) Successful in 5m50s
Project CI / AI game creator shell web tests (pull_request) Successful in 2m30s
Project CI / Native shell tests (pull_request) Successful in 6m1s
- 技术方案/后端契约/玩法链路三份主规范改成当前状态:文件草稿、build:taonier、multipart objectKey 直传与域内公开读
- decision-log 2026-10-06 条目由计划态改写为落地态,含命名约定、硬切、E1、taptap skill-pack 例外
- pitfalls 新增 multipart 幂等摘要、发布账本、skill-pack 红与 zip 存档根入口四条
- 删除临时实施计划与里程碑规范,历史由 Git 保存
2026-10-07 01:26:37 +08:00
k88936 afbcc79978 陶泥儿产物按平台发行包上限预检
- build.rs 保留 512 MiB 读取安全线,另按 shared-contracts 的 GAME_DISTRIBUTION_MAX_PACKAGE_BYTES(200 MiB)做预检
- 构建收尾与发布读包两处都预检,超限给「精简资源后重新导出再发布」,不再等上传吃服务端 413
- 新增平台上限单测,并锁定读取安全线必须高于平台上限
2026-10-07 01:26:24 +08:00
k88936 d28b178c04 AGC 真实发布测试迁移到 multipart 媒体合同
- 删除平台素材直传代跑与 coverAssetId 种子,创建游戏/版本改 FormData(metadata + cover part)
- 断言改为创建响应与 frozenMetadata 的 coverObjectKey/screenshots
- 保留分片续传、复用 gameId、重复版本与版本回退等主链证据
2026-10-07 01:19:50 +08:00
k88936 307c796f89 补齐 jsdom 用例的 localStorage 内存实现
- vitest.config.ts 增加 setupFiles,在 Node 26 + jsdom 未注入 localStorage 时补同形内存实现
- 新增 tests/jsdomLocalStorageSetup.ts,供所有 jsdom 用例共用
- gameDistributionPublish.test.ts 去掉局部 polyfill,改用共享 setup
2026-10-07 01:14:07 +08:00
k88936 6ccb9f4571 AGC 陶泥儿面板文件草稿化与发布媒体直传
- 新增 export/state/taonier 状态层:字段校验、四命令失败载体、失败分类与 adapt/repair/fill 指令、600ms 自动保存与 2s 轮询
- 新增 tabs/taonier 面板:ArtifactsPane/FormCard/OnlineValuesCard/ConflictCard 与三个对话框,线上值并排显示与沿用动作
- 发布媒体改直传:草稿本地图读字节发 cover/screenshot part,空路径沿用线上 objectKey,幂等摘要纳入图片字节
- 退役 AI 资料建议/封面生成:删前端调用、Rust 命令与注册、api-server 路由与专属 DTO
- 删除旧 PublishPane、GameDistributionPublishFormView、GamePublishBlockedDialog、useGameDistributionPublishForm
- 新增 tests/taonierFields、taonierContract、taonierExport,check-config 与 dto parity 同步
2026-10-07 01:12:34 +08:00
k88936 b04aceb57d AGC 陶泥儿打包链路落地与 exports 全退役
- 新增 vite-export-taonier skill:vite.config.taonier.mjs 构建到 dist-taonier,pack.mjs 产出存档根含 index.html 的 .export/taonier.zip
- skill pack 锁步登记:EXPECTED_SKILL_NAMES、AGC_SKILL_PACK_FILES、manifest.json sha 与版本、codex mock 名单
- 新增 export/draft/taonier 文件草稿模块:build:taonier 脚本发现、.export/taonier.json 注册表、四个 tauri 命令与产物读取入口
- 发布暂存改读固定 .export/taonier.zip,删除 phaser/vite 发布门与 exports 打包读取链路
- 删除 exports 初始化目录、exports/README.md 生成与渲染、playtest-package 打包/读取/列举命令
- 生成契约与 prompts 去掉 publish-package artifact 声明,run-trace 白名单与五处排除列表同步
- 同步 ts-rs 生成绑定与 export/generated 行尾空白豁免
2026-10-07 00:54:31 +08:00
k88936 eea37f80f1 游戏分发真实链路脚本迁移到 multipart 媒体直传
- 12 个 check-game-distribution-* 脚本改用 multipart:metadata + cover/screenshot 二进制 part
- 删除 assetId/assetObjectId 断言与素材库直传前置,公开读改走 media/read-url 与 read-bytes
- media-e2e 负例重写:缺封面、超 6 张、非本作品 objectKey、槽位与 part 数量不匹配
- ratings-e2e 直连 reducer 字段改 cover_object_key/screenshots_json,test-creator-runtime 同步
- .gitattributes 为 export/generated 生成目录豁免行尾空白检查
2026-10-07 00:50:19 +08:00
k88936 d202c76099 游戏分发发布媒体改 objectKey 与 multipart 直传
- 契约:创建/编辑/建版请求去掉 `coverAssetId`,改为 `coverObjectKey` 与 `screenshots: (string|null)[]`,Rust 与 TS 同步。
- schema:`game_distribution_game` 删除 `cover_asset_id`;创建输入末尾追加 `cover_object_key`/`screenshots_json`;冻结资料截图改为 objectKey 数组并删除 `GameDistributionFrozenScreenshot`;同步迁移登记与生成绑定。
- 授权:删除按 assetId 的公开读授权,新增按 objectKey 的 `get_game_distribution_media_read_access` procedure;公开可见判定抽成 `game_distribution_game_is_publicly_visible`。
- api-server:三条写路径改收 `multipart/form-data`(`metadata` 文本 + `cover` + 重复 `screenshot`),新图直写项目快照桶、沿用图校验归属与数量;新增匿名 `GET /api/game-distribution/media/read-url` 与 `read-bytes`;幂等摘要覆盖图片字节。
- web:发布/编辑客户端改 FormData;封面与截图读取切到新读路由;移除发布前素材登记与 assetId 状态。
- AGC:发布命令先按 objectKey 做存在性校验以保持编译,multipart 直传改造留待 M3。
- 文档:实施计划与玩法链路合同章节同步新的 multipart 字段口径。
2026-10-07 00:30:26 +08:00
k88936 77126e06f9 抽取对象读签名与同源字节中转公共模块
- 新增 api-server::object_read:签名读地址、过期收敛、同源字节中转与错误映射
- assets.rs 的 read-url/read-bytes 改为复用该模块,授权判定仍留在素材域
- 移除 assets.rs 内重复的常量、作用域枚举与字节中转实现,行为不变
- 过期收敛单测随实现迁到 object_read
2026-10-07 00:10:05 +08:00
k88936 2fdf4078d0 新增陶泥儿导出与游戏分发媒体直传主规范与里程碑
- AGC 实施计划追加「2026-10-06 陶泥儿导出文件草稿化与游戏分发媒体直传」章节
- 玩法链路新增「游戏分发发布媒体直传合同(2026-10-06)」
- 后端数据契约补充 game_distribution_game 的媒体直传与 schema 变更约束
- decision-log 记录文件草稿、build:taonier/dist-taonier、快照桶+新读路由、硬切、exports 全退役、AI 建议/封面退役
- 新增里程碑规范与实施计划两份 plans 文档
2026-10-07 00:05:24 +08:00