PrimebrickPrimebrick
  • Primebrick.dev
  • GitHub
  • Documentation
  • Services
  • Libraries
  • API Catalog
Resources
  • Landing Page
  • API Catalog
  • GitHub
PrimebrickPrimebrick

© 2026 Primebrick. MIT License.

github
Backend
    Audit SystemAuditable Joins and Display Name ResolutionAuditService and Delta CalculatorAuth Router: Login, Token Refresh, and User Management APIAuthentication and AuthorizationAuthentication Middleware and Token NormalizationCore ArchitectureCustomers API RouterCustomers Data Access LayerCustomers ModuleDatabase ManagementDocker Infrastructure and Casdoor SetupDomain Entity SystemExport LibraryGetting StartedGitFlow, Versioning, and CI HooksGlossaryInfrastructure and DevOpsMigration Patch Registry and ApplicationOpenAPI DocumentationOrganizations ModuleOverviewProject StructureRBAC Middleware and Permission SystemRepository and Query DSLSchema Snapshot and Diff SystemServer Bootstrap and Middleware PipelineUtility Scripts ReferenceREADME
Frontend
Microservices
powered by Zudoku
Backend

Domain Entity System

Domain Entity System

Relevant source files

The following files were used as context for generating this wiki page:

  • src/domain/entities/column-pg-io.ts
  • src/domain/entities/entity-decorators.ts
  • src/domain/entities/entity-meta.ts
  • src/domain/entities/iauditable_entity.ts
  • src/domain/entities/ideletable_entity.ts
  • src/domain/entities/iexposable_entity.ts
  • src/domain/entities/registry.ts
  • src/index.ts

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.

DecoratorTargetPurpose
@Entity(tableName?)ClassMaps the class to a PostgreSQL table. Defaults to class name if tableName is omitted src/domain/entities/entity-decorators.ts:161-167.
@Key(opts?)PropertyMarks a property as the Primary Key. Supports identity or manual generation src/domain/entities/entity-decorators.ts:223-231.
@Column(opts)PropertyOverrides default mapping (SQL name, type, nullability, length, precision) src/domain/entities/entity-decorators.ts:192-212.
@Unique()PropertySignals a unique constraint for DDL generation src/domain/entities/entity-decorators.ts:237-241.
@IsNotColumn()PropertyExcludes the property from database snapshots and DAL persistence src/domain/entities/entity-decorators.ts:246-250.
@AuditableField(type)PropertyIdentifies metadata fields like CREATED_AT, UPDATED_BY, or VERSION src/domain/entities/entity-decorators.ts:261-267.
@DeletableField(type)PropertyIdentifies 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, VERSION src/domain/entities/entity-decorators.ts:26-32.
  • DeletableFieldType: DELETED_AT, DELETED_BY src/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
graph TD subgraph "Natural Language Intent" A["'I want a Customer table with a Primary Key'"] end subgraph "Code Entity Space" B["@Entity('customers')"] C["@Key() id: number"] D["CustomerEntity class"] E["ENTITY_REGISTRY"] F["META WeakMap"] end A --> B A --> C B --> D C --> D D -- "Imported into" --> E D -- "Stores metadata in" --> F

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:

  1. Instantiates a temporary object to discover enumerable keys src/domain/entities/entity-decorators.ts:124-130.
  2. Uses reflect-metadata (design:type) to infer the PostgreSQL type src/domain/entities/entity-decorators.ts:146-149.
  3. 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:

  • CustomerEntity src/domain/entities/registry.ts:15
  • UserProfileEntity src/domain/entities/registry.ts:16
  • RoleMappingEntity src/domain/entities/registry.ts:17
  • OrganizationEntity src/domain/entities/registry.ts:18
  • ServiceRegistryEntity src/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 Date maps to timestamptz src/domain/entities/column-pg-io.ts:4.
  • Explicit Date: If @Column({ pgType: 'date' }) is used, the system converts Date objects to YYYY-MM-DD strings for the driver src/domain/entities/column-pg-io.ts:47-49.
  • Hydration: After loading data from JSON, hydrateEntityDateFieldsFromJson converts ISO strings back into JS Date objects 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
graph LR subgraph "TypeScript Space" JS_VAL["JS Value (Date/String/Number)"] ENTITY_INST["Entity Instance"] end subgraph "Conversion Logic" JS_TO_PG["jsValueToPgParam()"] PG_TO_JS["pgValueToJsValue()"] HYDRATE["hydrateEntityDateFieldsFromJson()"] end subgraph "PostgreSQL Space" PG_PARAM["node-pg Parameter"] WIRE_VAL["Wire Value"] end JS_VAL -- "Pre-Query" --> JS_TO_PG JS_TO_PG --> PG_PARAM WIRE_VAL -- "Post-Query" --> PG_TO_JS PG_TO_JS --> ENTITY_INST ENTITY_INST -- "From JSON/API" --> HYDRATE HYDRATE --> JS_VAL

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 a uuid field for public API exposure src/domain/entities/iexposable_entity.ts:1-7.
  • IDeletableEntity: Includes deleted_at and deleted_by for soft-delete support src/domain/entities/ideletable_entity.ts:1-4.
  • IAuditableEntity: Extends IDeletableEntity and adds created_at, created_by, updated_at, updated_by, and version (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


Last modified on July 13, 2026
Docker Infrastructure and Casdoor SetupExport Library
On this page
  • Core Decorators
    • Special Field Types
  • Metadata Discovery and Mapping
    • Natural Language to Code Entity Space: Decorator Flow
    • Implicit Column Discovery
  • Entity Registry
  • Type Mapping (TS ↔ PostgreSQL)
    • Date Handling
    • Mapping Logic Diagram
  • Common Interfaces