Entity Metadata System
Entity Metadata System
Relevant source files
The following files were used as context for generating this wiki page:
The Entity Metadata System is the foundational layer of the @primebrick/dal-pg package. It uses TypeScript decorators and the reflect-metadata API to bridge the gap between JavaScript class definitions and PostgreSQL relational structures src/meta/entity-decorators.ts:1-23.
The system is designed with a "convention over configuration" philosophy: every own enumerable property of an entity class is implicitly treated as a database column unless explicitly excluded src/meta/entity-decorators.ts:11-13.
Metadata Storage and Retrieval
Metadata is stored using a WeakMap where the keys are the class constructors (functions) and the values are ClassEntityMeta objects src/meta/entity-decorators.ts:106-115. This ensures that metadata does not leak memory and is scoped strictly to the entity classes.
Core Metadata Functions
| Function | Purpose |
|---|---|
ensureMeta(ctor) | Retrieves or initializes the ClassEntityMeta for a given class src/meta/entity-decorators.ts:108-115. |
touchColumn(ctor, key) | Ensures a ColumnRegistration exists for a specific property, defaulting the sqlName to the property name src/meta/entity-decorators.ts:117-125. |
syncImplicitEntityColumns(ctor) | Discovers all instance properties and applies type inference to those not explicitly decorated src/meta/entity-decorators.ts:134-155. |
getEntityPersistenceMeta(ctor) | The primary public API to retrieve the complete, resolved metadata for an entity src/meta/entity-meta.ts:24. |
Metadata Data Flow
The following diagram illustrates how a class definition is transformed into a persistence metadata object used by the Repository.
Entity Metadata Extraction Flow
Code
Sources: src/meta/entity-decorators.ts:106-155, src/meta/entity-ts-to-pg.ts:137-143
Decorator API
The DAL provides a rich set of decorators to define table structure and behavior.
Table and Column Definition
@Entity(tableName?, schema?): Maps a class to a table. IftableNameis omitted, it defaults to the class name src/meta/entity-decorators.ts:161-168.@Column(opts): Overrides default naming or type inference. Required only for specifyingpgType,length,precision, ornullablesrc/meta/entity-decorators.ts:188-204.@Key(opts?): Marks a property as the Primary Key. Supportsidentity(default) ormanualgeneration src/meta/entity-decorators.ts:223-231.@Unique(): Marks a column as having a unique constraint src/meta/entity-decorators.ts:234-239.@IsNotColumn(): Explicitly excludes a property from persistence src/meta/entity-decorators.ts:242-247.
Specialized Field Decorators
These decorators mark fields for internal DAL subsystems like Audit and Soft-Delete.
@AuditableField(type): Links a property toCREATED_AT,CREATED_BY,UPDATED_AT,UPDATED_BY, orVERSIONsrc/meta/entity-decorators.ts:250-258.@DeletableField(type): Links a property toDELETED_ATorDELETED_BYfor soft-delete logic src/meta/entity-decorators.ts:265-273.@SynchronizableField(type): Marks fields for sync tracking, e.g.,LAST_SYNCED_ATsrc/meta/entity-decorators.ts:280-288.@CloneField(): Marks a field for tracking the source of a cloned record src/meta/entity-decorators.ts:295-300.@AuditTrail(): Indicates that the entity has a corresponding audit trail table src/meta/entity-decorators.ts:303-308.
Sources: src/meta/entity-decorators.ts:161-308, src/meta/entity-meta.ts:4-17
Type Inference Pipeline
The entity-ts-to-pg.ts module handles the mapping from TypeScript types and naming heuristics to PostgreSQL base types. This is critical when emitDecoratorMetadata is active or when developers rely on naming conventions.
Inference Logic
- Explicit Type: If
@Column({ pgType: '...' })is used, it always wins src/meta/entity-ts-to-pg.ts:139. - Design Type: Uses
design:typemetadata (e.g.,Number→integer,Date→timestamptz) src/meta/entity-ts-to-pg.ts:92-118. - Naming Heuristics: If types are ambiguous (like
Objectin some transpilation setups), it looks at the property name:- Ends in
_ator_on→timestamptzsrc/meta/entity-ts-to-pg.ts:76-85. - Named
uuid→uuidsrc/meta/entity-ts-to-pg.ts:64-66. - Named
idand is a Key →bigintsrc/meta/entity-ts-to-pg.ts:67-69.
- Ends in
Type Modifiers
The system applies modifiers for length, precision, and scale. For example, text with length: 20 becomes varchar(20) src/meta/entity-ts-to-pg.ts:25-58.
TS to PG Type Mapping Matrix
| TS Property / Type | Heuristic / Meta | PG Type |
|---|---|---|
id: number | @Key() | bigint |
version: number | Name match | integer |
createdAt: Date | Name *_at | timestamptz |
bio: string | Default | text |
price: number | precision: 10, scale: 2 | numeric(10,2) |
Sources: src/meta/entity-ts-to-pg.ts:60-143
System Interaction Diagram
This diagram shows how the metadata system connects the high-level TypeScript Entity definitions to the low-level PostgreSQL requirements.
Metadata Pipeline: TS Space to PG Space
Code
Sources: src/meta/entity-decorators.ts:134-155, src/meta/entity-ts-to-pg.ts:137-143, src/meta/entity-meta.ts:24-30