@venizia/ignis-docs 0.2.0 → 0.2.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 (142) hide show
  1. package/README.md +14 -14
  2. package/content/best-practices/api-usage-examples.md +39 -19
  3. package/content/best-practices/architectural-patterns.md +22 -11
  4. package/content/best-practices/architecture-decisions.md +29 -16
  5. package/content/best-practices/code-style-standards/advanced-patterns.md +43 -31
  6. package/content/best-practices/code-style-standards/constants-configuration.md +19 -4
  7. package/content/best-practices/code-style-standards/control-flow.md +33 -1
  8. package/content/best-practices/code-style-standards/documentation.md +28 -8
  9. package/content/best-practices/code-style-standards/function-patterns.md +15 -4
  10. package/content/best-practices/code-style-standards/index.md +7 -2
  11. package/content/best-practices/code-style-standards/naming-conventions.md +26 -2
  12. package/content/best-practices/code-style-standards/route-definitions.md +9 -5
  13. package/content/best-practices/code-style-standards/tooling.md +14 -1
  14. package/content/best-practices/code-style-standards/type-safety.md +39 -6
  15. package/content/best-practices/common-pitfalls.md +59 -35
  16. package/content/best-practices/contribution-workflow.md +6 -2
  17. package/content/best-practices/data-modeling.md +78 -62
  18. package/content/best-practices/deployment-strategies.md +56 -19
  19. package/content/best-practices/error-handling.md +182 -93
  20. package/content/best-practices/index.md +6 -0
  21. package/content/best-practices/performance-optimization.md +26 -13
  22. package/content/best-practices/security-guidelines.md +35 -9
  23. package/content/best-practices/testing-strategies.md +7 -2
  24. package/content/best-practices/troubleshooting-tips.md +27 -17
  25. package/content/extensions/components/api-reference.md +107 -322
  26. package/content/extensions/components/authentication/api.md +454 -603
  27. package/content/extensions/components/authentication/errors.md +121 -498
  28. package/content/extensions/components/authentication/index.md +88 -801
  29. package/content/extensions/components/authentication/usage.md +207 -956
  30. package/content/extensions/components/authorization/api.md +736 -656
  31. package/content/extensions/components/authorization/errors.md +168 -206
  32. package/content/extensions/components/authorization/index.md +82 -797
  33. package/content/extensions/components/authorization/usage.md +194 -527
  34. package/content/extensions/components/health-check.md +71 -243
  35. package/content/extensions/components/mail/api.md +504 -287
  36. package/content/extensions/components/mail/errors.md +73 -61
  37. package/content/extensions/components/mail/index.md +96 -467
  38. package/content/extensions/components/mail/usage.md +130 -172
  39. package/content/extensions/components/request-tracker.md +66 -173
  40. package/content/extensions/components/socket-io/api.md +195 -13
  41. package/content/extensions/components/socket-io/errors.md +3 -3
  42. package/content/extensions/components/socket-io/index.md +50 -337
  43. package/content/extensions/components/socket-io/usage.md +143 -26
  44. package/content/extensions/components/static-asset/api.md +410 -142
  45. package/content/extensions/components/static-asset/errors.md +110 -53
  46. package/content/extensions/components/static-asset/index.md +79 -608
  47. package/content/extensions/components/static-asset/usage.md +180 -300
  48. package/content/extensions/components/websocket/api.md +275 -399
  49. package/content/extensions/components/websocket/errors.md +47 -56
  50. package/content/extensions/components/websocket/index.md +74 -407
  51. package/content/extensions/components/websocket/usage.md +110 -341
  52. package/content/extensions/helpers/cron/index.md +51 -160
  53. package/content/extensions/helpers/crypto/index.md +62 -483
  54. package/content/extensions/helpers/crypto/reference.md +456 -0
  55. package/content/extensions/helpers/env/index.md +60 -178
  56. package/content/extensions/helpers/error/index.md +221 -207
  57. package/content/extensions/helpers/inversion/index.md +65 -556
  58. package/content/extensions/helpers/inversion/reference.md +522 -0
  59. package/content/extensions/helpers/kafka/admin.md +20 -1
  60. package/content/extensions/helpers/kafka/compile-binary.md +41 -35
  61. package/content/extensions/helpers/kafka/consumer.md +54 -20
  62. package/content/extensions/helpers/kafka/examples.md +21 -16
  63. package/content/extensions/helpers/kafka/index.md +80 -610
  64. package/content/extensions/helpers/kafka/producer.md +134 -5
  65. package/content/extensions/helpers/kafka/schema-registry.md +45 -70
  66. package/content/extensions/helpers/logger/hf-logger.md +193 -0
  67. package/content/extensions/helpers/logger/index.md +64 -563
  68. package/content/extensions/helpers/logger/pino.md +85 -0
  69. package/content/extensions/helpers/logger/reference.md +746 -0
  70. package/content/extensions/helpers/network/api.md +241 -195
  71. package/content/extensions/helpers/network/index.md +72 -530
  72. package/content/extensions/helpers/queue/index.md +72 -900
  73. package/content/extensions/helpers/queue/reference.md +467 -0
  74. package/content/extensions/helpers/redis/index.md +73 -645
  75. package/content/extensions/helpers/redis/reference.md +727 -0
  76. package/content/extensions/helpers/secrets/index.md +66 -0
  77. package/content/extensions/helpers/socket-io/api.md +305 -203
  78. package/content/extensions/helpers/socket-io/index.md +66 -432
  79. package/content/extensions/helpers/storage/api.md +564 -462
  80. package/content/extensions/helpers/storage/index.md +77 -573
  81. package/content/extensions/helpers/types/index.md +66 -499
  82. package/content/extensions/helpers/types/reference.md +650 -0
  83. package/content/extensions/helpers/uid/index.md +58 -227
  84. package/content/extensions/helpers/websocket/api.md +329 -216
  85. package/content/extensions/helpers/websocket/index.md +65 -503
  86. package/content/extensions/helpers/worker-thread/index.md +58 -396
  87. package/content/extensions/helpers/worker-thread/reference.md +428 -0
  88. package/content/guides/core-concepts/persistent/models.md +1 -1
  89. package/content/guides/core-concepts/persistent/search-typesense.md +3 -3
  90. package/content/guides/core-concepts/persistent/transactions.md +1 -1
  91. package/content/guides/core-concepts/secrets-vault.md +177 -0
  92. package/content/guides/core-concepts/services.md +1 -1
  93. package/content/guides/migrations/redis-helpers-migration.md +1 -1
  94. package/content/guides/migrations/unified-connectors-migration.md +2 -2
  95. package/content/guides/tutorials/ecommerce-api.md +3 -8
  96. package/content/references/base/application.md +1 -1
  97. package/content/references/base/connectors.md +79 -136
  98. package/content/references/base/datasources-reference.md +599 -0
  99. package/content/references/base/datasources.md +84 -444
  100. package/content/references/base/dependency-injection.md +17 -39
  101. package/content/references/base/filter-system/application-usage.md +69 -121
  102. package/content/references/base/filter-system/array-operators.md +12 -0
  103. package/content/references/base/filter-system/comparison-operators.md +12 -0
  104. package/content/references/base/filter-system/default-filter.md +136 -348
  105. package/content/references/base/filter-system/fields-order-pagination.md +38 -16
  106. package/content/references/base/filter-system/index.md +106 -257
  107. package/content/references/base/filter-system/json-filtering.md +12 -2
  108. package/content/references/base/filter-system/list-operators.md +16 -2
  109. package/content/references/base/filter-system/logical-operators.md +13 -0
  110. package/content/references/base/filter-system/null-operators.md +13 -0
  111. package/content/references/base/filter-system/pattern-matching.md +12 -0
  112. package/content/references/base/filter-system/quick-reference.md +11 -2
  113. package/content/references/base/filter-system/range-operators.md +12 -0
  114. package/content/references/base/filter-system/tips.md +70 -133
  115. package/content/references/base/filter-system/use-cases.md +156 -233
  116. package/content/references/base/middlewares.md +35 -21
  117. package/content/references/base/models-reference.md +886 -0
  118. package/content/references/base/models.md +80 -1452
  119. package/content/references/base/repositories/advanced.md +156 -192
  120. package/content/references/base/repositories/index.md +77 -650
  121. package/content/references/base/repositories/mixins.md +22 -18
  122. package/content/references/base/repositories/relations.md +123 -171
  123. package/content/references/base/repositories/soft-deletable.md +58 -56
  124. package/content/references/base/secrets.md +263 -0
  125. package/content/references/base/services.md +2 -2
  126. package/content/references/configuration/environment-variables.md +48 -4
  127. package/content/references/configuration/index.md +49 -31
  128. package/content/references/quick-reference.md +3 -16
  129. package/content/references/utilities/crypto.md +35 -76
  130. package/content/references/utilities/date.md +33 -73
  131. package/content/references/utilities/index.md +1 -1
  132. package/content/references/utilities/jsx-reference.md +298 -0
  133. package/content/references/utilities/jsx.md +82 -525
  134. package/content/references/utilities/module.md +29 -62
  135. package/content/references/utilities/parse.md +34 -64
  136. package/content/references/utilities/performance.md +33 -58
  137. package/content/references/utilities/promise.md +28 -62
  138. package/content/references/utilities/request.md +57 -218
  139. package/content/references/utilities/schema.md +43 -137
  140. package/content/references/utilities/statuses-reference.md +361 -0
  141. package/content/references/utilities/statuses.md +63 -667
  142. package/package.json +8 -8
@@ -106,3 +106,15 @@ PostgreSQL POSIX regex matching.
106
106
  | `nilike` | `NOT ILIKE` | Insensitive | PostgreSQL only |
107
107
  | `regexp` | `~` | Sensitive | POSIX regex match |
108
108
  | `iregexp` | `~*` | Insensitive | POSIX regex match |
109
+
110
+ ## See also
111
+
112
+ - [Filter System Overview](./) - the `filter` shape and the full `where` operator table
113
+ - [JSON Filtering](./json-filtering) - pattern operators also work on a `'column.path'` key, with no numeric casting
114
+ - [Quick Reference](./quick-reference) - every operator, one line each
115
+
116
+ **Files:**
117
+
118
+ - [`packages/core/src/connectors/postgres/repositories/dialect/query.ts`](https://github.com/VENIZIA-AI/ignis/blob/main/packages/core/src/connectors/postgres/repositories/dialect/query.ts) - `PostgresQueryOperators.FNS`, per-operator SQL builders
119
+ - [`packages/core/src/connectors/postgres/repositories/dialect/filter.ts`](https://github.com/VENIZIA-AI/ignis/blob/main/packages/core/src/connectors/postgres/repositories/dialect/filter.ts) - `FilterBuilder`, translates `TFilter` to Drizzle/SQL
120
+ - [`packages/core/src/base/repositories/common/operators.ts`](https://github.com/VENIZIA-AI/ignis/blob/main/packages/core/src/base/repositories/common/operators.ts) - `QueryOperators` constants
@@ -7,7 +7,7 @@ lastUpdated: 2026-03-15
7
7
 
8
8
  # Filter Operators Quick Reference
9
9
 
10
- Complete single-page reference for all IGNIS filter operators. For detailed explanations and examples, see the individual operator guides.
10
+ Complete single-page reference for all IGNIS filter operators. For detailed explanations and examples, see the individual operator guides linked below, or start at the [Filter System Overview](./) for the full `filter` shape.
11
11
 
12
12
  ## Comparison Operators
13
13
 
@@ -101,7 +101,7 @@ Complete single-page reference for all IGNIS filter operators. For detailed expl
101
101
 
102
102
  `exists`/`notExists`/`not` are supported on the PostgreSQL connector. `not` recurses: `{ not: { gt: 100 } }` becomes `NOT (col > 100)`, and `{ not: 5 }` becomes `NOT (col = 5)`. `exists` also works over JSON paths on PostgreSQL (`{ 'metadata.score': { exists: true } }`).
103
103
 
104
- **See:** [Null Operators Guide](./null-operators.md)
104
+ **See:** [Null Operators Guide](./null-operators.md) (`exists`/`notExists`), [Logical Operators Guide](./logical-operators.md) (`not`)
105
105
 
106
106
 
107
107
  ## Logical Operators
@@ -273,3 +273,12 @@ await userRepository.find({
273
273
  ```
274
274
 
275
275
  **See:** [Default Filter Guide](./default-filter.md)
276
+
277
+ ## See also
278
+
279
+ - [Filter System Overview](./) - the `filter` shape, `where` families at a glance, and links to every depth page
280
+
281
+ **Files:**
282
+
283
+ - [`packages/core/src/connectors/postgres/repositories/dialect/filter.ts`](https://github.com/VENIZIA-AI/ignis/blob/main/packages/core/src/connectors/postgres/repositories/dialect/filter.ts) - `FilterBuilder`, translates `TFilter` to Drizzle/SQL
284
+ - [`packages/core/src/base/repositories/common/operators.ts`](https://github.com/VENIZIA-AI/ignis/blob/main/packages/core/src/base/repositories/common/operators.ts) - `QueryOperators`/`Sorts` constants
@@ -67,3 +67,15 @@ You can also express ranges using comparison operators:
67
67
  { where: { price: { gt: 100, lt: 500 } } }
68
68
  // SQL: WHERE "price" > 100 AND "price" < 500
69
69
  ```
70
+
71
+ ## See also
72
+
73
+ - [Filter System Overview](./) - the `filter` shape and the full `where` operator table
74
+ - [Comparison Operators](./comparison-operators) - `gt`/`gte`/`lt`/`lte`, the building blocks of the `gte`/`lte` equivalent above
75
+ - [Quick Reference](./quick-reference) - every operator, one line each
76
+
77
+ **Files:**
78
+
79
+ - [`packages/core/src/connectors/postgres/repositories/dialect/query.ts`](https://github.com/VENIZIA-AI/ignis/blob/main/packages/core/src/connectors/postgres/repositories/dialect/query.ts) - `PostgresQueryOperators.FNS`, per-operator SQL builders
80
+ - [`packages/core/src/connectors/postgres/repositories/dialect/filter.ts`](https://github.com/VENIZIA-AI/ignis/blob/main/packages/core/src/connectors/postgres/repositories/dialect/filter.ts) - `FilterBuilder`, translates `TFilter` to Drizzle/SQL
81
+ - [`packages/core/src/base/repositories/common/operators.ts`](https://github.com/VENIZIA-AI/ignis/blob/main/packages/core/src/base/repositories/common/operators.ts) - `QueryOperators` constants
@@ -6,212 +6,149 @@ difficulty: intermediate
6
6
 
7
7
  # Pro Tips & Edge Cases
8
8
 
9
- Advanced tips and common edge cases when working with filters.
9
+ Behavior that is easy to assume incorrectly when writing a `filter` - each one verified against `FilterBuilder`/`PostgresQueryOperators`.
10
10
 
11
+ ## `NOT IN` and `!=` silently exclude `NULL`
11
12
 
12
- ## Tip 1: JSON Numeric vs String Comparison
13
+ SQL three-valued logic, not an IGNIS quirk: a row whose column is `NULL` never matches `nin`, `ne`, or `neq`, because `NULL <> value` evaluates to UNKNOWN rather than TRUE.
13
14
 
14
15
  ```typescript
15
- // JSON field contains: { "priority": "3" } (string)
16
- // Numeric comparison uses safe casting:
17
- { where: { 'metadata.priority': { gt: 2 } } }
18
- // The regex '^-?[0-9]+(\.[0-9]+)?$' matches "3", so it casts to numeric 3
19
- // Result: 3 > 2 -> matches
20
-
21
- // But if JSON field contains: { "priority": "high" }
22
- { where: { 'metadata.priority': { gt: 2 } } }
23
- // "high" fails regex -> NULL -> no match
16
+ { where: { status: { nin: ['deleted'] } } }
17
+ // Rows where status IS NULL are NOT returned
24
18
 
25
- // Best practice: ensure your data stores numbers as JSON numbers
26
- { "priority": 3 } // Store as number, not string "3"
19
+ // To include them, add an explicit NULL branch:
20
+ { where: { or: [{ status: { nin: ['deleted'] } }, { status: { is: null } }] } }
27
21
  ```
28
22
 
29
-
30
- ## Tip 2: Empty Array Handling
23
+ ## Empty arrays are not no-ops
31
24
 
32
25
  ```typescript
33
- // Empty IN -> no results
34
- { where: { id: { in: [] } } } // SQL: WHERE false
26
+ { where: { id: { in: [] } } } // SQL: WHERE false - matches nothing
27
+ { where: { id: { nin: [] } } } // SQL: WHERE true - matches everything
28
+ ```
35
29
 
36
- // Empty NIN -> all results
37
- { where: { id: { nin: [] } } } // SQL: WHERE true
30
+ This matters most when the array comes from user input - check its length before building the filter:
38
31
 
39
- // Check array length before filtering
32
+ ```typescript
40
33
  const ids = getUserSelectedIds();
41
34
  if (ids.length === 0) {
42
- return []; // Early return instead of empty IN
35
+ return []; // early return instead of an accidental WHERE false or WHERE true
43
36
  }
44
37
  ```
45
38
 
39
+ ## JSON numeric comparisons need actual JSON numbers
46
40
 
47
- ## Tip 3: Null-Safe JSON Paths
41
+ A JSON path comparison casts safely with `CASE WHEN (...) ~ '^-?[0-9]+(\.[0-9]+)?$' THEN (...)::numeric ELSE NULL END` - the regex has to match or the cast yields `NULL` and the row is excluded:
48
42
 
49
43
  ```typescript
50
- // If JSON field doesn't exist, #>> returns NULL
51
- // This is safe - no errors, just no matches
52
- { where: { 'metadata.nonexistent.field': 'value' } }
53
- // SQL: "metadata" #>> '{nonexistent,field}' = 'value'
54
- // Result: No rows (NULL != 'value')
44
+ // { "priority": "3" } (string) - regex matches "3" -> casts to numeric 3 -> 3 > 2 matches
45
+ { where: { 'metadata.priority': { gt: 2 } } }
46
+
47
+ // { "priority": "high" } - regex fails -> NULL -> never matches
48
+ { where: { 'metadata.priority': { gt: 2 } } }
55
49
  ```
56
50
 
51
+ Store numbers as JSON numbers (`{ "priority": 3 }`), not numeric strings, to avoid depending on the cast.
57
52
 
58
- ## Tip 4: Performance with Large IN Arrays
53
+ ## A missing JSON path is a null-safe miss, not an error
59
54
 
60
55
  ```typescript
61
- // For very large arrays (1000+ items), consider chunking
62
- const allIds = getLargeIdList(); // 5000 IDs
63
-
64
- const chunkSize = 500;
65
- const results = [];
66
- for (let i = 0; i < allIds.length; i += chunkSize) {
67
- const chunk = allIds.slice(i, i + chunkSize);
68
- const chunkResults = await repository.find({
69
- filter: { where: { id: { in: chunk } } }
70
- });
71
- results.push(...chunkResults);
72
- }
56
+ { where: { 'metadata.nonexistent.field': 'value' } }
57
+ // SQL: "metadata" #>> '{nonexistent,field}' = 'value'
58
+ // No rows match (NULL != 'value') - no exception either
73
59
  ```
74
60
 
61
+ ## JSON `order` uses `#>`, not `#>>`
75
62
 
76
- ## Tip 5: Order By JSON Fields
63
+ `#>` returns JSONB and preserves the value's type; the equality/comparison operators above use `#>>` (text) instead, because sorting needs JSONB's native ordering:
77
64
 
78
65
  ```typescript
79
- // JSON ordering uses #> (returns JSONB, preserves types) not #>> (returns text)
80
66
  { order: ['metadata.priority DESC'] }
81
67
  // SQL: "metadata" #> '{priority}' DESC
82
68
 
83
- // JSONB comparison order:
84
- // null < boolean < number < string < array < object
69
+ // JSONB comparison order: null < boolean < number < string < array < object
85
70
  ```
86
71
 
72
+ ## Array operators accept a bare value
87
73
 
88
- ## Tip 6: Debugging Filters
74
+ `contains`, `containedBy`, and `overlaps` wrap a non-array operand in a single-element array automatically:
89
75
 
90
76
  ```typescript
91
- // Enable logging to see generated SQL
92
- const result = await repository.find({
93
- filter: complexFilter,
94
- options: {
95
- log: { use: true, level: 'debug' },
96
- },
97
- });
98
-
99
- // Or use buildQuery to inspect without executing
100
- const queryOptions = repository.buildQuery({ filter: complexFilter });
101
- console.log('Generated query options:', queryOptions);
77
+ { where: { tags: { contains: ['featured'] } } }
78
+ { where: { tags: { contains: 'featured' } } }
79
+ // Equivalent
102
80
  ```
103
81
 
104
-
105
- ## Tip 7: NOT IN with NULL Columns
82
+ ## `fields` as an object only supports inclusion
106
83
 
107
84
  ```typescript
108
- // NOT IN excludes NULL values!
109
- { where: { status: { nin: ['deleted'] } } }
110
- // Rows where status IS NULL will NOT be returned
111
-
112
- // Include NULL values explicitly
113
- {
114
- where: {
115
- or: [
116
- { status: { nin: ['deleted'] } },
117
- { status: { is: null } }
118
- ]
119
- }
120
- }
85
+ { fields: { id: true, name: true, email: true } }
86
+
87
+ // Setting a key to `false` does NOT exclude it - the key is simply ignored.
88
+ // To exclude fields, list only the ones you want, as an array:
89
+ { fields: ['id', 'name', 'email'] }
121
90
  ```
122
91
 
92
+ ## Combining multiple array conditions
123
93
 
124
- ## Tip 8: Combining Multiple Array Conditions
94
+ `contains`, `containedBy`, and `overlaps` compose like any other operators - as separate keys under an implicit AND:
125
95
 
126
96
  ```typescript
127
97
  await productRepository.find({
128
98
  filter: {
129
99
  where: {
130
- // Must have ALL these categories
131
- categories: { contains: ['electronics', 'portable'] },
132
- // Tags must be subset of allowed tags
133
- tags: { containedBy: ['new', 'sale', 'featured', 'popular'] },
134
- // Must have at least one of these suppliers
135
- suppliers: { overlaps: ['supplier-a', 'supplier-b'] }
136
- }
137
- }
100
+ categories: { contains: ['electronics', 'portable'] }, // must have ALL these
101
+ tags: { containedBy: ['new', 'sale', 'featured', 'popular'] }, // must be a subset
102
+ suppliers: { overlaps: ['supplier-a', 'supplier-b'] }, // at least one match
103
+ },
104
+ },
138
105
  });
139
106
  ```
140
107
 
108
+ ## Chunk very large `in` arrays
141
109
 
142
- ## Tip 9: Date Range Queries
110
+ Postgres has no hard `IN`-list limit, but a multi-thousand-element array is worth chunking for query-plan and payload-size reasons:
143
111
 
144
112
  ```typescript
145
- // This week's events
146
- const startOfWeek = new Date();
147
- startOfWeek.setDate(startOfWeek.getDate() - startOfWeek.getDay());
148
- const endOfWeek = new Date(startOfWeek);
149
- endOfWeek.setDate(endOfWeek.getDate() + 6);
150
-
151
- {
152
- where: {
153
- eventDate: { between: [startOfWeek, endOfWeek] }
154
- }
155
- }
156
-
157
- // Last 30 days
158
- const thirtyDaysAgo = new Date();
159
- thirtyDaysAgo.setDate(thirtyDaysAgo.getDate() - 30);
113
+ const allIds = getLargeIdList(); // e.g. 5000 IDs
114
+ const chunkSize = 500;
115
+ const results = [];
160
116
 
161
- {
162
- where: {
163
- createdAt: { gte: thirtyDaysAgo }
164
- }
117
+ for (let i = 0; i < allIds.length; i += chunkSize) {
118
+ const chunk = allIds.slice(i, i + chunkSize);
119
+ results.push(...(await repository.find({ filter: { where: { id: { in: chunk } } } })));
165
120
  }
166
121
  ```
167
122
 
123
+ ## Factor out reusable `where`/pagination fragments
168
124
 
169
- ## Tip 10: Reusable Filter Builders
125
+ A `filter` is a plain object, so common fragments compose with spreads instead of being rewritten per call site:
170
126
 
171
127
  ```typescript
172
- // Create reusable filter builders
173
- const createActiveFilter = <T extends { status: string; deletedAt: Date | null }>(): TWhere<T> => ({
174
- status: 'active',
175
- deletedAt: { is: null },
176
- } as TWhere<T>);
128
+ const createActiveFilter = <T extends { status: string; deletedAt: Date | null }>(): TWhere<T> =>
129
+ ({ status: 'active', deletedAt: { is: null } }) as TWhere<T>;
177
130
 
178
- const createPaginationFilter = (page: number, size: number = 20) => ({
131
+ const createPaginationFilter = (page: number, size = 20) => ({
179
132
  limit: size,
180
133
  skip: (page - 1) * size,
181
134
  });
182
135
 
183
- // Usage
184
136
  const products = await productRepository.find({
185
137
  filter: {
186
- where: {
187
- ...createActiveFilter(),
188
- category: 'electronics',
189
- },
138
+ where: { ...createActiveFilter(), category: 'electronics' },
190
139
  ...createPaginationFilter(3),
191
- }
140
+ },
192
141
  });
193
142
  ```
194
143
 
144
+ ## See also
195
145
 
196
- ## Tip 11: Array Operators Accept Single Values
146
+ - [Filter System Overview](./) - the `filter` shape and every `where` operator family
147
+ - [Application Usage -> Debugging a filter](./application-usage#debugging-a-filter) - `buildQuery`, and why `options.log` doesn't apply to `find`
148
+ - [Use Case Gallery](./use-cases) - full runnable filters, including date-range and multi-condition examples
149
+ - [JSON Filtering](./json-filtering) - the full JSON path operator reference
197
150
 
198
- ```typescript
199
- // These are equivalent:
200
- { where: { tags: { contains: ['featured'] } } }
201
- { where: { tags: { contains: 'featured' } } }
202
-
203
- // Single values are automatically wrapped in an array
204
- // This works for contains, containedBy, and overlaps
205
- ```
151
+ **Files:**
206
152
 
207
-
208
- ## Tip 12: Field Selection Object Format
209
-
210
- ```typescript
211
- // Object format only supports inclusion (true values)
212
- { fields: { id: true, name: true, email: true } }
213
-
214
- // Setting a field to false does NOT exclude it -- it just ignores that key
215
- // If you want to exclude fields, list only the ones you want:
216
- { fields: ['id', 'name', 'email'] } // Array format is clearer for this
217
- ```
153
+ - [`packages/core/src/connectors/postgres/repositories/dialect/filter.ts`](https://github.com/VENIZIA-AI/ignis/blob/main/packages/core/src/connectors/postgres/repositories/dialect/filter.ts) - `FilterBuilder`, JSON path casting, `toColumns`
154
+ - [`packages/core/src/connectors/postgres/repositories/dialect/query.ts`](https://github.com/VENIZIA-AI/ignis/blob/main/packages/core/src/connectors/postgres/repositories/dialect/query.ts) - `PostgresQueryOperators.FNS`, empty-array and array-operator handling