Files
photo-live/packages/contracts/src/album-payload.ts
T
2026-09-20 17:53:44 +08:00

71 lines
2.6 KiB
TypeScript

// packages/contracts/src/album-payload.ts —— album.updated 载荷构建器(P4a Task 3
// 起为跨服务共享实现)。此前唯一实现在 api src/sync/payloads.ts;水印任务完成时
// **worker** 也要写 album.updated outbox(有效版本推进须同步 ov),为避免两份
// 实现漂移,构建器收敛到契约包:输入为结构化行形状(不依赖 Prisma 类型),
// api 的 sync/payloads.ts 包装本实现并叠加 categories 快照参数,worker 直接调用。
import type { AlbumUpdatedPayload } from './events.js';
/** 构建器所需的主行列子集(cn albums 行的结构化形状;两消费方的 Prisma 行天然满足)。 */
export interface AlbumPayloadRow {
id: string;
publicToken: string;
status: string;
uploadEnabled: boolean;
publicEnabled: boolean;
downloadEnabled: boolean;
originalDownloadEnabled: boolean;
/** 有效水印位(见 watermark.ts 版本语义;列由 P4a Task 3 迁移新增,行必含)。 */
watermarkEnabled: boolean;
watermarkEffectiveVersion: number;
defaultLocale: string;
timezone: string;
startAt: Date;
endAt: Date | null;
entityVersion: number;
}
/** 翻译行的结构化形状(cn album_translations 行满足)。 */
export interface AlbumTranslationRow {
locale: string;
title: string;
description: string | null;
venue: string | null;
address: string | null;
}
/**
* album.updated 载荷(无 categories 版):标量全集 + 翻译(locale 升序)+
* 水印副本位。与 api sync/payloads.ts 的完整版逐字节同形(categories 是其
* 独有的可选叠加参数,业务事务内事件与 worker 事件均不携带)。
*/
export function buildAlbumUpdatedPayloadCore(
album: AlbumPayloadRow,
translations: AlbumTranslationRow[],
): AlbumUpdatedPayload {
return {
albumId: album.id,
publicToken: album.publicToken,
status: album.status,
uploadEnabled: album.uploadEnabled,
publicEnabled: album.publicEnabled,
downloadEnabled: album.downloadEnabled,
originalDownloadEnabled: album.originalDownloadEnabled,
watermarkEnabled: album.watermarkEnabled,
watermarkConfigVersion: album.watermarkEffectiveVersion,
defaultLocale: album.defaultLocale,
timezone: album.timezone,
startAt: album.startAt.toISOString(),
endAt: album.endAt === null ? null : album.endAt.toISOString(),
translations: [...translations]
.sort((a, b) => (a.locale < b.locale ? -1 : 1))
.map((t) => ({
locale: t.locale,
title: t.title,
description: t.description,
venue: t.venue,
address: t.address,
})),
entityVersion: album.entityVersion,
};
}