import type { ResultContractExposureState, ResultContractResultType } from './result-contract-mapping'; import type { RiskAcceptance } from './risk-acceptance'; import type { EnvironmentObservation, ScannerReportSection } from './environment-context'; import type { SecurityScoringPolicy } from './security-scoring'; export type JsonPrimitive = string | number | boolean | null; export type JsonValue = JsonPrimitive | JsonValue[] | { [key: string]: JsonValue }; /** * result_type aus RESULT_CONTRACT 1.0.0 (docs/RESULT_CONTRACT.md). Additive * Facette, ausschließlich über src/domain/result-contract-mapping.ts abgeleitet. */ export type CanonicalResultType = ResultContractResultType; /** * exposure_state aus RESULT_CONTRACT 1.0.0, nur bei * CanonicalResultType = 'exposure_finding' belegt. */ export type CanonicalExposureState = ResultContractExposureState; export type CanonicalSeverity = 'critical' | 'high' | 'medium' | 'low' | 'info' | 'unknown'; export type CanonicalFindingStatus = | 'open' | 'failed' | 'passed' | 'resolved' | 'error' | 'unknown' | 'manual' | 'not-applicable' | 'not-run' | 'investigate'; export type CanonicalOutcome = | 'fail' | 'pass' | 'warning' | 'informational' | 'execution_error' | 'not_run' | 'not_applicable' | 'not_evaluated' | 'unknown'; export type CanonicalTechnicalExecutionState = 'completed' | 'failed' | 'not-run' | 'unknown'; export type MappingConfidenceLevel = 'high' | 'medium' | 'low' | 'unknown'; export type MappingDecisionSource = 'automatic' | 'user-confirmed' | 'source-native'; export interface MappingConfidence { level: MappingConfidenceLevel; score: number; reasons: string[]; } export interface MappingProvenance { decisionSource: MappingDecisionSource; confidence: MappingConfidence; mappingVersion: string; } export interface MappedValue { originalValue: JsonValue; normalizedValue: T | null; provenance: MappingProvenance; } export interface ToolIdentity { id: string; name: string; version?: string; } export interface ProcessingVersion { parserId: string; parserVersion: string; profileId: string; profileVersion: string; mappingVersion: string; /** Additive Felder; bei Altdaten aus dem versionierten Manifest aufloesbar. */ normalizationVersion?: string; presentationVersion?: string; compatibilityKey?: string; changeClass?: 'presentation-only' | 'compatible' | 'semantic-breaking'; reimportRequired?: boolean; } export interface AssessmentProject { id: string; name: string; description?: string; createdAt: string; updatedAt: string; attributes: Record; } export interface Assessment { id: string; projectId: string; name: string; description?: string; scope?: string; /** Fachlicher Stichtag dieses vollständigen Mandanten-Bewertungsstands. */ effectiveAt?: string; /** Persisted with the assessment JSON; absent historical values resolve to immutable v1. */ scoringPolicy?: SecurityScoringPolicy; createdAt: string; updatedAt: string; } export interface ScanRun { id: string; assessmentId: string; sequence: number; label: string; tool: ToolIdentity; startedAt?: string; completedAt?: string; importedAt: string; /** Reimport history: replaced runs remain immutable and auditable, but are no longer active projections. */ supersedesScanRunId?: string; supersededByScanRunId?: string; supersededAt?: string; } export type SourceArtifactContent = | { kind: 'embedded'; bytesBase64: string } | { kind: 'external'; storageKey: string } | { kind: 'not-retained'; reason: string }; export interface ImportFileRecord { id: string; scanRunId: string; fileName: string; mediaType?: string; format: string; sizeBytes: number; lastModifiedAt?: string; sha256?: string; importedAt: string; detectedTool: ToolIdentity; detection: MappingConfidence; processedWith: ProcessingVersion; sourceArtifact: SourceArtifactContent; /** Persistent, content-free outcome of preserving client work during reimport. */ reimportReviewTransfer?: { replacesScanRunId: string; transferred: number; retainedByStableIdentity: number; unresolved: number; }; } export interface SourceTableRecord { id: string; importFileId: string; name: string; index: number; hidden?: boolean; rowCount: number; columnCount: number; attributes: Record; rows?: SourceTableRow[]; } export interface SourceTableRow { index: number; fields: OriginalField[]; /** Der Bericht markiert diese Zeile selbst (z. B. CIS-CAT: ``). */ highlighted?: boolean; } export interface FrameworkReference { framework: string; controlId: string; version?: string; title?: string; url?: string; } export type FindingIdentityStrategy = 'tool-rule-id' | 'framework-control' | 'unresolved'; export interface FindingIdentity { version: 1; strategy: FindingIdentityStrategy; durable: boolean; evidence: string[]; } export interface FindingDefinition { id: string; canonicalKey: string; identity?: FindingIdentity; title: string; description?: string; category?: string; recommendation?: string; frameworkReferences: FrameworkReference[]; createdAt: string; updatedAt: string; } export interface OriginalField { key: string; label: string; value: JsonValue; rawValue?: string; path?: string; columnIndex?: number; } export interface SourcePosition { rowIndex?: number; columnIndex?: number; cellReference?: string; objectPath?: string; elementSelector?: string; } export interface SourceFindingIdentity { tool: ToolIdentity; originalRuleId?: string; canonicalRuleId?: string; originalTitle?: string; } export type CanonicalFieldRole = | 'rule-id' | 'title' | 'description' | 'category' | 'severity' | 'status' | 'score' | 'asset' | 'evidence' | 'recommendation' | 'framework-reference' | 'additional'; export interface FieldMapping { targetRole: CanonicalFieldRole; sourceFieldKeys: string[]; normalizedValue: JsonValue; provenance: MappingProvenance; } export interface FindingOccurrence { id: string; definitionId: string; scanRunId: string; importFileId: string; sourceTableId?: string; observedAt?: string; sourceIdentity: SourceFindingIdentity; sourcePosition: SourcePosition; originalFields: OriginalField[]; fieldMappings: FieldMapping[]; severity: MappedValue; status: MappedValue; outcome?: MappedValue; technicalExecutionState?: MappedValue; score?: MappedValue; affectedAsset?: MappedValue; /** * RESULT_CONTRACT-Facetten. Wie bei outcome/technicalExecutionState gilt: * ein hier gesetzter Wert wird beim Persistieren übernommen; fehlt er, wird * er aus tool_id sowie outcome/technicalExecutionState über * src/domain/result-contract-mapping.ts abgeleitet. Kein Producer setzt * diese Felder derzeit explizit. */ resultType?: CanonicalResultType; isIoe?: boolean; ioeRuleId?: string; ioeRuleVersion?: string; ioeDerivationMethod?: string; exposureState?: CanonicalExposureState; /** * Version des Feld-Mappings (dataset.mapping.mappingProfile.version), das * dieses Vorkommen erzeugt hat. Wird beim Persistieren übernommen; fehlt * sie, wird sie aus processedWith.mappingVersion der zugehörigen * ImportFileRecord übernommen. Ermöglicht, einen historischen Fund auf sein * damaliges Mapping zurückzuführen. */ mappingRuleVersion?: string; } export type EvidenceKind = 'text' | 'table' | 'object' | 'reference' | 'attachment'; export interface EvidenceRecord { id: string; occurrenceId: string; kind: EvidenceKind; title?: string; value: JsonValue; sourceFieldKeys: string[]; sourcePosition?: SourcePosition; } export type ReviewWorkflowStatus = 'unreviewed' | 'open' | 'in-progress' | 'accepted' | 'deferred' | 'resolved' | 'not-relevant'; export type ReviewPriority = 'critical' | 'high' | 'medium' | 'low' | 'none'; export type ReviewTarget = | { kind: 'definition'; definitionId: string } | { kind: 'occurrence'; occurrenceId: string }; export interface FindingReview { id: string; target: ReviewTarget; workflowStatus: ReviewWorkflowStatus; /** Exact FindingReader label when it is more specific than the canonical workflow state. */ workflowLabel?: string; priority: ReviewPriority; includeInActionPlan: boolean; owner?: string; dueAt?: string; comment?: string; prerequisites?: string; requiredAccess?: string; nextStep?: string; acceptanceEvidence?: string; riskAcceptance?: RiskAcceptance; markers: string[]; createdAt: string; updatedAt: string; revision: number; /** Audit reference when client-owned review data was carried to a reimported target. */ transferredFromReviewId?: string; transferredAt?: string; } export type DiagnosticSeverity = 'info' | 'warning' | 'error'; export interface ImportDiagnostic { id: string; importFileId: string; sourceTableId?: string; severity: DiagnosticSeverity; code: string; message: string; sourcePosition?: SourcePosition; details?: JsonValue; } export interface CanonicalAssessmentModel { /** Latest stored reference derivation per scan; canonical source facts remain unchanged. */ referenceRuns?: import('./reference-recognition').ReferenceRecognitionRun[]; schemaVersion: 1; project: AssessmentProject; assessment: Assessment; scanRuns: ScanRun[]; importFiles: ImportFileRecord[]; sourceTables: SourceTableRecord[]; /** Additive scanner context; absent on canonical model records created before Phase 13C. */ reportSections?: ScannerReportSection[]; /** Typed scan-level observations; absent on canonical model records created before Phase 13C. */ environmentObservations?: EnvironmentObservation[]; findingDefinitions: FindingDefinition[]; findingOccurrences: FindingOccurrence[]; evidence: EvidenceRecord[]; reviews: FindingReview[]; diagnostics: ImportDiagnostic[]; }