import { DomainConflictError } from '../../../common/errors/domain-conflict.error';
type OperationalCaseInput = Record<string, any>;
function assertObject(input: unknown, code: string): asserts input is OperationalCaseInput {
if (!input || typeof input !== 'object' || Array.isArray(input)) {
throw new DomainConflictError(code);
}
}
function assertText(value: unknown, max: number, code: string): asserts value is string {
if (typeof value !== 'string' || value.trim().length === 0 || value.length > max) {
throw new DomainConflictError(code);
}
}
function assertOptionalText(value: unknown, max: number, code: string): void {
if (value !== undefined && value !== null) assertText(value, max, code);
}
function assertScope(input: OperationalCaseInput, code: string): void {
assertText(input.organizationId, 200, code);
assertText(input.locationId, 200, code);
}
function assertJsonRecord(value: unknown, code: string): void {
if (!value || typeof value !== 'object' || Array.isArray(value)) {
throw new DomainConflictError(code);
}
if (Object.keys(value).length > 20) throw new DomainConflictError(code);
try {
if (JSON.stringify(value).length > 100_000) throw new DomainConflictError(code);
} catch (error) {
if (error instanceof DomainConflictError) throw error;
throw new DomainConflictError(code);
}
}
function assertVersion(value: unknown, code: string): void {
if (value !== undefined && value !== null &&
(!Number.isSafeInteger(value) || Number(value) <= 0)) {
throw new DomainConflictError(code);
}
}
export function assertOperationalCaseScope(input: unknown): asserts input is OperationalCaseInput {
const code = 'incidents.input_invalid';
assertObject(input, code);
assertScope(input, code);
}
export function assertOperationalCaseCreateInput(input: unknown): asserts input is OperationalCaseInput {
const code = 'incidents.input_invalid';
assertObject(input, code);
assertScope(input, code);
assertText(input.caseType, 100, code);
if (!['low', 'medium', 'high', 'critical'].includes(String(input.severity))) {
throw new DomainConflictError(code);
}
assertText(input.title, 500, code);
assertText(input.summary, 10_000, code);
assertOptionalText(input.affectedEntityType, 100, code);
assertOptionalText(input.affectedEntityId, 200, code);
assertOptionalText(input.openedByUserId, 200, code);
}
export function assertOperationalCaseEvidenceInput(input: unknown): asserts input is OperationalCaseInput {
const code = 'incidents.input_invalid';
assertObject(input, code);
assertScope(input, code);
assertText(input.caseId, 200, code);
assertJsonRecord(input.evidence, code);
assertVersion(input.expectedVersion, code);
}
export function assertOperationalCaseResolveInput(input: unknown): asserts input is OperationalCaseInput {
const code = 'incidents.input_invalid';
assertObject(input, code);
assertScope(input, code);
assertText(input.caseId, 200, code);
assertText(input.outcome, 10_000, code);
if (input.decision !== undefined && input.decision !== null) assertJsonRecord(input.decision, code);
assertOptionalText(input.userId, 200, code);
assertVersion(input.expectedVersion, code);
}
