@venizia/ignis-docs 0.0.8-3 → 0.1.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 (213) hide show
  1. package/README.md +7 -7
  2. package/{wiki → content}/best-practices/api-usage-examples.md +15 -12
  3. package/{wiki → content}/best-practices/architectural-patterns.md +70 -78
  4. package/{wiki → content}/best-practices/architecture-decisions.md +91 -60
  5. package/{wiki → content}/best-practices/code-style-standards/advanced-patterns.md +56 -44
  6. package/{wiki → content}/best-practices/code-style-standards/constants-configuration.md +11 -11
  7. package/{wiki → content}/best-practices/code-style-standards/control-flow.md +5 -2
  8. package/{wiki → content}/best-practices/code-style-standards/documentation.md +13 -13
  9. package/{wiki → content}/best-practices/code-style-standards/function-patterns.md +9 -10
  10. package/{wiki → content}/best-practices/code-style-standards/index.md +1 -1
  11. package/{wiki → content}/best-practices/code-style-standards/naming-conventions.md +10 -8
  12. package/{wiki → content}/best-practices/code-style-standards/route-definitions.md +30 -12
  13. package/{wiki → content}/best-practices/code-style-standards/tooling.md +8 -5
  14. package/{wiki → content}/best-practices/code-style-standards/type-safety.md +13 -12
  15. package/{wiki → content}/best-practices/common-pitfalls.md +56 -37
  16. package/{wiki → content}/best-practices/contribution-workflow.md +13 -14
  17. package/{wiki → content}/best-practices/data-modeling.md +44 -20
  18. package/{wiki → content}/best-practices/deployment-strategies.md +28 -27
  19. package/{wiki → content}/best-practices/error-handling.md +48 -24
  20. package/{wiki → content}/best-practices/index.md +5 -5
  21. package/{wiki → content}/best-practices/performance-optimization.md +36 -28
  22. package/{wiki → content}/best-practices/security-guidelines.md +52 -23
  23. package/{wiki → content}/best-practices/testing-strategies.md +65 -51
  24. package/{wiki → content}/best-practices/troubleshooting-tips.md +24 -24
  25. package/{wiki/extensions/components/swagger.md → content/extensions/components/api-reference.md} +40 -31
  26. package/{wiki → content}/extensions/components/authentication/api.md +19 -19
  27. package/{wiki → content}/extensions/components/authentication/errors.md +7 -7
  28. package/{wiki → content}/extensions/components/authentication/index.md +10 -8
  29. package/{wiki → content}/extensions/components/authentication/usage.md +101 -6
  30. package/{wiki → content}/extensions/components/authorization/api.md +45 -25
  31. package/{wiki → content}/extensions/components/authorization/errors.md +6 -6
  32. package/{wiki → content}/extensions/components/authorization/index.md +11 -10
  33. package/{wiki → content}/extensions/components/authorization/usage.md +21 -21
  34. package/{wiki → content}/extensions/components/health-check.md +1 -1
  35. package/{wiki → content}/extensions/components/index.md +5 -5
  36. package/{wiki → content}/extensions/components/mail/errors.md +15 -15
  37. package/{wiki → content}/extensions/components/mail/index.md +1 -2
  38. package/{wiki → content}/extensions/components/mail/usage.md +1 -1
  39. package/{wiki → content}/extensions/components/request-tracker.md +1 -1
  40. package/{wiki → content}/extensions/components/socket-io/api.md +9 -9
  41. package/{wiki → content}/extensions/components/socket-io/errors.md +5 -5
  42. package/{wiki → content}/extensions/components/socket-io/index.md +8 -8
  43. package/{wiki → content}/extensions/components/socket-io/usage.md +1 -1
  44. package/{wiki → content}/extensions/components/static-asset/api.md +17 -4
  45. package/{wiki → content}/extensions/components/static-asset/errors.md +4 -4
  46. package/{wiki → content}/extensions/components/static-asset/index.md +26 -28
  47. package/{wiki → content}/extensions/components/static-asset/usage.md +13 -12
  48. package/{wiki → content}/extensions/components/template/index.md +2 -2
  49. package/{wiki → content}/extensions/components/template/setup-page.md +1 -1
  50. package/{wiki → content}/extensions/components/websocket/api.md +3 -3
  51. package/{wiki → content}/extensions/components/websocket/errors.md +5 -5
  52. package/{wiki → content}/extensions/components/websocket/index.md +5 -5
  53. package/{wiki → content}/extensions/components/websocket/usage.md +3 -3
  54. package/{wiki → content}/extensions/helpers/cron/index.md +2 -2
  55. package/{wiki → content}/extensions/helpers/crypto/index.md +1 -1
  56. package/{wiki → content}/extensions/helpers/env/index.md +27 -12
  57. package/content/extensions/helpers/error/index.md +283 -0
  58. package/{wiki → content}/extensions/helpers/index.md +2 -3
  59. package/{wiki → content}/extensions/helpers/inversion/index.md +15 -7
  60. package/{wiki → content}/extensions/helpers/kafka/examples.md +1 -1
  61. package/{wiki → content}/extensions/helpers/logger/index.md +32 -2
  62. package/{wiki → content}/extensions/helpers/network/index.md +6 -0
  63. package/{wiki → content}/extensions/helpers/queue/index.md +14 -17
  64. package/content/extensions/helpers/redis/index.md +713 -0
  65. package/{wiki → content}/extensions/helpers/socket-io/index.md +14 -10
  66. package/{wiki → content}/extensions/helpers/storage/api.md +44 -8
  67. package/{wiki → content}/extensions/helpers/storage/index.md +43 -7
  68. package/{wiki → content}/extensions/helpers/template/index.md +6 -3
  69. package/{wiki → content}/extensions/helpers/types/index.md +11 -8
  70. package/{wiki → content}/extensions/helpers/websocket/api.md +9 -9
  71. package/{wiki → content}/extensions/helpers/websocket/index.md +7 -7
  72. package/{wiki → content}/extensions/helpers/worker-thread/index.md +2 -2
  73. package/{wiki → content}/extensions/index.md +3 -4
  74. package/{wiki → content}/extensions/src-details/mcp-server.md +18 -24
  75. package/{wiki → content}/guides/core-concepts/application/bootstrapping.md +11 -14
  76. package/{wiki → content}/guides/core-concepts/application/index.md +3 -3
  77. package/{wiki → content}/guides/core-concepts/components.md +19 -10
  78. package/{wiki → content}/guides/core-concepts/dependency-injection.md +6 -3
  79. package/{wiki → content}/guides/core-concepts/grpc-controllers.md +6 -5
  80. package/{wiki → content}/guides/core-concepts/persistent/datasources.md +33 -27
  81. package/{wiki → content}/guides/core-concepts/persistent/index.md +16 -5
  82. package/{wiki → content}/guides/core-concepts/persistent/models.md +24 -20
  83. package/content/guides/core-concepts/persistent/postgres-drivers.md +167 -0
  84. package/{wiki → content}/guides/core-concepts/persistent/repositories.md +40 -23
  85. package/content/guides/core-concepts/persistent/search-meilisearch.md +183 -0
  86. package/content/guides/core-concepts/persistent/search-typesense.md +429 -0
  87. package/{wiki → content}/guides/core-concepts/persistent/transactions.md +61 -25
  88. package/{wiki → content}/guides/core-concepts/rest-controllers.md +12 -9
  89. package/content/guides/core-concepts/services.md +389 -0
  90. package/{wiki → content}/guides/get-started/5-minute-quickstart.md +19 -19
  91. package/{wiki → content}/guides/get-started/philosophy.md +36 -36
  92. package/{wiki → content}/guides/get-started/setup.md +3 -3
  93. package/{wiki → content}/guides/index.md +3 -3
  94. package/content/guides/migrations/redis-helpers-migration.md +177 -0
  95. package/{wiki → content}/guides/migrations/scoped-rbac-migration.md +17 -17
  96. package/content/guides/migrations/unified-connectors-migration.md +113 -0
  97. package/{wiki → content}/guides/reference/glossary.md +19 -12
  98. package/{wiki → content}/guides/reference/mcp-docs-server.md +22 -18
  99. package/{wiki → content}/guides/tutorials/building-a-crud-api.md +30 -33
  100. package/{wiki → content}/guides/tutorials/complete-installation.md +17 -17
  101. package/{wiki → content}/guides/tutorials/ecommerce-api.md +158 -119
  102. package/{wiki → content}/guides/tutorials/realtime-chat.md +176 -130
  103. package/content/guides/tutorials/testing.md +264 -0
  104. package/content/index.md +5 -0
  105. package/content/public/apple-touch-icon.png +0 -0
  106. package/content/public/og-image.png +0 -0
  107. package/content/public/site.webmanifest +11 -0
  108. package/{wiki → content}/references/base/application.md +4 -5
  109. package/{wiki → content}/references/base/bootstrapping.md +18 -5
  110. package/{wiki → content}/references/base/components.md +149 -120
  111. package/content/references/base/connectors.md +178 -0
  112. package/{wiki → content}/references/base/controllers.md +41 -30
  113. package/content/references/base/datasources.md +527 -0
  114. package/{wiki → content}/references/base/dependency-injection.md +34 -22
  115. package/{wiki → content}/references/base/filter-system/application-usage.md +17 -14
  116. package/{wiki → content}/references/base/filter-system/array-operators.md +7 -2
  117. package/{wiki → content}/references/base/filter-system/comparison-operators.md +3 -0
  118. package/{wiki → content}/references/base/filter-system/default-filter.md +89 -71
  119. package/{wiki → content}/references/base/filter-system/fields-order-pagination.md +22 -22
  120. package/{wiki → content}/references/base/filter-system/index.md +6 -3
  121. package/{wiki → content}/references/base/filter-system/json-filtering.md +20 -1
  122. package/{wiki → content}/references/base/filter-system/list-operators.md +1 -1
  123. package/{wiki → content}/references/base/filter-system/logical-operators.md +33 -1
  124. package/{wiki → content}/references/base/filter-system/null-operators.md +30 -1
  125. package/{wiki → content}/references/base/filter-system/quick-reference.md +23 -4
  126. package/{wiki → content}/references/base/filter-system/tips.md +5 -5
  127. package/{wiki → content}/references/base/filter-system/use-cases.md +12 -12
  128. package/{wiki → content}/references/base/grpc-controllers.md +13 -13
  129. package/{wiki → content}/references/base/index.md +24 -12
  130. package/{wiki/references/base/middleware.md → content/references/base/middlewares.md} +205 -24
  131. package/{wiki → content}/references/base/models.md +63 -49
  132. package/{wiki → content}/references/base/providers.md +136 -130
  133. package/{wiki → content}/references/base/repositories/advanced.md +59 -58
  134. package/{wiki → content}/references/base/repositories/index.md +115 -91
  135. package/content/references/base/repositories/mixins.md +99 -0
  136. package/{wiki → content}/references/base/repositories/relations.md +54 -64
  137. package/{wiki → content}/references/base/repositories/soft-deletable.md +31 -30
  138. package/content/references/base/services.md +404 -0
  139. package/{wiki → content}/references/configuration/environment-variables.md +46 -30
  140. package/{wiki → content}/references/configuration/index.md +6 -6
  141. package/{wiki → content}/references/index.md +17 -12
  142. package/{wiki → content}/references/quick-reference.md +65 -106
  143. package/content/references/utilities/crypto.md +98 -0
  144. package/{wiki → content}/references/utilities/index.md +3 -3
  145. package/{wiki → content}/references/utilities/jsx.md +6 -4
  146. package/content/references/utilities/module.md +90 -0
  147. package/{wiki → content}/references/utilities/parse.md +4 -14
  148. package/{wiki → content}/references/utilities/promise.md +9 -7
  149. package/{wiki → content}/references/utilities/schema.md +5 -3
  150. package/dist/mcp-server/common/guards.d.ts +8 -0
  151. package/dist/mcp-server/common/guards.d.ts.map +1 -0
  152. package/dist/mcp-server/common/guards.js +14 -0
  153. package/dist/mcp-server/common/guards.js.map +1 -0
  154. package/dist/mcp-server/common/index.d.ts +1 -0
  155. package/dist/mcp-server/common/index.d.ts.map +1 -1
  156. package/dist/mcp-server/common/index.js +1 -0
  157. package/dist/mcp-server/common/index.js.map +1 -1
  158. package/dist/mcp-server/common/paths.d.ts.map +1 -1
  159. package/dist/mcp-server/common/paths.js +2 -2
  160. package/dist/mcp-server/common/paths.js.map +1 -1
  161. package/dist/mcp-server/helpers/docs.helper.d.ts.map +1 -1
  162. package/dist/mcp-server/helpers/docs.helper.js +4 -2
  163. package/dist/mcp-server/helpers/docs.helper.js.map +1 -1
  164. package/dist/mcp-server/helpers/github.helper.js +1 -1
  165. package/dist/mcp-server/index.js +7 -2
  166. package/dist/mcp-server/index.js.map +1 -1
  167. package/dist/mcp-server/tools/base.tool.d.ts +6 -2
  168. package/dist/mcp-server/tools/base.tool.d.ts.map +1 -1
  169. package/dist/mcp-server/tools/base.tool.js.map +1 -1
  170. package/dist/mcp-server/tools/docs/search-documents.tool.d.ts +1 -1
  171. package/dist/mcp-server/tools/github/list-project-files.tool.d.ts +1 -1
  172. package/dist/mcp-server/tools/github/search-code.tool.d.ts +1 -1
  173. package/dist/mcp-server/tools/github/search-code.tool.d.ts.map +1 -1
  174. package/dist/mcp-server/tools/github/search-code.tool.js +4 -1
  175. package/dist/mcp-server/tools/github/search-code.tool.js.map +1 -1
  176. package/dist/mcp-server/tools/github/verify-dependencies.tool.d.ts.map +1 -1
  177. package/dist/mcp-server/tools/github/verify-dependencies.tool.js +3 -1
  178. package/dist/mcp-server/tools/github/verify-dependencies.tool.js.map +1 -1
  179. package/package.json +12 -12
  180. package/wiki/extensions/helpers/error/index.md +0 -227
  181. package/wiki/extensions/helpers/redis/index.md +0 -488
  182. package/wiki/extensions/helpers/testing/index.md +0 -510
  183. package/wiki/guides/core-concepts/services.md +0 -119
  184. package/wiki/guides/tutorials/testing.md +0 -722
  185. package/wiki/index.md +0 -183
  186. package/wiki/references/base/datasources.md +0 -454
  187. package/wiki/references/base/middlewares.md +0 -590
  188. package/wiki/references/base/repositories/mixins.md +0 -335
  189. package/wiki/references/base/services.md +0 -201
  190. package/wiki/references/utilities/crypto.md +0 -56
  191. package/wiki/references/utilities/module.md +0 -42
  192. /package/{wiki → content}/extensions/components/mail/api.md +0 -0
  193. /package/{wiki → content}/extensions/components/template/api-page.md +0 -0
  194. /package/{wiki → content}/extensions/components/template/errors-page.md +0 -0
  195. /package/{wiki → content}/extensions/components/template/single-page.md +0 -0
  196. /package/{wiki → content}/extensions/components/template/usage-page.md +0 -0
  197. /package/{wiki → content}/extensions/helpers/kafka/admin.md +0 -0
  198. /package/{wiki → content}/extensions/helpers/kafka/consumer.md +0 -0
  199. /package/{wiki → content}/extensions/helpers/kafka/index.md +0 -0
  200. /package/{wiki → content}/extensions/helpers/kafka/producer.md +0 -0
  201. /package/{wiki → content}/extensions/helpers/kafka/schema-registry.md +0 -0
  202. /package/{wiki → content}/extensions/helpers/network/api.md +0 -0
  203. /package/{wiki → content}/extensions/helpers/socket-io/api.md +0 -0
  204. /package/{wiki → content}/extensions/helpers/template/single-page.md +0 -0
  205. /package/{wiki → content}/extensions/helpers/uid/index.md +0 -0
  206. /package/{wiki → content}/guides/core-concepts/components-guide.md +0 -0
  207. /package/{wiki → content}/public/logo.svg +0 -0
  208. /package/{wiki → content}/references/base/filter-system/pattern-matching.md +0 -0
  209. /package/{wiki → content}/references/base/filter-system/range-operators.md +0 -0
  210. /package/{wiki → content}/references/utilities/date.md +0 -0
  211. /package/{wiki → content}/references/utilities/performance.md +0 -0
  212. /package/{wiki → content}/references/utilities/request.md +0 -0
  213. /package/{wiki → content}/references/utilities/statuses.md +0 -0
@@ -9,7 +9,7 @@ Fetch related data using `include` for eager loading. This guide covers one-to-o
9
9
 
10
10
  ```typescript
11
11
  // Fetch user with their posts
12
- const user = await userRepo.findOne({
12
+ const user = await userRepository.findOne({
13
13
  filter: {
14
14
  where: { id: '123' },
15
15
  include: [{ relation: 'posts' }]
@@ -31,7 +31,7 @@ const user = await userRepo.findOne({
31
31
 
32
32
  ```typescript
33
33
  // Fetch post with its author
34
- const post = await postRepo.findOne({
34
+ const post = await postRepository.findOne({
35
35
  filter: {
36
36
  where: { id: 'p1' },
37
37
  include: [{ relation: 'author' }]
@@ -51,7 +51,7 @@ const post = await postRepo.findOne({
51
51
 
52
52
  ```typescript
53
53
  // Fetch post with author AND comments
54
- const post = await postRepo.findOne({
54
+ const post = await postRepository.findOne({
55
55
  filter: {
56
56
  where: { id: 'p1' },
57
57
  include: [
@@ -74,7 +74,7 @@ Apply filters, ordering, and limits to included relations using `scope`:
74
74
 
75
75
  ```typescript
76
76
  // User with only published posts
77
- const user = await userRepo.findOne({
77
+ const user = await userRepository.findOne({
78
78
  filter: {
79
79
  where: { id: '123' },
80
80
  include: [{
@@ -91,7 +91,7 @@ const user = await userRepo.findOne({
91
91
 
92
92
  ```typescript
93
93
  // User with posts ordered by date
94
- const user = await userRepo.findOne({
94
+ const user = await userRepository.findOne({
95
95
  filter: {
96
96
  where: { id: '123' },
97
97
  include: [{
@@ -108,7 +108,7 @@ const user = await userRepo.findOne({
108
108
 
109
109
  ```typescript
110
110
  // User with their 5 most recent posts
111
- const user = await userRepo.findOne({
111
+ const user = await userRepository.findOne({
112
112
  filter: {
113
113
  where: { id: '123' },
114
114
  include: [{
@@ -125,7 +125,7 @@ const user = await userRepo.findOne({
125
125
  ### Combined Scope Options
126
126
 
127
127
  ```typescript
128
- const user = await userRepo.findOne({
128
+ const user = await userRepository.findOne({
129
129
  filter: {
130
130
  where: { id: '123' },
131
131
  include: [{
@@ -147,7 +147,7 @@ Each inclusion can independently bypass the related model's default filter:
147
147
 
148
148
  ```typescript
149
149
  // Include soft-deleted posts that would normally be filtered out
150
- const user = await userRepo.findOne({
150
+ const user = await userRepository.findOne({
151
151
  filter: {
152
152
  where: { id: '123' },
153
153
  include: [{
@@ -167,7 +167,7 @@ Include relations of relations (up to 2 levels recommended):
167
167
 
168
168
  ```typescript
169
169
  // User -> Posts -> Comments
170
- const user = await userRepo.findOne({
170
+ const user = await userRepository.findOne({
171
171
  filter: {
172
172
  where: { id: '123' },
173
173
  include: [{
@@ -200,7 +200,7 @@ const user = await userRepo.findOne({
200
200
 
201
201
  ```typescript
202
202
  // Product -> SaleChannelProduct (junction) -> SaleChannel
203
- const product = await productRepo.findOne({
203
+ const product = await productRepository.findOne({
204
204
  filter: {
205
205
  where: { id: 'prod1' },
206
206
  include: [{
@@ -236,7 +236,7 @@ const product = await productRepo.findOne({
236
236
 
237
237
  ## Defining Relations
238
238
 
239
- Relations are defined using the `createRelations` helper and the `TRelationConfig` type. These use Drizzle ORM's relation system under the hood.
239
+ Relations are declared on the model as a static `relations` resolver returning an array of `TRelationConfig`. The framework translates them to Drizzle ORM relations internally during schema discovery.
240
240
 
241
241
  ### Relation Config Type
242
242
 
@@ -261,34 +261,32 @@ type TRelationConfig = {
261
261
 
262
262
  ```typescript
263
263
  // src/models/user.model.ts
264
- import { createRelations } from '@venizia/ignis';
264
+ import { model, RelationTypes } from '@venizia/ignis';
265
+ import { BasePostgresEntity, TRelationConfig } from '@venizia/ignis/postgres';
266
+ import { pgTable, text } from 'drizzle-orm/pg-core';
267
+ import { Post } from './post.model';
265
268
 
266
- export const userTable = pgTable('User', {
267
- id: text('id').primaryKey(),
268
- name: text('name').notNull(),
269
- email: text('email').notNull(),
270
- });
269
+ @model({ type: 'entity' })
270
+ export class User extends BasePostgresEntity<typeof User.schema> {
271
+ static override schema = pgTable('User', {
272
+ id: text('id').primaryKey(),
273
+ name: text('name').notNull(),
274
+ email: text('email').notNull(),
275
+ });
271
276
 
272
- const userRelationsConfig = createRelations({
273
- source: userTable,
274
- relations: [
277
+ static override relations = (): TRelationConfig[] => [
275
278
  {
276
- type: 'many',
277
- schema: postTable,
278
279
  name: 'posts',
280
+ type: RelationTypes.MANY,
281
+ schema: Post.schema,
279
282
  metadata: { relationName: 'posts' },
280
283
  },
281
- ],
282
- });
283
-
284
- @model({ type: 'entity' })
285
- export class User extends BaseEntity<typeof User.schema> {
286
- static override schema = userTable;
287
- static override relations = () => userRelationsConfig.definitions;
288
- static override TABLE_NAME = 'User';
284
+ ];
289
285
  }
290
286
  ```
291
287
 
288
+ The resolver form (`() => [...]`) defers evaluation until all `@model` classes are registered, avoiding circular-import ordering issues between related models.
289
+
292
290
  ### Relation Types
293
291
 
294
292
  | Type | Drizzle Function | Description | Example |
@@ -297,46 +295,38 @@ export class User extends BaseEntity<typeof User.schema> {
297
295
  | `'many'` | `many()` | One-to-many | User has many Posts |
298
296
 
299
297
  > [!NOTE]
300
- > Unlike LoopBack 4's `hasMany`/`hasOne`/`belongsTo` terminology, Ignis uses Drizzle ORM's relation model which has only `one` and `many` types. A "belongsTo" relationship is expressed as `type: 'one'` with `fields` (local FK) and `references` (remote PK) in the metadata.
298
+ > Unlike LoopBack 4's `hasMany`/`hasOne`/`belongsTo` terminology, IGNIS uses Drizzle ORM's relation model which has only `one` and `many` types. A "belongsTo" relationship is expressed as `type: 'one'` with `fields` (local FK) and `references` (remote PK) in the metadata.
301
299
 
302
300
  ### Example: Post Model with Both Types
303
301
 
304
302
  ```typescript
305
- const postRelationsConfig = createRelations({
306
- source: postTable,
307
- relations: [
303
+ @model({ type: 'entity' })
304
+ export class Post extends BasePostgresEntity<typeof Post.schema> {
305
+ static override schema = postTable;
306
+
307
+ static override relations = (): TRelationConfig[] => [
308
308
  {
309
- type: 'one',
310
- schema: userTable,
311
309
  name: 'author',
310
+ type: RelationTypes.ONE,
311
+ schema: User.schema,
312
312
  metadata: {
313
- fields: [postTable.authorId],
314
- references: [userTable.id],
313
+ fields: [Post.schema.authorId],
314
+ references: [User.schema.id],
315
315
  },
316
316
  },
317
317
  {
318
- type: 'many',
319
- schema: commentTable,
320
318
  name: 'comments',
319
+ type: RelationTypes.MANY,
320
+ schema: Comment.schema,
321
321
  metadata: { relationName: 'comments' },
322
322
  },
323
- ],
324
- });
323
+ ];
324
+ }
325
325
  ```
326
326
 
327
- ### createRelations Return Value
328
-
329
- `createRelations` returns an object with two properties:
330
-
331
- ```typescript
332
- const result = createRelations({ source, relations });
333
-
334
- result.definitions; // Record<string, TRelationConfig> - keyed by relation name
335
- result.relations; // Drizzle relations() call result - pass to DataSource schema
336
- ```
327
+ ### How Configs Become Drizzle Relations
337
328
 
338
- - **`definitions`**: Used by `BaseEntity.relations` for include resolution at runtime.
339
- - **`relations`**: The actual Drizzle ORM relations definition, needed for DataSource schema registration.
329
+ During schema discovery, `MetadataRegistry` resolves each model's `relations` array and passes it to the `createRelations` helper (`packages/core/src/connectors/postgres/repositories/operators/relation.ts`), which builds the actual Drizzle `relations()` definition registered on the DataSource schema. You do not call `createRelations` yourself in application code.
340
330
 
341
331
 
342
332
  ## Auto-Resolution
@@ -362,7 +352,7 @@ When building include queries, the `FilterBuilder.toInclude()` method automatica
362
352
 
363
353
  ```typescript
364
354
  // User model has hiddenProperties: ['password']
365
- const post = await postRepo.findOne({
355
+ const post = await postRepository.findOne({
366
356
  filter: {
367
357
  include: [{ relation: 'author' }]
368
358
  }
@@ -383,7 +373,7 @@ type UserWithPosts = User & {
383
373
  };
384
374
 
385
375
  // Use generic override
386
- const user = await userRepo.findOne<UserWithPosts>({
376
+ const user = await userRepository.findOne<UserWithPosts>({
387
377
  filter: {
388
378
  where: { id: '123' },
389
379
  include: [{ relation: 'posts' }]
@@ -405,7 +395,7 @@ type ProductWithChannels = Product & {
405
395
  })[];
406
396
  };
407
397
 
408
- const product = await productRepo.findOne<ProductWithChannels>({
398
+ const product = await productRepository.findOne<ProductWithChannels>({
409
399
  filter: {
410
400
  where: { id: 'prod1' },
411
401
  include: [{
@@ -441,7 +431,7 @@ type TInclusion = {
441
431
 
442
432
  ```typescript
443
433
  // Get users with post count
444
- const users = await userRepo.find({
434
+ const users = await userRepository.find({
445
435
  filter: {
446
436
  include: [{
447
437
  relation: 'posts',
@@ -465,7 +455,7 @@ async function getUser(id: string, includePosts: boolean) {
465
455
  ? [{ relation: 'posts' }]
466
456
  : [];
467
457
 
468
- return userRepo.findOne({
458
+ return userRepository.findOne({
469
459
  filter: {
470
460
  where: { id },
471
461
  include
@@ -483,7 +473,7 @@ If you try to include a relation that doesn't exist:
483
473
 
484
474
  ```typescript
485
475
  // Error: [FilterBuilder][toInclude] Relation NOT FOUND | relation: 'nonExistent'
486
- await userRepo.find({
476
+ await userRepository.find({
487
477
  filter: {
488
478
  include: [{ relation: 'nonExistent' }]
489
479
  }
@@ -520,14 +510,14 @@ in connector.query | Available keys: [Post, Comment]
520
510
 
521
511
  ```typescript
522
512
  // Instead of deep nesting, use separate queries
523
- const user = await userRepo.findById({ id: '123' });
524
- const posts = await postRepo.find({
513
+ const user = await userRepository.findById({ id: '123' });
514
+ const posts = await postRepository.find({
525
515
  filter: {
526
516
  where: { authorId: '123' },
527
517
  limit: 10
528
518
  }
529
519
  });
530
- const comments = await commentRepo.find({
520
+ const comments = await commentRepository.find({
531
521
  filter: {
532
522
  where: { postId: { inq: posts.map(p => p.id) } }
533
523
  }
@@ -563,7 +553,7 @@ const comments = await commentRepo.find({
563
553
 
564
554
  - **Related Topics:**
565
555
  - [Advanced Features](./advanced) - Hidden properties, transactions
566
- - [Repository Mixins](./mixins) - Default filter and fields visibility
556
+ - [Repository Mixins (Removed)](./mixins) - Where default-filter and fields-visibility behavior lives now
567
557
  - [Filter System](/references/base/filter-system/) - Query operators
568
558
 
569
559
  - **External Resources:**
@@ -8,7 +8,7 @@ difficulty: intermediate
8
8
 
9
9
  A repository that overrides delete operations to set a `deletedAt` timestamp instead of physically removing records. Extends `DefaultCRUDRepository` with restore capabilities.
10
10
 
11
- **File:** `packages/core/src/base/repositories/core/soft-deletable.ts`
11
+ **File:** `packages/core/src/connectors/postgres/repositories/core/soft-deletable.ts` (PostgreSQL connector - soft delete via `deletedAt` is a Drizzle/SQL-specific pattern, not part of the engine-neutral `AbstractRepository`)
12
12
 
13
13
 
14
14
  ## Setup
@@ -70,17 +70,17 @@ All delete methods set `deletedAt = new Date()` instead of removing the row. The
70
70
 
71
71
  ```typescript
72
72
  // Soft delete - sets deletedAt timestamp
73
- const result = await repo.deleteById({ id: '123' });
73
+ const result = await repository.deleteById({ id: '123' });
74
74
  // { count: 1, data: { id: '123', name: 'Electronics', deletedAt: '2026-03-06T...' } }
75
75
 
76
76
  // Without returning data
77
- const result = await repo.deleteById({
77
+ const result = await repository.deleteById({
78
78
  id: '123',
79
79
  options: { shouldReturn: false },
80
80
  });
81
81
 
82
82
  // Hard delete - physically removes the row
83
- const result = await repo.deleteById({
83
+ const result = await repository.deleteById({
84
84
  id: '123',
85
85
  options: { shouldHardDelete: true },
86
86
  });
@@ -90,13 +90,13 @@ const result = await repo.deleteById({
90
90
 
91
91
  ```typescript
92
92
  // Soft delete all matching records
93
- const result = await repo.deleteAll({
93
+ const result = await repository.deleteAll({
94
94
  where: { status: 'archived' },
95
95
  options: { force: true },
96
96
  });
97
97
 
98
98
  // Hard delete all matching records
99
- const result = await repo.deleteAll({
99
+ const result = await repository.deleteAll({
100
100
  where: { status: 'archived' },
101
101
  options: { shouldHardDelete: true, force: true },
102
102
  });
@@ -106,12 +106,12 @@ const result = await repo.deleteAll({
106
106
 
107
107
  ```typescript
108
108
  // Soft delete by where condition (alias for deleteAll)
109
- const result = await repo.deleteBy({
109
+ const result = await repository.deleteBy({
110
110
  where: { name: 'Obsolete' },
111
111
  });
112
112
 
113
113
  // Hard delete by where condition
114
- const result = await repo.deleteBy({
114
+ const result = await repository.deleteBy({
115
115
  where: { name: 'Obsolete' },
116
116
  options: { shouldHardDelete: true },
117
117
  });
@@ -125,11 +125,11 @@ Restore methods set `deletedAt = null` and automatically use `shouldSkipDefaultF
125
125
  ### restoreById
126
126
 
127
127
  ```typescript
128
- const result = await repo.restoreById({ id: '123' });
128
+ const result = await repository.restoreById({ id: '123' });
129
129
  // { count: 1, data: { id: '123', name: 'Electronics', deletedAt: null } }
130
130
 
131
131
  // Without returning data
132
- const result = await repo.restoreById({
132
+ const result = await repository.restoreById({
133
133
  id: '123',
134
134
  options: { shouldReturn: false },
135
135
  });
@@ -139,13 +139,13 @@ const result = await repo.restoreById({
139
139
 
140
140
  ```typescript
141
141
  // Restore all soft-deleted records (requires force for empty where)
142
- const result = await repo.restoreAll({
142
+ const result = await repository.restoreAll({
143
143
  where: {},
144
144
  options: { force: true },
145
145
  });
146
146
 
147
147
  // Restore matching records
148
- const result = await repo.restoreAll({
148
+ const result = await repository.restoreAll({
149
149
  where: { name: 'Electronics' },
150
150
  });
151
151
  ```
@@ -154,7 +154,7 @@ const result = await repo.restoreAll({
154
154
 
155
155
  ```typescript
156
156
  // Alias for restoreAll
157
- const result = await repo.restoreBy({
157
+ const result = await repository.restoreBy({
158
158
  where: { status: 'archived' },
159
159
  });
160
160
  ```
@@ -168,10 +168,10 @@ const result = await repo.restoreBy({
168
168
 
169
169
  ```typescript
170
170
  // Returns null if not found (default)
171
- const category = await repo.findById({ id: '123' });
171
+ const category = await repository.findById({ id: '123' });
172
172
 
173
173
  // Throws 404 if not found
174
- const category = await repo.findById({
174
+ const category = await repository.findById({
175
175
  id: '123',
176
176
  options: { isStrict: true },
177
177
  });
@@ -226,8 +226,8 @@ All other read operations (`find`, `findOne`, `count`, `existsWith`) work as nor
226
226
  ```typescript
227
227
  const tx = await this.dataSource.beginTransaction();
228
228
  try {
229
- await this.categoryRepo.deleteById({ id: '123', options: { transaction: tx } });
230
- await this.auditRepo.create({
229
+ await this.categoryRepository.deleteById({ id: '123', options: { transaction: tx } });
230
+ await this.auditRepository.create({
231
231
  data: { action: 'soft_delete', entityId: '123' },
232
232
  options: { transaction: tx },
233
233
  });
@@ -259,11 +259,12 @@ If your schema does not have a `deletedAt` column, you will get a TypeScript com
259
259
  ## Class Hierarchy
260
260
 
261
261
  ```
262
- AbstractRepository
263
- -> ReadableRepository
264
- -> PersistableRepository
265
- -> DefaultCRUDRepository
266
- -> SoftDeletableRepository <-- you are here
262
+ AbstractRepository (engine-neutral, src/base)
263
+ -> PostgresBaseRepository (connectors/postgres)
264
+ -> ReadableRepository
265
+ -> PersistableRepository
266
+ -> DefaultCRUDRepository
267
+ -> SoftDeletableRepository <-- you are here
267
268
  ```
268
269
 
269
270
 
@@ -271,19 +272,19 @@ AbstractRepository
271
272
 
272
273
  | Want to... | Code |
273
274
  |------------|------|
274
- | Soft delete by ID | `repo.deleteById({ id })` |
275
- | Hard delete by ID | `repo.deleteById({ id, options: { shouldHardDelete: true } })` |
276
- | Soft delete by condition | `repo.deleteAll({ where, options: { force: true } })` |
277
- | Restore by ID | `repo.restoreById({ id })` |
278
- | Restore by condition | `repo.restoreAll({ where })` |
279
- | Find including deleted | `repo.find({ filter, options: { shouldSkipDefaultFilter: true } })` |
280
- | Strict findById (404) | `repo.findById({ id, options: { isStrict: true } })` |
275
+ | Soft delete by ID | `repository.deleteById({ id })` |
276
+ | Hard delete by ID | `repository.deleteById({ id, options: { shouldHardDelete: true } })` |
277
+ | Soft delete by condition | `repository.deleteAll({ where, options: { force: true } })` |
278
+ | Restore by ID | `repository.restoreById({ id })` |
279
+ | Restore by condition | `repository.restoreAll({ where })` |
280
+ | Find including deleted | `repository.find({ filter, options: { shouldSkipDefaultFilter: true } })` |
281
+ | Strict findById (404) | `repository.findById({ id, options: { isStrict: true } })` |
281
282
 
282
283
 
283
284
  ## Next Steps
284
285
 
285
286
  - [Advanced Features](./advanced.md) - Transactions, hidden properties
286
- - [Repository Mixins](./mixins.md) - Default filter and fields visibility
287
+ - [Repository Mixins (Removed)](./mixins.md) - Where default-filter and fields-visibility behavior lives now
287
288
  - [Repository Overview](./index.md) - Repository basics
288
289
 
289
290
  ## See Also