Files
boc/packages/infrastructure/src/adapters/in-memory-event-store.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

46 lines
1.2 KiB
TypeScript

/**
* In-Memory Event Store
*
* Adapter: Implements EventStore using an array.
* Purpose: Testing, development, CI/CD pipelines.
* NOT for production.
*
* ADR-003: Event Sourcing for traceability
* - Events are immutable facts
* - State is a projection of event history
* - Replay reconstructs any past state
*/
import { DomainEvent } from '@landvex/domain';
import { EventStore } from '../repositories/repository-interfaces';
export class InMemoryEventStore implements EventStore {
private events: DomainEvent[] = [];
async append(event: DomainEvent): Promise<void> {
this.events.push(event);
}
async getEvents(aggregateId: string): Promise<DomainEvent[]> {
return this.events
.filter(e => e.aggregateId === aggregateId)
.sort((a, b) => a.occurredAt.getTime() - b.occurredAt.getTime());
}
async getAllEvents(since?: Date): Promise<DomainEvent[]> {
let filtered = this.events;
if (since) {
filtered = filtered.filter(e => e.occurredAt >= since);
}
return filtered.sort((a, b) => a.occurredAt.getTime() - b.occurredAt.getTime());
}
clear(): void {
this.events = [];
}
count(): number {
return this.events.length;
}
}