forked from wangziqi/gongxue-base
feat: establish production SaaS foundation
This commit is contained in:
80
scripts/tenant-foreign-key-audit-test.js
Normal file
80
scripts/tenant-foreign-key-audit-test.js
Normal file
@@ -0,0 +1,80 @@
|
||||
import assert from 'node:assert/strict';
|
||||
import fs from 'node:fs';
|
||||
import {
|
||||
EXPECTED_TENANT_FOREIGN_KEY_RELATION_COUNT,
|
||||
EXPECTED_TENANT_FOREIGN_KEY_SCHEMA_SHA256,
|
||||
buildTenantForeignKeyViolationQuery,
|
||||
tenantForeignKeyExceptions,
|
||||
tenantForeignKeySchemaSha256,
|
||||
} from './lib/tenant-foreign-key-audit.js';
|
||||
import {
|
||||
assertTenantForeignKeyAuditTarget,
|
||||
parseTenantForeignKeyAuditOptions,
|
||||
} from './tenant-foreign-key-audit.js';
|
||||
|
||||
const relation = overrides => ({
|
||||
childTable: 'child_rows',
|
||||
constraintName: 'child_rows_parent_id_fkey',
|
||||
childColumns: ['parent_id'],
|
||||
parentTable: 'parent_rows',
|
||||
parentColumns: ['id'],
|
||||
validated: true,
|
||||
updateAction: 'a',
|
||||
deleteAction: 'a',
|
||||
...overrides,
|
||||
});
|
||||
|
||||
assert.equal(EXPECTED_TENANT_FOREIGN_KEY_RELATION_COUNT, 189);
|
||||
assert.match(EXPECTED_TENANT_FOREIGN_KEY_SCHEMA_SHA256, /^[0-9a-f]{64}$/);
|
||||
assert.equal(tenantForeignKeyExceptions().length, 3);
|
||||
|
||||
const digestA = tenantForeignKeySchemaSha256([relation({ childTable: 'b' }), relation({ childTable: 'a' })]);
|
||||
const digestB = tenantForeignKeySchemaSha256([relation({ childTable: 'a' }), relation({ childTable: 'b' })]);
|
||||
assert.equal(digestA, digestB, 'schema fingerprint must not depend on catalog row ordering');
|
||||
|
||||
const defaultQuery = buildTenantForeignKeyViolationQuery([relation({})]);
|
||||
assert.match(defaultQuery, /child\.tenant_id is distinct from parent\.tenant_id/i);
|
||||
|
||||
const globalRuleQuery = buildTenantForeignKeyViolationQuery([
|
||||
relation({
|
||||
childTable: 'platform_audit_alerts',
|
||||
constraintName: 'platform_audit_alerts_rule_id_fkey',
|
||||
childColumns: ['rule_id'],
|
||||
parentTable: 'platform_audit_alert_rules',
|
||||
}),
|
||||
]);
|
||||
assert.match(globalRuleQuery, /parent\.tenant_id is not null and child\.tenant_id is distinct from parent\.tenant_id/i);
|
||||
|
||||
const platformBankQuery = buildTenantForeignKeyViolationQuery([
|
||||
relation({
|
||||
childTable: 'tenant_question_bank_adoptions',
|
||||
constraintName: 'tenant_question_bank_adoptions_source_question_bank_id_fkey',
|
||||
childColumns: ['source_question_bank_id'],
|
||||
parentTable: 'question_banks',
|
||||
}),
|
||||
]);
|
||||
assert.match(platformBankQuery, /parent\.source_scope is distinct from 'platform'/i);
|
||||
|
||||
assert.throws(
|
||||
() => parseTenantForeignKeyAuditOptions([], {}),
|
||||
/DATABASE_URL is required/,
|
||||
);
|
||||
assert.throws(
|
||||
() => assertTenantForeignKeyAuditTarget('postgresql://postgres:postgres@127.0.0.1:5432/postgres'),
|
||||
/reserved for tikupro-pg/,
|
||||
);
|
||||
assert.throws(
|
||||
() => assertTenantForeignKeyAuditTarget('postgresql://postgres:postgres@tikupro-pg:55432/postgres'),
|
||||
/tikupro-pg targets are forbidden/,
|
||||
);
|
||||
assert.deepEqual(
|
||||
assertTenantForeignKeyAuditTarget('postgresql://postgres:secret@127.0.0.1:55432/postgres'),
|
||||
{ host: '127.0.0.1', port: '55432', database: 'postgres', user: 'postgres' },
|
||||
);
|
||||
|
||||
const readiness = fs.readFileSync('scripts/production-readiness-check.js', 'utf8');
|
||||
assert.match(readiness, /db\.tenant_foreign_keys\.schema/);
|
||||
const launchGate = fs.readFileSync('scripts/production-launch-gate.js', 'utf8');
|
||||
assert.match(launchGate, /db\.tenant-foreign-key-audit/);
|
||||
|
||||
console.log('[PASS] tenant foreign key audit contract');
|
||||
Reference in New Issue
Block a user