Overview
@woltz/rich-domain-prisma provides seamless integration between rich-domain and Prisma ORM. It leverages Prisma’s nested writes and transaction support to align perfectly with rich-domain’s change tracking and Unit of Work patterns.
Unit of Work
Request-isolated transactions with AsyncLocalStorage
Repository Base Class
PrismaRepository with built-in Criteria support
Change Tracking
PrismaToPersistence with automatic change detection
Batch Operations
PrismaBatchExecutor for efficient bulk writes
For a complete working example, see the fastify-with-prisma example in the repository.
Quick Start
1. Setup
2. Create Repository
3. Use It
PrismaUnitOfWork
Manages transactions with per-request isolation usingAsyncLocalStorage.
Transaction Execution
Request Isolation
Each HTTP request gets its own transaction context, preventing cross-request interference:API Reference
| Method | Description |
|---|---|
transaction(work) | Execute work function in a transaction |
isInTransaction() | Check if currently in a transaction |
getCurrentContext() | Get current transaction context or null |
@Transactional Decorator
Decorator that automatically wraps a method in a transaction.With Explicit UoW Parameter
You can pass the UoW instance directly to the decorator instead of relying on constructor injection:UoW Resolution Order
The decorator looks for the UoW instance in this order:- Decorator parameter -
@Transactional({ uow: myUow }) - Instance property -
this.uow - Private property -
this._uow - Any property - Any property that is a
PrismaUnitOfWorkinstance
Behavior
| Scenario | Behavior |
|---|---|
| Direct call | Creates new transaction |
| Already in transaction | Reuses existing one |
| Error thrown | Automatic rollback |
PrismaRepository
Base class for repositories with full Criteria support.Complete Implementation
Context Awareness
The repository automatically uses the transaction context when available:EntitySchemaRegistry
Maps domain entities to database tables, handles field mapping, and configures relationships.See the complete Schema Registry documentation for all features.
Basic Registration
Collection Configuration (N:N Relations)
For N:N relationships, configure collections withtype: "reference":
Collection Types
| Type | Relationship | Batch Behavior |
|---|---|---|
owned | 1:N | createMany / deleteMany |
reference | N:N | connect / disconnect |
PrismaBatchExecutor automatically uses the correct Prisma operations based on collection type:
PrismaToPersistence
Base mapper class with change tracking integration.Complete Example
PrismaBatchExecutor
Executes batch operations fromAggregateChanges with proper ordering and relationship handling.
Execution Order
The executor respects referential integrity:-
Deletes - Leaf → Root (depth DESC)
owned: UsesdeleteManyreference: Usesdisconnect
-
Creates - Root → Leaf (depth ASC)
owned: UsescreateManyreference: Usesconnect
- Updates - Any order
Convenience Function
Complete Example
Domain Model
Schema Registry
Mappers
Repository
Use Case
Error Handling
The adapter provides specific error types:Complete Example
See the fastify-with-prisma example for a complete working application demonstrating:- User aggregate with Posts (1:N owned)
- Post with Tags (N:N reference via junction table)
- Case-insensitive search
- Transaction management
- CRUD operations
- Domain events with BullMQ
API Reference
Exports
PrismaUnitOfWork Methods
| Method | Returns | Description |
|---|---|---|
transaction(work) | Promise<T> | Execute work in transaction |
isInTransaction() | boolean | Check if in transaction |
getCurrentContext() | PrismaTransactionContext | null | Get current context |
PrismaRepository Methods
| Method | Returns | Description |
|---|---|---|
find(criteria) | Promise<PaginatedResult<T>> | Find with criteria |
findById(id) | Promise<T | null> | Find by ID |
findOne(criteria) | Promise<T | null> | Find first match |
count(criteria?) | Promise<number> | Count entities |
exists(id) | Promise<boolean> | Check if exists |
save(entity) | Promise<void> | Create or update |
delete(entity) | Promise<void> | Delete entity |
deleteById(id) | Promise<void> | Delete by ID |
transaction(work) | Promise<T> | Execute in transaction |