357 lines
9.9 KiB
TypeScript
357 lines
9.9 KiB
TypeScript
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<T extends JsonValue> {
|
|
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<string, JsonValue>;
|
|
}
|
|
|
|
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<string, JsonValue>;
|
|
rows?: SourceTableRow[];
|
|
}
|
|
|
|
export interface SourceTableRow {
|
|
index: number;
|
|
fields: OriginalField[];
|
|
/** Der Bericht markiert diese Zeile selbst (z. B. CIS-CAT: `<tr class="evaluated">`). */
|
|
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<CanonicalSeverity>;
|
|
status: MappedValue<CanonicalFindingStatus>;
|
|
outcome?: MappedValue<CanonicalOutcome>;
|
|
technicalExecutionState?: MappedValue<CanonicalTechnicalExecutionState>;
|
|
score?: MappedValue<number>;
|
|
affectedAsset?: MappedValue<string>;
|
|
/**
|
|
* 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[];
|
|
}
|
|
|