99 lines
4.5 KiB
TypeScript
99 lines
4.5 KiB
TypeScript
import type { GpoBackupInstance } from './gpo-ingestion';
|
|
import { gpoBackupInstanceValidationErrors } from './gpo-ingestion';
|
|
import type { GpoPolicyIdentityResolution } from './gpo-policy-identity';
|
|
import { gpoTechnicalPolicyIdentityValidationErrors } from './gpo-policy-identity';
|
|
|
|
export interface StoredGpoBackupInstance {
|
|
version: 1;
|
|
id: string;
|
|
projectId: string;
|
|
artifactId: string;
|
|
processingRunId: string;
|
|
instance: GpoBackupInstance;
|
|
createdAt: string;
|
|
}
|
|
|
|
export interface GpoPolicyIdentityAnalysisRun {
|
|
version: 1;
|
|
id: string;
|
|
projectId: string;
|
|
artifactId: string;
|
|
sourceProcessingRunId: string;
|
|
supersedesAnalysisRunId?: string;
|
|
analyzer: { id: 'gpo-policy-identity-analysis'; version: string };
|
|
identityResolver: { id: string; version: string };
|
|
status: 'complete' | 'partial';
|
|
observationCount: number;
|
|
resolvedCount: number;
|
|
diagnosticCodes: string[];
|
|
startedAt: string;
|
|
completedAt: string;
|
|
}
|
|
|
|
export interface StoredGpoPolicyIdentityResolution {
|
|
version: 1;
|
|
id: string;
|
|
projectId: string;
|
|
analysisRunId: string;
|
|
sourceProcessingRunId: string;
|
|
backupInstanceId: string;
|
|
observationId: string;
|
|
resolution: GpoPolicyIdentityResolution;
|
|
}
|
|
|
|
export interface StoredGpoPolicyAnalysis {
|
|
run: GpoPolicyIdentityAnalysisRun;
|
|
resolutions: StoredGpoPolicyIdentityResolution[];
|
|
}
|
|
|
|
export function storedGpoBackupInstanceValidationErrors(record: StoredGpoBackupInstance): string[] {
|
|
const errors = gpoBackupInstanceValidationErrors(record.instance);
|
|
if (record.version !== 1) errors.push('Unbekannte persistierte GPO-Backupversion.');
|
|
if (!record.id.trim() || !record.projectId.trim() || !record.artifactId.trim() || !record.processingRunId.trim()) {
|
|
errors.push('Persistierte GPO-Backup-, Projekt-, Artefakt- und Processing-Run-ID sind erforderlich.');
|
|
}
|
|
if (record.instance.projectId !== record.projectId || record.instance.sourceArtifactId !== record.artifactId) {
|
|
errors.push('GPO-Backupinstanz gehört nicht zum angegebenen Projekt oder Artefakt.');
|
|
}
|
|
if (!Number.isFinite(Date.parse(record.createdAt))) errors.push('Der Persistenzzeitpunkt der GPO-Backupinstanz ist ungültig.');
|
|
return errors;
|
|
}
|
|
|
|
export function storedGpoPolicyAnalysisValidationErrors(analysis: StoredGpoPolicyAnalysis): string[] {
|
|
const errors: string[] = [];
|
|
const { run, resolutions } = analysis;
|
|
if (run.version !== 1 || !run.id.trim() || !run.projectId.trim() || !run.artifactId.trim() || !run.sourceProcessingRunId.trim()) {
|
|
errors.push('Der Policy-Identitätslauf benötigt gültige IDs.');
|
|
}
|
|
if (run.supersedesAnalysisRunId === run.id) errors.push('Ein Policy-Identitätslauf darf sich nicht selbst ersetzen.');
|
|
if (run.analyzer.id !== 'gpo-policy-identity-analysis' || !run.analyzer.version.trim()
|
|
|| !run.identityResolver.id.trim() || !run.identityResolver.version.trim()) {
|
|
errors.push('Der Policy-Identitätslauf benötigt versionierte Analyse- und Resolverprovenienz.');
|
|
}
|
|
if (![run.observationCount, run.resolvedCount].every(value => Number.isSafeInteger(value) && value >= 0)
|
|
|| run.resolvedCount > run.observationCount || run.observationCount !== resolutions.length) {
|
|
errors.push('Die Zählwerte des Policy-Identitätslaufs sind inkonsistent.');
|
|
}
|
|
if (![run.startedAt, run.completedAt].every(value => Number.isFinite(Date.parse(value)))
|
|
|| Date.parse(run.completedAt) < Date.parse(run.startedAt)) {
|
|
errors.push('Die Zeitspanne des Policy-Identitätslaufs ist ungültig.');
|
|
}
|
|
const ids = new Set<string>();
|
|
const observations = new Set<string>();
|
|
for (const record of resolutions) {
|
|
if (record.version !== 1 || !record.id.trim() || record.projectId !== run.projectId
|
|
|| record.analysisRunId !== run.id || record.sourceProcessingRunId !== run.sourceProcessingRunId
|
|
|| !record.backupInstanceId.trim() || !record.observationId.trim() || ids.has(record.id) || observations.has(record.observationId)) {
|
|
errors.push('Eine persistierte Policy-Identitätsauflösung ist ungültig oder doppelt.');
|
|
}
|
|
ids.add(record.id);
|
|
observations.add(record.observationId);
|
|
if (record.resolution.status === 'resolved') errors.push(...gpoTechnicalPolicyIdentityValidationErrors(record.resolution.identity));
|
|
else if (!record.resolution.reasonCode.trim()) errors.push('Eine unaufgelöste Policy-Identität benötigt einen Grundcode.');
|
|
}
|
|
if (run.resolvedCount !== resolutions.filter(record => record.resolution.status === 'resolved').length) {
|
|
errors.push('Die Zahl aufgelöster Policy-Identitäten ist inkonsistent.');
|
|
}
|
|
return [...new Set(errors)];
|
|
}
|