@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
@@ -1,8 +1,11 @@
1
1
  # Repositories Overview
2
2
 
3
- Repositories are the data access layer in Ignis - they provide type-safe CRUD operations for your database entities.
3
+ Repositories are the data access layer in IGNIS - they provide type-safe CRUD operations for your database entities.
4
4
 
5
- **Files:** `packages/core/src/base/repositories/core/*.ts`
5
+ > [!IMPORTANT] Base vs. Connectors
6
+ > `AbstractRepository` (`packages/core/src/base/repositories/core/abstract.ts`) is the engine-neutral root shared by both connectors - it declares the CRUD contract but has no Drizzle, SQL, or mixin composition. The concrete classes documented on this page (`ReadableRepository`, `PersistableRepository`, `DefaultCRUDRepository`, `SoftDeletableRepository`) belong to the **PostgreSQL connector**, built on `PostgresBaseRepository`. Typesense has its own parallel tier - see [Connectors](/references/base/connectors) and [Search & Typesense](/guides/core-concepts/persistent/search-typesense).
7
+
8
+ **Files:** `packages/core/src/base/repositories/core/abstract.ts` (neutral) and `packages/core/src/connectors/postgres/repositories/core/*.ts` (PostgreSQL)
6
9
 
7
10
 
8
11
  ## Quick Start
@@ -25,7 +28,7 @@ export class TodoRepository extends DefaultCRUDRepository<typeof Todo.schema> {
25
28
 
26
29
  | Class | Capabilities | Use Case |
27
30
  |-------|--------------|----------|
28
- | **AbstractRepository** | Base class with properties, mixins, lazy resolution | Extend for custom repositories |
31
+ | **AbstractRepository** | Engine-neutral base class with lazy dataSource/entity resolution and @model settings getters | Extend for custom repositories |
29
32
  | **ReadableRepository** | Read-only operations (write methods throw errors) | Views, external tables, read-only access |
30
33
  | **PersistableRepository** | Read + Write operations | Full CRUD access |
31
34
  | **DefaultCRUDRepository** | Extends PersistableRepository (no additions) | Standard data tables (recommended) |
@@ -37,19 +40,22 @@ export class TodoRepository extends DefaultCRUDRepository<typeof Todo.schema> {
37
40
 
38
41
  ```
39
42
  BaseHelper
40
- + FieldsVisibilityMixin
41
- + DefaultFilterMixin
42
- = AbstractRepository (abstract base, declares all CRUD signatures)
43
+ = AbstractRepository (engine-neutral abstract base, declares all CRUD signatures, src/base)
43
44
  |
44
- +-- ReadableRepository (implements read ops; write ops throw errors)
45
+ +-- PostgresBaseRepository (PostgreSQL connector; hidden-fields + default-filter logic, no mixins)
45
46
  |
46
- +-- PersistableRepository (implements write + delete ops, READ_WRITE scope)
47
+ +-- ReadableRepository (implements read ops; write ops throw errors)
47
48
  |
48
- +-- DefaultCRUDRepository (empty subclass, recommended entry point)
49
+ +-- PersistableRepository (implements write + delete ops, READ_WRITE scope)
49
50
  |
50
- +-- SoftDeletableRepository (overrides delete with soft-delete)
51
+ +-- DefaultCRUDRepository (empty subclass, recommended entry point)
52
+ |
53
+ +-- SoftDeletableRepository (overrides delete with soft-delete)
51
54
  ```
52
55
 
56
+ > [!NOTE]
57
+ > Prior to the connectors restructure, `AbstractRepository` composed `FieldsVisibilityMixin`/`DefaultFilterMixin` directly onto `BaseHelper`. Those mixins have been **removed** - see [Repository Mixins](./mixins) - and the equivalent behavior lives in `AbstractRepository`'s settings getters and `PostgresBaseRepository` instead.
58
+
53
59
  ### Type Parameters
54
60
 
55
61
  All repository classes share the same four type parameters:
@@ -59,7 +65,7 @@ class DefaultCRUDRepository<
59
65
  EntitySchema extends TTableSchemaWithId = TTableSchemaWithId,
60
66
  DataObject extends TTableObject<EntitySchema> = TTableObject<EntitySchema>,
61
67
  PersistObject extends TTableInsert<EntitySchema> = TTableInsert<EntitySchema>,
62
- ExtraOptions extends IExtraOptions = IExtraOptions,
68
+ ExtraOptions extends IExtraOptions = IDatabaseExtraOptions,
63
69
  >
64
70
  ```
65
71
 
@@ -68,7 +74,7 @@ class DefaultCRUDRepository<
68
74
  | `EntitySchema` | The Drizzle `pgTable` schema type (e.g., `typeof User.schema`) |
69
75
  | `DataObject` | The inferred SELECT type from the schema |
70
76
  | `PersistObject` | The inferred INSERT type from the schema |
71
- | `ExtraOptions` | Extra options for operations (defaults to `IExtraOptions`) |
77
+ | `ExtraOptions` | Extra options for operations (defaults to `IDatabaseExtraOptions`, which narrows `IExtraOptions.transaction` to `IDatabaseTransaction`) |
72
78
 
73
79
 
74
80
  ## Available Methods
@@ -76,24 +82,24 @@ class DefaultCRUDRepository<
76
82
  ### Read Operations
77
83
  | Method | Description | Example |
78
84
  |--------|-------------|---------|
79
- | `find(opts)` | Find multiple records | `repo.find({ filter: { where: { status: 'active' } } })` |
80
- | `find(opts)` with range | Find with pagination range | `repo.find({ filter, options: { shouldQueryRange: true } })` |
81
- | `findOne(opts)` | Find single record | `repo.findOne({ filter: { where: { email } } })` |
82
- | `findById(opts)` | Find by primary key | `repo.findById({ id: '123' })` |
83
- | `count(opts)` | Count matching records | `repo.count({ where: { status: 'active' } })` |
84
- | `existsWith(opts)` | Check if exists | `repo.existsWith({ where: { email } })` |
85
+ | `find(opts)` | Find multiple records | `repository.find({ filter: { where: { status: 'active' } } })` |
86
+ | `find(opts)` with range | Find with pagination range | `repository.find({ filter, options: { shouldQueryRange: true } })` |
87
+ | `findOne(opts)` | Find single record | `repository.findOne({ filter: { where: { email } } })` |
88
+ | `findById(opts)` | Find by primary key | `repository.findById({ id: '123' })` |
89
+ | `count(opts)` | Count matching records | `repository.count({ where: { status: 'active' } })` |
90
+ | `existsWith(opts)` | Check if exists | `repository.existsWith({ where: { email } })` |
85
91
 
86
92
  ### Write Operations
87
93
  | Method | Description | Example |
88
94
  |--------|-------------|---------|
89
- | `create(opts)` | Create single record | `repo.create({ data: { title: 'New' } })` |
90
- | `createAll(opts)` | Create multiple records | `repo.createAll({ data: [{ title: 'A' }, { title: 'B' }] })` |
91
- | `updateById(opts)` | Update by primary key | `repo.updateById({ id: '123', data: { title: 'Updated' } })` |
92
- | `updateAll(opts)` | Update matching records | `repo.updateAll({ data: { status: 'published' }, where: { status: 'draft' } })` |
93
- | `updateBy(opts)` | Alias for `updateAll` | `repo.updateBy({ data: { status: 'published' }, where: { status: 'draft' } })` |
94
- | `deleteById(opts)` | Delete by primary key | `repo.deleteById({ id: '123' })` |
95
- | `deleteAll(opts)` | Delete matching records | `repo.deleteAll({ where: { status: 'archived' } })` |
96
- | `deleteBy(opts)` | Alias for `deleteAll` | `repo.deleteBy({ where: { status: 'archived' } })` |
95
+ | `create(opts)` | Create single record | `repository.create({ data: { title: 'New' } })` |
96
+ | `createAll(opts)` | Create multiple records | `repository.createAll({ data: [{ title: 'A' }, { title: 'B' }] })` |
97
+ | `updateById(opts)` | Update by primary key | `repository.updateById({ id: '123', data: { title: 'Updated' } })` |
98
+ | `updateAll(opts)` | Update matching records | `repository.updateAll({ data: { status: 'published' }, where: { status: 'draft' } })` |
99
+ | `updateBy(opts)` | Alias for `updateAll` | `repository.updateBy({ data: { status: 'published' }, where: { status: 'draft' } })` |
100
+ | `deleteById(opts)` | Delete by primary key | `repository.deleteById({ id: '123' })` |
101
+ | `deleteAll(opts)` | Delete matching records | `repository.deleteAll({ where: { status: 'archived' } })` |
102
+ | `deleteBy(opts)` | Alias for `deleteAll` | `repository.deleteBy({ where: { status: 'archived' } })` |
97
103
 
98
104
 
99
105
  ## Method Signatures
@@ -230,7 +236,7 @@ All repository operations accept an `options` parameter with these fields:
230
236
 
231
237
  ```typescript
232
238
  interface IExtraOptions {
233
- /** Transaction context switches the underlying Drizzle connector. */
239
+ /** Transaction context - switches the underlying Drizzle connector. */
234
240
  transaction?: ITransaction;
235
241
 
236
242
  /** Operation logging configuration. */
@@ -238,9 +244,15 @@ interface IExtraOptions {
238
244
 
239
245
  /** If true, bypass the default filter configured in model settings (e.g., soft delete). */
240
246
  shouldSkipDefaultFilter?: boolean;
247
+
248
+ /** Row-level locking (requires transaction, incompatible with Query API). */
249
+ lock?: TLockOptions;
241
250
  }
242
251
  ```
243
252
 
253
+ > [!NOTE]
254
+ > Postgres narrows this via `IDatabaseExtraOptions` (`connectors/postgres/repositories/common`), which overrides `transaction` to `IDatabaseTransaction` so `options.transaction.connector` needs no cast.
255
+
244
256
  Additional fields are available as intersections on specific methods:
245
257
 
246
258
  | Field | Type | Methods | Description |
@@ -263,16 +275,21 @@ type TDataRange = {
263
275
  ```
264
276
 
265
277
 
266
- ## AbstractRepository Properties
278
+ ## AbstractRepository / PostgresBaseRepository Properties
267
279
 
268
280
  ### dataSource
269
281
 
270
282
  Getter/setter for the repository's datasource. Throws if accessed before being set (either via constructor or `@repository` auto-injection).
271
283
 
272
284
  ```typescript
273
- get dataSource(): IDataSource;
274
- set dataSource(value: IDataSource);
275
- setDataSource(opts: { dataSource: IDataSource }): void;
285
+ // AbstractRepository (engine-neutral, src/base)
286
+ get dataSource(): AbstractDataSource;
287
+ set dataSource(value: AbstractDataSource);
288
+ setDataSource(opts: { dataSource: AbstractDataSource }): void;
289
+
290
+ // PostgresBaseRepository narrows the return type
291
+ get dataSource(): IPostgresDataSource;
292
+ set dataSource(value: IPostgresDataSource);
276
293
  ```
277
294
 
278
295
  ### entity
@@ -280,12 +297,19 @@ setDataSource(opts: { dataSource: IDataSource }): void;
280
297
  Lazy-resolved from `@repository` metadata on first access. Can also be set explicitly via constructor `entityClass` option.
281
298
 
282
299
  ```typescript
283
- get entity(): BaseEntity<EntitySchema>;
284
- set entity(value: BaseEntity<EntitySchema>);
285
- getEntity(): BaseEntity<EntitySchema>;
300
+ // AbstractRepository
301
+ get entity(): AbstractEntity;
302
+ set entity(value: AbstractEntity);
303
+ getEntity(): AbstractEntity;
304
+
305
+ // PostgresBaseRepository narrows the return type
306
+ get entity(): BasePostgresEntity<EntitySchema>;
307
+ set entity(value: BasePostgresEntity<EntitySchema>);
286
308
  getEntitySchema(): EntitySchema;
287
309
  ```
288
310
 
311
+ `BaseEntity` is a compatibility alias re-exported for `BasePostgresEntity` - prefer `BasePostgresEntity` in new code.
312
+
289
313
  ### operationScope
290
314
 
291
315
  Returns the repository's operation scope: `'READ_ONLY'`, `'WRITE_ONLY'`, or `'READ_WRITE'`.
@@ -297,21 +321,21 @@ get operationScope(): TRepositoryOperationScope;
297
321
  - `ReadableRepository` defaults to `READ_ONLY`
298
322
  - `PersistableRepository` and `DefaultCRUDRepository` default to `READ_WRITE`
299
323
 
300
- ### filterBuilder
324
+ ### filterBuilder (PostgresBaseRepository+)
301
325
 
302
- Access to the `FilterBuilder` instance used for converting filter objects to Drizzle SQL.
326
+ Access to the `FilterBuilder` instance used for converting filter objects to Drizzle SQL. Not present on the engine-neutral `AbstractRepository`.
303
327
 
304
328
  ```typescript
305
329
  get filterBuilder(): FilterBuilder;
306
330
  ```
307
331
 
308
- ### connector
332
+ ### connector (PostgresBaseRepository+)
309
333
 
310
- Shortcut for `this.dataSource.connector`.
334
+ Shortcut for `this.dataSource.connector`. Not present on the engine-neutral `AbstractRepository`.
311
335
 
312
336
  ```typescript
313
- get connector(): IDataSource['connector'];
314
- getConnector(): IDataSource['connector'];
337
+ get connector(): IPostgresDataSource['connector'];
338
+ getConnector(): IPostgresDataSource['connector'];
315
339
  ```
316
340
 
317
341
  ### updateBuilder (PersistableRepository+)
@@ -325,21 +349,21 @@ get updateBuilder(): UpdateBuilder;
325
349
 
326
350
  ## Key Methods
327
351
 
328
- ### beginTransaction
352
+ ### beginTransaction (PostgresBaseRepository+)
329
353
 
330
- Start a new database transaction through the repository's datasource:
354
+ Delegates to the repository's datasource. Not present on the engine-neutral `AbstractRepository` - each connector adds it with its own transaction type (or omits it, like typesense).
331
355
 
332
356
  ```typescript
333
- await repo.beginTransaction(opts?: ITransactionOptions): Promise<ITransaction>;
357
+ beginTransaction(opts?: IDatabaseTransactionOptions): Promise<IDatabaseTransaction>;
334
358
  ```
335
359
 
336
360
  Usage:
337
361
 
338
362
  ```typescript
339
- const tx = await repo.beginTransaction();
363
+ const tx = await repository.beginTransaction();
340
364
  try {
341
- await repo.create({ data: { name: 'John' }, options: { transaction: tx } });
342
- await repo.updateById({ id: '456', data: { count: 1 }, options: { transaction: tx } });
365
+ await repository.create({ data: { name: 'John' }, options: { transaction: tx } });
366
+ await repository.updateById({ id: '456', data: { count: 1 }, options: { transaction: tx } });
343
367
  await tx.commit();
344
368
  } catch (e) {
345
369
  await tx.rollback();
@@ -379,10 +403,10 @@ The selection is automatic based on filter complexity:
379
403
 
380
404
  ```typescript
381
405
  // Uses Core API (no include, no fields)
382
- await repo.find({ filter: { where: { status: 'active' }, limit: 10 } });
406
+ await repository.find({ filter: { where: { status: 'active' }, limit: 10 } });
383
407
 
384
408
  // Uses Query API (has include)
385
- await repo.find({
409
+ await repository.find({
386
410
  filter: {
387
411
  where: { status: 'active' },
388
412
  include: [{ relation: 'posts' }],
@@ -390,7 +414,7 @@ await repo.find({
390
414
  });
391
415
 
392
416
  // Uses Query API (has fields)
393
- await repo.find({
417
+ await repository.find({
394
418
  filter: {
395
419
  fields: { id: true, name: true },
396
420
  where: { status: 'active' },
@@ -405,37 +429,37 @@ await repo.find({
405
429
 
406
430
  ```typescript
407
431
  constructor(
408
- ds?: IDataSource,
432
+ dataSource?: AbstractDataSource,
409
433
  opts?: {
410
434
  scope?: string;
411
- entityClass?: TClass<BaseEntity<EntitySchema>>;
435
+ entityClass?: TClass<AbstractEntity>;
412
436
  operationScope?: TRepositoryOperationScope;
413
437
  },
414
438
  )
415
439
  ```
416
440
 
417
- - `ds` -- DataSource instance (optional; auto-injected by `@repository` decorator)
441
+ - `dataSource` -- DataSource instance (optional; auto-injected by `@repository` decorator)
418
442
  - `opts.scope` -- Logger scope name (defaults to class name)
419
443
  - `opts.entityClass` -- Entity class to instantiate (optional; lazy-resolved from `@repository` metadata)
420
444
  - `opts.operationScope` -- Defaults to `READ_ONLY`
421
445
 
422
- ### ReadableRepository
446
+ ### ReadableRepository (PostgreSQL)
423
447
 
424
448
  ```typescript
425
449
  constructor(
426
- ds?: IDataSource,
427
- opts?: { entityClass?: TClass<BaseEntity<EntitySchema>> },
450
+ ds?: IPostgresDataSource,
451
+ opts?: { entityClass?: TClass<BasePostgresEntity<EntitySchema>> },
428
452
  )
429
453
  ```
430
454
 
431
455
  Forces `operationScope` to `READ_ONLY`.
432
456
 
433
- ### PersistableRepository
457
+ ### PersistableRepository (PostgreSQL)
434
458
 
435
459
  ```typescript
436
460
  constructor(
437
- ds?: IDataSource,
438
- opts?: { entityClass?: TClass<BaseEntity<EntitySchema>> },
461
+ ds?: IPostgresDataSource,
462
+ opts?: { entityClass?: TClass<BasePostgresEntity<EntitySchema>> },
439
463
  )
440
464
  ```
441
465
 
@@ -451,7 +475,7 @@ Complete reference for querying data - operators, JSON filtering, array operator
451
475
 
452
476
  ```typescript
453
477
  // Preview
454
- await repo.find({
478
+ await repository.find({
455
479
  filter: {
456
480
  where: {
457
481
  status: 'active',
@@ -470,7 +494,7 @@ Fetch related data using `include` for eager loading and nested queries.
470
494
 
471
495
  ```typescript
472
496
  // Preview
473
- await repo.find({
497
+ await repository.find({
474
498
  filter: {
475
499
  include: [{
476
500
  relation: 'posts',
@@ -489,11 +513,11 @@ Soft-delete and restore operations using `deletedAt` timestamps instead of physi
489
513
  export class CategoryRepository extends SoftDeletableRepository<typeof Category.schema> {}
490
514
 
491
515
  // Soft delete (sets deletedAt)
492
- await repo.deleteById({ id: '123' });
516
+ await repository.deleteById({ id: '123' });
493
517
  // Restore
494
- await repo.restoreById({ id: '123' });
518
+ await repository.restoreById({ id: '123' });
495
519
  // Hard delete (physical removal)
496
- await repo.deleteById({ id: '123', options: { shouldHardDelete: true } });
520
+ await repository.deleteById({ id: '123', options: { shouldHardDelete: true } });
497
521
  ```
498
522
 
499
523
  ### [Advanced Features](./advanced.md)
@@ -501,17 +525,17 @@ Transactions, hidden properties, default filter bypass, performance optimization
501
525
 
502
526
  ```typescript
503
527
  // Preview
504
- const tx = await repo.beginTransaction();
528
+ const tx = await repository.beginTransaction();
505
529
  try {
506
- await repo.create({ data, options: { transaction: tx } });
530
+ await repository.create({ data, options: { transaction: tx } });
507
531
  await tx.commit();
508
532
  } catch (e) {
509
533
  await tx.rollback();
510
534
  }
511
535
  ```
512
536
 
513
- ### [Repository Mixins](./mixins.md)
514
- Composable mixins for repository features - `DefaultFilterMixin` and `FieldsVisibilityMixin`.
537
+ ### [Repository Mixins (Removed)](./mixins.md)
538
+ Tombstone for the removed `DefaultFilterMixin` and `FieldsVisibilityMixin` - where the equivalent behavior lives now.
515
539
 
516
540
 
517
541
  ## @repository Decorator
@@ -593,12 +617,12 @@ Prevents accidental mass updates/deletes (in `PersistableRepository` and above):
593
617
 
594
618
  ```typescript
595
619
  // Throws error - empty where without force flag
596
- await repo.deleteAll({ where: {} });
597
- await repo.updateAll({ data: { status: 'archived' }, where: {} });
620
+ await repository.deleteAll({ where: {} });
621
+ await repository.updateAll({ data: { status: 'archived' }, where: {} });
598
622
 
599
623
  // Explicitly allow with force flag (logs warning)
600
- await repo.deleteAll({ where: {}, options: { force: true } });
601
- await repo.updateAll({ data: { status: 'archived' }, where: {}, options: { force: true } });
624
+ await repository.deleteAll({ where: {}, options: { force: true } });
625
+ await repository.updateAll({ data: { status: 'archived' }, where: {}, options: { force: true } });
602
626
  ```
603
627
 
604
628
  | Scenario | `force: false` (default) | `force: true` |
@@ -608,7 +632,7 @@ await repo.updateAll({ data: { status: 'archived' }, where: {}, options: { force
608
632
 
609
633
  ### ReadableRepository Write Protection
610
634
 
611
- All write methods (`create`, `createAll`, `updateById`, `updateAll`, `deleteById`, `deleteAll`) throw errors on `ReadableRepository`, enforcing the read-only scope at runtime.
635
+ All write methods (`create`, `createAll`, `updateById`, `updateAll`, `deleteById`, `deleteAll`) throw errors on `ReadableRepository`, enforcing the read-only scope at runtime. The thrown error carries `messageCode: 'core.repository.operation_not_allowed'` (`RepositoryErrorCodes.OPERATION_NOT_ALLOWED`).
612
636
 
613
637
 
614
638
  ## TFilter Reference
@@ -634,24 +658,24 @@ type TFilter<T = any> = {
634
658
 
635
659
  | Want to... | Code |
636
660
  |------------|------|
637
- | Find all active | `repo.find({ filter: { where: { status: 'active' } } })` |
638
- | Find with range info | `repo.find({ filter, options: { shouldQueryRange: true } })` |
639
- | Find by ID | `repo.findById({ id: '123' })` |
640
- | Find with relations | `repo.find({ filter: { include: [{ relation: 'posts' }] } })` |
641
- | Create one | `repo.create({ data: { name: 'John' } })` |
642
- | Create without returning data | `repo.create({ data: { name: 'John' }, options: { shouldReturn: false } })` |
643
- | Create many | `repo.createAll({ data: [{ name: 'A' }, { name: 'B' }] })` |
644
- | Update by ID | `repo.updateById({ id: '123', data: { name: 'Jane' } })` |
645
- | Update by condition | `repo.updateAll({ data: { status: 'published' }, where: { status: 'draft' } })` |
646
- | Delete by ID | `repo.deleteById({ id: '123' })` |
647
- | Delete by condition | `repo.deleteBy({ where: { status: 'archived' } })` |
648
- | Soft delete | `repo.deleteById({ id: '123' })` (with `SoftDeletableRepository`) |
649
- | Restore soft-deleted | `repo.restoreById({ id: '123' })` (with `SoftDeletableRepository`) |
650
- | Hard delete (bypass soft) | `repo.deleteById({ id: '123', options: { shouldHardDelete: true } })` |
651
- | Count matching | `repo.count({ where: { status: 'active' } })` |
652
- | Check exists | `repo.existsWith({ where: { email: 'test@example.com' } })` |
653
- | Skip default filter | `repo.find({ filter, options: { shouldSkipDefaultFilter: true } })` |
654
- | Use transaction | `repo.create({ data, options: { transaction: tx } })` |
661
+ | Find all active | `repository.find({ filter: { where: { status: 'active' } } })` |
662
+ | Find with range info | `repository.find({ filter, options: { shouldQueryRange: true } })` |
663
+ | Find by ID | `repository.findById({ id: '123' })` |
664
+ | Find with relations | `repository.find({ filter: { include: [{ relation: 'posts' }] } })` |
665
+ | Create one | `repository.create({ data: { name: 'John' } })` |
666
+ | Create without returning data | `repository.create({ data: { name: 'John' }, options: { shouldReturn: false } })` |
667
+ | Create many | `repository.createAll({ data: [{ name: 'A' }, { name: 'B' }] })` |
668
+ | Update by ID | `repository.updateById({ id: '123', data: { name: 'Jane' } })` |
669
+ | Update by condition | `repository.updateAll({ data: { status: 'published' }, where: { status: 'draft' } })` |
670
+ | Delete by ID | `repository.deleteById({ id: '123' })` |
671
+ | Delete by condition | `repository.deleteBy({ where: { status: 'archived' } })` |
672
+ | Soft delete | `repository.deleteById({ id: '123' })` (with `SoftDeletableRepository`) |
673
+ | Restore soft-deleted | `repository.restoreById({ id: '123' })` (with `SoftDeletableRepository`) |
674
+ | Hard delete (bypass soft) | `repository.deleteById({ id: '123', options: { shouldHardDelete: true } })` |
675
+ | Count matching | `repository.count({ where: { status: 'active' } })` |
676
+ | Check exists | `repository.existsWith({ where: { email: 'test@example.com' } })` |
677
+ | Skip default filter | `repository.find({ filter, options: { shouldSkipDefaultFilter: true } })` |
678
+ | Use transaction | `repository.create({ data, options: { transaction: tx } })` |
655
679
 
656
680
 
657
681
  ## Next Steps
@@ -673,7 +697,7 @@ type TFilter<T = any> = {
673
697
  - **Repository Topics:**
674
698
  - [Relations & Includes](./relations) - Loading related data
675
699
  - [Advanced Features](./advanced) - JSON updates, transactions, performance tuning
676
- - [Repository Mixins](./mixins) - Soft delete and auditing
700
+ - [Repository Mixins (Removed)](./mixins) - Where mixin behavior lives now
677
701
 
678
702
  - **Filtering:**
679
703
  - [Filter System Overview](/references/base/filter-system/) - Complete filtering guide