import type { GpoAnalysisSnapshot } from './gpo-ingestion'; import type { GpoPolicyObservation, GpoPolicyValue } from './gpo-policy'; import type { GpoTechnicalPolicyIdentity } from './gpo-policy-identity'; import { gpoTechnicalPolicyIdentityValidationErrors } from './gpo-policy-identity'; export const GPO_POLICY_SNAPSHOT_AGGREGATOR = { id: 'gpo-policy-snapshot-aggregation', version: '1.0.0' } as const; export type EnvironmentProfileScope = 'computer' | 'user' | 'mixed'; export interface EnvironmentProfileContext { version: 1; id: string; kind: 'operating-system' | 'product'; productFamily: string; productVersion: string; role: string; scope: EnvironmentProfileScope; } export interface EnvironmentProfile { version: 1; id: string; projectId: string; name: string; revision: number; supersedesProfileId?: string; domainKey?: string; contexts: EnvironmentProfileContext[]; createdAt: string; } export interface CreateEnvironmentProfileRequest { name: string; supersedesProfileId?: string; domainKey?: string; contexts: Array>; } export type AggregatedPolicyStateStatus = 'configured' | 'deleted' | 'conflicted' | 'indeterminate'; export interface AggregatedPolicyState { version: 1; id: string; aggregationRunId: string; identity: GpoTechnicalPolicyIdentity; deliveryMechanism: GpoPolicyObservation['deliveryMechanism']; status: AggregatedPolicyStateStatus; values: GpoPolicyValue[]; observationIds: string[]; backupInstanceIds: string[]; applicableContextIds: string[]; ordering: 'single-gpo' | 'cross-gpo-identical' | 'cross-gpo-conflict' | 'indeterminate'; targeting: 'none' | 'unknown'; completeness: 'complete' | 'partial'; effectiveState: 'unknown'; diagnosticCodes: string[]; } export interface PolicyAggregationReviewHint { version: 1; id: string; code: string; identityId?: string; observationIds: string[]; backupInstanceIds: string[]; } export interface PolicySnapshotAggregationRun { version: 1; id: string; projectId: string; environmentProfileId: string; sourceAnalysisRunIds: string[]; snapshotId: string; aggregator: typeof GPO_POLICY_SNAPSHOT_AGGREGATOR; status: 'complete' | 'partial' | 'blocked'; stateCount: number; conflictCount: number; unresolvedIdentityCount: number; reviewHintCount: number; permitsFindingGeneration: false; diagnosticCodes: string[]; startedAt: string; completedAt: string; } export interface StoredPolicySnapshotAggregation { version: 1; run: PolicySnapshotAggregationRun; snapshot: GpoAnalysisSnapshot; states: AggregatedPolicyState[]; reviewHints: PolicyAggregationReviewHint[]; } export interface CreatePolicySnapshotAggregationRequest { environmentProfileId: string; sourceAnalysisRunIds: string[]; } function validText(value: unknown): value is string { return typeof value === 'string' && Boolean(value.trim()) && value.length <= 32_767 && !/[\u0000-\u001f]/.test(value); } function uniqueSorted(values: string[]): boolean { return new Set(values).size === values.length && values.every((value, index) => index === 0 || values[index - 1].localeCompare(value) < 0); } export function environmentProfileValidationErrors(profile: EnvironmentProfile): string[] { const errors: string[] = []; if (profile.version !== 1 || !validText(profile.id) || !validText(profile.projectId) || !validText(profile.name) || !Number.isSafeInteger(profile.revision) || profile.revision < 1 || !Number.isFinite(Date.parse(profile.createdAt))) { errors.push('Das Environment Profile besitzt keine gueltige Identitaet, Revision oder Zeitangabe.'); } if (profile.supersedesProfileId === profile.id) errors.push('Ein Environment Profile darf sich nicht selbst ersetzen.'); if (profile.domainKey !== undefined && !validText(profile.domainKey)) errors.push('Der optionale Domaenenschluessel ist ungueltig.'); const contexts = Array.isArray(profile.contexts) ? profile.contexts : []; if (!contexts.length || !contexts.some(context => context?.kind === 'operating-system')) { errors.push('Ein Environment Profile benoetigt mindestens einen Betriebssystemkontext.'); } const contextIds = new Set(); for (const context of contexts) { if (!context || context.version !== 1 || !['operating-system', 'product'].includes(context.kind) || !['computer', 'user', 'mixed'].includes(context.scope) || !validText(context.id) || !validText(context.productFamily) || !validText(context.productVersion) || !validText(context.role) || contextIds.has(context.id)) { errors.push('Das Environment Profile enthaelt einen ungueltigen oder doppelten Produktkontext.'); } contextIds.add(context.id); } return [...new Set(errors)]; } export function storedPolicySnapshotAggregationValidationErrors(record: StoredPolicySnapshotAggregation): string[] { const errors: string[] = []; const { run, snapshot, states, reviewHints } = record; if (record.version !== 1 || run.version !== 1 || !validText(run.id) || !validText(run.projectId) || !validText(run.environmentProfileId) || !validText(run.snapshotId) || run.snapshotId !== snapshot.id || snapshot.projectId !== run.projectId) { errors.push('Der Policy-Snapshot-Aggregationslauf besitzt ungueltige Referenzen.'); } if (run.aggregator.id !== GPO_POLICY_SNAPSHOT_AGGREGATOR.id || run.aggregator.version !== GPO_POLICY_SNAPSHOT_AGGREGATOR.version) { errors.push('Der Policy-Snapshot-Aggregationslauf benoetigt versionierte Aggregatorprovenienz.'); } if (!run.sourceAnalysisRunIds.length || !uniqueSorted(run.sourceAnalysisRunIds)) { errors.push('Quellanalyselaeufe muessen eindeutig und deterministisch sortiert sein.'); } if (![run.stateCount, run.conflictCount, run.unresolvedIdentityCount, run.reviewHintCount] .every(value => Number.isSafeInteger(value) && value >= 0) || run.stateCount !== states.length || run.conflictCount !== states.filter(state => state.status === 'conflicted').length || run.reviewHintCount !== reviewHints.length || run.permitsFindingGeneration !== false) { errors.push('Die Zaehler oder Finding-Grenze des Policy-Snapshot-Aggregationslaufs 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 Laufzeit des Policy-Snapshot-Aggregationslaufs ist ungueltig.'); } const stateIds = new Set(); const stateKeys = new Set(); for (const state of states) { const key = state.identity.id + '\0' + state.deliveryMechanism; if (state.version !== 1 || !validText(state.id) || state.aggregationRunId !== run.id || stateIds.has(state.id) || stateKeys.has(key) || !state.values.length || !uniqueSorted(state.observationIds) || !uniqueSorted(state.backupInstanceIds) || !uniqueSorted(state.applicableContextIds) || state.effectiveState !== 'unknown') { errors.push('Ein aggregierter Policyzustand ist ungueltig oder doppelt.'); } stateIds.add(state.id); stateKeys.add(key); errors.push(...gpoTechnicalPolicyIdentityValidationErrors(state.identity)); } const hintIds = new Set(); for (const hint of reviewHints) { if (hint.version !== 1 || !validText(hint.id) || !validText(hint.code) || hintIds.has(hint.id) || !uniqueSorted(hint.observationIds) || !uniqueSorted(hint.backupInstanceIds)) { errors.push('Ein Review-Hinweis der Policyaggregation ist ungueltig oder doppelt.'); } hintIds.add(hint.id); } return [...new Set(errors)]; }