feat(worker): watermark versioning with atomic history regeneration
Co-Authored-By: Claude Code <noreply@anthropic.com>
This commit is contained in:
@@ -222,6 +222,15 @@ export class PublicService {
|
||||
bucket.set(row.variant, row);
|
||||
}
|
||||
|
||||
// P4a Task 3 水印浏览图选择(cn):albums.watermarkEnabled(有效版本开关)
|
||||
// 且照片有 watermark 变体行 → 现签水印对象键;否则 browse。行是对象 put
|
||||
// 成功后才落库的(worker 先写对象再 upsert 行),故行存在 ⇒ 对象存在;
|
||||
// 失败照片行保留旧版本键(重生成失败不覆盖行——A20「失败照片保留旧图」),
|
||||
// 新发布照片行在最新版本键(WatermarkJobCreated:新照片即刻套用)——两者
|
||||
// 都直接用行的 objectKey,无需版本比较。disable 版任务逐张删行:删到哪张
|
||||
// 哪张回落 browse(渐进撤下,语义见 contracts watermark.ts)。
|
||||
const serveWatermark = album.watermarkEnabled;
|
||||
|
||||
const items: PublicPhotoListResponse['items'] = [];
|
||||
for (const photo of page) {
|
||||
const bucket = variantsByPhoto.get(photo.id);
|
||||
@@ -230,8 +239,14 @@ export class PublicService {
|
||||
if (thumbRow === undefined || browseRow === undefined) {
|
||||
continue;
|
||||
}
|
||||
const watermarkRow = serveWatermark
|
||||
? bucket?.get('watermark')
|
||||
: undefined;
|
||||
const browseKey =
|
||||
watermarkRow !== undefined ? watermarkRow.objectKey : browseRow.objectKey;
|
||||
// 宽高取 browse 变体尺寸(契约「浏览图宽高,用于列表占位」);变体行缺
|
||||
// 尺寸时回退 photos 主行(原始尺寸),两侧均缺 → 同样跳过(必返字段)。
|
||||
// 水印图与 browse 同源同尺寸(compose 基于 browse 管线),占位一致。
|
||||
const width = browseRow.width ?? photo.width;
|
||||
const height = browseRow.height ?? photo.height;
|
||||
if (width === null || height === null) {
|
||||
@@ -242,7 +257,7 @@ export class PublicService {
|
||||
width,
|
||||
height,
|
||||
thumb: await this.presign(thumbRow.objectKey),
|
||||
browse: await this.presign(browseRow.objectKey),
|
||||
browse: await this.presign(browseKey),
|
||||
likeCount: photo.likeCount,
|
||||
// published 行的 publishedAt 必非空(worker 发布事务写入);?? 兜底仅
|
||||
// 收窄类型,不构成可观察行为。
|
||||
@@ -290,6 +305,11 @@ export class PublicService {
|
||||
});
|
||||
const thumbRow = variants.find((v) => v.variant === 'thumb');
|
||||
const browseRow = variants.find((v) => v.variant === 'browse');
|
||||
// 水印浏览图选择同列表(有效开关 + 行存在 ⇒ 用行的对象键;A20 失败照片
|
||||
// 保留旧图——行未被失败任务覆盖,仍指向旧版本键)。
|
||||
const watermarkRow = album.watermarkEnabled
|
||||
? variants.find((v) => v.variant === 'watermark')
|
||||
: undefined;
|
||||
const width = browseRow?.width ?? photo.width;
|
||||
const height = browseRow?.height ?? photo.height;
|
||||
if (
|
||||
@@ -301,12 +321,14 @@ export class PublicService {
|
||||
// post-publish 不变量破坏:公开面按「不可展示」处理(同列表跳过语义)。
|
||||
throw photoNotPublic();
|
||||
}
|
||||
const browseKey =
|
||||
watermarkRow !== undefined ? watermarkRow.objectKey : browseRow.objectKey;
|
||||
return {
|
||||
photoId: photo.id,
|
||||
width,
|
||||
height,
|
||||
thumb: await this.presign(thumbRow.objectKey),
|
||||
browse: await this.presign(browseRow.objectKey),
|
||||
browse: await this.presign(browseKey),
|
||||
likeCount: photo.likeCount,
|
||||
publishedAt: (photo.publishedAt ?? new Date(0)).toISOString(),
|
||||
categoryId: photo.categoryId,
|
||||
|
||||
Reference in New Issue
Block a user