Files
ftb-project-management/apps/server/prisma/v22-prisma-models.spec.ts
2026-07-03 10:23:18 +08:00

51 lines
2.1 KiB
TypeScript

import { readFileSync } from 'node:fs';
import { join } from 'node:path';
const schemaPath = join(process.cwd(), 'prisma', 'schema.prisma');
function readSchema() {
return readFileSync(schemaPath, 'utf8');
}
function modelBlock(schema: string, modelName: string) {
const match = schema.match(new RegExp(`model ${modelName} \\{[\\s\\S]*?\\n\\}`));
if (!match) throw new Error(`Missing Prisma model: ${modelName}`);
return match[0];
}
describe('V2.2 Prisma partitioned model shape', () => {
it('models partitioned business tables with composite ids that include the partition key', () => {
const schema = readSchema();
expect(modelBlock(schema, 'Requirement')).toMatch(/@@id\(\[id, productId\]\)/);
expect(modelBlock(schema, 'DevTask')).toMatch(/@@id\(\[id, versionId\]\)/);
expect(modelBlock(schema, 'TestCase')).toMatch(/@@id\(\[id, versionId\]\)/);
expect(modelBlock(schema, 'Bug')).toMatch(/@@id\(\[id, versionId\]\)/);
});
it('keeps partition-key-scoped unique business codes in Prisma models', () => {
const schema = readSchema();
expect(modelBlock(schema, 'Requirement')).toMatch(/@@unique\(\[productId, code\]\)/);
expect(modelBlock(schema, 'DevTask')).toMatch(/@@unique\(\[versionId, code\]\)/);
expect(modelBlock(schema, 'TestCase')).toMatch(/@@unique\(\[versionId, code\]\)/);
expect(modelBlock(schema, 'Bug')).toMatch(/@@unique\(\[versionId, code\]\)/);
});
it('models append-only partitioned tables with createdAt in the composite id', () => {
const schema = readSchema();
expect(modelBlock(schema, 'WorkActivity')).toMatch(/@@id\(\[id, createdAt\]\)/);
expect(modelBlock(schema, 'TaskWorklog')).toMatch(/@@id\(\[id, createdAt\]\)/);
expect(modelBlock(schema, 'OvertimeRecord')).toMatch(/@@id\(\[id, createdAt\]\)/);
expect(modelBlock(schema, 'XiaobaoRiskSnapshot')).toMatch(/@@id\(\[id, createdAt\]\)/);
expect(modelBlock(schema, 'AiLog')).toMatch(/@@id\(\[id, createdAt\]\)/);
});
it('keeps Xiaobao current summaries keyed by version id only', () => {
const schema = readSchema();
expect(modelBlock(schema, 'XiaobaoRiskSummary')).toMatch(/versionId\s+String\s+@id/);
});
});