写入Tripo 3D泥点默认价并锁定credit换算口径

- 受控默认配置新增 model3d 段:底价按端点 × 模型版本 × 是否有贴图,add-on 六项独立计价

- 换算口径固定为泥点 = ceil(0.8 × Tripo 官方 credit),H 系列 10/20 与 20/30、P1 30/40 与 40/50、P2 100/110

- editor_generation_config 定向用例按 credit 表反算默认泥点价,改价必须先改 credit 表

- 段缺失语义改为显式摘段验证,仍保持 fail closed 不扣费不入队

- 主规范、里程碑、实施计划与定价管理方案同步默认价已确认与部署侧 override 风险
This commit is contained in:
2026-09-21 22:07:55 +08:00
parent 2691ca8aca
commit 9fc55a5cac
6 changed files with 166 additions and 13 deletions
@@ -73,7 +73,7 @@ Milestone Spec: `docs/project-memory/plans/【里程碑】Tripo生成Worker执
- 图片输入在提交时已补元数据预检(`tripo3d::image_source::preflight_image_source`):按 `source.kind` 分支配对记录类型并复用既有定点引用查询 `resolve_editor_reference_record_by_id_for_owner`,取代原先“列工程 / 列素材库再筛”的宽查询;跨 owner、未登记、已删除与 `kind` 不符都在扣费与入队前返回 400,worker 执行时再重新确认同一事实。
- 提交路由已补应用级验收用例:走真实 `build_router` 断言两个端点未鉴权 401、缺 `Idempotency-Key` 400、组合校验与定价必填字段冲突在定价与 provider 之前 400,因此路由 merge、鉴权中间件与校验顺序都有可执行证据,不依赖 provider 与 SpacetimeDB 环境。
- 默认配置里的 `model3d` 泥点定价数值仍未确认,缺段时提交按 fail closed 拒绝。
- `model3d` 泥点定价已写入受控默认配置:换算口径 `ceil(0.8 × Tripo 官方 credit)`H 系列文生 `10 / 20`、图生 `20 / 30`P1 文生 `30 / 40`、图生 `40 / 50`P2 两端均 `100 / 110`add-on 六项按同一系数换算;`editor_generation_config` 的定向用例按 credit 表反算默认价,段缺失仍按 fail closed 拒绝。
- worker 的纯逻辑部分已补定向用例:checkpoint 只在 provider task id 非空时才算存在、完成结果按端点严格区分且不含 provider 事实、预览图尺寸必须能真实解码;全量 `cargo test -p api-server` 1092 通过。
- `npm run check:spacetime-schema` 通过(144 张表,锚点 `6f161a6b3626588a197208ea6dd68316815c01b5`),`external_generation_job` 的 provider checkpoint 追加字段没有破坏 schema guard。
- TS 绑定仍是 `npm run contracts:model3d:generate` 目录化生成:重跑后 `packages/shared` 无 diff`packages/shared/src/contracts/model3d/``contracts/editor-canvas/` 与 Rust 契约一致,没有手写 TS。
@@ -93,7 +93,7 @@ git diff --check
## 风险与回退
- **真实扣费**定价数值未写入前 `model3d` 段缺失,提交 fail closed;接口开放前必须先完成定价配置
- **真实扣费**默认价已按 `ceil(0.8 × credit)` 写入并随代码发布,部署侧若用 override 文件覆盖定价,必须确保 override 里保留完整的 `model3d` 段,否则该段整体缺失会让 3D 提交 fail closed
- **provider 长任务**:单次 attempt 内轮询依赖 lease 续租与长任务超时;超时按现有语义收口为失败并退款。
- **共用 worker 分支**:新分支只消费自己的 job kind,不改既有分支的入队与写回路径。
- **worker 占用**3D 任务在单次 attempt 内阻塞轮询数分钟,会占住一个 worker 并发位;默认并发为 2,接入真实流量前需要确认并发与 `external_generation_worker_long_job_timeout` 是否够用。
@@ -33,4 +33,4 @@ Implementation Plan: `docs/project-memory/plans/【实施计划】Tripo生成Wor
## 依赖
- `docs/project-memory/plans/【里程碑】Tripo生成API契约与数据模型-2026-09-21.md` 验收通过。
- 生产泥点定价数值已确认并写入默认配置。
- 生产泥点定价数值已确认并写入默认配置:换算口径为 `ceil(0.8 × Tripo 官方 credit)`,已落到 `editor-generation-pricing.default.json``model3d`
@@ -131,7 +131,9 @@ price = basePrices[endpoint][modelVersion][texture ? "texture" : "noTexture"]
1. **加载即校验**`model3d` 段一旦存在,两个 endpoint × 每个受支持模型版本 × 两种贴图态与全部 add-on 键必须同时存在,缺一即配置非法、服务拒绝启动;段内不再写 `unit`3D 生成恒为按次计价。
2. **提交即拒绝**:价格计算发生在调用 provider 之前;拿不到价格就不提交、不扣费、不入队。
业务给出泥点数值之前,受控默认配置里不写 `model3d` 段:此时 3D 接口不开放,提交直接被拒绝(fail closed),既不会扣费也不会调用 provider;数值写入后即为上一条的强校验路径。
泥点数值已确认并写入受控默认配置 `server-rs/crates/api-server/config/editor-generation-pricing.default.json`。换算口径固定为 **泥点 = `ceil(0.8 × Tripo 官方 credit)`**credit 取自 Tripo 官方价目表的 H 系列与 P 系列:文生 3D 的 H 系列 `10 / 20`、P1 `30 / 40`、P2 `100 / 110`,图生 3D 的 H 系列 `20 / 30`、P1 `40 / 50`、P2 `100 / 110`(依次为无贴图 / 标准贴图),六个 add-on 为 `HD Texture 10``8K Ultra Texture 20``HD Geometry 20``Quad Mesh 5``Smart Low-poly 10``Generate Parts 20``editor_generation_config` 的定向用例按这张 credit 表反算默认泥点价,改价必须先改 credit 表,避免默认值脱离换算口径。
`model3d` 段缺失仍是合法形态:缺失即 3D 定价未配置,提交被拒绝(fail closed),既不扣费也不调用 provider;段存在时走上面的强校验路径。
扣费依据固定为**提交时定价**:用户在提交前就能得到确定价格,失败退款是单次冲正,不需要按实际消耗退差额。provider 返回的实际消耗只写日志用于成本对账,不进入契约、不进 API 响应、不进资源行。
@@ -30,7 +30,7 @@ Tripo 3D 生成的计费形态是「底价 + 可叠加 add-on」,现有「模
- 事实源仍是同一份文件配置(默认 JSON 与旧 override 种子),但**不写入 SpacetimeDB `models` 记录**`editor_generation_pricing_to_records` 只序列化 `models`,运行时读取时由 `editor_generation_pricing_from_record` 用本地文件配置补回 `model3d`。因此后台「模型定价」页面改价**不会覆盖** 3D 段,改 3D 价格必须改文件并重启进程。
- `model3d` 段存在时按强校验解析:两个端点 × 契约支持的全部模型版本都必须给出 `noTexture` / `texture` 两个底价键,缺键即启动失败;段缺失则 3D 提交一律 fail closed,不扣费也不调用 provider。
- 泥点数值是产品定价,不是 provider 的 credit 数值;未确认前保持段缺失,禁止写入猜测值或用 provider 计费数字顶替
- 默认价已确认并写入受控默认 JSON,换算口径固定为 **泥点 = `ceil(0.8 × Tripo 官方 credit)`**:文生 3D 的 H 系列 `10 / 20`、P1 `30 / 40`、P2 `100 / 110`,图生 3D 的 H 系列 `20 / 30`、P1 `40 / 50`、P2 `100 / 110`add-on 为 `HD Texture 10``8K Ultra Texture 20``HD Geometry 20``Quad Mesh 5``Smart Low-poly 10``Generate Parts 20`。泥点数值是产品定价,不是 provider 的 credit 数值;改价必须先改 credit 表并让 `editor_generation_config` 的定向用例同步,禁止写入未确认的猜测值
- 后续把 `models` 记录形状扩展成能表达「端点 × 模型版本 × 是否有贴图 + add-on」后,再把 3D 段迁入 SpacetimeDB 并接后台编辑,届时删除本节的例外说明。
- 关联规范:[技术方案 Tripo 3D生成API集成](technical/【技术方案】Tripo 3D生成API集成-2026-09-21.md)、[后端架构 server-rs与SpacetimeDB数据契约](【后端架构】server-rs与SpacetimeDB数据契约-2026-05-15.md)。