@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.
- package/README.md +7 -7
- package/content/best-practices/api-usage-examples.md +15 -12
- package/content/best-practices/architectural-patterns.md +70 -78
- package/content/best-practices/architecture-decisions.md +91 -60
- package/content/best-practices/code-style-standards/advanced-patterns.md +56 -44
- package/content/best-practices/code-style-standards/constants-configuration.md +11 -11
- package/content/best-practices/code-style-standards/control-flow.md +5 -2
- package/content/best-practices/code-style-standards/documentation.md +13 -13
- package/content/best-practices/code-style-standards/function-patterns.md +9 -10
- package/content/best-practices/code-style-standards/index.md +1 -1
- package/content/best-practices/code-style-standards/naming-conventions.md +10 -8
- package/content/best-practices/code-style-standards/route-definitions.md +30 -12
- package/content/best-practices/code-style-standards/tooling.md +8 -5
- package/content/best-practices/code-style-standards/type-safety.md +13 -12
- package/content/best-practices/common-pitfalls.md +56 -37
- package/content/best-practices/contribution-workflow.md +13 -14
- package/content/best-practices/data-modeling.md +46 -22
- package/content/best-practices/deployment-strategies.md +28 -27
- package/content/best-practices/error-handling.md +48 -24
- package/content/best-practices/index.md +5 -5
- package/content/best-practices/performance-optimization.md +40 -31
- package/content/best-practices/security-guidelines.md +52 -23
- package/content/best-practices/testing-strategies.md +65 -51
- package/content/best-practices/troubleshooting-tips.md +24 -24
- package/content/extensions/components/{swagger.md → api-reference.md} +40 -31
- package/content/extensions/components/authentication/api.md +19 -19
- package/content/extensions/components/authentication/errors.md +7 -7
- package/content/extensions/components/authentication/index.md +10 -8
- package/content/extensions/components/authentication/usage.md +101 -6
- package/content/extensions/components/authorization/api.md +45 -25
- package/content/extensions/components/authorization/errors.md +6 -6
- package/content/extensions/components/authorization/index.md +11 -10
- package/content/extensions/components/authorization/usage.md +21 -21
- package/content/extensions/components/health-check.md +1 -1
- package/content/extensions/components/index.md +5 -5
- package/content/extensions/components/mail/errors.md +15 -15
- package/content/extensions/components/mail/index.md +1 -2
- package/content/extensions/components/mail/usage.md +1 -1
- package/content/extensions/components/request-tracker.md +1 -1
- package/content/extensions/components/socket-io/api.md +9 -9
- package/content/extensions/components/socket-io/errors.md +5 -5
- package/content/extensions/components/socket-io/index.md +8 -8
- package/content/extensions/components/socket-io/usage.md +1 -1
- package/content/extensions/components/static-asset/api.md +17 -4
- package/content/extensions/components/static-asset/errors.md +4 -4
- package/content/extensions/components/static-asset/index.md +26 -28
- package/content/extensions/components/static-asset/usage.md +13 -12
- package/content/extensions/components/template/index.md +2 -2
- package/content/extensions/components/template/setup-page.md +1 -1
- package/content/extensions/components/websocket/api.md +3 -3
- package/content/extensions/components/websocket/errors.md +5 -5
- package/content/extensions/components/websocket/index.md +5 -5
- package/content/extensions/components/websocket/usage.md +3 -3
- package/content/extensions/helpers/cron/index.md +2 -2
- package/content/extensions/helpers/crypto/index.md +1 -1
- package/content/extensions/helpers/env/index.md +27 -12
- package/content/extensions/helpers/error/index.md +81 -25
- package/content/extensions/helpers/index.md +2 -3
- package/content/extensions/helpers/inversion/index.md +15 -7
- package/content/extensions/helpers/kafka/compile-binary.md +92 -0
- package/content/extensions/helpers/kafka/examples.md +1 -1
- package/content/extensions/helpers/kafka/index.md +3 -0
- package/content/extensions/helpers/logger/index.md +32 -2
- package/content/extensions/helpers/network/index.md +6 -0
- package/content/extensions/helpers/queue/index.md +14 -17
- package/content/extensions/helpers/redis/index.md +548 -323
- package/content/extensions/helpers/socket-io/index.md +14 -10
- package/content/extensions/helpers/storage/api.md +44 -8
- package/content/extensions/helpers/storage/index.md +43 -7
- package/content/extensions/helpers/template/index.md +6 -3
- package/content/extensions/helpers/types/index.md +11 -8
- package/content/extensions/helpers/websocket/api.md +9 -9
- package/content/extensions/helpers/websocket/index.md +7 -7
- package/content/extensions/helpers/worker-thread/index.md +2 -2
- package/content/extensions/index.md +3 -4
- package/content/extensions/src-details/mcp-server.md +18 -24
- package/content/guides/core-concepts/application/bootstrapping.md +11 -14
- package/content/guides/core-concepts/application/index.md +3 -3
- package/content/guides/core-concepts/components.md +19 -10
- package/content/guides/core-concepts/dependency-injection.md +6 -3
- package/content/guides/core-concepts/grpc-controllers.md +6 -5
- package/content/guides/core-concepts/persistent/datasources.md +42 -43
- package/content/guides/core-concepts/persistent/index.md +16 -7
- package/content/guides/core-concepts/persistent/models.md +24 -20
- package/content/guides/core-concepts/persistent/postgres-drivers.md +201 -0
- package/content/guides/core-concepts/persistent/repositories.md +40 -23
- package/content/guides/core-concepts/persistent/search-meilisearch.md +185 -0
- package/content/guides/core-concepts/persistent/search-typesense.md +431 -0
- package/content/guides/core-concepts/persistent/transactions.md +61 -25
- package/content/guides/core-concepts/rest-controllers.md +12 -9
- package/content/guides/core-concepts/services.md +330 -60
- package/content/guides/get-started/5-minute-quickstart.md +15 -15
- package/content/guides/get-started/philosophy.md +36 -36
- package/content/guides/get-started/setup.md +3 -3
- package/content/guides/index.md +3 -3
- package/content/guides/migrations/redis-helpers-migration.md +177 -0
- package/content/guides/migrations/scoped-rbac-migration.md +17 -17
- package/content/guides/migrations/unified-connectors-migration.md +113 -0
- package/content/guides/reference/glossary.md +19 -12
- package/content/guides/reference/mcp-docs-server.md +22 -18
- package/content/guides/tutorials/building-a-crud-api.md +37 -44
- package/content/guides/tutorials/complete-installation.md +17 -17
- package/content/guides/tutorials/ecommerce-api.md +163 -124
- package/content/guides/tutorials/realtime-chat.md +181 -135
- package/content/guides/tutorials/testing.md +65 -523
- package/content/index.md +2 -180
- package/content/public/apple-touch-icon.png +0 -0
- package/content/public/og-image.png +0 -0
- package/content/public/site.webmanifest +11 -0
- package/content/references/base/application.md +4 -5
- package/content/references/base/bootstrapping.md +18 -5
- package/content/references/base/components.md +149 -120
- package/content/references/base/connectors.md +178 -0
- package/content/references/base/controllers.md +41 -30
- package/content/references/base/datasources.md +163 -92
- package/content/references/base/dependency-injection.md +34 -22
- package/content/references/base/filter-system/application-usage.md +17 -14
- package/content/references/base/filter-system/array-operators.md +7 -2
- package/content/references/base/filter-system/comparison-operators.md +3 -0
- package/content/references/base/filter-system/default-filter.md +89 -71
- package/content/references/base/filter-system/fields-order-pagination.md +22 -22
- package/content/references/base/filter-system/index.md +6 -3
- package/content/references/base/filter-system/json-filtering.md +20 -1
- package/content/references/base/filter-system/list-operators.md +1 -1
- package/content/references/base/filter-system/logical-operators.md +33 -1
- package/content/references/base/filter-system/null-operators.md +30 -1
- package/content/references/base/filter-system/quick-reference.md +23 -4
- package/content/references/base/filter-system/tips.md +5 -5
- package/content/references/base/filter-system/use-cases.md +12 -12
- package/content/references/base/grpc-controllers.md +13 -13
- package/content/references/base/index.md +24 -12
- package/content/references/base/middlewares.md +265 -327
- package/content/references/base/models.md +63 -49
- package/content/references/base/providers.md +136 -130
- package/content/references/base/repositories/advanced.md +59 -58
- package/content/references/base/repositories/index.md +115 -91
- package/content/references/base/repositories/mixins.md +55 -291
- package/content/references/base/repositories/relations.md +54 -64
- package/content/references/base/repositories/soft-deletable.md +31 -30
- package/content/references/base/services.md +296 -93
- package/content/references/configuration/environment-variables.md +49 -31
- package/content/references/configuration/index.md +6 -6
- package/content/references/index.md +17 -12
- package/content/references/quick-reference.md +65 -106
- package/content/references/utilities/crypto.md +65 -23
- package/content/references/utilities/index.md +3 -3
- package/content/references/utilities/jsx.md +6 -4
- package/content/references/utilities/module.md +68 -20
- package/content/references/utilities/parse.md +4 -14
- package/content/references/utilities/promise.md +9 -7
- package/content/references/utilities/schema.md +5 -3
- package/dist/mcp-server/common/guards.d.ts +8 -0
- package/dist/mcp-server/common/guards.d.ts.map +1 -0
- package/dist/mcp-server/common/guards.js +14 -0
- package/dist/mcp-server/common/guards.js.map +1 -0
- package/dist/mcp-server/common/index.d.ts +1 -0
- package/dist/mcp-server/common/index.d.ts.map +1 -1
- package/dist/mcp-server/common/index.js +1 -0
- package/dist/mcp-server/common/index.js.map +1 -1
- package/dist/mcp-server/helpers/docs.helper.d.ts.map +1 -1
- package/dist/mcp-server/helpers/docs.helper.js +4 -2
- package/dist/mcp-server/helpers/docs.helper.js.map +1 -1
- package/dist/mcp-server/helpers/github.helper.js +1 -1
- package/dist/mcp-server/index.js +7 -2
- package/dist/mcp-server/index.js.map +1 -1
- package/dist/mcp-server/tools/base.tool.d.ts +6 -2
- package/dist/mcp-server/tools/base.tool.d.ts.map +1 -1
- package/dist/mcp-server/tools/base.tool.js.map +1 -1
- package/dist/mcp-server/tools/docs/search-documents.tool.d.ts +1 -1
- package/dist/mcp-server/tools/github/list-project-files.tool.d.ts +1 -1
- package/dist/mcp-server/tools/github/search-code.tool.d.ts +1 -1
- package/dist/mcp-server/tools/github/search-code.tool.d.ts.map +1 -1
- package/dist/mcp-server/tools/github/search-code.tool.js +4 -1
- package/dist/mcp-server/tools/github/search-code.tool.js.map +1 -1
- package/dist/mcp-server/tools/github/verify-dependencies.tool.d.ts.map +1 -1
- package/dist/mcp-server/tools/github/verify-dependencies.tool.js +3 -1
- package/dist/mcp-server/tools/github/verify-dependencies.tool.js.map +1 -1
- package/package.json +9 -9
- package/content/extensions/helpers/testing/index.md +0 -510
- 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
|
|
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/
|
|
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
|
-
| **
|
|
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
|
-
## `
|
|
26
|
+
## `BasePostgresEntity` Class (alias: `BaseEntity`)
|
|
27
|
+
|
|
28
|
+
PostgreSQL connector's entity class, wrapping a Drizzle ORM schema. Extends the neutral `AbstractEntity`.
|
|
23
29
|
|
|
24
|
-
|
|
30
|
+
**File:** `packages/core/src/connectors/postgres/models/base.ts`
|
|
25
31
|
|
|
26
|
-
|
|
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
|
|
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
|
|
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
|
|
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 =
|
|
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
|
|
188
|
+
await postRepository.find({ filter: {} });
|
|
182
189
|
// WHERE isDeleted = false LIMIT 100
|
|
183
190
|
|
|
184
191
|
// Admin query - bypass default filter
|
|
185
|
-
await
|
|
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()`
|
|
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
|
|
311
|
-
extends
|
|
317
|
+
export class BasePostgresEntity<Schema extends TTableSchemaWithId = TTableSchemaWithId>
|
|
318
|
+
extends AbstractEntity
|
|
312
319
|
implements IEntity<Schema>
|
|
313
320
|
{
|
|
314
|
-
// Instance
|
|
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 (
|
|
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
|
|
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({
|
|
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 =
|
|
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`
|
|
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/
|
|
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`** |
|
|
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/
|
|
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/
|
|
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<
|
|
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/
|
|
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()`
|
|
892
|
-
- **`modifiedBy`**: Set via both `$default()` and `$onUpdate()`
|
|
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/
|
|
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/
|
|
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
|
|
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:
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|