Files
boc/packages/domain/src/common/ids.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

69 lines
2.5 KiB
TypeScript

/**
* Branded ID types for type safety
* Prevents mixing different ID types accidentally
*/
export type SessionId = string & { readonly __brand: 'SessionId' };
export type MissionId = string & { readonly __brand: 'MissionId' };
export type ArtifactId = string & { readonly __brand: 'ArtifactId' };
export type ObservationId = string & { readonly __brand: 'ObservationId' };
export type DecisionId = string & { readonly __brand: 'DecisionId' };
export type EvidenceId = string & { readonly __brand: 'EvidenceId' };
export type FindingId = string & { readonly __brand: 'FindingId' };
export type ReviewId = string & { readonly __brand: 'ReviewId' };
export type ActionId = string & { readonly __brand: 'ActionId' };
export type OutcomeId = string & { readonly __brand: 'OutcomeId' };
export type DecisionCaseId = string & { readonly __brand: 'DecisionCaseId' };
/**
* ID factory functions
* Ensures consistent ID format across the domain
*/
export const IdFactory = {
session: (date: Date, sequence: number): SessionId => {
const dateStr = date.toISOString().split('T')[0].replace(/-/g, '');
return `session_${dateStr}_${sequence.toString().padStart(6, '0')}` as SessionId;
},
mission: (date: Date, sequence: number): MissionId => {
const dateStr = date.toISOString().split('T')[0].replace(/-/g, '');
return `mission_${dateStr}_${sequence.toString().padStart(6, '0')}` as MissionId;
},
artifact: (sequence: number): ArtifactId => {
return `artifact_${sequence.toString().padStart(6, '0')}` as ArtifactId;
},
observation: (sequence: number): ObservationId => {
return `obs_${sequence.toString().padStart(6, '0')}` as ObservationId;
},
decision: (sequence: number): DecisionId => {
return `decision_${sequence.toString().padStart(6, '0')}` as DecisionId;
},
evidence: (sequence: number): EvidenceId => {
return `evidence_${sequence.toString().padStart(6, '0')}` as EvidenceId;
},
finding: (sequence: number): FindingId => {
return `finding_${sequence.toString().padStart(6, '0')}` as FindingId;
},
review: (sequence: number): ReviewId => {
return `review_${sequence.toString().padStart(6, '0')}` as ReviewId;
},
action: (sequence: number): ActionId => {
return `action_${sequence.toString().padStart(6, '0')}` as ActionId;
},
outcome: (sequence: number): OutcomeId => {
return `outcome_${sequence.toString().padStart(6, '0')}` as OutcomeId;
},
decisionCase: (sequence: number): DecisionCaseId => {
return `decision_${sequence.toString().padStart(6, '0')}` as DecisionCaseId;
}
};