Files
boc/packages/domain/src/common/value-objects.ts
T
Bernt 02b51d7814 PR-002: Persistence Adapters — in-memory, zero external dependencies
- Repository interfaces defined by domain (@landvex/domain)
- 6 in-memory adapters: Session, Mission, DecisionCase, Artifact, EventStore, UnitOfWork
- 9 tests verifying adapter contracts
- Domain unchanged — infrastructure depends on domain, never reverse
- ADR-006: In-Memory Adapters for Testing

Definition of Done met:
- All adapters compile against domain interfaces
- Unit tests pass (9/9)
- No PostgreSQL, S3, Express, AI in this PR
- Ready for PR-003: PostgreSQL adapters
2026-07-02 14:59:37 +00:00

105 lines
2.2 KiB
TypeScript

/**
* 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
};