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

© 2026 Primebrick. MIT License.

github
Backend
Frontend
Microservices
    Agent Skills & Execution PermissionsAI Agent GovernanceBrevo Email ProviderCode Guardrails & File Operation RulesData Layer & Database ToolingDeployment & DockerEmail Services & Business LogicEmailSender MicroserviceEntity Model & DecoratorsGetting Started & Local DevelopmentGitFlow Branching StrategyGlossaryHTTP Server & Webhook EndpointNATS Messaging LayerOverviewRelease Lifecycle & Pre-commit HooksRepository Structure & Tech StackSchema Snapshot & Migration PipelineVersion Control & Release ProcessWorkflow & Planning Rules (Tic-Toc)
powered by Zudoku
Microservices

Entity Model & Decorators

Entity Model & Decorators

Relevant source files

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

  • emailsender/src/domain/entities/email_config_entity.ts
  • emailsender/src/domain/entities/email_template_entity.ts
  • emailsender/src/domain/entities/entity-decorators.ts
  • emailsender/src/domain/entities/iauditable_entity.ts
  • emailsender/src/domain/entities/ideletable_entity.ts
  • emailsender/src/domain/entities/registry.ts

The Primebrick v3 Data Layer utilizes a custom TypeScript decorator-based system to define database schemas directly within the domain entities. This system bridges the gap between TypeScript classes and PostgreSQL tables, providing metadata for schema migration, DDL generation, and Data Access Layer (DAL) operations.

Decorator System Architecture

The core of the entity model is a WeakMap-based metadata registry defined in emailsender/src/domain/entities/entity-decorators.ts:99-108. Unlike standard ORMs that might store metadata on the class prototype directly, this system uses a private META WeakMap to store ClassEntityMeta objects, ensuring that metadata is encapsulated and keyed by the class constructor emailsender/src/domain/entities/entity-decorators.ts:99-99.

Metadata Storage Flow

The system discovers entity structures through a combination of explicit decorators and implicit reflection via reflect-metadata.

  1. Registration: When a class is decorated with @Entity, it is registered in the META registry emailsender/src/domain/entities/entity-decorators.ts:158-164.
  2. Property Discovery: Property decorators like @Column, @Key, and @Unique populate the columns Map within the metadata emailsender/src/domain/entities/entity-decorators.ts:110-118.
  3. Type Inference: The system uses design:type metadata to infer PostgreSQL types (e.g., TS Date maps to timestamptz) and nullability emailsender/src/domain/entities/entity-decorators.ts:143-151.

Mapping Natural Language to Code Entities

The following diagram illustrates how conceptual database requirements are translated into specific TypeScript code constructs.

Diagram: Requirement to Code Mapping

Code
graph TD subgraph "Natural Language Concepts" A["'This class represents a Table'"] B["'This property is the Primary Key'"] C["'This field must be Unique'"] D["'This field is for internal logic only'"] E["'Track who created this record'"] end subgraph "Code Entities (Decorators & Interfaces)" A1["@Entity('table_name')"] B1["@Key()"] C1["@Unique()"] D1["@IsNotColumn()"] E1["@AuditableField(AuditableFieldType.CREATED_BY)"] F1["IAuditableEntity"] end A --> A1 B --> B1 C --> C1 D --> D1 E --> E1 E1 -.-> F1

Sources: emailsender/src/domain/entities/entity-decorators.ts:18-22, emailsender/src/domain/entities/entity-decorators.ts:158-164, emailsender/src/domain/entities/iauditable_entity.ts:1-10

Core Decorators

DecoratorPurposeImplementation Detail
@Entity(name?)Defines the table name.Defaults to class name if name is omitted emailsender/src/domain/entities/entity-decorators.ts:161-161.
@Key()Marks the Primary Key.Supports single-column PKs; defaults to identity generation emailsender/src/domain/entities/entity-decorators.ts:52-53.
@Unique()Adds a unique constraint.Used by DDL patch tools to generate UNIQUE indexes emailsender/src/domain/entities/entity-decorators.ts:20-20.
@Column(opts)Configures SQL specifics.Allows overriding sqlName, pgType, length, precision, and nullable emailsender/src/domain/entities/entity-decorators.ts:69-86.
@IsNotColumn()Excludes property.Prevents the property from being included in database snapshots or DAL queries emailsender/src/domain/entities/entity-decorators.ts:21-21.

Sources: emailsender/src/domain/entities/entity-decorators.ts:8-22, emailsender/src/domain/entities/entity-decorators.ts:69-86

Auditing and Soft Deletion

The system enforces standardized tracking for record lifecycles through specific interfaces and field decorators.

IAuditableEntity

Entities implementing IAuditableEntity must include fields for creation and update tracking emailsender/src/domain/entities/iauditable_entity.ts:3-9. These are mapped to database columns using the @AuditableField decorator.

  • created_at: AuditableFieldType.CREATED_AT
  • created_by: AuditableFieldType.CREATED_BY
  • updated_at: AuditableFieldType.UPDATED_AT
  • updated_by: AuditableFieldType.UPDATED_BY
  • version: AuditableFieldType.VERSION (used for optimistic locking)

IDeletableEntity

Provides support for soft-delete patterns emailsender/src/domain/entities/ideletable_entity.ts:1-5.

  • deleted_at: DeletableFieldType.DELETED_AT
  • deleted_by: DeletableFieldType.DELETED_BY

Sources: emailsender/src/domain/entities/iauditable_entity.ts:1-10, emailsender/src/domain/entities/ideletable_entity.ts:1-5, emailsender/src/domain/entities/entity-decorators.ts:26-37

Entity Registry

The ENTITY_REGISTRY serves as the central manifest for the database patch tooling. Every new entity class must be added to this array to be included in schema introspection and migration generation emailsender/src/domain/entities/registry.ts:1-15.

Diagram: Metadata Extraction Flow

Code
flowchart LR subgraph "Registry" REG["ENTITY_REGISTRY"] end subgraph "Entity Classes" E1["EmailConfigEntity"] E2["EmailTemplateEntity"] end subgraph "Metadata Registry (WeakMap)" WM["META WeakMap"] end subgraph "Database Tooling" DT["Schema Snapshot / Migration"] end REG --> E1 & E2 E1 & E2 -- "Decorators populate" --> WM DT -- "Scans" --> REG DT -- "Reads Metadata" --> WM

Sources: emailsender/src/domain/entities/registry.ts:11-14, emailsender/src/domain/entities/entity-decorators.ts:99-108

Implementation Example: EmailConfigEntity

The EmailConfigEntity demonstrates the full usage of the decorator system, combining identity, uniqueness, custom column types, and auditing emailsender/src/domain/entities/email_config_entity.ts:11-51.

Code
@Entity("email_config") export class EmailConfigEntity implements IAuditableEntity { @Key() id: number; // Primary Key @Unique() uuid: string; // Unique Constraint @Column({ length: 50, nullable: false }) provider: string; // Varchar(50) NOT NULL @AuditableField(AuditableFieldType.CREATED_AT) created_at: Date; // Tracked timestamp // ... other fields }

Sources: emailsender/src/domain/entities/email_config_entity.ts:11-51


Last modified on July 13, 2026
EmailSender MicroserviceGetting Started & Local Development
On this page
  • Decorator System Architecture
    • Metadata Storage Flow
    • Mapping Natural Language to Code Entities
  • Core Decorators
  • Auditing and Soft Deletion
    • IAuditableEntity
    • IDeletableEntity
  • Entity Registry
  • Implementation Example: EmailConfigEntity
TypeScript