Domain Entity System
Domain Entity System
Relevant source files
The following files were used as context for generating this wiki page:
The Domain Entity System is a decorator-based metadata engine that bridges TypeScript classes and PostgreSQL tables. It utilizes TypeScript's legacy decorator reflection and reflect-metadata to define schema properties, constraints, and audit behaviors directly on domain models.
Core Decorators
The system uses decorators to define how class properties map to database columns. By convention, every enumerable property on a class prototype is treated as a column unless explicitly excluded.
| Decorator | Target | Purpose |
|---|---|---|
@Entity(tableName?) | Class | Maps the class to a PostgreSQL table. Defaults to class name if tableName is omitted src/domain/entities/entity-decorators.ts:161-167. |
@Key(opts?) | Property | Marks a property as the Primary Key. Supports identity or manual generation src/domain/entities/entity-decorators.ts:223-231. |
@Column(opts) | Property | Overrides default mapping (SQL name, type, nullability, length, precision) src/domain/entities/entity-decorators.ts:192-212. |
@Unique() | Property | Signals a unique constraint for DDL generation src/domain/entities/entity-decorators.ts:237-241. |
@IsNotColumn() | Property | Excludes the property from database snapshots and DAL persistence src/domain/entities/entity-decorators.ts:246-250. |
@AuditableField(type) | Property | Identifies metadata fields like CREATED_AT, UPDATED_BY, or VERSION src/domain/entities/entity-decorators.ts:261-267. |
@DeletableField(type) | Property | Identifies soft-delete fields like DELETED_AT src/domain/entities/entity-decorators.ts:273-279. |
Special Field Types
The system defines enums for specialized tracking fields:
- AuditableFieldType:
CREATED_AT,CREATED_BY,UPDATED_AT,UPDATED_BY,VERSIONsrc/domain/entities/entity-decorators.ts:26-32. - DeletableFieldType:
DELETED_AT,DELETED_BYsrc/domain/entities/entity-decorators.ts:34-37.
Sources: src/domain/entities/entity-decorators.ts:26-279, src/domain/entities/entity-meta.ts:4-31
Metadata Discovery and Mapping
The system uses a WeakMap named META to store ClassEntityMeta against class constructors src/domain/entities/entity-decorators.ts:102-111.
Natural Language to Code Entity Space: Decorator Flow
This diagram shows how a developer's intent (Natural Language) is translated into the ENTITY_REGISTRY and metadata structures.
Code
Sources: src/domain/entities/entity-decorators.ts:102-111, src/domain/entities/registry.ts:14-20
Implicit Column Discovery
TypeScript class fields declared with ! (e.g., name!: string) do not exist at runtime unless initialized. To handle this, the system uses syncImplicitEntityColumns which:
- Instantiates a temporary object to discover enumerable keys src/domain/entities/entity-decorators.ts:124-130.
- Uses
reflect-metadata(design:type) to infer the PostgreSQL type src/domain/entities/entity-decorators.ts:146-149. - Determines nullability based on the TypeScript type src/domain/entities/entity-decorators.ts:150-153.
Sources: src/domain/entities/entity-decorators.ts:124-155
Entity Registry
The ENTITY_REGISTRY in src/domain/entities/registry.ts is the central source of truth for all domain entities. Database patch tooling and the migration system scan this registry to generate DDL or compare the current database state against the code src/domain/entities/registry.ts:1-4.
Current Registered Entities:
CustomerEntitysrc/domain/entities/registry.ts:15UserProfileEntitysrc/domain/entities/registry.ts:16RoleMappingEntitysrc/domain/entities/registry.ts:17OrganizationEntitysrc/domain/entities/registry.ts:18ServiceRegistryEntitysrc/domain/entities/registry.ts:19
Sources: src/domain/entities/registry.ts:14-20
Type Mapping (TS ↔ PostgreSQL)
The column-pg-io.js utility handles the conversion of data between the application and the database driver.
Date Handling
- Standard: TS
Datemaps totimestamptzsrc/domain/entities/column-pg-io.ts:4. - Explicit Date: If
@Column({ pgType: 'date' })is used, the system convertsDateobjects toYYYY-MM-DDstrings for the driver src/domain/entities/column-pg-io.ts:47-49. - Hydration: After loading data from JSON,
hydrateEntityDateFieldsFromJsonconverts ISO strings back into JSDateobjects based on metadata src/domain/entities/column-pg-io.ts:76-92.
Mapping Logic Diagram
This diagram maps the code-level transformation functions to the data flow between TypeScript and PostgreSQL.
Code
Sources: src/domain/entities/column-pg-io.ts:43-69, src/domain/entities/column-pg-io.ts:76-92
Common Interfaces
Entities often implement standard interfaces to ensure compatibility with generic DAL features like soft-delete and audit tracking.
IExposableEntity: Requires auuidfield for public API exposure src/domain/entities/iexposable_entity.ts:1-7.IDeletableEntity: Includesdeleted_atanddeleted_byfor soft-delete support src/domain/entities/ideletable_entity.ts:1-4.IAuditableEntity: ExtendsIDeletableEntityand addscreated_at,created_by,updated_at,updated_by, andversion(for optimistic concurrency) src/domain/entities/iauditable_entity.ts:3-9.
Sources: src/domain/entities/iexposable_entity.ts:1-7, src/domain/entities/ideletable_entity.ts:1-4, src/domain/entities/iauditable_entity.ts:1-9