// 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, }; }