@venizia/ignis-docs 0.0.8 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (180) hide show
  1. package/README.md +7 -7
  2. package/content/best-practices/api-usage-examples.md +15 -12
  3. package/content/best-practices/architectural-patterns.md +70 -78
  4. package/content/best-practices/architecture-decisions.md +91 -60
  5. package/content/best-practices/code-style-standards/advanced-patterns.md +56 -44
  6. package/content/best-practices/code-style-standards/constants-configuration.md +11 -11
  7. package/content/best-practices/code-style-standards/control-flow.md +5 -2
  8. package/content/best-practices/code-style-standards/documentation.md +13 -13
  9. package/content/best-practices/code-style-standards/function-patterns.md +9 -10
  10. package/content/best-practices/code-style-standards/index.md +1 -1
  11. package/content/best-practices/code-style-standards/naming-conventions.md +10 -8
  12. package/content/best-practices/code-style-standards/route-definitions.md +30 -12
  13. package/content/best-practices/code-style-standards/tooling.md +8 -5
  14. package/content/best-practices/code-style-standards/type-safety.md +13 -12
  15. package/content/best-practices/common-pitfalls.md +56 -37
  16. package/content/best-practices/contribution-workflow.md +13 -14
  17. package/content/best-practices/data-modeling.md +46 -22
  18. package/content/best-practices/deployment-strategies.md +28 -27
  19. package/content/best-practices/error-handling.md +48 -24
  20. package/content/best-practices/index.md +5 -5
  21. package/content/best-practices/performance-optimization.md +40 -31
  22. package/content/best-practices/security-guidelines.md +52 -23
  23. package/content/best-practices/testing-strategies.md +65 -51
  24. package/content/best-practices/troubleshooting-tips.md +24 -24
  25. package/content/extensions/components/{swagger.md → api-reference.md} +40 -31
  26. package/content/extensions/components/authentication/api.md +19 -19
  27. package/content/extensions/components/authentication/errors.md +7 -7
  28. package/content/extensions/components/authentication/index.md +10 -8
  29. package/content/extensions/components/authentication/usage.md +101 -6
  30. package/content/extensions/components/authorization/api.md +45 -25
  31. package/content/extensions/components/authorization/errors.md +6 -6
  32. package/content/extensions/components/authorization/index.md +11 -10
  33. package/content/extensions/components/authorization/usage.md +21 -21
  34. package/content/extensions/components/health-check.md +1 -1
  35. package/content/extensions/components/index.md +5 -5
  36. package/content/extensions/components/mail/errors.md +15 -15
  37. package/content/extensions/components/mail/index.md +1 -2
  38. package/content/extensions/components/mail/usage.md +1 -1
  39. package/content/extensions/components/request-tracker.md +1 -1
  40. package/content/extensions/components/socket-io/api.md +9 -9
  41. package/content/extensions/components/socket-io/errors.md +5 -5
  42. package/content/extensions/components/socket-io/index.md +8 -8
  43. package/content/extensions/components/socket-io/usage.md +1 -1
  44. package/content/extensions/components/static-asset/api.md +17 -4
  45. package/content/extensions/components/static-asset/errors.md +4 -4
  46. package/content/extensions/components/static-asset/index.md +26 -28
  47. package/content/extensions/components/static-asset/usage.md +13 -12
  48. package/content/extensions/components/template/index.md +2 -2
  49. package/content/extensions/components/template/setup-page.md +1 -1
  50. package/content/extensions/components/websocket/api.md +3 -3
  51. package/content/extensions/components/websocket/errors.md +5 -5
  52. package/content/extensions/components/websocket/index.md +5 -5
  53. package/content/extensions/components/websocket/usage.md +3 -3
  54. package/content/extensions/helpers/cron/index.md +2 -2
  55. package/content/extensions/helpers/crypto/index.md +1 -1
  56. package/content/extensions/helpers/env/index.md +27 -12
  57. package/content/extensions/helpers/error/index.md +81 -25
  58. package/content/extensions/helpers/index.md +2 -3
  59. package/content/extensions/helpers/inversion/index.md +15 -7
  60. package/content/extensions/helpers/kafka/compile-binary.md +92 -0
  61. package/content/extensions/helpers/kafka/examples.md +1 -1
  62. package/content/extensions/helpers/kafka/index.md +3 -0
  63. package/content/extensions/helpers/logger/index.md +32 -2
  64. package/content/extensions/helpers/network/index.md +6 -0
  65. package/content/extensions/helpers/queue/index.md +14 -17
  66. package/content/extensions/helpers/redis/index.md +548 -323
  67. package/content/extensions/helpers/socket-io/index.md +14 -10
  68. package/content/extensions/helpers/storage/api.md +44 -8
  69. package/content/extensions/helpers/storage/index.md +43 -7
  70. package/content/extensions/helpers/template/index.md +6 -3
  71. package/content/extensions/helpers/types/index.md +11 -8
  72. package/content/extensions/helpers/websocket/api.md +9 -9
  73. package/content/extensions/helpers/websocket/index.md +7 -7
  74. package/content/extensions/helpers/worker-thread/index.md +2 -2
  75. package/content/extensions/index.md +3 -4
  76. package/content/extensions/src-details/mcp-server.md +18 -24
  77. package/content/guides/core-concepts/application/bootstrapping.md +11 -14
  78. package/content/guides/core-concepts/application/index.md +3 -3
  79. package/content/guides/core-concepts/components.md +19 -10
  80. package/content/guides/core-concepts/dependency-injection.md +6 -3
  81. package/content/guides/core-concepts/grpc-controllers.md +6 -5
  82. package/content/guides/core-concepts/persistent/datasources.md +42 -43
  83. package/content/guides/core-concepts/persistent/index.md +16 -7
  84. package/content/guides/core-concepts/persistent/models.md +24 -20
  85. package/content/guides/core-concepts/persistent/postgres-drivers.md +201 -0
  86. package/content/guides/core-concepts/persistent/repositories.md +40 -23
  87. package/content/guides/core-concepts/persistent/search-meilisearch.md +185 -0
  88. package/content/guides/core-concepts/persistent/search-typesense.md +431 -0
  89. package/content/guides/core-concepts/persistent/transactions.md +61 -25
  90. package/content/guides/core-concepts/rest-controllers.md +12 -9
  91. package/content/guides/core-concepts/services.md +330 -60
  92. package/content/guides/get-started/5-minute-quickstart.md +15 -15
  93. package/content/guides/get-started/philosophy.md +36 -36
  94. package/content/guides/get-started/setup.md +3 -3
  95. package/content/guides/index.md +3 -3
  96. package/content/guides/migrations/redis-helpers-migration.md +177 -0
  97. package/content/guides/migrations/scoped-rbac-migration.md +17 -17
  98. package/content/guides/migrations/unified-connectors-migration.md +113 -0
  99. package/content/guides/reference/glossary.md +19 -12
  100. package/content/guides/reference/mcp-docs-server.md +22 -18
  101. package/content/guides/tutorials/building-a-crud-api.md +37 -44
  102. package/content/guides/tutorials/complete-installation.md +17 -17
  103. package/content/guides/tutorials/ecommerce-api.md +163 -124
  104. package/content/guides/tutorials/realtime-chat.md +181 -135
  105. package/content/guides/tutorials/testing.md +65 -523
  106. package/content/index.md +2 -180
  107. package/content/public/apple-touch-icon.png +0 -0
  108. package/content/public/og-image.png +0 -0
  109. package/content/public/site.webmanifest +11 -0
  110. package/content/references/base/application.md +4 -5
  111. package/content/references/base/bootstrapping.md +18 -5
  112. package/content/references/base/components.md +149 -120
  113. package/content/references/base/connectors.md +178 -0
  114. package/content/references/base/controllers.md +41 -30
  115. package/content/references/base/datasources.md +163 -92
  116. package/content/references/base/dependency-injection.md +34 -22
  117. package/content/references/base/filter-system/application-usage.md +17 -14
  118. package/content/references/base/filter-system/array-operators.md +7 -2
  119. package/content/references/base/filter-system/comparison-operators.md +3 -0
  120. package/content/references/base/filter-system/default-filter.md +89 -71
  121. package/content/references/base/filter-system/fields-order-pagination.md +22 -22
  122. package/content/references/base/filter-system/index.md +6 -3
  123. package/content/references/base/filter-system/json-filtering.md +20 -1
  124. package/content/references/base/filter-system/list-operators.md +1 -1
  125. package/content/references/base/filter-system/logical-operators.md +33 -1
  126. package/content/references/base/filter-system/null-operators.md +30 -1
  127. package/content/references/base/filter-system/quick-reference.md +23 -4
  128. package/content/references/base/filter-system/tips.md +5 -5
  129. package/content/references/base/filter-system/use-cases.md +12 -12
  130. package/content/references/base/grpc-controllers.md +13 -13
  131. package/content/references/base/index.md +24 -12
  132. package/content/references/base/middlewares.md +265 -327
  133. package/content/references/base/models.md +63 -49
  134. package/content/references/base/providers.md +136 -130
  135. package/content/references/base/repositories/advanced.md +59 -58
  136. package/content/references/base/repositories/index.md +115 -91
  137. package/content/references/base/repositories/mixins.md +55 -291
  138. package/content/references/base/repositories/relations.md +54 -64
  139. package/content/references/base/repositories/soft-deletable.md +31 -30
  140. package/content/references/base/services.md +296 -93
  141. package/content/references/configuration/environment-variables.md +49 -31
  142. package/content/references/configuration/index.md +6 -6
  143. package/content/references/index.md +17 -12
  144. package/content/references/quick-reference.md +65 -106
  145. package/content/references/utilities/crypto.md +65 -23
  146. package/content/references/utilities/index.md +3 -3
  147. package/content/references/utilities/jsx.md +6 -4
  148. package/content/references/utilities/module.md +68 -20
  149. package/content/references/utilities/parse.md +4 -14
  150. package/content/references/utilities/promise.md +9 -7
  151. package/content/references/utilities/schema.md +5 -3
  152. package/dist/mcp-server/common/guards.d.ts +8 -0
  153. package/dist/mcp-server/common/guards.d.ts.map +1 -0
  154. package/dist/mcp-server/common/guards.js +14 -0
  155. package/dist/mcp-server/common/guards.js.map +1 -0
  156. package/dist/mcp-server/common/index.d.ts +1 -0
  157. package/dist/mcp-server/common/index.d.ts.map +1 -1
  158. package/dist/mcp-server/common/index.js +1 -0
  159. package/dist/mcp-server/common/index.js.map +1 -1
  160. package/dist/mcp-server/helpers/docs.helper.d.ts.map +1 -1
  161. package/dist/mcp-server/helpers/docs.helper.js +4 -2
  162. package/dist/mcp-server/helpers/docs.helper.js.map +1 -1
  163. package/dist/mcp-server/helpers/github.helper.js +1 -1
  164. package/dist/mcp-server/index.js +7 -2
  165. package/dist/mcp-server/index.js.map +1 -1
  166. package/dist/mcp-server/tools/base.tool.d.ts +6 -2
  167. package/dist/mcp-server/tools/base.tool.d.ts.map +1 -1
  168. package/dist/mcp-server/tools/base.tool.js.map +1 -1
  169. package/dist/mcp-server/tools/docs/search-documents.tool.d.ts +1 -1
  170. package/dist/mcp-server/tools/github/list-project-files.tool.d.ts +1 -1
  171. package/dist/mcp-server/tools/github/search-code.tool.d.ts +1 -1
  172. package/dist/mcp-server/tools/github/search-code.tool.d.ts.map +1 -1
  173. package/dist/mcp-server/tools/github/search-code.tool.js +4 -1
  174. package/dist/mcp-server/tools/github/search-code.tool.js.map +1 -1
  175. package/dist/mcp-server/tools/github/verify-dependencies.tool.d.ts.map +1 -1
  176. package/dist/mcp-server/tools/github/verify-dependencies.tool.js +3 -1
  177. package/dist/mcp-server/tools/github/verify-dependencies.tool.js.map +1 -1
  178. package/package.json +9 -9
  179. package/content/extensions/helpers/testing/index.md +0 -510
  180. package/content/references/base/middleware.md +0 -347
@@ -6,24 +6,31 @@ difficulty: intermediate
6
6
 
7
7
  # Deep Dive: Models and Enrichers
8
8
 
9
- Technical reference for model architecture and schema enrichers in Ignis.
9
+ Technical reference for model architecture and schema enrichers in IGNIS.
10
+
11
+ > [!IMPORTANT] Base vs. Connectors
12
+ > The engine-neutral root `AbstractEntity` (`packages/core/src/base/models/base.ts`) has no Drizzle, no `pgTable`, and no `drizzle-zod` - just a `name`, an abstract `getSchema()`, a `getIdType(): TIdSchemaType` method (default `'string'`), and `toObject()`/`toJSON()`. Everything described below - the Drizzle-backed `BaseEntity`, `drizzle-zod` schema generation, and all schema enrichers - belongs to the **PostgreSQL connector**'s `BasePostgresEntity`, not the neutral base. See [Connectors](./connectors) for the full base-vs-connectors architecture.
10
13
 
11
14
  **Files:**
12
- - `packages/core/src/base/models/base.ts`
13
- - `packages/core/src/base/models/enrichers/*.ts`
15
+ - `packages/core/src/base/models/base.ts` (neutral `AbstractEntity`)
16
+ - `packages/core/src/connectors/postgres/models/base.ts` (PostgreSQL `BasePostgresEntity`)
17
+ - `packages/core/src/connectors/postgres/models/enrichers/*.ts`
14
18
 
15
19
  ## Quick Reference
16
20
 
17
21
  | Component | Purpose | Key Features |
18
22
  |-----------|---------|--------------|
19
- | **BaseEntity** | Wraps Drizzle schema | Schema encapsulation, Zod generation, `toObject()`/`toJSON()` |
23
+ | **BasePostgresEntity** (alias: `BaseEntity`) | Wraps Drizzle schema | Schema encapsulation, Zod generation, `toObject()`/`toJSON()` |
20
24
  | **Schema Enrichers** | Add common columns to tables | `generateIdColumnDefs()`, `generateTzColumnDefs()`, etc. |
21
25
 
22
- ## `BaseEntity` Class
26
+ ## `BasePostgresEntity` Class (alias: `BaseEntity`)
27
+
28
+ PostgreSQL connector's entity class, wrapping a Drizzle ORM schema. Extends the neutral `AbstractEntity`.
23
29
 
24
- Fundamental building block wrapping a Drizzle ORM schema.
30
+ **File:** `packages/core/src/connectors/postgres/models/base.ts`
25
31
 
26
- **File:** `packages/core/src/base/models/base.ts`
32
+ > [!TIP] Naming
33
+ > `BasePostgresEntity` is the canonical, engine-carrying name. `BaseEntity` is a compatibility alias re-exporting the same class from `connectors/postgres/models/index.ts` (`export { BasePostgresEntity as BaseEntity } from './base'`) - both resolve to identical runtime behavior. Code samples on this page use `BaseEntity` since it remains the most common import today.
27
34
 
28
35
  ### Purpose
29
36
 
@@ -68,13 +75,13 @@ The `@model` decorator marks a class as a database entity and configures its beh
68
75
  | `settings.hiddenProperties` | `string[]` | Array of property names to exclude from all repository query results |
69
76
  | `settings.defaultFilter` | `TFilter` | Filter automatically applied to all repository queries (see [Default Filter](/references/base/filter-system/default-filter)) |
70
77
  | `settings.defaultLimit` | `number` | Default row limit applied when a query omits `limit`. Must be a positive integer (validated at decoration time). Falls back to the global `DEFAULT_LIMIT` (10). See [Pagination](/references/base/filter-system/fields-order-pagination#default-limit) |
71
- | `settings.authorize` | `IModelAuthorizeSettings` | Authorization settings declares the model's authorization principal (see [Authorization](/extensions/components/authorization/usage#model-based-resource-references)) |
78
+ | `settings.authorize` | `IModelAuthorizeSettings` | Authorization settings - declares the model's authorization principal (see [Authorization](/extensions/components/authorization/usage#model-based-resource-references)) |
72
79
  | `settings.authorize.principal` | `string` | The authorization subject name for this model. Auto-populates `AUTHORIZATION_SUBJECT` static property |
73
80
 
74
81
  #### `@model` Behavior
75
82
 
76
83
  When the `@model` decorator is applied:
77
- 1. If `settings.defaultLimit` is provided, it is validated to be a positive integer otherwise the decorator throws at decoration (boot) time
84
+ 1. If `settings.defaultLimit` is provided, it is validated to be a positive integer - otherwise the decorator throws at decoration (boot) time
78
85
  2. If `settings.authorize.principal` is provided and `AUTHORIZATION_SUBJECT` is not already defined on the class, it auto-populates `AUTHORIZATION_SUBJECT` with the principal value
79
86
  3. The model is registered in the `MetadataRegistry` model registry, keyed by table name (resolved as: `metadata.tableName` > `static TABLE_NAME` > class name)
80
87
  4. The static `relations` property is stored as a resolver (not immediately resolved) to avoid circular dependency issues between models
@@ -126,11 +133,11 @@ export class User extends BaseEntity<typeof User.schema> {
126
133
 
127
134
  ```typescript
128
135
  // Repository query - password/secret NOT included
129
- const user = await userRepo.findById({ id: '123' });
136
+ const user = await userRepository.findById({ id: '123' });
130
137
  // user = { id: '123', email: 'john@example.com' }
131
138
 
132
139
  // Direct connector query - ALL fields included
133
- const connector = userRepo.getConnector();
140
+ const connector = userRepository.getConnector();
134
141
  const [fullUser] = await connector
135
142
  .select()
136
143
  .from(User.schema)
@@ -178,11 +185,11 @@ Use `shouldSkipDefaultFilter: true` to bypass:
178
185
 
179
186
  ```typescript
180
187
  // Normal query - includes default filter
181
- await postRepo.find({ filter: {} });
188
+ await postRepository.find({ filter: {} });
182
189
  // WHERE isDeleted = false LIMIT 100
183
190
 
184
191
  // Admin query - bypass default filter
185
- await postRepo.find({
192
+ await postRepository.find({
186
193
  filter: {},
187
194
  options: { shouldSkipDefaultFilter: true }
188
195
  });
@@ -271,7 +278,7 @@ interface IEntity<Schema extends TTableSchemaWithId = TTableSchemaWithId> {
271
278
  |--------|-------------|
272
279
  | `getSchema({ type })` | Get Zod schema for validation (`'select'`, `'create'`, `'update'`) |
273
280
  | `toObject()` | Convert to plain object (shallow spread of `this`) |
274
- | `toJSON()` | Delegates to `toObject()` returns a plain object (used by `JSON.stringify`) |
281
+ | `toJSON()` | Delegates to `toObject()` - returns a plain object (used by `JSON.stringify`) |
275
282
 
276
283
  ### `getSchema` Method
277
284
 
@@ -307,12 +314,11 @@ The `schemaFactory` is a static lazy singleton created via `drizzle-zod`'s `crea
307
314
  ### Class Definition
308
315
 
309
316
  ```typescript
310
- export class BaseEntity<Schema extends TTableSchemaWithId = TTableSchemaWithId>
311
- extends BaseHelper
317
+ export class BasePostgresEntity<Schema extends TTableSchemaWithId = TTableSchemaWithId>
318
+ extends AbstractEntity
312
319
  implements IEntity<Schema>
313
320
  {
314
- // Instance properties
315
- name: string;
321
+ // Instance property (name, toObject(), toJSON() are inherited from AbstractEntity)
316
322
  schema: Schema;
317
323
 
318
324
  // Static properties - override in subclass
@@ -325,23 +331,27 @@ export class BaseEntity<Schema extends TTableSchemaWithId = TTableSchemaWithId>
325
331
  // Performance optimization: avoids creating new factory per entity
326
332
  private static _schemaFactory?: ReturnType<typeof createSchemaFactory>;
327
333
  protected static get schemaFactory(): ReturnType<typeof createSchemaFactory> {
328
- return (BaseEntity._schemaFactory ??= createSchemaFactory());
334
+ return (BasePostgresEntity._schemaFactory ??= createSchemaFactory());
329
335
  }
330
336
 
331
337
  // Constructor supports both patterns
332
338
  constructor(opts?: { name?: string; schema?: Schema }) {
333
- const ctor = new.target as typeof BaseEntity;
339
+ const ctor = new.target as typeof BasePostgresEntity;
334
340
  // Resolution order: opts.name > static TABLE_NAME > class name
335
341
  const name = opts?.name ?? ctor.TABLE_NAME ?? ctor.name;
336
342
 
337
- super({ scope: name });
343
+ super({ name });
338
344
 
339
- this.name = name;
340
345
  this.schema = opts?.schema || (ctor.schema as Schema);
341
346
  }
342
347
 
348
+ // Maps the pgTable id column's Drizzle dataType to 'number' or 'string'
349
+ override getIdType(): TIdSchemaType {
350
+ return getIdType({ entity: this.schema }) === 'number' ? 'number' : 'string';
351
+ }
352
+
343
353
  getSchema(opts: { type: TSchemaType }) {
344
- const factory = BaseEntity.schemaFactory; // Uses static singleton
354
+ const factory = BasePostgresEntity.schemaFactory; // Uses static singleton
345
355
  switch (opts.type) {
346
356
  case SchemaTypes.CREATE:
347
357
  return factory.createInsertSchema(this.schema);
@@ -355,14 +365,6 @@ export class BaseEntity<Schema extends TTableSchemaWithId = TTableSchemaWithId>
355
365
  });
356
366
  }
357
367
  }
358
-
359
- toObject() {
360
- return { ...this };
361
- }
362
-
363
- toJSON() {
364
- return this.toObject();
365
- }
366
368
  }
367
369
  ```
368
370
 
@@ -441,11 +443,11 @@ From `@venizia/ignis-helpers`, enables lazy resolution to avoid circular depende
441
443
  type TValueOrResolver<T> = T | TResolver<T>; // T or () => T
442
444
  ```
443
445
 
444
- Used for `relations` on `BaseEntity` store a function that returns the relations array, resolved lazily when `DataSource.buildSchema()` is called.
446
+ Used for `relations` on `BaseEntity` - store a function that returns the relations array, resolved lazily when `DataSource.buildSchema()` is called.
445
447
 
446
448
  ## Schema Enrichers
447
449
 
448
- Enrichers are helper functions located in `packages/core/src/base/models/enrichers/` that return an object of Drizzle ORM column definitions. They are designed to be spread into a `pgTable` definition to quickly add common, standardized fields to your models.
450
+ Enrichers are helper functions located in `packages/core/src/connectors/postgres/models/enrichers/` that return an object of Drizzle ORM column definitions. They are designed to be spread into a `pgTable` definition to quickly add common, standardized fields to your models.
449
451
 
450
452
  ### Available Enrichers
451
453
 
@@ -456,7 +458,7 @@ Enrichers are helper functions located in `packages/core/src/base/models/enriche
456
458
  | **`generateUserAuditColumnDefs`** | `enrichUserAudit` | Adds `createdBy` and `modifiedBy` columns to track user audit information. |
457
459
  | **`generatePrincipalColumnDefs`** | `enrichPrincipal` | Adds polymorphic principal columns (`{discriminator}Id` and `{discriminator}Type`). |
458
460
  | **`generateDataTypeColumnDefs`** | `enrichDataTypes` | Adds generic data type columns (`dataType`, `nValue`, `tValue`, `bValue`, `jValue`, `boValue`) for flexible data storage. |
459
- | **`extraUserColumns`** | | Adds common user fields (`realm`, `status`, `type`, `activatedAt`, `lastLoginAt`, `parentId`). Imported from `@venizia/ignis` (part of auth component). |
461
+ | **`extraUserColumns`** | - | Adds common user fields (`realm`, `status`, `type`, `activatedAt`, `lastLoginAt`, `parentId`). Imported from `@venizia/ignis` (part of auth component). |
460
462
 
461
463
  Each `generate*` function returns column definition objects for spreading into `pgTable`. The `enrich*` convenience wrappers accept an existing `TColumnDefinitions` object as the first argument and merge the generated columns into it.
462
464
 
@@ -488,7 +490,7 @@ export const myTable = pgTable('MyTable', {
488
490
 
489
491
  Adds a primary key `id` column with support for string UUID, integer, or big integer types with full TypeScript type inference.
490
492
 
491
- **File:** `packages/core/src/base/models/enrichers/id.enricher.ts`
493
+ **File:** `packages/core/src/connectors/postgres/models/enrichers/id.enricher.ts`
492
494
 
493
495
  #### Signature
494
496
 
@@ -688,7 +690,7 @@ const columns = enrichId(
688
690
 
689
691
  Adds timestamp columns for tracking entity creation, modification, and soft deletion.
690
692
 
691
- **File:** `packages/core/src/base/models/enrichers/tz.enricher.ts`
693
+ **File:** `packages/core/src/connectors/postgres/models/enrichers/tz.enricher.ts`
692
694
 
693
695
  #### Signature
694
696
 
@@ -722,7 +724,7 @@ The `modified` and `deleted` options use a discriminated union pattern:
722
724
  | Column | Type | Constraints | Default | Description |
723
725
  |--------|------|-------------|---------|-------------|
724
726
  | `createdAt` | `timestamp` | `NOT NULL` | `now()` | When the record was created (always included) |
725
- | `modifiedAt` | `timestamp` | `NOT NULL` | `now()`, auto-updates via `$onUpdate(() => new Date())` | When the record was last modified (optional, enabled by default) |
727
+ | `modifiedAt` | `timestamp` | `NOT NULL` | `now()`, auto-updates via `$onUpdate(() => new Date().toISOString())` | When the record was last modified (optional, enabled by default) |
726
728
  | `deletedAt` | `timestamp` | nullable | `null` | When the record was soft-deleted (optional, **disabled by default**) |
727
729
 
728
730
  #### Usage Examples
@@ -831,8 +833,10 @@ await db.update(myTable)
831
833
  The enricher provides **conditional TypeScript type inference** based on the options:
832
834
 
833
835
  ```typescript
836
+ type TIsoTimestampColumn = ReturnType<typeof isoTimestamp>; // custom ISO 8601 timestamp column
837
+
834
838
  type TTzEnricherResult<Opts extends TTzEnricherOptions | undefined = undefined> = {
835
- createdAt: NotNull<HasDefault<PgTimestampBuilderInitial<string>>>;
839
+ createdAt: NotNull<HasDefault<TIsoTimestampColumn>>;
836
840
  } & (/* modifiedAt included unless opts.modified.enable === false */)
837
841
  & (/* deletedAt included only when opts.deleted.enable === true */);
838
842
  ```
@@ -854,7 +858,7 @@ Merges timestamp columns into an existing column definitions object.
854
858
 
855
859
  Adds `createdBy` and `modifiedBy` columns to track which user created or modified a record.
856
860
 
857
- **File:** `packages/core/src/base/models/enrichers/user-audit.enricher.ts`
861
+ **File:** `packages/core/src/connectors/postgres/models/enrichers/user-audit.enricher.ts`
858
862
 
859
863
  #### Signature
860
864
 
@@ -888,8 +892,8 @@ type TUserAuditEnricherOptions = {
888
892
 
889
893
  The enricher uses Hono's `contextStorage` (via `tryGetContext()`) to automatically retrieve the current user ID from the request context at insert/update time:
890
894
 
891
- - **`createdBy`**: Set via `$default()` only populated on record creation
892
- - **`modifiedBy`**: Set via both `$default()` and `$onUpdate()` populated on creation and updated on every modification
895
+ - **`createdBy`**: Set via `$default()` - only populated on record creation
896
+ - **`modifiedBy`**: Set via both `$default()` and `$onUpdate()` - populated on creation and updated on every modification
893
897
 
894
898
  The user ID is read from the `Authentication.AUDIT_USER_ID` key in the Hono context.
895
899
 
@@ -1023,7 +1027,7 @@ Merges user audit columns into an existing column definitions object with proper
1023
1027
 
1024
1028
  Adds polymorphic principal columns for associating a record with different entity types. This is the polymorphic association pattern where a row can belong to different parent types (e.g., a comment can belong to a Post, User, or Product).
1025
1029
 
1026
- **File:** `packages/core/src/base/models/enrichers/principal.enricher.ts`
1030
+ **File:** `packages/core/src/connectors/postgres/models/enrichers/principal.enricher.ts`
1027
1031
 
1028
1032
  #### Signature
1029
1033
 
@@ -1142,7 +1146,7 @@ Merges principal columns into an existing column definitions object.
1142
1146
 
1143
1147
  Adds polymorphic data storage columns for entities that need to store values of different types in a single table. This is useful for key-value stores, settings tables, or any schema where a row's value type is determined at runtime.
1144
1148
 
1145
- **File:** `packages/core/src/base/models/enrichers/data-type.enricher.ts`
1149
+ **File:** `packages/core/src/connectors/postgres/models/enrichers/data-type.enricher.ts`
1146
1150
 
1147
1151
  #### Signature
1148
1152
 
@@ -1215,7 +1219,7 @@ export const settingTable = pgTable('Setting', {
1215
1219
  // Generates columns with SQL defaults:
1216
1220
  // data_type text DEFAULT 'text'
1217
1221
  // t_value text DEFAULT ''
1218
- // nValue, bValue, jValue, boValue no defaults
1222
+ // nValue, bValue, jValue, boValue - no defaults
1219
1223
  ```
1220
1224
 
1221
1225
  **Key-value store pattern:**
@@ -1276,7 +1280,7 @@ Generates a Zod schema for path parameters containing an `id` field, suitable fo
1276
1280
  #### Signature
1277
1281
 
1278
1282
  ```typescript
1279
- idParamsSchema(opts?: { idType: string }): z.ZodObject<{ id: z.ZodNumber | z.ZodString }>
1283
+ idParamsSchema(opts?: { idType: TIdSchemaType }): z.ZodObject<{ id: z.ZodNumber | z.ZodString }>
1280
1284
  ```
1281
1285
 
1282
1286
  | `idType` | Default | Zod Type | Examples |
@@ -1479,13 +1483,23 @@ try {
1479
1483
 
1480
1484
  ### `getIdType`
1481
1485
 
1482
- Utility function to determine the data type of an entity's `id` column at runtime:
1486
+ There are two distinct `getIdType`s in the framework - don't confuse them:
1487
+
1488
+ | | Neutral instance method | PostgreSQL utility function |
1489
+ |---|---|---|
1490
+ | **Location** | `AbstractEntity.getIdType()` (`packages/core/src/base/models/base.ts`) | `getIdType()` (`packages/core/src/connectors/postgres/models/common/types.ts`) |
1491
+ | **Signature** | `getIdType(): TIdSchemaType` | `getIdType<T extends TTableSchemaWithId>(opts: { entity: T }): string` |
1492
+ | **Purpose** | Neutral capability every engine's entity implements - returns `'string'` \| `'number'` at the entity level. Used by `idParamsSchema` to build the right Zod schema for path parameters. | PostgreSQL-specific: inspects a Drizzle table schema's `id` column and returns its `dataType` (e.g., `'number'`, `'string'`), or `'unknown'` if not determinable |
1483
1493
 
1484
1494
  ```typescript
1485
- getIdType<T extends TTableSchemaWithId>(opts: { entity: T }): string
1486
- ```
1495
+ // Neutral - instance method every AbstractEntity subclass exposes (default 'string', BasePostgresEntity overrides based on the column)
1496
+ const entity = new User();
1497
+ entity.getIdType(); // 'string' | 'number'
1487
1498
 
1488
- Returns the `dataType` property of the entity's `id` column (e.g., `'number'`, `'string'`), or `'unknown'` if not determinable.
1499
+ // PostgreSQL connector - standalone utility inspecting a raw Drizzle schema
1500
+ import { getIdType } from '@venizia/ignis/postgres';
1501
+ getIdType({ entity: User.schema }); // 'string' | 'number' | 'unknown'
1502
+ ```
1489
1503
 
1490
1504
  ## See Also
1491
1505