feat(api): album domain schema

Co-Authored-By: Claude Code <noreply@anthropic.com>
This commit is contained in:
浅念
2026-09-17 20:05:09 +08:00
parent 2801e4f158
commit a99b8f200b
5 changed files with 240 additions and 11 deletions
@@ -6,6 +6,9 @@
// 3) audit_logs 的 Json 元数据落库与 actor 关系;
// 4) 必选关系默认 Restrict:删除仍持有 session 的用户抛 P2003——保留可审计性,
// 刻意不做 onDelete: Cascade(用户决策,见计划 Task 8)。
// 5) 相册域(Task 9 增补):多语言翻译按 @@unique([albumId, locale]) 双向
// 精确命中、publicToken 唯一约束拒绝重复(P2002)——相册域为扁平字符串
// 外键(无 Prisma relation),完整 CRUD 语义由 Task 15 展开。
import { PrismaClient } from '@photo/db-cn';
import { resetDb } from './reset';
@@ -115,4 +118,50 @@ describe('db semantics (e2e)', () => {
prisma.users.delete({ where: { id: user.id } }),
).rejects.toMatchObject({ code: 'P2003' });
});
it('album translations resolve by (albumId, locale) both ways and publicToken is unique (Task 9)', async () => {
const album = await prisma.albums.create({
data: {
publicToken: 'album-tok-e2e-01',
ownerId: 'owner-flat-fk', // 相册域扁平字符串外键,无 FK 约束
startAt: new Date('2026-10-01T00:00:00Z'),
defaultLocale: 'zh-CN',
},
});
await prisma.album_translations.create({
data: { albumId: album.id, locale: 'zh-CN', title: '婚礼相册' },
});
await prisma.album_translations.create({
data: { albumId: album.id, locale: 'en', title: 'Wedding Album' },
});
// 复合唯一键两个方向都能精确命中(bin 校对:locale 大小写敏感)。
const zh = await prisma.album_translations.findUnique({
where: { albumId_locale: { albumId: album.id, locale: 'zh-CN' } },
});
expect(zh?.title).toBe('婚礼相册');
const en = await prisma.album_translations.findUnique({
where: { albumId_locale: { albumId: album.id, locale: 'en' } },
});
expect(en?.title).toBe('Wedding Album');
// 同一 (albumId, locale) 重复写入被唯一约束拒绝(P2002)。
await expect(
prisma.album_translations.create({
data: { albumId: album.id, locale: 'en', title: 'Dup' },
}),
).rejects.toMatchObject({ code: 'P2002' });
// publicToken 全局唯一:第二个相册复用同 token 抛 P2002。
await expect(
prisma.albums.create({
data: {
publicToken: 'album-tok-e2e-01',
ownerId: 'owner-flat-fk',
startAt: new Date('2026-11-01T00:00:00Z'),
defaultLocale: 'zh-CN',
},
}),
).rejects.toMatchObject({ code: 'P2002' });
});
});