Commit Graph

1183 Commits

Author SHA1 Message Date
k88936 d231cc4602 合并 origin/master:保留 3D 契约与 provider checkpoint,旧玩法表随主线退役
- server-rs/crates/shared-contracts/src/lib.rs:采用主线的模块裁剪(删掉 cfg(any()) 遗留模块、补上 agc_analytics 与 game_distribution),同时保留本分支的 editor_canvas、model3d 模块与 EDITOR_GENERATION_OPERATION_KINDS 导出
- server-rs/crates/spacetime-module/src/migration.rs:主线删除的 410 行旧玩法表 normalize 段保持删除,保留本分支的 provider_kind / provider_task_id 兼容段与对应用例
- docs/【开发运维】本地开发验证与生产运维-2026-05-15.md:校验清单同时保留 Tripo 3D 生成任务与 editor_background_music_generation / model3d_text_to_model / model3d_image_to_model
- .gitignore:补回本分支新增的 3D 模型文件忽略规则(*.glb / *.gltf 等 12 行),压测数据段随主线一并删除
- 共享记忆:本分支的 3D 决策与踩坑条目保留在主线重排后的 decision-log.md 与 pitfalls.md 中
2026-09-23 19:39:30 +08:00
k88936 f198b7a6d0 multiview 视图输入显式化为 url / fileToken,线上按文档 view-key 形态发出
- 契约新增 Model3dViewInput(url / fileToken 的 tagged enum),views 的四个视图都改用它,裸字符串在契约层即被拒绝
- platform-tripo 不再走 SDK 的位置数组形态:按 Tripo 文档推荐的 view-key 构造 inputs,值写成显式 {url} / {file_token},种类由契约字段决定、链路上不再猜前缀
- 视图校验(front 必填、至少两张、空白按未提供)与 inputs 构造合并成一条路径,不再两处重复规则
- 新增 4 条定向用例钉住发出的 JSON 形状、空白视图、视图数量与 taskId 复用;契约用例补齐裸字符串与视图内未知字段被拒
- 重新生成 ts-rs 绑定与导出索引,技术方案同步 multiview 输入口径
2026-09-23 18:59:05 +08:00
k88936 df6694c4a9 图生 3D 的资源派生来源改为取自请求的 source
- job.rs 新增 Model3dJobRequest::source_resource_id():resource 来源带出画布资源 id,素材库来源与文生 3D 没有可登记的来源资源
- worker.rs 落库时资源行与素材行都改用它:资源行记派生来源,素材行优先指向本项目的资源行、只落素材库时退回请求里的来源资源
- 新增单测钉住三种来源(resource / asset / 文生)的取值,不再拿本次新生成的输出资源 id 冒充来源
2026-09-23 18:51:10 +08:00
k88936 6b1114356c 59/60/61/65 按决定不修复,改为在代码里写清取舍
- worker.rs:说明 last_error_message 是落库且前端直接展示的摘要,只取 provider message,不塞内部 reason/taskStatus(#59)
- platform-tripo error.rs:说明 ADR 0001 要求平台层不带出 SDK 错误模型,Io/Serde 只保留文本(#60)
- platform-tripo mapping.rs:说明 Tripo 文档把 generated_image_url 列为 text_to_model 固定字段,按 ADR 0001 失败关闭保留必填(#61)
- platform-tripo image_to_model/client.rs:说明 PublicUrl 只做非空白校验的边界条件与将来接外部地址时的校验位置(#65)
2026-09-23 18:04:29 +08:00
k88936 985955205c 把 checkpoint 分支写实为 at-most-once 硬约束而非续跑能力
- worker.rs 模块注释明确 Tripo job 固定 max_attempts = 1,崩溃后租约耗尽直接终态失败、不会被重新 claim,因此不存在续跑路径
- worker.rs 说明 existing_checkpoint 是防御性硬约束,checkpoint 的日常用途是人工对账
- 技术方案与 ADR 把「崩溃后重新 claim 只查询」改写为「不重新 claim,带 checkpoint 的路径绝不二次 submit」
- 实施计划与里程碑同步 checkpoint 语义,不再宣称续跑
2026-09-23 17:50:04 +08:00
k88936 85219ad1d4 提交前先判预算,耗尽时不再发起计费的 submit
- run_model3d_job 在没有 checkpoint 的分支上先走 ensure_submit_budget:
  预算已被解析 / 排队耗光时直接按 provider 超时终态失败,不去白花一次 provider 提交
- 续跑(已有 checkpoint)分支不受影响,仍然只轮询不提交
- 新增用例:预算耗尽必须拒绝提交,仍有预算必须放行
2026-09-23 17:45:22 +08:00
k88936 42b4315b4f 可重试性改为显式判定,不再由 status 缺省推断
- TripoError::Request 增加 retryable 字段:由产生错误的一方按真实分类判定
- 传输层失败按 reqwest 的 is_timeout / is_connect 分类(新增 transport_error_is_transient,
  以及状态集合 http_status_is_transient)
- SDK 的 Error::Request 只在带瞬时状态码、或底层 reqwest 错误确实瞬时时可重试;
  source 为空(空 body / 格式错误 / 缺 data 字段)不再重试
- 产物客户端构造失败标为不可重试;无数据推进、body 读取失败与长度不一致标为可重试
- 新增四组用例:显式标记、状态集合、SDK 分类,以及用真实 reqwest 错误(连接被拒 vs 非法地址)验证分类
- 同步技术方案:写明「可重试性由产生错误处判定」的口径
2026-09-23 17:40:18 +08:00
kdletters 297d7bf1e7 优化 AGC 发布资料与截图交互
Project CI / AI game creator shell Rust crates (push) Successful in 1m24s
Project CI / AI game creator shell Rust smoke (push) Successful in 1m56s
Project CI / Backend tests (push) Successful in 4m39s
Project CI / Native shell tests (push) Successful in 5m49s
Project CI / Frontend tests (push) Successful in 2m1s
Project CI / AI game creator shell Rust lane 2/2 (push) Successful in 8m29s
Project CI / AI game creator shell Rust lane 1/2 (push) Successful in 8m31s
Project CI / AI game creator shell web tests (push) Successful in 1m53s
Project CI / Repository checks (push) Successful in 2m25s
发布门禁阻断提示改为独立弹窗且不写入聊天记录
移除发布面板发行包技术摘要
新增免费发布简介与分类建议接口和前端回填
接入封面泥点定价、确认与生成流程
截图改为并行上传,单张失败隔离且不阻断发布
截图操作改为图标,失败项内嵌错误与删除
同步发布合同、实施计划和决策记录
2026-09-23 17:40:08 +08:00
k88936 f6f41f22c3 geometry_quality 预检只拒绝 detailed,standard 按不传处理
- validate_generation_options 对非 v3.1 / v3.0 家族只在取值 detailed 时拒绝,
  与 quad / smart_low_poly / generate_parts「只拒绝启用值」的处理对称
- 新增 wire_geometry_quality:不支持的家族把 standard 收敛成不发(等价于 provider 默认档),
  三个 endpoint 的请求映射都过这一层,避免 provider 因「不支持该字段」整单拒绝
- 新增两组表驱动用例:非 v3 家族 standard 放行 / detailed 拒绝,以及映射层的收敛结果
- 同步技术方案:写明「预检只拒绝启用值」与映射层收敛 standard 的口径
2026-09-23 17:33:51 +08:00
lhk229 5bc5328c06 客户端埋点复用已有下载渠道配置 (#496)
Project CI / AI game creator shell Rust crates (push) Successful in 1m18s
Project CI / AI game creator shell Rust smoke (push) Successful in 1m55s
Project CI / Backend tests (push) Successful in 3m42s
Project CI / Frontend tests (push) Successful in 1m44s
Project CI / Native shell tests (push) Successful in 5m37s
Project CI / AI game creator shell Rust lane 2/2 (push) Successful in 8m24s
Project CI / AI game creator shell Rust lane 1/2 (push) Successful in 8m30s
Project CI / Repository checks (push) Successful in 2m0s
Project CI / AI game creator shell web tests (push) Successful in 1m31s
删除独立埋点 origin 环境变量及配置字段,按 dev/release 渠道校验官方站点。
本地开发、测试及容器的 dev 渠道允许规范回环地址,兼容可变端口。
同步环境变量示例、技术方案和运维说明,补充渠道隔离与身份校验测试。

Reviewed-on: https://git.genarrative.world/git/GenarrativeAI/Genarrative/pulls/496
2026-09-23 17:03:17 +08:00
k88936 b33a8a141c 3D 产物下载的重试改为覆盖整个响应体
- download_model / download_rendered_image 把「取响应头 + 读完 body」作为一次可重试事务,
  每次尝试都重新取响应头并整体重下,不做断点续传
- body 传输失败与长度不一致归一成可重试的传输错误(不再带 HTTP 200),HTTP 状态只留在文案里
- 新增 TripoArtifactBytes(读完的产物)并公开 download_model / download_rendered_image 的 max_bytes 上限;
  超限按 OutputSchema 失败且不重试,流式句柄 TripoDownloadedArtifact 收回 crate 内部
- api-server 的 read_artifact 改成对完整产物做落库前校验(只判空),体积上限转由调用方传入
- smoke 示例改为一次写入完整字节;新增「body 中途断开后整体重下成功」与「超限不重试」两个用例
- 同步技术方案与实施计划:把「只重试响应头」的描述改成「重试包住整个 body」
2026-09-23 17:01:40 +08:00
k88936 a4132616d8 3D 产物 content type 只认字节或槽位白名单,去掉兜底
- 删除 fallback_extension 与「未知声明原样放行 + 扩展名兜底」的归一逻辑
- 槽位白名单收敛为唯一映射表(content type ↔ 对象键扩展名),跨槽位类型返回 None
- resolve_artifact_content_type 改为返回 Result:字节认不出且声明不在白名单时按 502 失败,
  不再把 text/plain 之类的声明连同拼出来的 .glb 扩展名落进 OSS 与 asset_object
- 错误体只回显截断到 64 字符的声明值,避免把任意长度的 provider 文本带进响应
- 重写 storage 测试:新增白名单外声明、跨槽位类型与字节认不出三类用例
- 同步技术方案:说明白名单范围与「不做任何兜底」的口径
2026-09-23 16:39:15 +08:00
k88936 6a7cf294a0 3D 生成请求允许缺省 textureQuality 并按 standard 计价
Project CI / AI game creator shell Rust crates (pull_request) Has been cancelled
Project CI / Backend tests (pull_request) Has been cancelled
Project CI / Native shell tests (pull_request) Has been cancelled
Project CI / Frontend tests (pull_request) Has been cancelled
Project CI / Repository checks (pull_request) Has been cancelled
Project CI / AI game creator shell web tests (pull_request) Has been cancelled
Project CI / AI game creator shell Rust lane 2/2 (pull_request) Has been cancelled
Project CI / AI game creator shell Rust lane 1/2 (pull_request) Has been cancelled
Project CI / AI game creator shell Rust smoke (pull_request) Has been cancelled
- PricingParamView::validate 不再要求 texture=true 时显式给出 textureQuality,缺省按 standard 计价
- 只有显式 detailed / extreme 才命中 hdTexture / ultraTexture 加价,缺省不改变报价
- v2.5 拒绝任何显式 texture_quality,必填规则会让 H25 + texture=true 永远不可达
- texture=false 仍禁止出现贴图档位,原有冲突校验与用例保持不变
- 同步技术方案:说明 geometryQuality / textureQuality 两个字段允许缺省的共同理由
2026-09-23 16:30:22 +08:00
k88936 427b9f19a1 3D 生成请求允许缺省 geometryQuality 并按 standard 计价
- PricingParamView::validate 去掉 geometryQuality 必填,缺省按 standard 计入定价
- 只有显式 detailed 才命中 hdGeometry 加价,缺省不会改变报价
- 新增缺省几何质量的定价用例(v3.1 与 v2.5 两条路径),并把它从必填字段用例里移除
- 同步技术方案:说明该字段允许缺省的原因,v2.5 / P1 / P2 因 provider 不支持该参数而必须允许缺省
2026-09-23 16:24:18 +08:00
k88936 ffee739774 platform-tripo 构造配置时拒绝零超时与空白凭据
- TripoSettings::new 改为返回 Result:request_timeout 必须大于零,api_key / base_url 不能是空白
- 新增 TripoSettings::validate 与 TripoError::Configuration,字段是公开的,因此 TripoProviderClient::new 在使用前再校验一次
- 拒绝零超时的理由是同一个值存在两种语义:tokio::time::timeout 立即超时,reqwest 却当成不超时
- api-server 构造入口把构造失败按既有 503 口径映射,并补全 TripoError 的匹配分支
- smoke 示例与 platform-tripo 测试跟进新的构造签名,新增零超时 / 空白凭据用例
2026-09-23 16:16:27 +08:00
k88936 158f9b741d 3D 落点放宽为「至少一个」并把结果引用改成平坦字段
- 校验层不再要求「projectId 与 assetFolderId 恰好一个」:两个都不给 400 点名 projectId,canvasCompletion 与「没有 projectId」同现 400 点名 canvasCompletion,两个都给按合法处理;与其它画布生成工具同一口径。
- 落点预检改成对给出的每个落点逐个定点查,出错字段只在「只给一个」时点名该键,两个都给无法归因回落到 target;去掉已经没有意义的旧用法注释。
- 结果侧 Model3dGenerationTargetRef 从 tagged enum(kind=projectResource/assetLibrary)改成与请求落点同形的平坦可选字段 resourceId / assetId,两个落点都写就两个都带;生成绑定同步变宽。
- worker 的 target_ref 改为按「写了哪条落点行」分别带 ID,完成结果用例改成断言平坦字段且只落项目资源时不得凭空出现 assetId;契约测试对称覆盖「只落素材库」形态。
- 验证:cargo test -p api-server tripo3d::(56 passed)、cargo test -p shared-contracts、npm run contracts:model3d:generate、check:rustfmt / check:encoding / git diff --check 通过。
2026-09-23 15:54:07 +08:00
k88936 c64bfc3867 3D 预览产物 content type 改为按字节识别
- storage.rs 新增 sniff_preview_content_type(PNG / JPEG / WebP),resolve_artifact_content_type 改为按槽位判定:预览与模型一样先嗅探字节,嗅不出才回落声明值(最终仍回落 image/webp)
- 修掉 provider / CDN 不写或写错 Content-Type 时 PNG 预览被写成 image/webp 并传播到 OSS metadata、asset_object.content_type 与生成结果的问题;对象键扩展名随之正确
- 定向用例重写为「字节优先 / 未知回落」两组,替换原先钉住「预览不嗅探」的用例
- 技术方案与决策记录同步该口径,并记录与其它图片链路(bgfilter / VectorEngine / 生成图落 OSS 适配器)的一致性对照
2026-09-23 15:28:23 +08:00
k88936 11d1324857 3D 图生输入解析的测试改为断言可观察行为
- 删掉 include_str! 嵌源码、按 token 断言「没出现列工程 / 列素材库」的守卫:它测的是实现文本,改名、换格式、调顺序都会误伤
- 定点查询用例改成覆盖 resource / asset 两个分支,断言每个分支只发起一次按 ID 的查询、且对象键原样来自记录
- 模块文档写明定点查询由注入签名收口(一个 ID → 一条记录),失败语义与测试口径一并写实
2026-09-23 14:58:44 +08:00
k88936 1be77d2f99 3D 图生输入解析只收敛「引用不可用」状态码
- resolve_source_object_key_with 的 4xx 收敛从 is_client_error() 收窄为 400 / 404,不再把 403 服务身份校验失败与 409 并发冲突也说成「图片必须是已登记资源」
- 与模块注释「只有基础设施失败保留原状态码」的实际口径统一,403 / 409 / 5xx 一律按原状态码上报
- 定向用例改名 image_source_resolution_only_collapses_unavailable_references,覆盖 400 / 404 收敛与 403 / 409 / 500 保留
2026-09-23 14:51:09 +08:00
k88936 8a8c00fbb6 3D 图生输入解析把「缺对象键」改判为服务端问题
- resolve_source_object_key_with 在记录已解析但缺对象键时返回 502 与 model3d-image-source-object-key-missing,不再复用「引用不可用」的 400
- 未登记 / 跨 owner / 已删除仍收敛成同一句 400;缺对象键口径与 editor_project::validate_editor_reference_id_for_owner 的 BAD_GATEWAY 对齐
- 定向用例改名为 image_source_resolution_reports_missing_object_key_as_server_side_failure,断言状态码与 reason
2026-09-23 14:49:18 +08:00
k88936 9edb4e5f80 3D 提交侧归一落点并删掉 Standard 顶层 result 透传
- 提交侧新增归一并写回请求:项目 ID 只 trim,素材夹 ID 走其它工具同一套 normalize_generated_asset_folder_id(project / 旧 folder-* 收敛到 owner 默认素材夹),素材名走 resolve_editor_generated_asset_label(trim、截断到上限、缺省「3D 模型」),保证预检值 = 队列载荷 = 落库值。
- 队列行 sourceEntityId 改用共用 editor_generation_source_entity_id(项目 ID,缺项目回落 job kind),不再拿素材夹 ID 顶替。
- 按你的决定删掉 Standard 消费者顶层 result 逐字透传:标准消费者只回来源身份,3D 结果与图片等画布任务一样靠画布 placement / 素材行读回,连带删掉「3D 生成没有画布读回路径」这条错注释。
- 技术方案与共享记忆同步落点归一、身份口径与结果读取路径;job.rs 补归一用例(含素材名截断)。
- 验证:cargo test -p api-server(1193 passed)、cargo test -p api-server tripo3d::(55 passed)、npx vitest run src/components/image-editor/model3d-generation src/components/image-editor/model3d-preview(63 passed)、check:rustfmt / check:encoding / check-doc-index / git diff --check 通过。
2026-09-23 14:36:50 +08:00
k88936 fd48829c24 3D 生成请求落点改为平坦可选字段并复用统一落点预检
- shared-contracts 的 text-to-model / image-to-model 请求用平坦可选 projectId / canvasCompletion / assetFolderId / assetLabel 取代 tagged enum target,删除 Model3dGenerationTarget 及其契约测试。
- 同步 ts-rs 生成绑定:新增四个可选字段并移除 Model3dGenerationTarget.ts 与 barrel 导出。
- api-server 校验层改按「项目资源 / 素材库二选一」校验,缺失、冲突与空白值都返回 400 并点名具体字段。
- 落点预检改用其它付费编辑器生成共用的 preflight_editor_generation_target_and_return,素材库落点不再读整库。
- worker 按平坦字段落库,素材名缺省回落到 MODEL3D_DEFAULT_ASSET_LABEL。
- 定向验证:cargo test -p shared-contracts 与 cargo test -p api-server tripo3d:: 全绿(54 passed)。
2026-09-23 14:02:44 +08:00
k88936 48ba8b3133 3D 结果序列化失败不再落「完成但 result 为空」的终态
- job_result_payload 改为返回 Result,失败按 500 上报服务端问题,去掉 result:null 兜底形状
- worker 持久化前用 ? 把失败交给既有失败链路:任务按失败终态处理并冲正扣费
- worker 测试夹具同步改为 expect,断言完成结果可序列化
2026-09-23 12:15:02 +08:00
k88936 83913785ae 补齐 Tripo 3D 错误映射的剩余分支测试
- 增补 SDK 参数错误、无状态码 Api、Api 5xx、Sdk 兜底与传输错误的 502 用例,断言只回固定文案、不回显上游报文与 task id
- 增补 map_request_error 的字段口径用例:平台字段路径、provider 字段名与字段未知时不写 field
- 增补 map_pricing_error / map_pricing_store_error / oss_unavailable 的状态码、provider 与 reason 断言
2026-09-23 12:12:26 +08:00
kdletters 43b7aa809b 清理旧创作模板退役过程记录与死代码 (#489)
Project CI / AI game creator shell Rust crates (push) Successful in 1m6s
Project CI / AI game creator shell Rust smoke (push) Successful in 1m16s
Project CI / Backend tests (push) Successful in 4m49s
Project CI / AI game creator shell Rust lane 2/2 (push) Successful in 8m1s
Project CI / AI game creator shell Rust lane 1/2 (push) Successful in 8m50s
Project CI / Native shell tests (push) Successful in 6m5s
Project CI / Frontend tests (push) Successful in 2m6s
Project CI / AI game creator shell web tests (push) Successful in 1m19s
Project CI / Repository checks (push) Successful in 1m43s
- 删除一次性 schema guard 退役表白名单、isApprovedRetiredTableDeletion 导出与专属测试,compareTables 收回为内部函数
- 删除 shared-contracts 未挂载的旧玩法契约模块、api-server 旧 story 模块与旧压测资源 scripts/loadtest/ 及对应忽略/排除配置
- 清理 decision-log、pitfalls 中旧表退役、两阶段清表窗口与旧玩法过程记录,保留改写后的通用条目
- 移除权威文档、模块 README 与运维文档中的旧模板、历史表与旧压测叙述

Reviewed-on: http://192.168.35.82/git/GenarrativeAI/Genarrative/pulls/489
Co-authored-by: kdletters <kdletters@qq.com>
Co-committed-by: kdletters <kdletters@qq.com>
2026-09-23 11:46:39 +08:00
k88936 ee4a9434fa 后台定价读取带版本、保存整段必填并做事务内乐观锁
- shared-contracts 新增定价版本冲突标记,module 与 api-server 共用一处声明
- SpacetimeDB upsert input 增加期望版本,事务内比对不一致即整笔拒绝(种子写入显式不比对)
- 定价 store 记录当前版本,读取路径带出 updated_at 微秒值
- 后台 GET 返回 models / 3D 两段 / updatedAtMicros,POST 要求两段显式给出且带期望版本
- 缺 3D 段 400、版本不匹配 409,退役 with_previous_model3d 与「省略即沿用」用例
- 绑定按 input 新字段重新生成,模块补乐观锁比对用例
2026-09-23 11:38:23 +08:00
k88936 952bc1ccaa 覆盖文件缺 3D 段时按受控默认价补齐,不再把 3D 整段算成未配置
- 新增 backfill_legacy_model3d_pricing:旧覆盖文件整段没有 3D 时补上默认 JSON 的两段并告警
- 覆盖文件继续只承担种子与兜底,避免老种子文件把 3D 生成整段关掉
- 补用例覆盖覆盖文件缺 3D 段的读取
2026-09-23 11:15:42 +08:00
k88936 5e47f0c41e 3D 定价记录转换与读取归一化接上 SpacetimeDB 两段列
- 新增 editor_generation_model3d_records 深模块:配置与两段记录行之间双向转换
- 写入方向严格:落库前按契约强校验,缺键与契约外键都不写
- 读取方向归一化:记录缺键(含整段缺失的老行)用本地配置同段补齐,契约外键剔除并告警,补齐后仍不合法才判非法
- 定价配置读取以表为准,覆盖文件降级为种子与兜底;state.rs 保存路径写入两段
- spacetime-client 补导出 3D 定价记录类型,api-server 定向用例覆盖往返、补齐、剔除与拒绝
2026-09-23 11:12:57 +08:00
k88936 ebd904e193 公开读模型 3D 段保持迁移前的旧形状
- 新增 Model3dPricingPublicView,把内部两段结构投影回 basePrices 端点判别 + addOnPrices 单表
- 公开路由改用投影视图,画布 3D 入口与前端类型不需要随本次迁移改动
- 投影取文生 3D 段的加价项,两段不一致时打告警提示前端升级前不要差异化
- 公开路由用例补断言钉住 3D 段旧形状
2026-09-23 11:04:50 +08:00
k88936 9f4a71d2e3 3D 定价段拆成端点并列的两段结构
- Model3dPricingConfig 改为 textToModelPricing / imageToModelPricing 两段并列,各持自己的 versionPrices 与 addOnPrices
- 新增 Model3dEndpointPricing 承接单端点定价,校验与查价按端点委派,溢出检查覆盖两段
- 受控默认 JSON 的 model3d 段同步改为两段结构
- 3D 定价相关用例夹具与断言更新到两段形状
2026-09-23 11:01:20 +08:00
k88936 774b74d3d6 SpacetimeDB 定价表追加 3D 两段列,记录形状先能表达端点 × 版本 × 贴图与加价项
- editor_generation_pricing_config 末尾追加 text_to_model_pricing / image_to_model_pricing 两个 Option 列并带显式默认值
- 新增模型版本底价、加价项、端点定价三个 SpacetimeType 行类型,模块侧按段校验空段、缺半段、重复键与非正价格
- upsert 输入、快照、生成绑定与客户端记录映射同步两段字段
- api-server 保存路径本次先写空值,读取仍走本地文件缓存;补模块段级归一化用例
2026-09-23 10:54:01 +08:00
lhk229 20b594d4f2 清理后端未使用代码及废弃测试
Project CI / AI game creator shell Rust crates (pull_request) Successful in 1m20s
Project CI / AI game creator shell Rust smoke (pull_request) Successful in 1m49s
Project CI / Backend tests (pull_request) Successful in 3m38s
Project CI / Frontend tests (pull_request) Successful in 1m47s
Project CI / Native shell tests (pull_request) Successful in 5m40s
Project CI / AI game creator shell Rust lane 2/2 (pull_request) Successful in 7m44s
Project CI / AI game creator shell Rust lane 1/2 (pull_request) Successful in 8m17s
Project CI / Repository checks (pull_request) Successful in 1m48s
Project CI / AI game creator shell web tests (pull_request) Successful in 1m18s
Project CI / AI game creator shell Rust crates (push) Successful in 1m22s
Project CI / AI game creator shell Rust smoke (push) Successful in 1m52s
Project CI / Backend tests (push) Successful in 3m41s
Project CI / Frontend tests (push) Successful in 1m54s
Project CI / Native shell tests (push) Successful in 5m39s
Project CI / AI game creator shell Rust lane 2/2 (push) Successful in 7m42s
Project CI / AI game creator shell Rust lane 1/2 (push) Successful in 8m30s
Project CI / Repository checks (push) Successful in 2m7s
Project CI / AI game creator shell web tests (push) Successful in 1m35s
删除编辑器旧分段持久化、生成任务收尾和音频发布链路
删除未使用辅助函数及其专属测试,修正受影响的现有测试边界
保留现役实现,将纯退款测试辅助函数移入测试模块
同步原子提交、角色生成文档和计费验证说明
验证:API 全目标编译零警告,格式、编码和 diff 检查通过
定向测试:391 项通过,11 项退款 outbox 测试失败,含 Windows 权限错误
2026-09-23 02:52:01 +00:00
lhk229 1e186369c9 客户端埋点设置 (#446)
Project CI / AI game creator shell Rust crates (push) Successful in 1m24s
Project CI / AI game creator shell Rust smoke (push) Successful in 1m56s
Project CI / AI game creator shell Rust lane 1/2 (push) Has been cancelled
Project CI / Frontend tests (push) Has been cancelled
Project CI / Backend tests (push) Has been cancelled
Project CI / Repository checks (push) Has been cancelled
Project CI / AI game creator shell web tests (push) Has been cancelled
Project CI / AI game creator shell Rust lane 2/2 (push) Has been cancelled
Project CI / Native shell tests (push) Has been cancelled
Reviewed-on: https://git.genarrative.world/git/GenarrativeAI/Genarrative/pulls/446
Co-authored-by: Linghong <ink29535@proton.me>
Co-committed-by: Linghong <ink29535@proton.me>
2026-09-23 00:09:12 +08:00
kdletters f502829fde 发布灰度默认关闭:修掉客户端“看得到点不动”与后台看不到 key (#482)
Project CI / AI game creator shell Rust crates (push) Successful in 1m28s
Project CI / AI game creator shell Rust smoke (push) Successful in 2m2s
Project CI / Backend tests (push) Successful in 5m19s
Project CI / AI game creator shell Rust lane 2/2 (push) Successful in 6m59s
Project CI / AI game creator shell Rust lane 1/2 (push) Successful in 8m19s
Project CI / Native shell tests (push) Successful in 6m48s
Project CI / Frontend tests (push) Successful in 2m54s
Project CI / Repository checks (push) Successful in 2m58s
Project CI / AI game creator shell web tests (push) Successful in 2m34s
## 解决什么

你反馈的两个现象都是真问题,这个 PR 一次修掉:

1. **没开灰度也能看到发布按钮**:发布开关此前是「无 gate 行 = 默认开放」,所以没配灰度时后端把 `gameDistributionPublishEnabled` 判成 true,客户端就渲染了发布入口。
2. **按钮点了没反应**:发布动作的提示原先只写 `workspaceStatus`,而普通项目走 `DirectProjectChatView` 时并不渲染工作台状态行,于是「先打开一个项目再发布」「构建失败…」这类信息全都看不见。
3. **后台看不到 key**:预设项此前在未合并的另一个 PR 里,而且后台只列「已创建」的 gate 行。

## 改成什么

- `is_game_distribution_publish_enabled_for_user` 要求 gate 行存在且 `enabled=true`:**灰度默认关闭**,未登录/无行/`enabled=false` 一律不开放;只有白名单 / 灰度比例 / 用户标签命中才开放。作者写入与新版本激活都按这条判据。
- 新增与作者无关的总开关 `is_game_distribution_publish_open`:管理员审核激活新版本只看「灰度是否开启」,不会因为审核员不在作者白名单里而被挡住(这是合入后立刻发现的回归,已修 + 有用例)。
- AGC 新增 `announcePublishMessage`:发布相关提示同时写工作台状态与 DirectProject 对话,点「发布到游戏广场」不会再像没反应。
- 后台「灰度发布配置」新增「可配置开关」列表:`game-distribution:publish` 等预设即使还没创建行也会显示,点「配置」按默认关闭填表,运营开启后填白名单/比例即可放量。

## 验证

- `npm run check:game-distribution-media-e2e`(真实 Phaser 构建产物)现在覆盖:灰度关闭 → 作者拿不到入口 + 写入口 503 → 开启灰度 → 真实封面/截图直传 → 创建游戏/版本/上传/送审 → 管理员审核通过 → 网关 index.html 与 bundle 200 → nosniff;全流程通过。
- 后端:`cargo test -p api-server game_distribution` 19 passed(含新增 `game_distribution_publish_open_ignores_author_allowlist_for_activation`)、`frontend_runtime_config` 6 passed。
- 前端:admin 灰度页 10 用例(含「未创建的预设开关可见并可一键配置」)、AGC 聊天头 3 用例、网页发布页 15 用例;三端 typecheck、`check:encoding`、`check:doc-index`、`check:rustfmt`、全量 `npm test`(400 文件 / 4441 用例)与 `check:repository-ci -- origin/master HEAD` 全绿。

## 上线注意

灰度默认关闭是**刻意**的:合入后到运营在后台把 `game-distribution:publish` 配置并开启之前,作者看不到发布入口、写入口 503;已公开游戏、目录、详情、发行网关、安全下架不受影响。

Reviewed-on: http://192.168.35.82/git/GenarrativeAI/Genarrative/pulls/482
Co-authored-by: kdletters <kdletters@qq.com>
Co-committed-by: kdletters <kdletters@qq.com>
2026-09-22 21:38:03 +08:00
kdletters a56790eaa6 合并 Phaser 一键发布自动构建与打包
Project CI / AI game creator shell Rust crates (push) Successful in 1m36s
Project CI / AI game creator shell Rust smoke (push) Successful in 2m9s
Project CI / Backend tests (push) Successful in 5m41s
Project CI / AI game creator shell Rust lane 2/2 (push) Successful in 7m33s
Project CI / AI game creator shell Rust lane 1/2 (push) Successful in 8m53s
Project CI / Native shell tests (push) Successful in 7m28s
Project CI / Frontend tests (push) Successful in 3m38s
Project CI / Repository checks (push) Successful in 3m36s
Project CI / AI game creator shell web tests (push) Successful in 2m55s
2026-09-22 21:03:57 +08:00
kdletters 57a72f652c Phaser 项目一键发布:发布前自动构建与打包
Project CI / AI game creator shell Rust lane 1/2 (pull_request) Has been cancelled
Project CI / AI game creator shell Rust lane 2/2 (pull_request) Has been cancelled
Project CI / AI game creator shell Rust smoke (pull_request) Has been cancelled
Project CI / AI game creator shell Rust crates (pull_request) Has been cancelled
Project CI / Backend tests (pull_request) Has been cancelled
Project CI / Native shell tests (pull_request) Has been cancelled
Project CI / Frontend tests (pull_request) Has been cancelled
Project CI / Repository checks (pull_request) Has been cancelled
Project CI / AI game creator shell web tests (pull_request) Has been cancelled
- AGC:export_local_project_package 改为发布前构建——已有可玩入口直接打包;否则解析 game/(Phaser 4 + Vite 脚手架)或项目根的 npm build 脚本,缺 game/node_modules 时先跑 project.bootstrap(npm install),再走 project.verify 的受控 npm 运行器执行 npm run build,最后校验入口并打包;安装/构建失败返回带日志尾部的可操作错误。
- 新增 resolve_publish_build_plan 纯函数与用例:game 子工程优先并要求先装依赖、根 npm 工程回退、没有可构建工程时失败关闭。
- 后端:发行网关根路径(含尾斜杠)等价于 index.html,路由级用例覆盖 Cookie 拒绝门与根路径;生产仍由每游戏 origin 把根路径映射到该游戏入口。
- 脚本:check:game-distribution-media-e2e 支持 E2E_PACKAGE_ZIP 直接发布真实构建产物,断言从包内派生入口/资源,本地审核入口改为发行网关路径。
- 文档:玩法链路与实施计划记录「作者不构建、不打 ZIP」的 Phaser 发布口径与验证证据。
- 验证:真实 Phaser 4.2.1 + Vite 7 构建产物(相对引用)经发布链路后网关 index.html 200 / assets 1,388,719 B 200,播放页在 allow-scripts 沙箱 iframe 内渲染 PHASER-PUBLISH-OK 且点击交互生效。
2026-09-22 20:38:00 +08:00
kdletters fd0c1007ad 清除旧创作模板历史表定义与绑定
删除 63 张旧玩法表的 module 定义与 legacy schema
移除清空 procedure、迁移白名单和旧行兼容逻辑
重新生成 spacetime-client bindings
新增一次性 schema guard 删除白名单与回归测试
清理后台表名映射、旧回填工具和权威文档
2026-09-22 19:42:29 +08:00
kdletters 56fd5a98f7 修复 release 客户端下载清单的编码空格校验
Project CI / AI game creator shell Rust lane 1/2 (push) Failing after 21s
Project CI / Backend tests (push) Failing after 21s
Project CI / Native shell tests (push) Failing after 21s
Project CI / Frontend tests (push) Failing after 21s
Project CI / Repository checks (push) Failing after 20s
Project CI / AI game creator shell web tests (push) Failing after 14s
Project CI / AI game creator shell Rust lane 2/2 (push) Failing after 1m56s
Project CI / AI game creator shell Rust crates (push) Failing after 1m54s
Project CI / AI game creator shell Rust smoke (push) Failing after 1m56s
放行客户端下载清单 URL 中百分号编码的空格
补充 release 安装包文件名回归测试
更新客户端下载规范与排障文档
2026-09-22 17:29:19 +08:00
kdletters e5460280ce 发布入口接入灰度开关
Project CI / AI game creator shell Rust lane 1/2 (pull_request) Has been cancelled
Project CI / AI game creator shell Rust lane 2/2 (pull_request) Has been cancelled
Project CI / AI game creator shell Rust smoke (pull_request) Has been cancelled
Project CI / AI game creator shell Rust crates (pull_request) Has been cancelled
Project CI / Backend tests (pull_request) Has been cancelled
Project CI / Native shell tests (pull_request) Has been cancelled
Project CI / Frontend tests (pull_request) Has been cancelled
Project CI / Repository checks (pull_request) Has been cancelled
Project CI / AI game creator shell web tests (pull_request) Has been cancelled
- 后端:GET /api/runtime/frontend-config 新增 gameDistributionPublishEnabled,复用 `game-distribution:publish` 判据(未配置或 enabled=false 时对已登录作者默认开放,显式收紧后只放行白名单/灰度命中用户,匿名恒为 false),前端入口与写入口共用同一事实源。
- 后端用例:新增 frontend_runtime_config_game_distribution_publish_is_scoped_to_authenticated_gate,覆盖默认开放、enabled=true 无白名单、白名单命中、deny 名单、enabled=false 回退与 rolloutPercent=100。
- 网页:平台壳按灰度隐藏「发布游戏 / 发布新版本」入口;/games/publish 直接访问时渲染「发布功能正在灰度中」并提供重新检查;读取失败按放行处理,由后端写入口把关并返回可读文案。
- AGC:新增 readGamePublishAvailability(同一运行时配置字段),只有命中才把发布回调交给 DirectProject 聊天头;字段缺失或读取失败按不开放处理。
- 文档:玩法链路、后端数据契约与实施计划记录灰度口径、入口行为与验证命令。
2026-09-22 17:12:04 +08:00
k88936 aa6e3b8d79 SDK 请求错误不再丢弃响应体与底层错误链
- 映射 tripo3d_sdk::Error::Request 时带上 body 与 source 字段
- 响应体截断到 512 字符,疑似带 http(s) 地址的响应体整体丢弃
- 只取错误链底层文本,避免 reqwest 顶层 Display 带出完整签名 URL
- 补错误链收集、响应体过滤与截断的用例
2026-09-22 16:55:16 +08:00
k88936 3ab7b386f1 补外部生成主表 provider checkpoint 归一化单测
- 新增 old_external_generation_job_rows_default_to_unsubmitted_provider
- 断言旧迁移行的 provider_kind 与 provider_task_id 都归一成 null
- 守住 at-most-once submit 的向后兼容路径
2026-09-22 16:52:19 +08:00
k88936 ed2eb43fe6 补 3D 生成选项校验的表驱动单测
- 覆盖最简选项全模型放行、fast 必须配 v3.5 贴图版本
- 覆盖 generate_parts 的 texture/pbr/quad/smart_low_poly 互斥组合
- 覆盖 quad 家族限制与各模式 face_limit 的 min-1/min/max/max+1 边界
- 覆盖空白 task id 按 OutputSchema 失败与 trim 行为
2026-09-22 16:50:06 +08:00
k88936 62bf602fb1 多视图请求 DTO 补齐字段级说明并重生成绑定
- Model3dMultiviewToModelRequest 每个字段补一行中文语义说明与取值范围
- 结构体补严格反序列化与组合校验归属的说明
- 重新生成 ts-rs TS 绑定,注释同步进 Model3dMultiviewToModelRequest.ts
2026-09-22 16:48:57 +08:00
k88936 2348315dba 3D 结果打标契约测试补齐 preview 与 imageToModel 分支
- textToModel 用例补 preview 产物的相等断言
- 新增对称的 imageToModel 用例,守住 tag 路由与分支字段
- 裸字符串 source 的负例改为点名 Model3dGenerationSource 并单独反序列化 source 值
2026-09-22 16:46:19 +08:00
kdletters f1b282f3cd 合并 master 并接入 DirectProject 新聊天架构
- 合并 origin/master(304 个提交:DirectProject 聊天容器重构、Project Supervisor 退役、策划附件导入、CI 隔离编译缓存等)。
- 接受 master 对 ProjectSupervisorView / SupervisorChatOnlyView 的退役与预览快捷测试收敛;发布入口改由 DirectProject 聊天头承载。
- DirectProjectChatHeader 新增「发布到游戏广场」入口(无回调不渲染、回合忙态禁用),DirectProjectChatView 透传 onRequestGamePublish。
- App.tsx 继续由工作台壳持有试玩包导出与 GameDistributionPublishPanel,沿用 project.export_package 权限确认队列;check-config 把该命令从 native-only 清单移回 App invoke。
- 后台游戏审核 API / 类型 / 路由测试与 master 新增的 AGC 模板管理按双方保留合并,并修掉拼接造成的接口与用例闭合缺陷。
- 修正 master 自带的 viteProxyConfig 断言:/api/creation-entry 属退役路由,测试改为断言不进入代理。
- 记录合并踩坑:语法结构内部的冲突不能简单按「双方保留」拼接,必须按某一侧骨架重建并跑 tsc 与单文件测试。
- 验证:全量 vitest 393 文件 / 4374 用例通过,root / AGC / admin-web 三端 typecheck,cargo check 与游戏分发 Rust 测试,encoding、doc-index、rustfmt、SpacetimeDB schema guard。
2026-09-22 16:45:29 +08:00
k88936 bba96e18a1 队列状态映射改为借用记录避免提交路径整行克隆
- editor_generation_queue_state 收 &ExternalGenerationJobRecord,只克隆输出需要的三个字段
- Model3dSubmissionResponse::from_job 不再克隆整行 job,status_url 提前算好避免额外克隆
- 其余调用点改为传引用,行为不变
2026-09-22 16:44:47 +08:00
k88936 433ffb4a15 落库的模型版本改用严格 wire 取值
- Model3dJobRequest::model_version 改为返回 Result 并使用 wire_str
- worker 落库前取不到契约取值即按服务端问题失败,不再写 Debug 兜底名
- 新增用例断言落库取值为契约线上值 v3.1-20260211
2026-09-22 16:40:48 +08:00
k88936 4e5ff179b2 3D 查价拒绝 texture=false 与贴图加价项的矛盾组合
- Model3dPricingError 新增 InconsistentTextureAddOn 变体与对应文案
- price() 在命中的 add-on 含贴图类而 texture=false 时失败关闭,不再照价收费
- 补齐矛盾组合报错与 texture=true 合法组合的价格用例
2026-09-22 16:38:24 +08:00
k88936 87ca86ae6a 图片输入解析抽出可注入查询的解析规则并补齐行为用例
- resolve_source_object_key 拆出 resolve_source_object_key_with 与 ResolvedReference 窄结果
- 新增按 ID 定点查询、类型不符、缺对象键、4xx 收敛与基础设施错误保留状态码的用例
- 源码文本断言不再按函数签名切片,只检查本模块不出现列工程 / 列素材库
2026-09-22 16:36:16 +08:00
k88936 48cde9624c operation_kind 白名单改为两 crate 共用的共享常量
- 白名单常量迁到 shared-contracts 并从 crate 根导出
- spacetime-module 的原子落库事务改为引用该常量,删除本地重复定义
- api-server 的登记测试不再解析对方源码文本,改为直接断言常量内容
- 后端架构文档补上白名单常量的位置与共用口径
2026-09-22 16:30:28 +08:00