Critical: Follow Archstone Conventions
Everything you know about DDD patterns may differ from how Archstone implements them. Always follow the rules below — do not apply generic DDD patterns that contradict them.
When working with Archstone:
- Check
node_modules/archstone/for the installed version - All entities must extend
Entity<Props>orAggregateRoot<Props>— never use plain classes - All value objects must extend
ValueObject<Props> - Use cases must implement
UseCase<Input, Output>and never throw — always returnEither - Repository contracts are interfaces only — implementations belong in infrastructure
- Domain events are raised inside aggregates and dispatched after persistence — never before
- Use
UniqueEntityIdfor all entity identifiers — never a plainstring - The left side of
Eithermustimplement UseCaseError— notextend Error
If you are unsure about a pattern, check Conventions Reference before writing code.
Layer Boundaries
Always respect the layer rules. Never place infrastructure code in domain/, and never import concrete implementations into use cases.
See Layer Rules for details.
Entities & Aggregates
Use a static create() factory. Pass id as the second constructor argument. Use Optional<T, K> for auto-generated fields. See Entity Patterns.
Value Objects
Use a static create() factory with validation. Value object create() may throw — wrap calls inside use cases with try/catch and return left(). See Value Object Patterns.
Use Cases
Implement UseCase<Input, Output>. Return left() for errors, right() for success. Error classes must implement UseCaseError. See Use Case Patterns.
Repository Contracts
Define as interfaces only. Use Repository<T> or compose Findable, Creatable, Saveable, Deletable. Note: findById takes string — pass entity.id.toValue(). See Repository Patterns.
Domain Events
Raise inside the aggregate via addDomainEvent(). Dispatch after persistence via DomainEvents.dispatchEventsForAggregate(aggregate.id). Define handlers as classes implementing EventHandler<T>. See Domain Event Patterns.
Testing
Use bun:test. Co-locate test files as *.spec.ts. Use in-memory repository implementations. See Testing Patterns.
References
- Conventions — quick rules summary
- Imports — import paths for all exports
- Layers — layer boundary rules
- Entity Patterns — Entity and AggregateRoot examples
- Value Object Patterns — ValueObject examples
- Use Case Patterns — UseCase and Either examples
- Repository Patterns — repository interface and in-memory examples
- Domain Event Patterns — EventHandler and dispatch examples
- Testing Patterns — bun:test and in-memory repo examples