k88936
|
5748cf303f
|
种子字段的对外类型改成普通数字,不再导出 bigint
- shared-contracts:多视图请求与文生 / 图生参数的 seed 注记从 `bigint | null` 改成 `number | null`,并写明只支持 JS 安全整数范围(2^53-1)内的取值;Rust 侧仍是 `Option<i64>`,反序列化行为不变
- packages/shared:重新生成 model3d 绑定,seed 变成 `number | null`,请求体可以直接 JSON 序列化(带 bigint 的请求在 JSON.stringify 阶段必定抛错);顺带补上此前漏生成的多视图请求文档注释(「多视图生 3D」→「多视图生成 3D」)
- docs/technical:在 Tripo Provider 集成方案里写明 seed 为什么按 number 导出、代价是超出 2^53-1 的取值无法从 TS 侧精确构造
|
2026-09-24 19:17:42 +08:00 |
|
k88936
|
c39798e491
|
写明 ts-rs 的 feature 一律保持全开
- server-rs/Cargo.toml:把注释里「ts-rs 一律常开」改成明确口径——保持默认 features 原样,不写 default-features = false、也不逐个关掉,成员 crate 需要新能力时优先用默认已覆盖的部分,不改任何依赖声明
|
2026-09-24 19:07:48 +08:00 |
|
k88936
|
9bcd8f728b
|
后台各页的整数解析统一到共享助手
- apps/admin-web/src/pages/pageUtils.ts:新增 parsePositiveInteger,用 Number + Number.isSafeInteger,空串 / 非数字 / 小数 / 0 / 负数一律收敛成 0
- 删除 AdminTaskConfigPage、AdminProfileWalletConfigPage、AdminRechargeProductPage、AdminRedeemCodePage 与 adminEditorGenerationPricing 里各自的一份实现,5 个页面统一从 pageUtils 引入,修掉「钱包页拒 1.5、任务页把 1.5 当 1」这类口径不一致
- adminEditorGenerationPricing.test.ts 的引入路径同步改到 pageUtils
|
2026-09-24 19:07:32 +08:00 |
|
k88936
|
acdfb8ed73
|
3D 冒烟示例把产物写到 target 目录,不再落到仓库里
- server-rs/crates/platform-tripo/examples/tripo_generation_smoke.rs:产物落盘目录从「当前工作目录」改为 <cargo target>/tripo-smoke-artifacts,开始前建目录并打印路径;该目录本来就在入库排除范围内,根目录不会再攒出临时模型
- server-rs/crates/platform-tripo/examples/tripo_generation_smoke.rs:文件头文档同步改为说明新的产物落点
|
2026-09-24 19:05:51 +08:00 |
|
k88936
|
02f334b04a
|
删掉根目录临时 3D 样例模型并移除对应的根级忽略规则
- 删除仓库根目录手工下载的 image_to_model.glb / multiview_to_model.glb / text_to_model.glb 三个临时样例(合计约 125 MB,本来就没入库)
- .gitignore:移除只为它们存在的十条根级规则(/*.glb、/*.gltf、/*.fbx、/*.bin、/*.png、/*.jpg、/*.jpeg、/*.webp、/*.ktx2、/*.tga),根目录再出现同类文件会正常显示为未跟踪,不再被静默忽略
|
2026-09-24 19:05:43 +08:00 |
|
k88936
|
cc472d0736
|
图生 3D 的引用类型判别改用枚举
- server-rs/crates/api-server/src/tripo3d/image_source.rs:ResolvedReference.kind 从 &'static str 改成 ResolvedReferenceKind 枚举,From<EditorReferenceRecord> 写值与匹配比较由同一处产出,字符串错字不再只在运行期暴露
- server-rs/crates/api-server/src/tripo3d/image_source.rs:对外文案仍由 as_str() 生成,用例同步改用枚举取值
|
2026-09-24 18:03:05 +08:00 |
|
k88936
|
06f091f0ff
|
平台层校验补上 pbr 依赖贴图
- server-rs/crates/platform-tripo/src/common/validation.rs:validate_generation_options 增加 texture=false 与 pbr=true 的组合拒绝(TripoField::Pbr),直连调用方不用再把这种不会成立的组合拖到 provider 侧才报错;放在 generate_parts 分支之后,不改变该分支原有的归因
- server-rs/crates/platform-tripo/src/common/validation.rs:补用例锁住 texture=false + pbr=true 被拒、texture=true 时放行
|
2026-09-24 18:01:24 +08:00 |
|
k88936
|
b83113619e
|
产物结构体不再派生 Debug,改成只打元数据
- server-rs/crates/platform-tripo/src/common/types.rs:TripoArtifactBytes 去掉 derive(Debug),改为手写实现,只输出 url / content_type / content_length / 字节数,几十 MB 的 bytes 不会再被一次 {:?} 刷进日志
- server-rs/crates/platform-tripo/src/common/types.rs:补用例锁住 Debug 只带字节数、不带字节内容
|
2026-09-24 18:00:45 +08:00 |
|
k88936
|
03aec35350
|
写明 TripoUrl 脱敏只覆盖 query 与 fragment
- server-rs/crates/platform-tripo/src/common/types.rs:redacted() 的文档注明脱敏范围只到 query / fragment,若 provider 改成把 token 写进路径(如 path-style SAS)则需一并处理路径段;无 query 分支补注释说明路径原样保留
|
2026-09-24 18:00:30 +08:00 |
|
k88936
|
925be4573d
|
产物扩展名兜底认下 image/jpg
- server-rs/crates/platform-tripo/src/common/types.rs:fallback_artifact_extension 补上 image/jpg 分支,非标准写法但确有 provider 这么回,预览图不再落到默认 .glb 后缀
- server-rs/crates/platform-tripo/src/common/types.rs:补用例覆盖 png / jpg / webp 与读不出形态时的 glb 兜底
|
2026-09-24 18:00:21 +08:00 |
|
k88936
|
0c716d7d9c
|
产物文件名主干加上长度上限
- server-rs/crates/platform-tripo/src/common/types.rs:sanitize_artifact_file_stem 在字符过滤后按 MAX_ARTIFACT_FILE_STEM_LEN=128 截断,远端来的超长主干不再拼出超过文件系统名字上限的一长串
- server-rs/crates/platform-tripo/src/common/types.rs:新建 types 的用例模块,锁住超长 / 带路径的主干被中性化并截断、全中性化后为空时退回固定名
|
2026-09-24 18:00:05 +08:00 |
|
k88936
|
2330a25172
|
传输判据补上 is_body,并把截断体的归因写清
- server-rs/crates/platform-tripo/src/common/error.rs:transport_error_is_transient 补上 is_body(),与 TripoError::Request.retryable 文档列举的瞬时类型对齐
- server-rs/crates/platform-tripo/src/common/error.rs:注释写明「传输中途截断的响应体在 reqwest 里落在 Decode」这一实测结论,说明为何不把 Decode 判成可重试
- server-rs/crates/platform-tripo/src/common/error.rs:补用例用截断响应体锁住 Decode 不判可重试
|
2026-09-24 17:59:26 +08:00 |
|
k88936
|
ebce5f9304
|
平台层转发 base_url 前去掉首尾空白
- server-rs/crates/platform-tripo/src/common/config.rs:client_options 里 base_url 先 trim 再交给 SDK,带空白的地址不再以低层解析错误的形式暴露出来
- server-rs/crates/platform-tripo/src/common/config.rs:把 client_options 的用例扩到 base_url,锁住「校验看到的」与「发出去的」是同一个值
|
2026-09-24 17:58:03 +08:00 |
|
k88936
|
80ae730dc5
|
平台层转发 API Key 前去掉首尾空白
- server-rs/crates/platform-tripo/src/common/config.rs:client_options 里 api_key 先 trim 再交给 SDK,校验口径与发送口径统一,带空白的密钥不再变成 provider 侧的 401
- server-rs/crates/platform-tripo/src/common/config.rs:补用例锁住 client_options 发送的 api_key 已 trim
|
2026-09-24 17:57:44 +08:00 |
|
k88936
|
b54ff06bc7
|
平台层 Tripo 配置把 base_url 校验成绝对 http(s) 地址
- server-rs/crates/platform-tripo/src/common/config.rs:validate 用 url::Url 解析 base_url,缺 scheme(openapi.tripo3d.com)、非 http(s)(ftp://)与无 host 的值都在构造点按 Configuration 失败,不再拖到请求期变成传输层报错
- server-rs/crates/platform-tripo/src/common/config.rs:补用例覆盖缺 scheme / 非 http(s) / 非法 URL 被拒、前后带空白的合法地址放行
|
2026-09-24 17:57:31 +08:00 |
|
k88936
|
7a4ccb8bfe
|
3D 产物哈希挪到 blocking 线程池
- server-rs/crates/api-server/src/tripo3d/storage.rs:上传前对最大 512 MiB 的产物做 sha256 会占住一个 Tokio worker,改成 spawn_blocking 并把 bytes 原样带回(不做整块复制),失败按 500 收口
|
2026-09-24 17:56:51 +08:00 |
|
k88936
|
f82eba4c94
|
3D 查价的加价累加改成溢出即报错
- server-rs/crates/api-server/src/tripo3d/pricing.rs:endpoint 查价用 checked_add 替换 saturating_add,溢出走新的 Model3dPricingError::PriceOverflow,与加载校验的 fail-closed 口径一致,不再静默夹到 u32 上限按错价收费
- server-rs/crates/api-server/src/tripo3d/pricing.rs:补用例锁住「底价 + 加价项溢出必须报错」
|
2026-09-24 17:55:12 +08:00 |
|
k88936
|
98f2c21872
|
3D 定价整段兜底也要过端点校验
- server-rs/crates/api-server/src/editor_generation_model3d_records.rs:记录整段缺失时回退到本地配置前先跑 endpoint.validate(),缺键分支与兜底分支走同一条 fail-closed 路径,不再依赖调用方事后补 config.validate()
- server-rs/crates/api-server/src/editor_generation_model3d_records.rs:补用例锁住「整段缺失 + 兜底配置不合法」必须被拒绝
|
2026-09-24 17:53:34 +08:00 |
|
k88936
|
a8dc0d8870
|
后台定价用例改键前先断言目标键存在
- server-rs/crates/api-server/src/app.rs:改默认定价 fixture 时先用 pointer_mut 断言目标键存在再赋值,不再依赖 Value::index_mut 的隐式 panic,键名或版本号漂移时报错能指出是哪一层对不上
|
2026-09-24 17:51:08 +08:00 |
|
k88936
|
f2d3e2218d
|
后台缺 3D 段的负例改成断言中文文案
- server-rs/crates/api-server/src/app.rs:用例文案说「必须以中文文案拒绝」,断言却只查小写英文 model3d,改成断言「定价段必须整段给出」,真正守住中文拒绝这条契约
|
2026-09-24 17:51:02 +08:00 |
|
k88936
|
40c97bf876
|
旧 external_generation_job 归一化用例改成真断言
- server-rs/crates/spacetime-module/src/migration.rs:provider_kind / provider_task_id 的断言改成先 as_object() 取键再比 null,原先用 Value 索引在键缺失时返回 Null,归一化被删掉也照样通过
|
2026-09-24 17:48:41 +08:00 |
|
k88936
|
14294a2c9b
|
修掉多视图生成 3D 请求文档注释里的漏字
- server-rs/crates/shared-contracts/src/model3d/multiview_to_model/request.rs:公开文档注释「多视图生 3D」补回漏字,改成「多视图生成 3D」
|
2026-09-24 17:46:54 +08:00 |
|
k88936
|
82e889dc6d
|
带地址响应体的过滤改成大小写不敏感
- server-rs/crates/platform-tripo/src/common/error.rs:body_snippet 先整串转小写再匹配 http:// 与 https://,`HTTPS://…` 这类大小写变体不再绕过过滤,签名 URL 不会被带进持久化的任务错误信息
|
2026-09-24 17:44:20 +08:00 |
|
k88936
|
79ae24fa43
|
3D 产物的 content type 与落库值同源
- server-rs/crates/api-server/src/tripo3d/storage.rs:返回给调用方的 content_type 改为优先取 HEAD 复核回来的值(取不到才回落到本地解析值),与 asset_object.content_type 用同一份取值。此前接口返回的是本地解析值、落库的是 OSS 回显值,OSS 一旦归一化或回显空值,两个来源就会给出互相矛盾的元数据
|
2026-09-24 17:43:52 +08:00 |
|
k88936
|
8af4287bf3
|
落点校验的文档注释改成与实现一致
- server-rs/crates/api-server/src/tripo3d/validation.rs:validate_target 的注释此前写「项目资源与素材库二选一 / 不接受两个都给」,与实际实现(两个都接受、只要求至少一个)以及用例 target_accepts_both_locators_but_requires_at_least_one 矛盾,改为按实际口径描述
|
2026-09-24 17:43:43 +08:00 |
|
k88936
|
791011eacf
|
落点纵深防御的兜底字段名与归因口径对齐
- server-rs/crates/api-server/src/tripo3d/target.rs:两个落点都没给时的兜底报错由点 projectId 改为点 target,与 target_unavailable_field 对 both-missing 的归因一致,不再把错误指到一个调用方可能根本没传的键上
|
2026-09-24 17:43:36 +08:00 |
|
k88936
|
d927a8cfa7
|
后台保存定价的版本推进改为饱和加法
- server-rs/crates/api-server/src/state.rs:expected_updated_at_micros 来自后台请求体、只校验了必须给出,没有范围校验;expected + 1 在 i64::MAX 上会溢出(debug 下 panic、release 下回绕成 i64::MIN 并让版本推进失效),改用 saturating_add(与测试分支同一口径)
|
2026-09-24 17:43:32 +08:00 |
|
k88936
|
0b3c15ee7c
|
图生 3D 的源图对象键为空时按缺失处理
- server-rs/crates/api-server/src/tripo3d/image_source.rs:预检对 object_key 加非空判断,空串 / 纯空白与缺字段同义。此前 Some("") 能过预检,等任务已入队计费后才在下载源图时失败
|
2026-09-24 17:43:24 +08:00 |
|
k88936
|
643ffedfb6
|
provider 4xx 不再把原文错误体回给客户端
- server-rs/crates/api-server/src/tripo3d/errors.rs:400..=499 分支不再拼接 error.to_string()。TripoError::Api 的 Display 直接转述 provider 的 code/message/suggestion(HTTP 错误体原文,未做 URL 清洗),可能把带签名的地址等内部信息带进用户可见的任务错误;改为固定中文文案
|
2026-09-24 17:43:17 +08:00 |
|
k88936
|
72cdabbef3
|
定点引用查询补上调用方必须传本人 user_id 的说明
- server-rs/crates/api-server/src/editor_project.rs:resolve_editor_reference_record_by_id_for_owner 从 pub 收窄到 pub(crate) 后授权边界移到调用方,给函数补上「必须传已认证用户自己的 ID,本函数不做授权」的前置条件说明,避免后续 crate 内调用方传入客户端可控的 owner 造成越权读取
|
2026-09-24 17:43:13 +08:00 |
|
k88936
|
110354fad9
|
请求路径也拦住写歪的 Tripo 网关地址
- server-rs/crates/api-server/src/tripo3d/provider.rs:URL 判据(合法 URL + HTTP(S) + 有主机名)抽成 validate_tripo_base_url_syntax,启动期门禁与 tripo_settings 共用;非空但缺 scheme / 非 HTTP(S) / 无主机名的地址在请求前就映射 503,不再拖到 SDK 里变成一条指向连接失败的报错
- server-rs/crates/api-server/src/tripo3d/provider.rs:补请求期拒绝写歪地址的用例
|
2026-09-24 17:38:28 +08:00 |
|
k88936
|
62600fe881
|
请求路径也拦住越界的 TRIPO_RETRIES
- server-rs/crates/api-server/src/tripo3d/provider.rs:tripo_settings 显式校验 config.tripo_retries 不超过 TRIPO_MAX_RETRIES 并映射 503。TripoSettings::validate 只查空值与零超时,越界值会原样进 artifact_retries,把产物下载的挂起时间成倍拉长;注释里「第二道防线」的说法此前并不成立
- server-rs/crates/api-server/src/tripo3d/provider.rs:补越界拒绝 / 上限放行的用例
|
2026-09-24 17:36:55 +08:00 |
|
k88936
|
1600c107e0
|
修掉没测到 API Key 分支的用例
- server-rs/crates/api-server/src/tripo3d/provider.rs:missing_api_key_is_reported_as_unavailable 先补全 TRIPO_BASE_URL 再断言缺密钥。AppConfig::default() 的网关是空串,原用例一直停在「缺网关」分支上,API Key 校验删掉也能过
|
2026-09-24 17:35:45 +08:00 |
|
k88936
|
2877ede719
|
3D 面板的栅格覆盖不再依赖规则先后顺序
- src/index.css:`--model3d` 面板的 grid/width/gap 覆盖把 `--image` 一起写进选择器提高特异性。它与 `--image` 的声明特异性相同,此前只靠 `--model3d` 排在后面取胜,规则顺序一变就会退回两栏布局
|
2026-09-24 17:33:25 +08:00 |
|
k88936
|
0d2c81a3ce
|
画布导出的目录名单一来源
- src/components/image-editor/useImageCanvasAssetExportWorkflow.ts:images / media / 3d_models 三个目录名提成 EXPORT_FOLDER 常量,建目录、挑目录与按层分流共用同一份字面量(写错目录名不会编译报错,只会在 zip 里悄悄换目录)
|
2026-09-24 17:33:02 +08:00 |
|
k88936
|
9c2a9383fc
|
3D 两个生成模式也随失焦与关闭收起面板
- src/components/image-editor/ImageCanvasGenerationDialogModel.ts:hideGeneratedLayerComposerAfterBlur 与 closeGenerateComposerDialog 的模式清单补上 model3d-text-to-model / model3d-image-to-model,此前点空白画布或关闭操作都收不起 3D 面板(其它生成模式都能收起)
- src/components/image-editor/ImageCanvasGenerationDialogModel.test.ts:补两个 3D 模式的收起断言
|
2026-09-24 17:32:39 +08:00 |
|
k88936
|
946c101630
|
画布没接住任务状态时按失败收口
- src/components/image-editor/model3d-generation/useModel3dGenerationTask.ts:applyQueuedGeneration 返回 false 时不再静默复位成 idle(用户会以为没提交过、再点一次就是又一次已扣费的外部生成),改为写回失败态与明确文案
- src/components/image-editor/model3d-generation/Model3dGenerationSubmission.ts:新增 MODEL3D_QUEUE_HANDOFF_FAILED_MESSAGE,与「服务端没返回任务状态」区分开
- src/components/image-editor/model3d-generation/useModel3dGenerationTask.test.tsx:原「回到空闲态」用例改为断言失败态
|
2026-09-24 17:32:13 +08:00 |
|
k88936
|
3455b7a00f
|
3D 提交失败路径也刷新钱包余额
- src/components/image-editor/model3d-generation/useModel3dGenerationTask.ts:请求失败与「2xx 但没有任务状态」两条路径都调用 onWalletBalanceMayHaveChanged,与其它画布生成链路的 runEditorGenerationWithWalletRefresh 同一口径(超时或空 body 的 2xx 都可能已经扣费)
- src/components/image-editor/model3d-generation/useModel3dGenerationTask.test.tsx:补两条失败路径各刷新一次钱包的断言
|
2026-09-24 17:31:28 +08:00 |
|
k88936
|
5ba7a993de
|
3D 提交编排整段落在错误边界内
- src/components/image-editor/model3d-generation/useModel3dGenerationTask.ts:把取占位框、算结果标题与构造提交计划一并移进 try,注入的回调或老快照缺字段导致的抛错不再漏成未捕获 rejection,而是照常写回失败态与提示
- src/components/image-editor/model3d-generation/useModel3dGenerationTask.test.tsx:补「计划构造阶段抛错」的用例(缺 prompt 的老快照)
|
2026-09-24 17:30:53 +08:00 |
|
k88936
|
2350c56f2f
|
3D 失败提示只透出服务端给的文案
- src/components/image-editor/model3d-generation/Model3dGenerationSubmission.ts:resolveModel3dGenerationErrorMessage 只对 ApiClientError 原样透出 message;原生 SyntaxError(2xx 但 body 不是 JSON)与其它运行时 TypeError 的英文技术文案不再直接显示给用户
- src/components/image-editor/model3d-generation/Model3dGenerationSubmission.test.ts、useModel3dGenerationTask.test.tsx:用例改用 ApiClientError 构造服务端文案,并补非服务端错误退回兜底文案的断言
|
2026-09-24 17:30:01 +08:00 |
|
k88936
|
96b52ae7ee
|
提交计划把非图生模式显式判为不支持
- src/components/image-editor/model3d-generation/Model3dGenerationSubmission.ts:图生分支之后补显式模式判断,契约将来新增端点时直接失败关闭,而不是静默按文生请求发出、丢掉新端点的输入
|
2026-09-24 17:28:46 +08:00 |
|
k88936
|
8d17855133
|
提交计划去掉无人读取的 title 字段
- src/components/image-editor/model3d-generation/Model3dGenerationSubmission.ts:Model3dSubmissionPlanBase.title 没有任何消费方(调用方自己按 resolveModel3dResultTitle 重算),删除该字段与它的装配代码,避免把死数据当成权威标题
|
2026-09-24 17:28:29 +08:00 |
|
k88936
|
bc68a9e884
|
查看器未知失败原因退回兜底文案
- src/components/image-editor/model3d-preview/Model3dViewerModel.ts:default 分支保留 `never` 的编译期穷尽检查,但运行时(宿主与查看器版本错配)改回 fallbackText,不再把原始原因码当用户文案显示
|
2026-09-24 17:28:02 +08:00 |
|
k88936
|
7b8bbac098
|
报价缺价文案提成具名常量
- src/components/image-editor/model3d-generation/Model3dGenerationFormModel.ts:底价缺失与加价项缺失两句文案按模块既有约定提成 MODEL3D_PRICING_MISSING_BASE_PRICE_REASON 与 resolveModel3dPricingMissingAddOnReason,不再散落在计算路径里
|
2026-09-24 17:27:37 +08:00 |
|
k88936
|
fe44054aa2
|
退役模型版本在报价与提交路径上一起回落默认版本
- src/components/image-editor/model3d-generation/Model3dGenerationFormModel.ts:resolveModel3dModelVersion 改为走 normalizeModel3dModelVersion,老快照里契约中已不存在的版本不再直接进 MODEL3D_MODEL_TABLE 查表(原来会抛异常),报价与提交体也不会分裂成两个版本;此前该归一化函数只有测试在用
- src/components/image-editor/model3d-generation/Model3dGenerationFormModel.test.ts:补 resolveModel3dModelVersion 收到退役版本的用例
|
2026-09-24 17:27:17 +08:00 |
|
k88936
|
9840f17189
|
模型版本判据不再认下原型链上的键
- src/components/image-editor/model3d-generation/Model3dGenerationValidation.ts:isModel3dModelVersion 改用 Object.hasOwn,`toString` / `__proto__` 这类继承键不再被判成契约版本(之后查表会拿到 undefined)
- src/components/image-editor/model3d-generation/Model3dGenerationFormModel.test.ts:补原型链键回落默认版本的用例
|
2026-09-24 17:26:49 +08:00 |
|
k88936
|
3191ca9d89
|
3D 面板的重试代次改在点击时铸造
- src/components/image-editor/model3d-generation/Model3dGenerationModal.tsx:失败态下的代次刷新由渲染体里的常量改为点击时调用的 resolveSubmitDialog(),提交键不再随每次重渲染(含 StrictMode 双渲染)变化,渲染保持纯函数
|
2026-09-24 17:26:17 +08:00 |
|
k88936
|
cd5218535e
|
3D 面板参考图菜单的边界 refs 数组稳定下来
- src/components/image-editor/model3d-generation/Model3dGenerationModal.tsx:boundaryRefs 用 useMemo 缓存,避免每次渲染都新建数组导致浮层 dismiss effect 反复解绑/重挂 document 监听
|
2026-09-24 17:26:02 +08:00 |
|
k88936
|
89b8211b94
|
生成中禁用图生 3D 参考图的删除按钮
- src/components/image-editor/model3d-generation/Model3dGenerationForm.tsx:已选参考图槽位补 disabled={disabled},提交中不再能删掉这次请求用的参考图,与面板其余控件的禁用口径一致
|
2026-09-24 17:25:37 +08:00 |
|
k88936
|
fb0be97609
|
图生 3D 的素材库空确认不再清掉已选参考图
- src/components/image-editor/ImageCanvasGenerationDialogModel.ts:单槽对话框只在素材库确实选到了图时才做「替换」,空确认退回原行为(保留画布点选/上传的那张)。此前确认按钮不校验空选,空确认会把已有参考图直接清掉
- src/components/image-editor/projectAssetReferencePickerModel.test.ts:补空确认保留画布参考图的用例
|
2026-09-24 17:25:16 +08:00 |
|