Files
lisglosips/packages/database/src/schema-contract.spec.ts
T

113 lines
4.9 KiB
TypeScript

import { describe, expect, it } from 'vitest';
import { readFileSync } from 'node:fs';
import { join } from 'node:path';
const schema = readFileSync(join(process.cwd(), 'prisma/schema.prisma'), 'utf8');
const migration = readFileSync(join(process.cwd(), 'prisma/migrations/20260621090000_init_v2_schema/migration.sql'), 'utf8');
const authMigration = readFileSync(join(process.cwd(), 'prisma/migrations/20260621093000_auth_sessions/migration.sql'), 'utf8');
const numberLibraryMigration = readFileSync(join(process.cwd(), 'prisma/migrations/20260624095000_number_library/migration.sql'), 'utf8');
const businessPrefixMigration = readFileSync(
join(process.cwd(), 'prisma/migrations/20260624121000_business_prefix_gateway_rewrite/migration.sql'),
'utf8'
);
describe('Prisma schema contract', () => {
it('defines every V2 core business table', () => {
const tables = [
'customers',
'customer_gateways',
'customer_gateway_ips',
'business_prefixes',
'customer_gateway_business_prefixes',
'customer_gateway_caller_prefixes',
'customer_gateway_policies',
'customer_recharges',
'vendors',
'vendor_recharges',
'vendor_gateways',
'vendor_gateway_blocked_regions',
'vendor_gateway_forbidden_periods',
'vendor_gateway_codecs',
'vendor_gateway_prefix_rules',
'vendor_gateway_caller_rewrite_pool',
'landing_line_groups',
'landing_line_group_items',
'geo_cities',
'phone_number_segments',
'phone_area_codes',
'carrier_prefix_rules',
'raw_cdrs',
'rated_cdrs',
'recordings',
'quality_sampling_rules',
'quality_reviews',
'users',
'roles',
'permissions',
'user_roles',
'user_sessions',
'role_permissions',
'audit_logs',
'outbox_events',
'idempotency_keys'
];
for (const table of tables) {
expect(schema).toContain(`@@map("${table}")`);
expect(`${migration}\n${authMigration}\n${numberLibraryMigration}\n${businessPrefixMigration}`).toContain(
`CREATE TABLE \`${table}\``
);
}
});
it('keeps money and idempotent facts constrained', () => {
expect(migration).toContain('DECIMAL(20, 6)');
expect(migration).toContain('UNIQUE INDEX `raw_cdrs_event_id_key`');
expect(migration).toContain('UNIQUE INDEX `raw_cdrs_call_id_ended_at_key`');
expect(migration).toContain('UNIQUE INDEX `customer_recharges_idempotency_key_key`');
expect(migration).toContain('UNIQUE INDEX `vendor_recharges_idempotency_key_key`');
expect(migration).toContain('UNIQUE INDEX `idempotency_keys_key_key`');
});
it('captures number library and CDR callee attribution fields', () => {
expect(schema).toContain('model GeoCity');
expect(schema).toContain('model PhoneNumberSegment');
expect(schema).toContain('model CarrierPrefixRule');
expect(numberLibraryMigration).toContain('`segment7` CHAR(7) NOT NULL');
expect(numberLibraryMigration).toContain('`callee_city_code` VARCHAR(12) NULL');
expect(numberLibraryMigration).toContain('`callee_operator` ENUM');
expect(numberLibraryMigration).toContain('CREATE INDEX `raw_cdrs_callee_operator_started_at_idx`');
});
it('models phase-2 business prefix gateway matching and landing rewrites', () => {
expect(schema).toContain('model BusinessPrefix');
expect(schema).toContain('model CustomerGatewayIp');
expect(schema).toContain('model CustomerGatewayBusinessPrefix');
expect(schema).toContain('model CustomerGatewayCallerPrefix');
expect(schema).toContain('model VendorGatewayCallerRewrite');
expect(schema).toContain('enum CustomerGatewayCallerMatchMode');
expect(schema).toContain('enum CustomerGatewayCalleeMatchMode');
expect(businessPrefixMigration).toContain('`billing_cycle_sec` INTEGER NOT NULL DEFAULT 60');
expect(businessPrefixMigration).toContain('`landing_callee_prefix` VARCHAR(64) NULL');
expect(businessPrefixMigration).toContain('`raw_callee` VARCHAR(64) NULL');
expect(businessPrefixMigration).toContain('`landing_caller` VARCHAR(64) NULL');
expect(businessPrefixMigration).toContain('CREATE INDEX `raw_cdrs_business_prefix_id_started_at_idx`');
});
it('models audit columns and outbox publishing state', () => {
expect(schema).toContain('createdAt');
expect(schema).toContain('updatedAt');
expect(schema).toContain('version');
expect(schema).toContain('model OutboxEvent');
expect(schema).toContain('enum OutboxStatus');
});
it('stores refresh sessions as revocable token digests', () => {
expect(schema).toContain('model UserSession');
expect(authMigration).toContain('`refresh_token_hash` CHAR(64) NOT NULL');
expect(authMigration).toContain('UNIQUE INDEX `user_sessions_refresh_token_hash_key`');
expect(authMigration).toContain('`revoked_at` DATETIME(3) NULL');
expect(authMigration).toContain('`rotated_from_id` VARCHAR(40) NULL');
});
});