fix: stop puzzle covers writing to public path
This commit is contained in:
@@ -196,10 +196,10 @@ Rust DTO 只承载对前端公开的 HTTP contract,不直接泄露 `module-puz
|
|||||||
|
|
||||||
## 6. 结果页图片生成策略
|
## 6. 结果页图片生成策略
|
||||||
|
|
||||||
本轮不引入新的真实图像模型编排,而是复用 `api-server` 里已有的占位资产写盘模式:
|
本轮后续已经接入 `api-server` 统一资产链路:拼图候选图由 `api-server` 调用图像服务生成,再以 OSS 对象作为持久化真值,SpacetimeDB 只保存候选图 URL、assetId 与 prompt snapshot。
|
||||||
|
|
||||||
1. 每次生成 2 张候选图。
|
1. 每次生成 2 张候选图。
|
||||||
2. 候选图通过 `api-server` 写入 `public/generated-puzzle-covers/...`。
|
2. 候选图通过 `api-server` 写入 OSS,兼容展示路径统一为 `/generated-puzzle-assets/...`,禁止再落到仓库 `public/` 目录。
|
||||||
3. Axum 把候选图 URL、assetId、prompt snapshot 回写到 Spacetime session draft。
|
3. Axum 把候选图 URL、assetId、prompt snapshot 回写到 Spacetime session draft。
|
||||||
4. 创作者在结果页选择其中 1 张作为正式图。
|
4. 创作者在结果页选择其中 1 张作为正式图。
|
||||||
|
|
||||||
@@ -207,7 +207,7 @@ Rust DTO 只承载对前端公开的 HTTP contract,不直接泄露 `module-puz
|
|||||||
|
|
||||||
1. 结果页图片生成、重生、应用正式图完整可用。
|
1. 结果页图片生成、重生、应用正式图完整可用。
|
||||||
2. 发布链有正式图片可校验。
|
2. 发布链有正式图片可校验。
|
||||||
3. 不额外扩到模型供应商集成。
|
3. 不再依赖本地 `public/` 占位目录,避免开发工作区混入运行时生成文件。
|
||||||
|
|
||||||
### 6.1 发布前编辑真相补充
|
### 6.1 发布前编辑真相补充
|
||||||
|
|
||||||
|
|||||||
@@ -683,8 +683,10 @@ pub fn build_generated_candidates(
|
|||||||
let candidate_id = format!("{session_id}-candidate-{}", index + 1);
|
let candidate_id = format!("{session_id}-candidate-{}", index + 1);
|
||||||
PuzzleGeneratedImageCandidate {
|
PuzzleGeneratedImageCandidate {
|
||||||
candidate_id: candidate_id.clone(),
|
candidate_id: candidate_id.clone(),
|
||||||
|
// 拼图候选图的正式持久化由 api-server 上传 OSS;这里仅保留 reducer
|
||||||
|
// 单测/保底路径构造,前缀必须与 OSS 兼容路由一致,不能再指向 public 目录。
|
||||||
image_src: format!(
|
image_src: format!(
|
||||||
"/generated-puzzle-covers/{session_id}/{candidate_seed}/cover.svg"
|
"/generated-puzzle-assets/{session_id}/{candidate_seed}/cover.svg"
|
||||||
),
|
),
|
||||||
asset_id: format!("puzzle-cover-{candidate_seed}"),
|
asset_id: format!("puzzle-cover-{candidate_seed}"),
|
||||||
prompt: prompt.clone(),
|
prompt: prompt.clone(),
|
||||||
@@ -1543,6 +1545,21 @@ mod tests {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn generated_candidates_use_oss_compatible_prefix() {
|
||||||
|
let anchor_pack = infer_anchor_pack("雨夜猫咪", Some("雨夜猫咪"));
|
||||||
|
let draft = compile_result_draft(&anchor_pack, &[]);
|
||||||
|
let candidates = build_generated_candidates("session-1", None, &draft, 2, 1_000)
|
||||||
|
.expect("candidates should build");
|
||||||
|
|
||||||
|
assert_eq!(candidates.len(), 2);
|
||||||
|
assert!(candidates[0]
|
||||||
|
.image_src
|
||||||
|
.starts_with("/generated-puzzle-assets/session-1/"));
|
||||||
|
let legacy_public_prefix = ["generated-puzzle", "covers"].join("-");
|
||||||
|
assert!(!candidates[0].image_src.contains(&legacy_public_prefix));
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn tag_similarity_score_uses_jaccard() {
|
fn tag_similarity_score_uses_jaccard() {
|
||||||
let score = tag_similarity_score(
|
let score = tag_similarity_score(
|
||||||
|
|||||||
Reference in New Issue
Block a user