/** * Value Objects - immutable, compared by value, not identity */ export interface GeoLocation { readonly lat: number; readonly lng: number; readonly accuracy?: number; // meters } export interface BoundingBox { readonly x: number; readonly y: number; readonly width: number; readonly height: number; } export interface Confidence { readonly value: number; // 0.0 to 1.0 } export interface Hash { readonly algorithm: 'sha256'; readonly value: string; } export interface StorageUri { readonly protocol: 's3' | 'r2' | 'file'; readonly bucket?: string; readonly path: string; } export interface Version { readonly major: number; readonly minor: number; readonly patch: number; } export interface TimeRange { readonly start: Date; readonly end: Date; } export interface DeviceInfo { readonly model: string; readonly os: string; readonly appVersion: string; } export interface ExifData { readonly device?: string; readonly iso?: number; readonly exposure?: string; readonly focalLength?: string; readonly timestamp?: Date; } export interface AssetMetadata { readonly exif: ExifData; readonly gps: GeoLocation; readonly device: DeviceInfo; } export interface BusinessImpact { readonly risk: string; readonly cost: string; readonly time: string; readonly opportunity: string; } export interface EvidenceContext { readonly historicalData?: boolean; readonly weatherData?: boolean; readonly trafficData?: boolean; readonly gisData?: boolean; } export interface QualityIssue { readonly type: 'blur' | 'duplicate' | 'bad_gps' | 'low_resolution' | 'missing_metadata' | 'wrong_timestamp' | 'occlusion'; readonly severity: Severity; readonly description: string; } export interface ValidationResult { readonly valid: boolean; readonly issues: QualityIssue[]; } export type Severity = 'low' | 'medium' | 'high' | 'critical'; export type PriorityValue = 'low' | 'medium' | 'high' | 'urgent'; export const Severity = { LOW: 'low' as Severity, MEDIUM: 'medium' as Severity, HIGH: 'high' as Severity, CRITICAL: 'critical' as Severity }; export const Priority = { LOW: 'low' as PriorityValue, MEDIUM: 'medium' as PriorityValue, HIGH: 'high' as PriorityValue, URGENT: 'urgent' as PriorityValue };