import type { AssessmentProject } from '../domain/canonical-model'; import type { ImportedDataset } from '../domain/dataset'; import type { EnvironmentSnapshot } from '../domain/environment-context'; import type { FindingRecord } from '../domain/finding'; import type { Review } from '../domain/review'; import { buildReportProjection, reportPriorityBases, type ReportPolicyEntry, type ReportProjection, type ReportProjectionInput, type ReportScoreSource } from './report-projection'; import type { UnifiedResultProjection } from '../domain/unified-result'; import { toolProfileDefinitions } from '../profiles/profile-definition-catalog'; import { securityDomainCatalog, securityDomainIdForRecord, securityDomainIdForUnifiedResult } from '../evaluation/security-domains'; import { summarizeWorkspaceResults } from '../features/project-import/datahub-scan-analysis'; import { profileForSheet } from '../features/project-import/workspace-profile'; import { dashboardResultState } from '../features/dashboard/dashboard-result-state'; import { managementWorkspaceDeviationKeys } from './management-business-impact'; function field(record: FindingRecord, label: string): string { return record.fields.find(item => item.label.toLocaleLowerCase('en-US') === label.toLocaleLowerCase('en-US'))?.value?.trim() ?? ''; } function policyEntry(record: FindingRecord): ReportPolicyEntry | undefined { if (field(record, 'Category') !== 'GPOs') return undefined; const status = field(record, 'Status'); const verdict = status === 'Deviation' ? 'Fail' : status === 'Passed' ? 'Pass' : status; if (!['Fail', 'Pass', 'Not configured', 'No baseline rule', 'Not comparable', 'Review required'].includes(verdict)) return undefined; return { id: record.id, verdict: verdict as ReportPolicyEntry['verdict'], conflict: Boolean(field(record, 'Conflict')), duplicate: Boolean(field(record, 'Duplicates')), title: record.title, scope: field(record, 'Scope'), identity: field(record, 'Technical Identity'), backupInstanceIds: [...new Set((record.policySourceEvidence ?? []).flatMap(source => source.backupInstanceId ? [source.backupInstanceId] : []))] }; } export interface ClientReportProjectionInput { project: AssessmentProject; assessmentIds?: string[]; generatedAt: string; results: UnifiedResultProjection[]; dataset: ImportedDataset; workspaceDataset?: ImportedDataset; environment?: EnvironmentSnapshot; overallScore?: number; scoreSources?: ReportScoreSource[]; reviews?: Record; } /** One frozen, filter-independent cut for both HTML files. */ export function clientReportInput(input: ClientReportProjectionInput): ReportProjectionInput { const projectSheet = input.dataset.sheets.find(sheet => sheet.isProjectSheet); const countDataset = input.workspaceDataset ?? input.dataset; const countSheet = countDataset.sheets.find(sheet => sheet.isProjectSheet); const counts = countSheet ? summarizeWorkspaceResults(countSheet.analysis.records, profileForSheet(countDataset, countSheet)) : undefined; const deviationKeys = countSheet ? managementWorkspaceDeviationKeys(countSheet.analysis.records, record => dashboardResultState(record, profileForSheet(countDataset, countSheet)) === 'deviation') : undefined; const policyRecords = (projectSheet?.analysis.records ?? []).filter(record => field(record, 'Category') === 'GPOs'); const policyEntries = policyRecords.flatMap(record => { const entry = policyEntry(record); return entry ? [entry] : []; }); const workRecordByOccurrence = new Map((projectSheet?.analysis.records ?? []) .flatMap(record => record.findingOccurrenceId ? [[record.findingOccurrenceId, record] as const] : [])); const policyRecordByIdentity = new Map(policyRecords .map(record => [`${field(record, 'Scope')}|${field(record, 'Technical Identity')}`, record] as const)); const reviewInputs = input.results.flatMap(result => { const record = workRecordByOccurrence.get(result.sourceResultId); const review = record && input.reviews?.[record.id]; if (!review) return []; return [{ resultProjectionId: result.resultProjectionId, include: review.include, status: review.status, priority: review.priority, owner: review.owner || undefined, due: review.due || undefined, prerequisites: review.prerequisites || undefined, access: review.access || undefined, nextStep: review.nextStep || undefined, markers: [review.markerQuickwin && 'quickwin', review.markerBlocked && 'blocked', review.markerExternal && 'external', review.markerQuestion && 'question', review.markerNotRelevant && 'notRelevant'].filter((value): value is string => Boolean(value)), riskAccepted: Boolean(review.riskAcceptance) }]; }); const environment = [ ['Domain', 'domain.fqdn'], ['Forest', 'forest.name'], ['Domain Controller', 'domain.controller_count'] ].map(([key, property]) => ({ key, value: input.environment?.observations.find(item => item.property === property && item.state === 'observed')?.originalValue?.toString() })); const provenance = input.results.flatMap(result => [ { kind: 'ScanRun', id: result.scanRunId ?? result.collectionRunId, observedAt: result.sourceObservedAt }, ...(result.importArtifactId ? [{ kind: 'ImportArtifact', id: result.importArtifactId }] : []), ...(result.evaluationRunId ? [{ kind: 'EvaluationRun', id: result.evaluationRunId }] : []), ...(result.sourceProfileVersion ? [{ kind: `${result.sourceTool ?? 'Source'} profile`, id: result.sourceProfileId ?? 'unknown', version: result.sourceProfileVersion }] : []), ...(result.mappingRuleVersion ? [{ kind: 'Mapping', id: result.sourceTool ?? 'unknown', version: result.mappingRuleVersion }] : []) ]); const uniqueProvenance = [...new Map(provenance.map(item => [`${item.kind}\u0000${item.id}\u0000${item.version ?? ''}`, item])).values()]; return { generatedAt: input.generatedAt, project: { id: input.project.id, name: input.project.name }, assessmentId: input.assessmentIds?.length === 1 ? input.assessmentIds[0] : undefined, results: input.results, domains: securityDomainCatalog.map(({ id, label }) => ({ id, label })), // The same classifier and Raw Data record as Work, so a check has one domain everywhere. domainOf: result => { const record = result.sourceKind.startsWith('policy-') ? policyRecordByIdentity.get(`${result.policyScope ?? ''}|${result.policyIdentityKey ?? ''}`) : workRecordByOccurrence.get(result.sourceResultId); return record ? securityDomainIdForRecord(record) : securityDomainIdForUnifiedResult(result); }, priorityBases: reportPriorityBases(toolProfileDefinitions), overallScore: input.overallScore, scoreSources: input.scoreSources, workspaceCounts: counts ? { deviations: counts.deviation, assessed: counts.deviation + counts.passed } : undefined, workspaceDeviationKeys: deviationKeys, environment, policyEntries, reviews: reviewInputs, technicalPolicySources: policyRecords.map(record => ({ settingId: record.id, sources: record.policySourceEvidence ?? [] })), technicalFindingFields: input.results.flatMap(result => { const record = workRecordByOccurrence.get(result.sourceResultId); return record ? [{ resultProjectionId: result.resultProjectionId, fields: record.fields }] : []; }), policyScopeLimited: true, provenance: uniqueProvenance, priorityLimitPerDomain: 8 }; } export function buildClientReportProjection(input: ClientReportProjectionInput): ReportProjection { return buildReportProjection(clientReportInput(input)); }