> For the complete documentation index, see [llms.txt](https://docs.nestjstools.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.nestjstools.com/domain-driven-starter/getting-started/usage-example.md).

# Usage example

## Uuid Value Object

A strongly-typed, immutable UUID wrapper.

Prevents primitive obsession and ensures valid IDs.

```
import { Uuid } from '@nestjstools/domain-driven-starter';

const id = Uuid.generate();
const fromString = Uuid.fromString('f47ac10b-58cc-4372-a567-0e02b2c3d479');

console.log(id.toString());
```

#### Why use Uuid as a Value Object?

Instead of:

```
const id: string = '...';
```

You get:

* Validation
* Explicit domain meaning
* Type safety
* Immutable identity

Supports:

* UUID v7 (recommended)
* UUID v4 (compatible)

***

## 2️⃣ DomainEvent Interface

Minimal interface for domain events.

```
export interface DomainEvent {
  readonly id: string;
}
```

You define your own events:

```
export class OrderCreatedEvent implements DomainEvent {
  readonly occurredAt = new Date();
  readonly eventName = 'order.created';

  constructor(
    public readonly id: string,
    public readonly customerId: string
  ) {}
}
```

***

### Why Domain Events?

They allow:

* Decoupled side effects
* Clear domain traceability
* Event-driven architecture
* Integration with messaging systems
* Auditability

***

## 3️⃣ AggregateRoot\<T extends DomainEvent>

The central building block of your domain model.

Provides:

* Identity handling
* Event recording
* Controlled creation
* Event extraction

***

### Constructor Pattern

```
protected constructor(id: Uuid)
```

The constructor is **protected**, meaning:

* Only subclasses can instantiate it
* Prevents uncontrolled aggregate creation
* Encourages static factory methods

In your aggregate, you usually make the constructor `private` and expose a `createNew()` method.

***

### Methods

#### recordEvent(event: T): void

Records a domain event internally.

Used inside aggregate methods when something meaningful changes.

***

#### popRecordedEvents(): T\[]

Returns recorded events and clears the internal list.

Used after persisting the aggregate to publish events externally.

***

## 🧩 Example: Order Aggregate

```
import { AggregateRoot, Uuid } from '@nestjstools/domain-driven-starter';

export class OrderAggregate extends AggregateRoot<OrderEvents> {
  private constructor(
    id: Uuid,
    private readonly customerId: Uuid
  ) {
    super(id);
  }

  static createNew(
    id: Uuid,
    customerId: Uuid,
    now: Date
  ): OrderAggregate {
    const order = new OrderAggregate(id, customerId);

    order.recordEvent(
      new OrderCreatedEvent(
        id.toString(),
        customerId.toString()
      )
    );

    return order;
  }
}
```

***

## 🔁 Typical Usage Flow

1. Create aggregate via static factory.
2. Aggregate records domain events.
3. Repository saves aggregate.
4. Application layer calls `popRecordedEvents()`.
5. Events are published to an event bus (e.g. messaging library).

This keeps:

* Domain pure
* Infrastructure separate
* Side effects decoupled

***

## 🏗 Where This Library Fits

Perfect for:

* DDD projects
* CQRS systems
* Event-driven architecture
* Clean architecture
* Microservices
* Monoliths with strong domain boundaries

Works with:

* NestJS
* Express
* Fastify
* Standalone Node.js
* Any framework

***

## 🧪 Testing

Because it is framework-agnostic:

* No DI required
* No mocking frameworks needed
* Pure unit tests
* Aggregates are deterministic

Example:

```
it('records OrderCreatedEvent', () => {
  const id = Uuid.generate();
  const customerId = Uuid.generate();

  const order = OrderAggregate.createNew(id, customerId, new Date());

  const events = order.popRecordedEvents();

  expect(events).toHaveLength(1);
});
```


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.nestjstools.com/domain-driven-starter/getting-started/usage-example.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
