woltz-rich-domain

woltz-rich-domain

Guide for @woltz/rich-domain DDD library and ecosystem. Use when building domain models, repositories, or working with Prisma/TypeORM adapters.

3Star
0Fork
更新于 1/25/2026
SKILL.md
readonly只读
name
woltz-rich-domain
description

Guide for @woltz/rich-domain DDD library and ecosystem. Use when building domain models, repositories, or working with Prisma/TypeORM adapters.

@woltz/rich-domain

TypeScript library for Domain-Driven Design with automatic change tracking and Standard Schema validation.

Requirements

  • Node.js >= 22.12
  • TypeScript >= 5.4

Ecosystem

Package Purpose
@woltz/rich-domain Core DDD building blocks
@woltz/rich-domain-prisma Prisma ORM adapter
@woltz/rich-domain-typeorm TypeORM adapter
@woltz/rich-domain-criteria-zod Zod schemas for Criteria API
@woltz/rich-domain-export Multi-format data export

Quick Start

1. Define a Value Object

import { ValueObject } from "@woltz/rich-domain";
import { z } from "zod";

class Email extends ValueObject<string> {
  protected static validation = {
    schema: z.string().email(),
  };

  getDomain(): string {
    return this.value.split("@")[1];
  }
}

2. Define an Entity

import { Entity, Id } from "@woltz/rich-domain";

const PostSchema = z.object({
  id: z.custom<Id>(),
  title: z.string().min(1),
  content: z.string(),
  published: z.boolean(),
});

class Post extends Entity<z.infer<typeof PostSchema>> {
  protected static validation = { schema: PostSchema };

  publish(): void {
    this.props.published = true;
  }

  get title() {
    return this.props.title;
  }
}

3. Define an Aggregate

import { Aggregate, Id, EntityHooks } from "@woltz/rich-domain";
import { UserCreatedEvent } from "./events";
import { Email } from "./email";

const UserSchema = z.object({
  id: z.custom<Id>(),
  email: z.custom<Email>(),
  name: z.string().min(2),
  posts: z.array(z.instanceof(Post)),
  createdAt: z.date(),
});
export type UserProps = z.infer<typeof UserSchema>;

class User extends Aggregate<UserProps, "createdAt"> {
  protected static validation = { schema: UserSchema };
  protected static hooks: EntityHooks<UserProps, User> = {
    onBeforeCreate: (props) => {
      if (!props.createdAt) props.createdAt = new Date();
    },
    onCreate: (entity) => {
      if (entity.isNew()) {
        entity.addDomainEvent(new UserCreatedEvent({ id: entity.id.value }));
      }
    },
  };

  getTypedChanges() {
    interface Entities {
      Post: Post;
    }
    return this.getChanges<Entities>();
  }

  addPost(title: string, content: string): void {
    this.props.posts.push(new Post({ title, content, published: false }));
  }

  get email() {
    return this.props.email.value;
  }
  get posts() {
    return this.props.posts;
  }
}

4. Use Change Tracking

const user = await userRepository.findById(userId);

// Make changes
user.addPost("New Post", "Content");
user.posts[0].publish();

// Get changes automatically
// We strongly recommend using this `getTypedChanges` helper pattern for better DX
const changes = user.getTypedChanges();
// { creates: [...], updates: [...], deletes: [...] }

// After saving
user.markAsClean();

5. Query with Criteria

import { Criteria } from "@woltz/rich-domain";

// fully type-safe, fields inferred from schema
const criteria = Criteria.create<User>()
  .where("status", "equals", "active")
  .whereContains("email", "@company.com")
  .orderBy("createdAt", "desc")
  .paginate(1, 20);

const result = await userRepository.find(criteria);

Core Principles

  1. Aggregates define consistency boundaries - Modify entities through their aggregate root
  2. Value Objects are immutable - Use clone() to create modified copies
  3. Id tracks new vs existing - new Id() for INSERT, Id.from(value) for UPDATE
  4. Change tracking is automatic - Use getChanges() and markAsClean()
  5. Repositories abstract persistence - Domain layer doesn't know about database

References

For detailed documentation on specific topics:

  • Core Concepts - Entities, Aggregates, Value Objects, Lifecycle Hooks
  • Domain Events - Event-driven architecture with example using BullMQ
  • Criteria API - Type-safe query building with filters, ordering, pagination
  • Criteria Zod - Zod schemas for API query validation
  • Schema Registry - EntitySchemaRegistry for field mapping and relationships
  • Prisma Adapter - PrismaRepository, UnitOfWork, Transactions
  • TypeORM Adapter - TypeORMRepository, change tracking
  • Export - CSV, JSON export with streaming support

DO NOT read all files at once. Load based on context.

Resources

You Might Also Like

Related Skills

zig-system-calls

zig-system-calls

87Kdev-database

Guides using bun.sys for system calls and file I/O in Zig. Use when implementing file operations instead of std.fs or std.posix.

oven-sh avataroven-sh
获取
bun-file-io

bun-file-io

86Kdev-database

Use this when you are working on file operations like reading, writing, scanning, or deleting files. It summarizes the preferred file APIs and patterns used in this repo. It also notes when to use filesystem helpers for directories.

anomalyco avataranomalyco
获取
vector-index-tuning

vector-index-tuning

26Kdev-database

Optimize vector index performance for latency, recall, and memory. Use when tuning HNSW parameters, selecting quantization strategies, or scaling vector search infrastructure.

wshobson avatarwshobson
获取

Implement efficient similarity search with vector databases. Use when building semantic search, implementing nearest neighbor queries, or optimizing retrieval performance.

wshobson avatarwshobson
获取

Master dbt (data build tool) for analytics engineering with model organization, testing, documentation, and incremental strategies. Use when building data transformations, creating data models, or implementing analytics engineering best practices.

wshobson avatarwshobson
获取
event-store-design

event-store-design

26Kdev-database

Design and implement event stores for event-sourced systems. Use when building event sourcing infrastructure, choosing event store technologies, or implementing event persistence patterns.

wshobson avatarwshobson
获取