@vytches/ddd-aggregates 0.30.0 → 0.31.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LLMGUIDE.md +99 -31
- package/README.md +5 -1
- package/dist/aggregate-interfaces.d.ts +16 -184
- package/dist/capabilities/audit-capability.d.ts +1 -1
- package/dist/capabilities/event-sourcing-capability.d.ts +1 -1
- package/dist/capabilities/snapshot-capability.d.ts +1 -1
- package/dist/capabilities/versioning-capability.d.ts +15 -2
- package/dist/core/aggregate-root.builder.d.ts +1 -1
- package/dist/core/aggregate-root.d.ts +171 -5
- package/dist/core/aggregate-utilities.d.ts +2 -2
- package/dist/core/entity.d.ts +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +298 -139
- package/package.json +8 -7
package/LLMGUIDE.md
CHANGED
|
@@ -41,44 +41,61 @@ class Order extends AggregateRoot<string> {
|
|
|
41
41
|
// Usage
|
|
42
42
|
const order = Order.create('c-1', 500);
|
|
43
43
|
const events = order.getDomainEvents(); // [{ eventName: 'OrderCreated', ... }]
|
|
44
|
-
order.
|
|
44
|
+
order.getDomainEvents() === events; // true — same array reference until the next mutation
|
|
45
|
+
order.commit(); // clear pending events after saving; getDomainEvents() now returns a new, empty array
|
|
45
46
|
```
|
|
46
47
|
|
|
47
48
|
## Key API
|
|
48
49
|
|
|
49
|
-
| Export
|
|
50
|
-
|
|
|
51
|
-
| `AggregateRoot<TId>`
|
|
52
|
-
| `Entity<TId>`
|
|
53
|
-
| `AggregateBuilder<TId>`
|
|
54
|
-
| `aggregateBuilder(params)`
|
|
55
|
-
| `AggregateError`
|
|
56
|
-
| `SnapshotCapability`
|
|
57
|
-
| `AuditCapability`
|
|
58
|
-
| `VersioningCapability`
|
|
59
|
-
| `EventSourcingCapability`
|
|
60
|
-
| `asSnapshotAggregate(agg)`
|
|
61
|
-
| `asAuditAggregate(agg)`
|
|
62
|
-
| `
|
|
63
|
-
| `
|
|
64
|
-
| `
|
|
65
|
-
| `
|
|
50
|
+
| Export | Kind | Description |
|
|
51
|
+
| ------------------------------------------- | -------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
52
|
+
| `AggregateRoot<TId>` | class | Base aggregate root; manages version, events, capabilities — the _transactional_ root |
|
|
53
|
+
| `Entity<TId>` | abstract class | Base for **non-root** domain entities (VF-CANON-001) — identity-based equality, no version/event machinery. Use for `OrderLine`, inner aggregate entities |
|
|
54
|
+
| `AggregateBuilder<TId>` | class | Fluent builder for constructing aggregates with capabilities |
|
|
55
|
+
| `aggregateBuilder(params)` | function | Shorthand factory for `AggregateBuilder.create(params)` |
|
|
56
|
+
| `AggregateError` | class | Domain error for aggregate-level failures |
|
|
57
|
+
| `SnapshotCapability` | class | Enables snapshot creation and restoration |
|
|
58
|
+
| `AuditCapability` | class | Attaches an audit log to every event applied |
|
|
59
|
+
| `VersioningCapability` | class | Registers event upcasters for schema evolution |
|
|
60
|
+
| `EventSourcingCapability` | class | Integrates with `IEventStore` for persistence |
|
|
61
|
+
| `asSnapshotAggregate(agg)` | function | Casts aggregate, throws if no `SnapshotCapability` |
|
|
62
|
+
| `asAuditAggregate(agg)` | function | Casts aggregate, throws if no `AuditCapability` |
|
|
63
|
+
| `asVersioningAggregate(agg)` | function | Casts aggregate, throws if no `VersioningCapability` |
|
|
64
|
+
| `asEventSourcingAggregate(agg)` | function | Casts aggregate, throws if no `EventSourcingCapability` |
|
|
65
|
+
| `tryAsSnapshotAggregate(agg)` | function | Non-throwing sibling of `asSnapshotAggregate`; returns `Result.ok(aggregate)` or `Result.fail(AggregateError)` instead of throwing |
|
|
66
|
+
| `tryAsAuditAggregate(agg)` | function | Non-throwing sibling of `asAuditAggregate`; returns a `Result<AggregateWithAuditCapability<TId>, AggregateError>` |
|
|
67
|
+
| `tryAsVersioningAggregate(agg)` | function | Non-throwing sibling of `asVersioningAggregate`; returns a `Result<AggregateWithVersioningCapability<TId>, AggregateError>` |
|
|
68
|
+
| `tryAsEventSourcingAggregate(agg)` | function | Non-throwing sibling of `asEventSourcingAggregate`; returns a `Result<AggregateWithEventSourcingCapability<TId>, AggregateError>` |
|
|
69
|
+
| `hasAllCapabilities(agg, [...])` | function | Returns `true` if aggregate has every listed capability |
|
|
70
|
+
| `getAggregateCapabilities(agg)` | function | Returns string array of capability type names |
|
|
71
|
+
| `AggregateWithSnapshotCapability<TId>` | type | Type-safe alias for snapshot-capable aggregates; return type of `asSnapshotAggregate`/`tryAsSnapshotAggregate` |
|
|
72
|
+
| `AggregateWithAuditCapability<TId>` | type | Type-safe alias for audit-capable aggregates; return type of `asAuditAggregate`/`tryAsAuditAggregate` |
|
|
73
|
+
| `AggregateWithVersioningCapability<TId>` | type | Type-safe alias for versioning-capable aggregates; return type of `asVersioningAggregate`/`tryAsVersioningAggregate` |
|
|
74
|
+
| `AggregateWithEventSourcingCapability<TId>` | type | Type-safe alias for event-sourcing-capable aggregates; return type of `asEventSourcingAggregate`/`tryAsEventSourcingAggregate` |
|
|
75
|
+
| `IAggregateRoot<TId>` | interface | Full contract for aggregates |
|
|
76
|
+
| `IAggregateCapability` | interface | Base contract every capability implements: `attach(aggregate)` (required) + `detach?()` (optional). `SnapshotCapability`, `AuditCapability`, `VersioningCapability`, `EventSourcingCapability` all satisfy it |
|
|
77
|
+
| `IAggregateEventHandler<T>` | interface | Callable shape `(payload: T, metadata?) => void` — the handler function type registered via `registerEventHandler(type, fn)` |
|
|
78
|
+
|
|
79
|
+
> **BREAKING (v0.31.0):** `IAggregateBuilder<TId>` was removed — it was exported
|
|
80
|
+
> but shape-incompatible with the concrete `AggregateBuilder` class. Use
|
|
81
|
+
> `AggregateBuilder` directly for `withSnapshots()`, `withVersioning()`,
|
|
82
|
+
> `withEventSourcing()`, `withAudit()`, `withCustomCapability()`, `build()`.
|
|
66
83
|
|
|
67
84
|
### `AggregateRoot` method reference
|
|
68
85
|
|
|
69
|
-
| Method | Description
|
|
70
|
-
| --------------------------------------- |
|
|
71
|
-
| `apply(eventType, payload?, metadata?)` | Record a domain event, increment version, call handler
|
|
72
|
-
| `loadFromHistory(events)` | Replay historical events to restore state without accumulating new events
|
|
73
|
-
| `getDomainEvents()` | Return readonly array of uncommitted events since last `commit()`
|
|
74
|
-
| `commit()` | Clear uncommitted events; call after persisting to storage
|
|
75
|
-
| `hasChanges()` | `true` if there are uncommitted events
|
|
76
|
-
| `getVersion()` | Current version after all applied events
|
|
77
|
-
| `getInitialVersion()` | Version when last loaded from storage (for optimistic locking)
|
|
78
|
-
| `addCapability(cap)` | Attach a capability; calls `cap.attach(this)`
|
|
79
|
-
| `getCapability(CapClass)` | Retrieve capability by constructor, returns `undefined` if absent
|
|
80
|
-
| `hasCapability(CapClass)` | Type-safe capability presence check
|
|
81
|
-
| `registerEventHandler(type, fn)` | Protected; wire event name to state mutation function
|
|
86
|
+
| Method | Description |
|
|
87
|
+
| --------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
88
|
+
| `apply(eventType, payload?, metadata?)` | Record a domain event, increment version, call handler |
|
|
89
|
+
| `loadFromHistory(events)` | Replay historical events to restore state without accumulating new events |
|
|
90
|
+
| `getDomainEvents()` | Return readonly, deep-frozen array of uncommitted events since last `commit()`. Same array reference on repeat calls — rebuilt only on the next mutation (`apply`/`commit`/`loadFromHistory`/`transformDomainEvents`) |
|
|
91
|
+
| `commit()` | Clear uncommitted events; call after persisting to storage |
|
|
92
|
+
| `hasChanges()` | `true` if there are uncommitted events |
|
|
93
|
+
| `getVersion()` | Current version after all applied events |
|
|
94
|
+
| `getInitialVersion()` | Version when last loaded from storage (for optimistic locking) |
|
|
95
|
+
| `addCapability(cap)` | Attach a capability; calls `cap.attach(this)` |
|
|
96
|
+
| `getCapability(CapClass)` | Retrieve capability by constructor, returns `undefined` if absent |
|
|
97
|
+
| `hasCapability(CapClass)` | Type-safe capability presence check |
|
|
98
|
+
| `registerEventHandler(type, fn)` | Protected; wire event name to state mutation function |
|
|
82
99
|
|
|
83
100
|
## Patterns
|
|
84
101
|
|
|
@@ -136,6 +153,57 @@ if (hasAllCapabilities(order, [AuditCapability])) {
|
|
|
136
153
|
}
|
|
137
154
|
```
|
|
138
155
|
|
|
156
|
+
### Composing multiple capabilities and narrowing with `tryAs*` helpers
|
|
157
|
+
|
|
158
|
+
Build one aggregate with two capabilities (versioning + event sourcing), then
|
|
159
|
+
narrow it back to each capability-specific type with the non-throwing `tryAs*`
|
|
160
|
+
variants — useful in application-layer code where a missing capability should be
|
|
161
|
+
handled as a `Result`, not an exception.
|
|
162
|
+
|
|
163
|
+
```typescript
|
|
164
|
+
import {
|
|
165
|
+
AggregateBuilder,
|
|
166
|
+
VersioningCapability,
|
|
167
|
+
EventSourcingCapability,
|
|
168
|
+
tryAsVersioningAggregate,
|
|
169
|
+
tryAsEventSourcingAggregate,
|
|
170
|
+
type AggregateWithVersioningCapability,
|
|
171
|
+
type AggregateWithEventSourcingCapability,
|
|
172
|
+
} from '@vytches/ddd-aggregates';
|
|
173
|
+
import { EntityId } from '@vytches/ddd-value-objects';
|
|
174
|
+
|
|
175
|
+
const order = AggregateBuilder.create({ id: EntityId.create() })
|
|
176
|
+
.withVersioning()
|
|
177
|
+
.withEventSourcing()
|
|
178
|
+
.build(Order);
|
|
179
|
+
|
|
180
|
+
// Narrow to versioning-capable: register an upcaster for an old event shape.
|
|
181
|
+
const versioningResult = tryAsVersioningAggregate(order);
|
|
182
|
+
if (versioningResult.isSuccess) {
|
|
183
|
+
const versioned: AggregateWithVersioningCapability<string> =
|
|
184
|
+
versioningResult.value;
|
|
185
|
+
versioned
|
|
186
|
+
.getCapability(VersioningCapability)!
|
|
187
|
+
.registerUpcaster('OrderCreated', 1, {
|
|
188
|
+
upcast: (payload: { amount: number }) => ({
|
|
189
|
+
...payload,
|
|
190
|
+
currency: 'USD',
|
|
191
|
+
}),
|
|
192
|
+
});
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
// Narrow to event-sourcing-capable: persist to the configured event store.
|
|
196
|
+
const eventSourcingResult = tryAsEventSourcingAggregate(order);
|
|
197
|
+
if (eventSourcingResult.isSuccess) {
|
|
198
|
+
const sourced: AggregateWithEventSourcingCapability<string> =
|
|
199
|
+
eventSourcingResult.value;
|
|
200
|
+
await sourced.getCapability(EventSourcingCapability)!.saveToEventStore();
|
|
201
|
+
} else {
|
|
202
|
+
// eventSourcingResult.error is an AggregateError — handle without throwing.
|
|
203
|
+
console.error(eventSourcingResult.error.message);
|
|
204
|
+
}
|
|
205
|
+
```
|
|
206
|
+
|
|
139
207
|
## Anti-Patterns
|
|
140
208
|
|
|
141
209
|
**Mutating state directly instead of using `apply()`.** Assigning
|
package/README.md
CHANGED
|
@@ -181,7 +181,11 @@ class OrderLine extends Entity<string> {
|
|
|
181
181
|
| `IAggregateCapability` | interface | Base capability contract |
|
|
182
182
|
| `IAggregateConstructorParams<TId>` | interface | Constructor parameter shape for aggregates |
|
|
183
183
|
| `IAggregateEventHandler` | interface | Event handler registration contract |
|
|
184
|
-
|
|
184
|
+
|
|
185
|
+
> **BREAKING (v0.31.0):** `IAggregateBuilder` was removed. It was
|
|
186
|
+
> shape-incompatible with the concrete `AggregateBuilder` class (a broken public
|
|
187
|
+
> interface is worse than none). Use the `AggregateBuilder` class directly for
|
|
188
|
+
> the builder's fluent contract.
|
|
185
189
|
|
|
186
190
|
### Utility Types
|
|
187
191
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Capability, CapabilityConstructor, EntityId, IAggregateSnapshot, IAuditEvent, IDomainEvent, IEventMetadata,
|
|
1
|
+
import { Capability, CapabilityConstructor, EntityId, IAggregateSnapshot, IAuditEvent, IDomainEvent, IEventMetadata, IEventUpcaster } from '@vytches/ddd-contracts';
|
|
2
2
|
/**
|
|
3
3
|
* Core interface for aggregate root functionality.
|
|
4
4
|
* Provides the foundation for domain aggregates with event sourcing, versioning, and capability management.
|
|
@@ -80,6 +80,21 @@ export interface IAggregateConstructorParams<TId = string> {
|
|
|
80
80
|
* Leave undefined for "no limit" (preserves backward compatibility).
|
|
81
81
|
*/
|
|
82
82
|
maxEvents?: number;
|
|
83
|
+
/**
|
|
84
|
+
* VF-023 (D-4, AC6, non-breaking addition): controls what happens when
|
|
85
|
+
* `apply()` (live) or `loadFromHistory()` (replay) processes an event for
|
|
86
|
+
* which no handler was registered via `registerEventHandler()`.
|
|
87
|
+
*
|
|
88
|
+
* - `"warn"` (default): the event is still recorded/replayed, but a
|
|
89
|
+
* warning is logged via the library's internal logger. Preserves the
|
|
90
|
+
* previous behavior's intent (missing handlers did not throw) without
|
|
91
|
+
* silently swallowing the condition.
|
|
92
|
+
* - `"throw"`: fail fast instead — useful in tests or strict environments
|
|
93
|
+
* where a missing handler indicates a real bug.
|
|
94
|
+
*
|
|
95
|
+
* Leave undefined for the default `"warn"` behavior (backward compatible).
|
|
96
|
+
*/
|
|
97
|
+
onMissingHandler?: 'warn' | 'throw';
|
|
83
98
|
}
|
|
84
99
|
/**
|
|
85
100
|
* Base interface for all aggregate capabilities.
|
|
@@ -174,36 +189,6 @@ export interface IMiddlewareCapability extends IAggregateCapability {
|
|
|
174
189
|
*/
|
|
175
190
|
use(middleware: EventAggregateMiddleware): this;
|
|
176
191
|
}
|
|
177
|
-
/**
|
|
178
|
-
* Builder interface for creating aggregates with capabilities.
|
|
179
|
-
* Provides fluent API for configuring aggregate features before construction.
|
|
180
|
-
*/
|
|
181
|
-
export interface IAggregateBuilder<TId> {
|
|
182
|
-
/**
|
|
183
|
-
* Adds snapshot capability
|
|
184
|
-
*/
|
|
185
|
-
withSnapshots<TState = unknown, TMeta = unknown>(): this;
|
|
186
|
-
/**
|
|
187
|
-
* Adds versioning capability
|
|
188
|
-
*/
|
|
189
|
-
withVersioning(): this;
|
|
190
|
-
/**
|
|
191
|
-
* Adds event sourcing capability
|
|
192
|
-
*/
|
|
193
|
-
withEventSourcing(eventStore?: IEventStore): this;
|
|
194
|
-
/**
|
|
195
|
-
* Adds audit capability
|
|
196
|
-
*/
|
|
197
|
-
withAudit(): this;
|
|
198
|
-
/**
|
|
199
|
-
* Adds custom capability
|
|
200
|
-
*/
|
|
201
|
-
withCustomCapability<T extends IAggregateCapability>(name: string, capability: T): this;
|
|
202
|
-
/**
|
|
203
|
-
* Builds the aggregate with all configured capabilities
|
|
204
|
-
*/
|
|
205
|
-
build(): IAggregateRoot<TId>;
|
|
206
|
-
}
|
|
207
192
|
/**
|
|
208
193
|
* Handler function for processing aggregate events.
|
|
209
194
|
* Used internally by aggregates to handle domain events.
|
|
@@ -243,156 +228,3 @@ export type AggregateIdType<T> = T extends IAggregateRoot<infer TId> ? TId : nev
|
|
|
243
228
|
export type AggregateWithCapabilities<TId, TCapabilities extends CapabilityName[]> = IAggregateRoot<TId> & {
|
|
244
229
|
[K in TCapabilities[number] as `getCapability`]: (name: K) => K extends 'snapshot' ? ISnapshotCapability : K extends 'versioning' ? IVersioningCapability : K extends 'eventSourcing' ? IEventSourcingCapability : K extends 'audit' ? IAuditCapability : K extends 'middleware' ? IMiddlewareCapability : IAggregateCapability;
|
|
245
230
|
};
|
|
246
|
-
/**
|
|
247
|
-
* Factory interface for creating and rebuilding aggregates.
|
|
248
|
-
* Provides standard methods for aggregate lifecycle management.
|
|
249
|
-
* @template TId - The type of the aggregate ID value (string, number, etc.)
|
|
250
|
-
*/
|
|
251
|
-
export interface IAggregateFactory<TId = string, TAggregate extends IAggregateRoot<TId> = IAggregateRoot<TId>> {
|
|
252
|
-
/**
|
|
253
|
-
* Creates a new aggregate instance
|
|
254
|
-
*/
|
|
255
|
-
create(id: EntityId<TId>, ...args: unknown[]): TAggregate;
|
|
256
|
-
/**
|
|
257
|
-
* Rebuilds aggregate from events
|
|
258
|
-
*/
|
|
259
|
-
fromEvents(id: EntityId<TId>, events: IDomainEvent[]): TAggregate;
|
|
260
|
-
/**
|
|
261
|
-
* Rebuilds aggregate from snapshot and subsequent events
|
|
262
|
-
*/
|
|
263
|
-
fromSnapshot<TState, TMeta>(snapshot: IAggregateSnapshot<TState, TMeta>, events: IDomainEvent[]): TAggregate;
|
|
264
|
-
}
|
|
265
|
-
/**
|
|
266
|
-
* Interface for validating aggregate state and operations.
|
|
267
|
-
* Enables business rule validation at the aggregate level.
|
|
268
|
-
*/
|
|
269
|
-
export interface IAggregateValidator<TAggregate extends IAggregateRoot<unknown>> {
|
|
270
|
-
/**
|
|
271
|
-
* Validates aggregate state
|
|
272
|
-
*/
|
|
273
|
-
validate(aggregate: TAggregate): ValidationResult;
|
|
274
|
-
/**
|
|
275
|
-
* Validates aggregate before applying event
|
|
276
|
-
*/
|
|
277
|
-
validateBeforeEvent(aggregate: TAggregate, event: IDomainEvent): ValidationResult;
|
|
278
|
-
}
|
|
279
|
-
/**
|
|
280
|
-
* Result of aggregate validation operation.
|
|
281
|
-
* Contains validation status and any error details.
|
|
282
|
-
*/
|
|
283
|
-
export interface ValidationResult {
|
|
284
|
-
/** Whether the validation passed */
|
|
285
|
-
isValid: boolean;
|
|
286
|
-
/** List of validation errors if any */
|
|
287
|
-
errors: IValidationError[];
|
|
288
|
-
}
|
|
289
|
-
/**
|
|
290
|
-
* Represents a single validation error.
|
|
291
|
-
* Provides details about what failed validation and why.
|
|
292
|
-
*/
|
|
293
|
-
export interface IValidationError {
|
|
294
|
-
/** The field or property that failed validation */
|
|
295
|
-
field: string;
|
|
296
|
-
/** Human-readable error message */
|
|
297
|
-
message: string;
|
|
298
|
-
/** Optional error code for programmatic handling */
|
|
299
|
-
code?: string;
|
|
300
|
-
}
|
|
301
|
-
/**
|
|
302
|
-
* Capability for caching aggregate data.
|
|
303
|
-
* Provides key-value storage with TTL support for performance optimization.
|
|
304
|
-
*/
|
|
305
|
-
export interface ICachingCapability extends IAggregateCapability {
|
|
306
|
-
/**
|
|
307
|
-
* Gets cached value
|
|
308
|
-
*/
|
|
309
|
-
get<T>(key: string): T | undefined;
|
|
310
|
-
/**
|
|
311
|
-
* Sets cached value
|
|
312
|
-
*/
|
|
313
|
-
set<T>(key: string, value: T, ttl?: number): void;
|
|
314
|
-
/**
|
|
315
|
-
* Clears all cached values
|
|
316
|
-
*/
|
|
317
|
-
clear(): void;
|
|
318
|
-
/**
|
|
319
|
-
* Invalidates specific cached value
|
|
320
|
-
*/
|
|
321
|
-
invalidate(key: string): void;
|
|
322
|
-
}
|
|
323
|
-
/**
|
|
324
|
-
* Capability for collecting aggregate metrics.
|
|
325
|
-
* Enables monitoring and observability of aggregate operations.
|
|
326
|
-
*/
|
|
327
|
-
export interface IMetricsCapability extends IAggregateCapability {
|
|
328
|
-
/**
|
|
329
|
-
* Records a metric
|
|
330
|
-
*/
|
|
331
|
-
record(name: string, value: number, tags?: Record<string, string>): void;
|
|
332
|
-
/**
|
|
333
|
-
* Increments a counter
|
|
334
|
-
*/
|
|
335
|
-
increment(name: string, tags?: Record<string, string>): void;
|
|
336
|
-
/**
|
|
337
|
-
* Records timing information
|
|
338
|
-
*/
|
|
339
|
-
timing(name: string, duration: number, tags?: Record<string, string>): void;
|
|
340
|
-
/**
|
|
341
|
-
* Gets recorded metrics
|
|
342
|
-
*/
|
|
343
|
-
getMetrics(): MetricData[];
|
|
344
|
-
}
|
|
345
|
-
/**
|
|
346
|
-
* Represents a single metric data point.
|
|
347
|
-
* Contains metric information with optional tags and timestamp.
|
|
348
|
-
*/
|
|
349
|
-
export interface MetricData {
|
|
350
|
-
/** Metric name */
|
|
351
|
-
name: string;
|
|
352
|
-
/** Metric value */
|
|
353
|
-
value: number;
|
|
354
|
-
/** Type of metric */
|
|
355
|
-
type: 'counter' | 'gauge' | 'timing';
|
|
356
|
-
/** Optional tags for metric categorization */
|
|
357
|
-
tags?: Record<string, string>;
|
|
358
|
-
/** When the metric was recorded */
|
|
359
|
-
timestamp: Date;
|
|
360
|
-
}
|
|
361
|
-
/**
|
|
362
|
-
* Capability for security features like encryption and authorization.
|
|
363
|
-
* Provides security controls for sensitive aggregate operations.
|
|
364
|
-
*/
|
|
365
|
-
export interface ISecurityCapability extends IAggregateCapability {
|
|
366
|
-
/**
|
|
367
|
-
* Encrypts sensitive data
|
|
368
|
-
*/
|
|
369
|
-
encrypt(data: unknown): string;
|
|
370
|
-
/**
|
|
371
|
-
* Decrypts sensitive data
|
|
372
|
-
*/
|
|
373
|
-
decrypt(encryptedData: string): unknown;
|
|
374
|
-
/**
|
|
375
|
-
* Checks if user has permission to perform action
|
|
376
|
-
*/
|
|
377
|
-
hasPermission(action: string, user?: unknown): boolean;
|
|
378
|
-
/**
|
|
379
|
-
* Logs security events
|
|
380
|
-
*/
|
|
381
|
-
logSecurityEvent(event: SecurityEvent): void;
|
|
382
|
-
}
|
|
383
|
-
/**
|
|
384
|
-
* Represents a security-related event.
|
|
385
|
-
* Used for audit trails and security monitoring.
|
|
386
|
-
*/
|
|
387
|
-
export interface SecurityEvent {
|
|
388
|
-
/** Type of security event */
|
|
389
|
-
type: 'access' | 'modification' | 'failure';
|
|
390
|
-
/** Action that was performed */
|
|
391
|
-
action: string;
|
|
392
|
-
/** User who performed the action */
|
|
393
|
-
user?: unknown;
|
|
394
|
-
/** When the event occurred */
|
|
395
|
-
timestamp: Date;
|
|
396
|
-
/** Additional event metadata */
|
|
397
|
-
metadata?: Record<string, unknown>;
|
|
398
|
-
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Capability, IAuditCapability, IAuditEvent, IDomainEvent } from '
|
|
1
|
+
import { Capability, IAuditCapability, IAuditEvent, IDomainEvent } from '@vytches/ddd-contracts';
|
|
2
2
|
/**
|
|
3
3
|
* Capability that records every domain event applied to the aggregate as
|
|
4
4
|
* an `IAuditEvent`. Useful for compliance, debugging, behavior analytics,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { IEventSourcingCapability, IEventStore, Capability } from '
|
|
1
|
+
import { IEventSourcingCapability, IEventStore, Capability } from '@vytches/ddd-contracts';
|
|
2
2
|
/**
|
|
3
3
|
* Capability that integrates an aggregate with an external `IEventStore` —
|
|
4
4
|
* the persistence boundary for an event-sourced system. Allows the
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { IAggregateSnapshot, ISnapshotCapability, Capability } from '
|
|
1
|
+
import { IAggregateSnapshot, ISnapshotCapability, Capability } from '@vytches/ddd-contracts';
|
|
2
2
|
/**
|
|
3
3
|
* Capability that enables snapshot creation and restoration on an aggregate
|
|
4
4
|
* — a performance optimization for event-sourced aggregates with long
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Capability, IVersioningCapability, IDomainEvent, IEventUpcaster } from '
|
|
1
|
+
import { Capability, IVersioningCapability, IDomainEvent, IEventUpcaster } from '@vytches/ddd-contracts';
|
|
2
2
|
import { IAggregateEventHandler } from '../aggregate-interfaces';
|
|
3
3
|
/**
|
|
4
4
|
* Capability that handles **event schema evolution** — when a stored event
|
|
@@ -63,7 +63,20 @@ export declare class VersioningCapability extends Capability<'versioning'> imple
|
|
|
63
63
|
*/
|
|
64
64
|
registerUpcaster<TFrom = unknown, TTo = unknown>(eventType: string, sourceVersion: number, upcaster: IEventUpcaster<TFrom, TTo>): void;
|
|
65
65
|
/**
|
|
66
|
-
*
|
|
66
|
+
* Applies registered upcasters to bring `event` from its stored version up
|
|
67
|
+
* to the aggregate's current version, then invokes the matching handler.
|
|
68
|
+
*
|
|
69
|
+
* **Upcasting only activates if `event.metadata.targetVersion` is set.**
|
|
70
|
+
* This is NOT inferred automatically from registered upcasters or from
|
|
71
|
+
* any aggregate-level "current version" — the caller (typically your
|
|
72
|
+
* event-sourcing replay/load path) must explicitly stamp each historical
|
|
73
|
+
* event's metadata with `targetVersion` before calling this method. If
|
|
74
|
+
* `targetVersion` is absent, `currentVersion` falls back to `eventVersion`
|
|
75
|
+
* (i.e. no upcasting happens — the event is passed through unchanged even
|
|
76
|
+
* if upcasters are registered for it).
|
|
77
|
+
*
|
|
78
|
+
* @param {IDomainEvent} event - Event to process with version handling;
|
|
79
|
+
* set `event.metadata.targetVersion` to enable upcasting
|
|
67
80
|
* @param {Map<string, IAggregateEventHandler>} handlers - Map of event handlers
|
|
68
81
|
*/
|
|
69
82
|
handleVersionedEvent(event: IDomainEvent, handlers: Map<string, IAggregateEventHandler>): void;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Capability, IEventStore, EntityId } from '
|
|
1
|
+
import { Capability, IEventStore, EntityId } from '@vytches/ddd-contracts';
|
|
2
2
|
import { IAggregateCapability, IAggregateConstructorParams } from '../aggregate-interfaces';
|
|
3
3
|
import { AggregateRoot } from './aggregate-root';
|
|
4
4
|
/**
|