@venizia/ignis-docs 0.0.3 → 0.0.4-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 (131) hide show
  1. package/README.md +1 -1
  2. package/package.json +4 -2
  3. package/wiki/best-practices/api-usage-examples.md +591 -0
  4. package/wiki/best-practices/architectural-patterns.md +415 -0
  5. package/wiki/best-practices/architecture-decisions.md +488 -0
  6. package/wiki/{get-started/best-practices → best-practices}/code-style-standards.md +406 -17
  7. package/wiki/{get-started/best-practices → best-practices}/common-pitfalls.md +109 -4
  8. package/wiki/{get-started/best-practices → best-practices}/contribution-workflow.md +34 -7
  9. package/wiki/best-practices/data-modeling.md +376 -0
  10. package/wiki/best-practices/deployment-strategies.md +698 -0
  11. package/wiki/best-practices/index.md +27 -0
  12. package/wiki/best-practices/performance-optimization.md +196 -0
  13. package/wiki/best-practices/security-guidelines.md +218 -0
  14. package/wiki/{get-started/best-practices → best-practices}/troubleshooting-tips.md +97 -1
  15. package/wiki/changelogs/2025-12-16-initial-architecture.md +1 -1
  16. package/wiki/changelogs/2025-12-16-model-repo-datasource-refactor.md +1 -1
  17. package/wiki/changelogs/2025-12-17-refactor.md +1 -1
  18. package/wiki/changelogs/2025-12-18-performance-optimizations.md +5 -5
  19. package/wiki/changelogs/2025-12-18-repository-validation-security.md +13 -7
  20. package/wiki/changelogs/2025-12-26-nested-relations-and-generics.md +2 -2
  21. package/wiki/changelogs/2025-12-29-dynamic-binding-registration.md +104 -0
  22. package/wiki/changelogs/2025-12-29-snowflake-uid-helper.md +100 -0
  23. package/wiki/changelogs/2025-12-30-repository-enhancements.md +214 -0
  24. package/wiki/changelogs/2025-12-31-json-path-filtering-array-operators.md +214 -0
  25. package/wiki/changelogs/2025-12-31-string-id-custom-generator.md +137 -0
  26. package/wiki/changelogs/2026-01-02-default-filter-and-repository-mixins.md +418 -0
  27. package/wiki/changelogs/index.md +6 -0
  28. package/wiki/changelogs/planned-schema-migrator.md +0 -8
  29. package/wiki/{get-started/core-concepts → guides/core-concepts/application}/bootstrapping.md +18 -5
  30. package/wiki/{get-started/core-concepts/application.md → guides/core-concepts/application/index.md} +47 -104
  31. package/wiki/guides/core-concepts/components-guide.md +509 -0
  32. package/wiki/{get-started → guides}/core-concepts/components.md +24 -17
  33. package/wiki/{get-started → guides}/core-concepts/controllers.md +30 -13
  34. package/wiki/{get-started → guides}/core-concepts/dependency-injection.md +97 -0
  35. package/wiki/guides/core-concepts/persistent/datasources.md +179 -0
  36. package/wiki/guides/core-concepts/persistent/index.md +119 -0
  37. package/wiki/guides/core-concepts/persistent/models.md +241 -0
  38. package/wiki/guides/core-concepts/persistent/repositories.md +219 -0
  39. package/wiki/guides/core-concepts/persistent/transactions.md +170 -0
  40. package/wiki/{get-started → guides}/core-concepts/services.md +26 -3
  41. package/wiki/{get-started → guides/get-started}/5-minute-quickstart.md +59 -14
  42. package/wiki/guides/get-started/philosophy.md +682 -0
  43. package/wiki/guides/get-started/setup.md +157 -0
  44. package/wiki/guides/index.md +89 -0
  45. package/wiki/guides/reference/glossary.md +243 -0
  46. package/wiki/{get-started → guides/reference}/mcp-docs-server.md +0 -10
  47. package/wiki/{get-started → guides/tutorials}/building-a-crud-api.md +134 -132
  48. package/wiki/{get-started/quickstart.md → guides/tutorials/complete-installation.md} +107 -71
  49. package/wiki/guides/tutorials/ecommerce-api.md +1399 -0
  50. package/wiki/guides/tutorials/realtime-chat.md +1261 -0
  51. package/wiki/guides/tutorials/testing.md +723 -0
  52. package/wiki/index.md +176 -37
  53. package/wiki/references/base/application.md +27 -0
  54. package/wiki/references/base/bootstrapping.md +30 -26
  55. package/wiki/references/base/components.md +24 -7
  56. package/wiki/references/base/controllers.md +51 -20
  57. package/wiki/references/base/datasources.md +30 -0
  58. package/wiki/references/base/dependency-injection.md +39 -3
  59. package/wiki/references/base/filter-system/application-usage.md +224 -0
  60. package/wiki/references/base/filter-system/array-operators.md +132 -0
  61. package/wiki/references/base/filter-system/comparison-operators.md +109 -0
  62. package/wiki/references/base/filter-system/default-filter.md +428 -0
  63. package/wiki/references/base/filter-system/fields-order-pagination.md +155 -0
  64. package/wiki/references/base/filter-system/index.md +127 -0
  65. package/wiki/references/base/filter-system/json-filtering.md +197 -0
  66. package/wiki/references/base/filter-system/list-operators.md +71 -0
  67. package/wiki/references/base/filter-system/logical-operators.md +156 -0
  68. package/wiki/references/base/filter-system/null-operators.md +58 -0
  69. package/wiki/references/base/filter-system/pattern-matching.md +108 -0
  70. package/wiki/references/base/filter-system/quick-reference.md +431 -0
  71. package/wiki/references/base/filter-system/range-operators.md +63 -0
  72. package/wiki/references/base/filter-system/tips.md +190 -0
  73. package/wiki/references/base/filter-system/use-cases.md +452 -0
  74. package/wiki/references/base/index.md +90 -0
  75. package/wiki/references/base/middlewares.md +602 -0
  76. package/wiki/references/base/models.md +215 -23
  77. package/wiki/references/base/providers.md +732 -0
  78. package/wiki/references/base/repositories/advanced.md +555 -0
  79. package/wiki/references/base/repositories/index.md +228 -0
  80. package/wiki/references/base/repositories/mixins.md +331 -0
  81. package/wiki/references/base/repositories/relations.md +486 -0
  82. package/wiki/references/base/repositories.md +40 -635
  83. package/wiki/references/base/services.md +28 -4
  84. package/wiki/references/components/authentication.md +22 -2
  85. package/wiki/references/components/health-check.md +12 -0
  86. package/wiki/references/components/index.md +23 -0
  87. package/wiki/references/components/mail.md +687 -0
  88. package/wiki/references/components/request-tracker.md +16 -0
  89. package/wiki/references/components/socket-io.md +18 -0
  90. package/wiki/references/components/static-asset.md +14 -26
  91. package/wiki/references/components/swagger.md +17 -0
  92. package/wiki/references/configuration/environment-variables.md +427 -0
  93. package/wiki/references/configuration/index.md +73 -0
  94. package/wiki/references/helpers/cron.md +14 -0
  95. package/wiki/references/helpers/crypto.md +15 -0
  96. package/wiki/references/helpers/env.md +16 -0
  97. package/wiki/references/helpers/error.md +17 -0
  98. package/wiki/references/helpers/index.md +14 -0
  99. package/wiki/references/helpers/inversion.md +24 -4
  100. package/wiki/references/helpers/logger.md +19 -0
  101. package/wiki/references/helpers/network.md +11 -0
  102. package/wiki/references/helpers/queue.md +19 -0
  103. package/wiki/references/helpers/redis.md +21 -0
  104. package/wiki/references/helpers/socket-io.md +24 -5
  105. package/wiki/references/helpers/storage.md +18 -10
  106. package/wiki/references/helpers/testing.md +18 -0
  107. package/wiki/references/helpers/types.md +16 -0
  108. package/wiki/references/helpers/uid.md +167 -0
  109. package/wiki/references/helpers/worker-thread.md +16 -0
  110. package/wiki/references/index.md +177 -0
  111. package/wiki/references/quick-reference.md +634 -0
  112. package/wiki/references/src-details/boot.md +3 -3
  113. package/wiki/references/src-details/dev-configs.md +0 -4
  114. package/wiki/references/src-details/docs.md +2 -2
  115. package/wiki/references/src-details/index.md +86 -0
  116. package/wiki/references/src-details/inversion.md +1 -6
  117. package/wiki/references/src-details/mcp-server.md +3 -15
  118. package/wiki/references/utilities/index.md +86 -10
  119. package/wiki/references/utilities/jsx.md +577 -0
  120. package/wiki/references/utilities/request.md +0 -2
  121. package/wiki/references/utilities/statuses.md +740 -0
  122. package/wiki/get-started/best-practices/api-usage-examples.md +0 -266
  123. package/wiki/get-started/best-practices/architectural-patterns.md +0 -170
  124. package/wiki/get-started/best-practices/data-modeling.md +0 -177
  125. package/wiki/get-started/best-practices/deployment-strategies.md +0 -121
  126. package/wiki/get-started/best-practices/performance-optimization.md +0 -97
  127. package/wiki/get-started/best-practices/security-guidelines.md +0 -99
  128. package/wiki/get-started/core-concepts/persistent.md +0 -539
  129. package/wiki/get-started/index.md +0 -65
  130. package/wiki/get-started/philosophy.md +0 -296
  131. package/wiki/get-started/prerequisites.md +0 -113
@@ -0,0 +1,108 @@
1
+ ---
2
+ title: Pattern Matching Operators
3
+ description: Operators for string pattern matching and regular expressions
4
+ difficulty: intermediate
5
+ ---
6
+
7
+ # Pattern Matching Operators
8
+
9
+ Operators for string pattern matching and regular expressions.
10
+
11
+
12
+ ## like - Pattern Matching (Case-Sensitive)
13
+
14
+ Matches strings using SQL LIKE patterns.
15
+
16
+ ```typescript
17
+ // Starts with
18
+ { where: { email: { like: '%@gmail.com' } } }
19
+ // SQL: WHERE "email" LIKE '%@gmail.com'
20
+
21
+ // Contains
22
+ { where: { name: { like: '%john%' } } }
23
+ // SQL: WHERE "name" LIKE '%john%'
24
+
25
+ // Ends with
26
+ { where: { filename: { like: '%.pdf' } } }
27
+ // SQL: WHERE "filename" LIKE '%.pdf'
28
+
29
+ // Single character wildcard
30
+ { where: { code: { like: 'A_B' } } } // Matches 'A1B', 'AXB', etc.
31
+ // SQL: WHERE "code" LIKE 'A_B'
32
+ ```
33
+
34
+ **Pattern Characters:**
35
+ - `%` - Matches any sequence of characters (including empty)
36
+ - `_` - Matches exactly one character
37
+
38
+
39
+ ## nlike - Not Like
40
+
41
+ ```typescript
42
+ { where: { email: { nlike: '%@test.com' } } }
43
+ // SQL: WHERE "email" NOT LIKE '%@test.com'
44
+ ```
45
+
46
+
47
+ ## ilike - Case-Insensitive Pattern Matching
48
+
49
+ PostgreSQL-specific case-insensitive LIKE.
50
+
51
+ ```typescript
52
+ { where: { name: { ilike: '%john%' } } }
53
+ // SQL: WHERE "name" ILIKE '%john%'
54
+ // Matches: 'John', 'JOHN', 'john', 'JoHn'
55
+
56
+ { where: { email: { ilike: '%@GMAIL.COM' } } }
57
+ // Matches: 'user@gmail.com', 'USER@Gmail.Com'
58
+ ```
59
+
60
+
61
+ ## nilike - Not ILike
62
+
63
+ ```typescript
64
+ { where: { email: { nilike: '%@example%' } } }
65
+ // SQL: WHERE NOT ("email" ILIKE '%@example%')
66
+ ```
67
+
68
+
69
+ ## regexp - Regular Expression (Case-Sensitive)
70
+
71
+ PostgreSQL POSIX regex matching.
72
+
73
+ ```typescript
74
+ // Starts with letter
75
+ { where: { code: { regexp: '^[A-Z]' } } }
76
+ // SQL: WHERE "code" ~ '^[A-Z]'
77
+
78
+ // Email pattern
79
+ { where: { email: { regexp: '^[a-z]+@[a-z]+\\.[a-z]+$' } } }
80
+ // SQL: WHERE "email" ~ '^[a-z]+@[a-z]+\.[a-z]+$'
81
+
82
+ // Phone number pattern
83
+ { where: { phone: { regexp: '^\\+?[0-9]{10,15}$' } } }
84
+ ```
85
+
86
+ > [!NOTE]
87
+ > Escape backslashes in TypeScript strings: `\\d` for regex `\d`.
88
+
89
+
90
+ ## iregexp - Case-Insensitive Regular Expression
91
+
92
+ ```typescript
93
+ { where: { name: { iregexp: '^john' } } }
94
+ // SQL: WHERE "name" ~* '^john'
95
+ // Matches: 'John Doe', 'JOHN SMITH', 'john'
96
+ ```
97
+
98
+
99
+ ## Summary
100
+
101
+ | Operator | SQL | Case | Description |
102
+ |----------|-----|------|-------------|
103
+ | `like` | `LIKE` | Sensitive | Pattern with wildcards |
104
+ | `nlike` | `NOT LIKE` | Sensitive | Negative pattern |
105
+ | `ilike` | `ILIKE` | Insensitive | PostgreSQL only |
106
+ | `nilike` | `NOT ILIKE` | Insensitive | PostgreSQL only |
107
+ | `regexp` | `~` | Sensitive | POSIX regex match |
108
+ | `iregexp` | `~*` | Insensitive | POSIX regex match |
@@ -0,0 +1,431 @@
1
+ ---
2
+ title: Filter Operators Quick Reference
3
+ description: Single-page cheat sheet of all filter operators
4
+ difficulty: intermediate
5
+ lastUpdated: 2026-01-03
6
+ ---
7
+
8
+ # Filter Operators Quick Reference
9
+
10
+ Complete single-page reference for all IGNIS filter operators. For detailed explanations and examples, see the individual operator guides.
11
+
12
+ ## Comparison Operators
13
+
14
+ | Operator | SQL | TypeScript Example | Description |
15
+ |----------|-----|-------------------|-------------|
16
+ | `eq` | `=` | `{ status: { eq: 'active' } }` | Equal to |
17
+ | `neq` | `!=` | `{ status: { neq: 'deleted' } }` | Not equal to |
18
+ | `gt` | `>` | `{ age: { gt: 18 } }` | Greater than |
19
+ | `gte` | `>=` | `{ age: { gte: 18 } }` | Greater than or equal |
20
+ | `lt` | `<` | `{ price: { lt: 100 } }` | Less than |
21
+ | `lte` | `<=` | `{ price: { lte: 100 } }` | Less than or equal |
22
+
23
+ **See:** [Comparison Operators Guide](./comparison-operators.md)
24
+
25
+ ---
26
+
27
+ ## Range Operators
28
+
29
+ | Operator | SQL | TypeScript Example | Description |
30
+ |----------|-----|-------------------|-------------|
31
+ | `between` | `BETWEEN` | `{ age: { between: [18, 65] } }` | Value is within range (inclusive) |
32
+ | `notBetween` | `NOT BETWEEN` | `{ age: { notBetween: [0, 18] } }` | Value is outside range |
33
+
34
+ **See:** [Range Operators Guide](./range-operators.md)
35
+
36
+ ---
37
+
38
+ ## List Operators
39
+
40
+ | Operator | SQL | TypeScript Example | Description |
41
+ |----------|-----|-------------------|-------------|
42
+ | `in` / `inq` | `IN` | `{ status: { in: ['active', 'pending'] } }` | Value matches any in array |
43
+ | `notIn` / `nin` | `NOT IN` | `{ status: { notIn: ['deleted', 'banned'] } }` | Value doesn't match any in array |
44
+
45
+ **See:** [List Operators Guide](./list-operators.md)
46
+
47
+ ---
48
+
49
+ ## Pattern Matching Operators
50
+
51
+ | Operator | SQL | TypeScript Example | Description |
52
+ |----------|-----|-------------------|-------------|
53
+ | `like` | `LIKE` | `{ name: { like: '%john%' } }` | Pattern match (case-sensitive) |
54
+ | `ilike` | `ILIKE` | `{ email: { ilike: '%@gmail.com' } }` | Pattern match (case-insensitive) |
55
+ | `notLike` | `NOT LIKE` | `{ name: { notLike: '%test%' } }` | Inverse pattern match (case-sensitive) |
56
+ | `notILike` | `NOT ILIKE` | `{ email: { notILike: '%spam%' } }` | Inverse pattern match (case-insensitive) |
57
+ | `startsWith` | `LIKE 'value%'` | `{ name: { startsWith: 'John' } }` | Starts with value |
58
+ | `endsWith` | `LIKE '%value'` | `{ email: { endsWith: '@example.com' } }` | Ends with value |
59
+ | `regexp` | `~` | `{ code: { regexp: '^[A-Z]{3}$' } }` | Regular expression (PostgreSQL) |
60
+ | `iregexp` | `~*` | `{ code: { iregexp: '^[a-z]{3}$' } }` | Case-insensitive regex (PostgreSQL) |
61
+
62
+ **Wildcard Patterns:**
63
+ - `%` - Matches any sequence of characters
64
+ - `_` - Matches any single character
65
+
66
+ **See:** [Pattern Matching Guide](./pattern-matching.md)
67
+
68
+ ---
69
+
70
+ ## Null Check Operators
71
+
72
+ | Operator | SQL | TypeScript Example | Description |
73
+ |----------|-----|-------------------|-------------|
74
+ | `isNull` | `IS NULL` | `{ deletedAt: { isNull: true } }` | Value is NULL |
75
+ | `isNotNull` | `IS NOT NULL` | `{ email: { isNotNull: true } }` | Value is not NULL |
76
+
77
+ **Alternative Syntax:**
78
+ ```typescript
79
+ // Using 'is' operator
80
+ { deletedAt: { is: null } } // IS NULL
81
+ { email: { is: { not: null } } } // IS NOT NULL
82
+ ```
83
+
84
+ **See:** [Null Operators Guide](./null-operators.md)
85
+
86
+ ---
87
+
88
+ ## Logical Operators
89
+
90
+ | Operator | SQL | TypeScript Example | Description |
91
+ |----------|-----|-------------------|-------------|
92
+ | `and` | `AND` | `{ and: [{ age: { gt: 18 } }, { status: 'active' }] }` | All conditions must be true |
93
+ | `or` | `OR` | `{ or: [{ role: 'admin' }, { role: 'moderator' }] }` | At least one condition must be true |
94
+ | `not` | `NOT` | `{ not: { status: 'deleted' } }` | Inverts the condition |
95
+
96
+ **Implicit AND:**
97
+ ```typescript
98
+ // Multiple fields = implicit AND
99
+ {
100
+ status: 'active',
101
+ age: { gte: 18 },
102
+ role: 'user'
103
+ }
104
+ // WHERE status = 'active' AND age >= 18 AND role = 'user'
105
+ ```
106
+
107
+ **See:** [Logical Operators Guide](./logical-operators.md)
108
+
109
+ ---
110
+
111
+ ## PostgreSQL Array Operators
112
+
113
+ These operators work with PostgreSQL array columns (`varchar[]`, `text[]`, `integer[]`, etc.).
114
+
115
+ | Operator | PostgreSQL | TypeScript Example | Description |
116
+ |----------|------------|-------------------|-------------|
117
+ | `contains` | `@>` | `{ tags: { contains: ['typescript', 'nodejs'] } }` | Array contains **ALL** specified elements |
118
+ | `containedBy` | `<@` | `{ tags: { containedBy: ['ts', 'js', 'go', 'rust'] } }` | Array is subset of specified array |
119
+ | `overlaps` | `&&` | `{ tags: { overlaps: ['react', 'vue', 'angular'] } }` | Arrays have at least one common element |
120
+
121
+ **Important:** These are array-specific operators, not to be confused with `in`/`notIn` which match scalar values against an array.
122
+
123
+ **See:** [Array Operators Guide](./array-operators.md)
124
+
125
+ ---
126
+
127
+ ## JSON/JSONB Operators (PostgreSQL)
128
+
129
+ Query nested fields within JSON/JSONB columns using dot notation.
130
+
131
+ ### Basic JSON Path
132
+
133
+ | Syntax | Example | Description |
134
+ |--------|---------|-------------|
135
+ | Dot notation | `metadata.user.name` | Access nested properties |
136
+ | Array index | `metadata.tags[0]` | Access array elements |
137
+ | Combined | `metadata.users[0].email` | Nested arrays and objects |
138
+
139
+ ### JSON Path with Filters
140
+
141
+ ```typescript
142
+ // Query JSON field
143
+ {
144
+ metadata: {
145
+ jsonPath: '$.user.name',
146
+ eq: 'John'
147
+ }
148
+ }
149
+
150
+ // Multiple JSON conditions
151
+ {
152
+ and: [
153
+ { metadata: { jsonPath: '$.user.age', gt: 18 } },
154
+ { metadata: { jsonPath: '$.user.country', eq: 'US' } }
155
+ ]
156
+ }
157
+ ```
158
+
159
+ ### Supported Operators with JSON
160
+
161
+ All comparison operators work with JSON path queries:
162
+ - `eq`, `neq`, `gt`, `gte`, `lt`, `lte`
163
+ - `in`, `notIn`
164
+ - `like`, `ilike` (for string fields)
165
+ - `isNull`, `isNotNull`
166
+
167
+ **See:** [JSON Filtering Guide](./json-filtering.md)
168
+
169
+ ---
170
+
171
+ ## Fields, Ordering & Pagination
172
+
173
+ ### Select Specific Fields
174
+
175
+ ```typescript
176
+ const users = await userRepo.find({
177
+ where: { isActive: true },
178
+ fields: ['id', 'name', 'email'], // Only return these fields
179
+ });
180
+ ```
181
+
182
+ ### Ordering
183
+
184
+ ```typescript
185
+ // Single field
186
+ { orderBy: { createdAt: 'desc' } }
187
+
188
+ // Multiple fields
189
+ { orderBy: [
190
+ { createdAt: 'desc' },
191
+ { name: 'asc' }
192
+ ]}
193
+ ```
194
+
195
+ ### Pagination
196
+
197
+ ```typescript
198
+ {
199
+ limit: 10, // Max records to return
200
+ offset: 20, // Skip first 20 records
201
+ orderBy: { id: 'asc' }
202
+ }
203
+
204
+ // Page 3 with 10 items per page
205
+ {
206
+ limit: 10,
207
+ offset: 20, // (page - 1) * limit = (3 - 1) * 10
208
+ orderBy: { createdAt: 'desc' }
209
+ }
210
+ ```
211
+
212
+ **See:** [Fields, Ordering & Pagination Guide](./fields-order-pagination.md)
213
+
214
+ ---
215
+
216
+ ## Default Filters
217
+
218
+ Automatically apply filters to all repository queries (e.g., soft delete, multi-tenant).
219
+
220
+ ```typescript
221
+ import { model, DefaultFilterMixin } from '@venizia/ignis';
222
+
223
+ @model()
224
+ class User extends DefaultFilterMixin(BaseEntity) {
225
+ static readonly schema = pgTable('users', {
226
+ id: integer('id').primaryKey(),
227
+ name: text('name'),
228
+ isDeleted: boolean('is_deleted').default(false),
229
+ });
230
+
231
+ // Define default filter
232
+ static getDefaultFilter() {
233
+ return {
234
+ isDeleted: false, // Exclude deleted users by default
235
+ };
236
+ }
237
+ }
238
+
239
+ // All queries automatically exclude deleted users
240
+ await userRepo.find({});
241
+ // WHERE is_deleted = false
242
+
243
+ // Skip default filter for admin operations
244
+ await userRepo.find({
245
+ where: {},
246
+ options: { shouldSkipDefaultFilter: true },
247
+ });
248
+ // No automatic filter applied
249
+ ```
250
+
251
+ **See:** [Default Filter Guide](./default-filter.md)
252
+
253
+ ---
254
+
255
+ ## Common Filter Patterns
256
+
257
+ ### Multi-Condition Search
258
+
259
+ ```typescript
260
+ {
261
+ and: [
262
+ { age: { gte: 18, lte: 65 } }, // Between 18 and 65
263
+ { status: { in: ['active', 'pending'] } },
264
+ { or: [
265
+ { email: { endsWith: '@company.com' } },
266
+ { role: 'admin' }
267
+ ]}
268
+ ]
269
+ }
270
+ ```
271
+
272
+ ### Text Search
273
+
274
+ ```typescript
275
+ {
276
+ or: [
277
+ { name: { ilike: '%john%' } },
278
+ { email: { ilike: '%john%' } },
279
+ { username: { ilike: '%john%' } }
280
+ ]
281
+ }
282
+ ```
283
+
284
+ ### Date Range
285
+
286
+ ```typescript
287
+ {
288
+ createdAt: {
289
+ gte: new Date('2024-01-01'),
290
+ lt: new Date('2024-02-01')
291
+ }
292
+ }
293
+ ```
294
+
295
+ ### Exclude Soft Deleted
296
+
297
+ ```typescript
298
+ {
299
+ and: [
300
+ { isDeleted: false },
301
+ { status: 'active' }
302
+ ]
303
+ }
304
+ ```
305
+
306
+ ### Multi-Tenant Filtering
307
+
308
+ ```typescript
309
+ {
310
+ and: [
311
+ { tenantId: currentTenantId },
312
+ { isActive: true }
313
+ ]
314
+ }
315
+ ```
316
+
317
+ ---
318
+
319
+ ## Operator Precedence
320
+
321
+ When combining operators, IGNIS follows standard SQL precedence:
322
+
323
+ 1. **NOT** - Highest precedence
324
+ 2. **AND** - Medium precedence
325
+ 3. **OR** - Lowest precedence
326
+
327
+ Use explicit parentheses (via nested `and`/`or`) for clarity:
328
+
329
+ ```typescript
330
+ // Clear precedence
331
+ {
332
+ and: [
333
+ { status: 'active' },
334
+ { or: [
335
+ { role: 'admin' },
336
+ { role: 'moderator' }
337
+ ]}
338
+ ]
339
+ }
340
+ ```
341
+
342
+ ---
343
+
344
+ ## Type Safety
345
+
346
+ All filter operators are fully typed based on your model schema:
347
+
348
+ ```typescript
349
+ interface User {
350
+ id: number;
351
+ name: string;
352
+ age: number;
353
+ email: string;
354
+ tags: string[];
355
+ }
356
+
357
+ // ✅ Type-safe filters
358
+ await userRepo.find({
359
+ where: {
360
+ age: { gt: 18 }, // number operators
361
+ name: { like: '%john%' }, // string operators
362
+ tags: { contains: ['typescript'] } // array operators
363
+ }
364
+ });
365
+
366
+ // ❌ TypeScript error: wrong operator for type
367
+ await userRepo.find({
368
+ where: {
369
+ age: { like: '%18%' } // Error: 'like' not valid for numbers
370
+ }
371
+ });
372
+ ```
373
+
374
+ ---
375
+
376
+ ## Performance Tips
377
+
378
+ 1. **Index frequently filtered columns:**
379
+ ```sql
380
+ CREATE INDEX idx_users_status ON users(status);
381
+ CREATE INDEX idx_posts_created_at ON posts(created_at DESC);
382
+ ```
383
+
384
+ 2. **Use `eq` instead of `like` when possible:**
385
+ ```typescript
386
+ // ✅ Fast: Uses index
387
+ { status: { eq: 'active' } }
388
+
389
+ // ❌ Slower: Full table scan
390
+ { status: { like: 'active' } }
391
+ ```
392
+
393
+ 3. **Limit array contains operations:**
394
+ ```typescript
395
+ // Better performance with smaller arrays
396
+ { tags: { contains: ['typescript'] } } // ✅ Good
397
+ { tags: { contains: ['tag1', 'tag2', /* ... 100 tags */] } } // ❌ Slow
398
+ ```
399
+
400
+ 4. **Use pagination for large result sets:**
401
+ ```typescript
402
+ {
403
+ where: { isActive: true },
404
+ limit: 100,
405
+ offset: 0,
406
+ orderBy: { id: 'asc' }
407
+ }
408
+ ```
409
+
410
+ ---
411
+
412
+ ## See Also
413
+
414
+ - **Detailed Guides:**
415
+ - [Comparison Operators](./comparison-operators.md)
416
+ - [Logical Operators](./logical-operators.md)
417
+ - [Pattern Matching](./pattern-matching.md)
418
+ - [JSON Filtering](./json-filtering.md)
419
+ - [Array Operators](./array-operators.md)
420
+
421
+ - **Related References:**
422
+ - [Repositories](../repositories/) - Using filters in repository queries
423
+ - [Models](../models.md) - Defining model schemas
424
+
425
+ - **Usage Guides:**
426
+ - [Application Usage](./application-usage.md) - Filters in the full stack
427
+ - [Use Case Gallery](./use-cases.md) - Real-world examples
428
+ - [Pro Tips & Edge Cases](./tips.md) - Advanced patterns
429
+
430
+ - **Quick Reference:**
431
+ - [Main Quick Reference](/references/quick-reference.md) - All IGNIS APIs
@@ -0,0 +1,63 @@
1
+ ---
2
+ title: Range Operators
3
+ description: Operators for matching values within or outside a range
4
+ difficulty: intermediate
5
+ ---
6
+
7
+ # Range Operators
8
+
9
+ Operators for matching values within or outside a range.
10
+
11
+
12
+ ## between
13
+
14
+ Find values within a range (inclusive):
15
+
16
+ ```typescript
17
+ // Numeric range
18
+ { where: { price: { between: [100, 500] } } }
19
+ // SQL: WHERE "price" BETWEEN 100 AND 500
20
+
21
+ // Date range
22
+ {
23
+ where: {
24
+ createdAt: {
25
+ between: [new Date('2024-01-01'), new Date('2024-12-31')]
26
+ }
27
+ }
28
+ }
29
+ // SQL: WHERE "created_at" BETWEEN '2024-01-01' AND '2024-12-31'
30
+
31
+ // String range (lexicographic)
32
+ { where: { lastName: { between: ['A', 'M'] } } }
33
+ // SQL: WHERE "last_name" BETWEEN 'A' AND 'M'
34
+ ```
35
+
36
+ > [!WARNING]
37
+ > The value MUST be an array with exactly 2 elements `[min, max]`. Invalid values throw an error.
38
+
39
+
40
+ ## notBetween
41
+
42
+ Find values outside a range:
43
+
44
+ ```typescript
45
+ { where: { score: { notBetween: [40, 60] } } }
46
+ // SQL: WHERE NOT ("score" BETWEEN 40 AND 60)
47
+ // Matches: scores < 40 OR scores > 60
48
+ ```
49
+
50
+
51
+ ## Alternative: Using gte/lte
52
+
53
+ You can also express ranges using comparison operators:
54
+
55
+ ```typescript
56
+ // Equivalent to between: [100, 500]
57
+ { where: { price: { gte: 100, lte: 500 } } }
58
+ // SQL: WHERE "price" >= 100 AND "price" <= 500
59
+
60
+ // Exclusive range (not including boundaries)
61
+ { where: { price: { gt: 100, lt: 500 } } }
62
+ // SQL: WHERE "price" > 100 AND "price" < 500
63
+ ```