@venizia/ignis-docs 0.0.2 → 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 (134) 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 +647 -182
  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 +86 -0
  21. package/wiki/changelogs/2025-12-26-transaction-support.md +57 -0
  22. package/wiki/changelogs/2025-12-29-dynamic-binding-registration.md +104 -0
  23. package/wiki/changelogs/2025-12-29-snowflake-uid-helper.md +100 -0
  24. package/wiki/changelogs/2025-12-30-repository-enhancements.md +214 -0
  25. package/wiki/changelogs/2025-12-31-json-path-filtering-array-operators.md +214 -0
  26. package/wiki/changelogs/2025-12-31-string-id-custom-generator.md +137 -0
  27. package/wiki/changelogs/2026-01-02-default-filter-and-repository-mixins.md +418 -0
  28. package/wiki/changelogs/index.md +8 -1
  29. package/wiki/changelogs/planned-schema-migrator.md +2 -10
  30. package/wiki/{get-started/core-concepts → guides/core-concepts/application}/bootstrapping.md +18 -5
  31. package/wiki/{get-started/core-concepts/application.md → guides/core-concepts/application/index.md} +47 -104
  32. package/wiki/guides/core-concepts/components-guide.md +509 -0
  33. package/wiki/guides/core-concepts/components.md +122 -0
  34. package/wiki/{get-started → guides}/core-concepts/controllers.md +30 -13
  35. package/wiki/{get-started → guides}/core-concepts/dependency-injection.md +97 -0
  36. package/wiki/guides/core-concepts/persistent/datasources.md +179 -0
  37. package/wiki/guides/core-concepts/persistent/index.md +119 -0
  38. package/wiki/guides/core-concepts/persistent/models.md +241 -0
  39. package/wiki/guides/core-concepts/persistent/repositories.md +219 -0
  40. package/wiki/guides/core-concepts/persistent/transactions.md +170 -0
  41. package/wiki/{get-started → guides}/core-concepts/services.md +26 -3
  42. package/wiki/{get-started → guides/get-started}/5-minute-quickstart.md +59 -14
  43. package/wiki/guides/get-started/philosophy.md +682 -0
  44. package/wiki/guides/get-started/setup.md +157 -0
  45. package/wiki/guides/index.md +89 -0
  46. package/wiki/guides/reference/glossary.md +243 -0
  47. package/wiki/{get-started → guides/reference}/mcp-docs-server.md +0 -10
  48. package/wiki/{get-started → guides/tutorials}/building-a-crud-api.md +134 -132
  49. package/wiki/{get-started/quickstart.md → guides/tutorials/complete-installation.md} +107 -71
  50. package/wiki/guides/tutorials/ecommerce-api.md +1399 -0
  51. package/wiki/guides/tutorials/realtime-chat.md +1261 -0
  52. package/wiki/guides/tutorials/testing.md +723 -0
  53. package/wiki/index.md +176 -37
  54. package/wiki/references/base/application.md +27 -0
  55. package/wiki/references/base/bootstrapping.md +30 -26
  56. package/wiki/references/base/components.md +532 -31
  57. package/wiki/references/base/controllers.md +136 -38
  58. package/wiki/references/base/datasources.md +108 -5
  59. package/wiki/references/base/dependency-injection.md +39 -3
  60. package/wiki/references/base/filter-system/application-usage.md +224 -0
  61. package/wiki/references/base/filter-system/array-operators.md +132 -0
  62. package/wiki/references/base/filter-system/comparison-operators.md +109 -0
  63. package/wiki/references/base/filter-system/default-filter.md +428 -0
  64. package/wiki/references/base/filter-system/fields-order-pagination.md +155 -0
  65. package/wiki/references/base/filter-system/index.md +127 -0
  66. package/wiki/references/base/filter-system/json-filtering.md +197 -0
  67. package/wiki/references/base/filter-system/list-operators.md +71 -0
  68. package/wiki/references/base/filter-system/logical-operators.md +156 -0
  69. package/wiki/references/base/filter-system/null-operators.md +58 -0
  70. package/wiki/references/base/filter-system/pattern-matching.md +108 -0
  71. package/wiki/references/base/filter-system/quick-reference.md +431 -0
  72. package/wiki/references/base/filter-system/range-operators.md +63 -0
  73. package/wiki/references/base/filter-system/tips.md +190 -0
  74. package/wiki/references/base/filter-system/use-cases.md +452 -0
  75. package/wiki/references/base/index.md +90 -0
  76. package/wiki/references/base/middlewares.md +602 -0
  77. package/wiki/references/base/models.md +215 -23
  78. package/wiki/references/base/providers.md +732 -0
  79. package/wiki/references/base/repositories/advanced.md +555 -0
  80. package/wiki/references/base/repositories/index.md +228 -0
  81. package/wiki/references/base/repositories/mixins.md +331 -0
  82. package/wiki/references/base/repositories/relations.md +486 -0
  83. package/wiki/references/base/repositories.md +40 -549
  84. package/wiki/references/base/services.md +28 -4
  85. package/wiki/references/components/authentication.md +22 -2
  86. package/wiki/references/components/health-check.md +12 -0
  87. package/wiki/references/components/index.md +23 -0
  88. package/wiki/references/components/mail.md +687 -0
  89. package/wiki/references/components/request-tracker.md +16 -0
  90. package/wiki/references/components/socket-io.md +18 -0
  91. package/wiki/references/components/static-asset.md +14 -26
  92. package/wiki/references/components/swagger.md +17 -0
  93. package/wiki/references/configuration/environment-variables.md +427 -0
  94. package/wiki/references/configuration/index.md +73 -0
  95. package/wiki/references/helpers/cron.md +14 -0
  96. package/wiki/references/helpers/crypto.md +15 -0
  97. package/wiki/references/helpers/env.md +16 -0
  98. package/wiki/references/helpers/error.md +17 -0
  99. package/wiki/references/helpers/index.md +15 -0
  100. package/wiki/references/helpers/inversion.md +24 -4
  101. package/wiki/references/helpers/logger.md +19 -0
  102. package/wiki/references/helpers/network.md +11 -0
  103. package/wiki/references/helpers/queue.md +19 -0
  104. package/wiki/references/helpers/redis.md +21 -0
  105. package/wiki/references/helpers/socket-io.md +24 -5
  106. package/wiki/references/helpers/storage.md +18 -10
  107. package/wiki/references/helpers/testing.md +18 -0
  108. package/wiki/references/helpers/types.md +167 -0
  109. package/wiki/references/helpers/uid.md +167 -0
  110. package/wiki/references/helpers/worker-thread.md +16 -0
  111. package/wiki/references/index.md +177 -0
  112. package/wiki/references/quick-reference.md +634 -0
  113. package/wiki/references/src-details/boot.md +3 -3
  114. package/wiki/references/src-details/dev-configs.md +0 -4
  115. package/wiki/references/src-details/docs.md +2 -2
  116. package/wiki/references/src-details/index.md +86 -0
  117. package/wiki/references/src-details/inversion.md +1 -6
  118. package/wiki/references/src-details/mcp-server.md +3 -15
  119. package/wiki/references/utilities/index.md +86 -10
  120. package/wiki/references/utilities/jsx.md +577 -0
  121. package/wiki/references/utilities/request.md +0 -2
  122. package/wiki/references/utilities/statuses.md +740 -0
  123. package/wiki/changelogs/planned-transaction-support.md +0 -216
  124. package/wiki/get-started/best-practices/api-usage-examples.md +0 -266
  125. package/wiki/get-started/best-practices/architectural-patterns.md +0 -170
  126. package/wiki/get-started/best-practices/data-modeling.md +0 -177
  127. package/wiki/get-started/best-practices/deployment-strategies.md +0 -121
  128. package/wiki/get-started/best-practices/performance-optimization.md +0 -88
  129. package/wiki/get-started/best-practices/security-guidelines.md +0 -99
  130. package/wiki/get-started/core-concepts/components.md +0 -98
  131. package/wiki/get-started/core-concepts/persistent.md +0 -543
  132. package/wiki/get-started/index.md +0 -65
  133. package/wiki/get-started/philosophy.md +0 -296
  134. package/wiki/get-started/prerequisites.md +0 -113
@@ -0,0 +1,224 @@
1
+ ---
2
+ title: Using Filters in Your Application
3
+ description: How filters flow through application layers
4
+ difficulty: intermediate
5
+ ---
6
+
7
+ # Using Filters in Your Application
8
+
9
+ How filters flow through the application layers.
10
+
11
+
12
+ ## Architecture Overview
13
+
14
+ ```
15
+ +-----------------------------------------------------------------+
16
+ | HTTP Request |
17
+ | GET /products?filter={"where":{"status":"active"},"limit":10} |
18
+ +--------------------------------+--------------------------------+
19
+ |
20
+ v
21
+ +-----------------------------------------------------------------+
22
+ | Controller Layer |
23
+ | - Validates filter via Zod schema |
24
+ | - Parses JSON string -> Filter object |
25
+ | - Passes to service/repository |
26
+ +-----------------------------------------------------------------+
27
+ |
28
+ v
29
+ +-----------------------------------------------------------------+
30
+ | Service Layer (Optional) |
31
+ | - Business logic, authorization |
32
+ | - May modify filter before passing |
33
+ +-----------------------------------------------------------------+
34
+ |
35
+ v
36
+ +-----------------------------------------------------------------+
37
+ | Repository Layer |
38
+ | - FilterBuilder transforms Filter -> SQL |
39
+ | - Executes query via Drizzle ORM |
40
+ | - Returns typed results |
41
+ +-----------------------------------------------------------------+
42
+ ```
43
+
44
+
45
+ ## Controller Layer
46
+
47
+ ### Using ControllerFactory (Recommended)
48
+
49
+ The `ControllerFactory` automatically handles filter parsing and validation:
50
+
51
+ ```typescript
52
+ // src/controllers/product.controller.ts
53
+ import { Product } from '@/models';
54
+ import { ProductRepository } from '@/repositories';
55
+ import {
56
+ controller,
57
+ ControllerFactory,
58
+ inject,
59
+ BindingKeys,
60
+ BindingNamespaces,
61
+ } from '@venizia/ignis';
62
+
63
+ const BASE_PATH = '/products';
64
+
65
+ const _Controller = ControllerFactory.defineCrudController({
66
+ repository: { name: ProductRepository.name },
67
+ controller: {
68
+ name: 'ProductController',
69
+ basePath: BASE_PATH,
70
+ isStrict: true,
71
+ defaultLimit: 20,
72
+ },
73
+ entity: () => Product,
74
+ });
75
+
76
+ @controller({ path: BASE_PATH })
77
+ export class ProductController extends _Controller {
78
+ constructor(
79
+ @inject({
80
+ key: BindingKeys.build({
81
+ namespace: BindingNamespaces.REPOSITORY,
82
+ key: ProductRepository.name,
83
+ }),
84
+ })
85
+ repository: ProductRepository,
86
+ ) {
87
+ super(repository);
88
+ }
89
+ }
90
+ ```
91
+
92
+ **Generated Endpoints:**
93
+
94
+ | Method | Endpoint | Filter Location |
95
+ |--------|----------|-----------------|
96
+ | GET | `/products` | Query param: `?filter={...}` |
97
+ | GET | `/products/:id` | Query param: `?filter={...}` (for includes) |
98
+ | GET | `/products/one` | Query param: `?filter={...}` |
99
+ | GET | `/products/count` | Query param: `?where={...}` |
100
+
101
+ ### Custom Controller with Manual Filter Handling
102
+
103
+ ```typescript
104
+ @controller({ path: '/products' })
105
+ export class ProductController extends BaseController {
106
+ constructor(
107
+ @inject({ key: 'repositories.ProductRepository' })
108
+ private _productRepo: ProductRepository,
109
+ ) {
110
+ super({ scope: 'ProductController', path: '/products' });
111
+ }
112
+
113
+ override binding() {
114
+ this.defineRoute({
115
+ configs: {
116
+ path: '/search',
117
+ method: 'get',
118
+ query: {
119
+ filter: FilterSchema,
120
+ },
121
+ },
122
+ handler: async (context) => {
123
+ const { filter = {} } = context.req.valid('query');
124
+ const results = await this._productRepo.find({ filter });
125
+ return context.json(results);
126
+ },
127
+ });
128
+ }
129
+ }
130
+ ```
131
+
132
+
133
+ ## Service Layer
134
+
135
+ Services can modify filters before passing to repositories:
136
+
137
+ ```typescript
138
+ @service()
139
+ export class ProductService {
140
+ constructor(
141
+ @inject({ key: 'repositories.ProductRepository' })
142
+ private _productRepo: ProductRepository,
143
+ ) {}
144
+
145
+ async findProducts(filter: TFilter<TProductSchema> = {}) {
146
+ // Merge user filter with soft-delete condition
147
+ const enhancedFilter: TFilter<TProductSchema> = {
148
+ ...filter,
149
+ where: {
150
+ ...filter.where,
151
+ deletedAt: { is: null },
152
+ },
153
+ };
154
+
155
+ return this._productRepo.find({ filter: enhancedFilter });
156
+ }
157
+
158
+ async findProductsForTenant(
159
+ tenantId: string,
160
+ filter: TFilter<TProductSchema> = {},
161
+ ) {
162
+ const isolatedFilter: TFilter<TProductSchema> = {
163
+ ...filter,
164
+ where: {
165
+ ...filter.where,
166
+ tenantId,
167
+ },
168
+ };
169
+
170
+ return this._productRepo.find({ filter: isolatedFilter });
171
+ }
172
+ }
173
+ ```
174
+
175
+
176
+ ## HTTP Request Examples
177
+
178
+ **cURL:**
179
+ ```bash
180
+ # Simple filter
181
+ curl "http://localhost:3000/products?filter=%7B%22where%22%3A%7B%22status%22%3A%22active%22%7D%2C%22limit%22%3A10%7D"
182
+
183
+ # Decoded filter: {"where":{"status":"active"},"limit":10}
184
+
185
+ # Complex filter with URL encoding
186
+ curl -G "http://localhost:3000/products" \
187
+ --data-urlencode 'filter={"where":{"price":{"gte":100,"lte":500},"tags":{"contains":["featured"]}},"order":["price ASC"],"limit":20}'
188
+ ```
189
+
190
+ **JavaScript/TypeScript:**
191
+ ```typescript
192
+ // Using fetch
193
+ const filter = {
194
+ where: { status: 'active', price: { lte: 100 } },
195
+ order: ['createdAt DESC'],
196
+ limit: 10,
197
+ };
198
+
199
+ const response = await fetch(
200
+ `/api/products?filter=${encodeURIComponent(JSON.stringify(filter))}`
201
+ );
202
+
203
+ // Using axios
204
+ const response = await axios.get('/api/products', {
205
+ params: { filter: JSON.stringify(filter) },
206
+ });
207
+ ```
208
+
209
+
210
+ ## Debugging Filters
211
+
212
+ ```typescript
213
+ // Enable logging to see generated SQL
214
+ const result = await repo.find({
215
+ filter: complexFilter,
216
+ options: {
217
+ log: { use: true, level: 'debug' },
218
+ },
219
+ });
220
+
221
+ // Or use buildQuery to inspect without executing
222
+ const queryOptions = repo.buildQuery({ filter: complexFilter });
223
+ console.log('Generated query options:', queryOptions);
224
+ ```
@@ -0,0 +1,132 @@
1
+ ---
2
+ title: PostgreSQL Array Operators
3
+ description: Operators for PostgreSQL array columns
4
+ difficulty: intermediate
5
+ ---
6
+
7
+ # PostgreSQL Array Operators
8
+
9
+ Operators for PostgreSQL array columns (`varchar[]`, `text[]`, `integer[]`, etc.).
10
+
11
+ | Operator | PostgreSQL | Description |
12
+ |----------|------------|-------------|
13
+ | `contains` | `@>` | Array contains **ALL** specified elements |
14
+ | `containedBy` | `<@` | Array is a **subset** of specified elements |
15
+ | `overlaps` | `&&` | Array shares **ANY** element with specified |
16
+
17
+
18
+ ## contains (@>)
19
+
20
+ Find rows where the array column contains **all** specified elements.
21
+
22
+ ```typescript
23
+ // Schema: tags varchar(100)[]
24
+ // Data: Product A has ['electronics', 'featured', 'sale']
25
+
26
+ // Find products with BOTH 'electronics' AND 'featured'
27
+ { where: { tags: { contains: ['electronics', 'featured'] } } }
28
+ // SQL: "tags"::text[] @> ARRAY['electronics', 'featured']::text[]
29
+
30
+ // Single element
31
+ { where: { tags: { contains: ['featured'] } } }
32
+ // Matches: ['featured'], ['featured', 'sale'], ['a', 'featured', 'b']
33
+ ```
34
+
35
+
36
+ ## containedBy (<@)
37
+
38
+ Find rows where **all** array elements are within the specified set.
39
+
40
+ ```typescript
41
+ // Find products where ALL tags are in the allowed list
42
+ { where: { tags: { containedBy: ['sale', 'featured', 'new', 'popular'] } } }
43
+ // SQL: "tags"::text[] <@ ARRAY['sale', 'featured', 'new', 'popular']::text[]
44
+
45
+ // Product A ['featured', 'sale'] -> matches (all in list)
46
+ // Product B ['featured', 'clearance'] -> no match ('clearance' not in list)
47
+ // Product C [] -> matches (empty is subset of everything)
48
+ ```
49
+
50
+
51
+ ## overlaps (&&)
52
+
53
+ Find rows where the arrays share at least one common element.
54
+
55
+ ```typescript
56
+ // Find products with 'premium' OR 'sale' tag
57
+ { where: { tags: { overlaps: ['premium', 'sale'] } } }
58
+ // SQL: "tags"::text[] && ARRAY['premium', 'sale']::text[]
59
+
60
+ // Product A ['featured', 'sale'] -> matches (has 'sale')
61
+ // Product B ['premium', 'luxury'] -> matches (has 'premium')
62
+ // Product C ['new', 'featured'] -> no match (no overlap)
63
+ ```
64
+
65
+
66
+ ## Visual Comparison
67
+
68
+ | Product | tags | `contains ['featured']` | `containedBy ['a','b','featured']` | `overlaps ['sale','premium']` |
69
+ |---------|------|------------------------|-----------------------------------|------------------------------|
70
+ | A | `['featured', 'sale']` | Yes | No (has 'sale') | Yes (has 'sale') |
71
+ | B | `['featured']` | Yes | Yes | No |
72
+ | C | `['a', 'b']` | No | Yes | No |
73
+ | D | `['premium']` | No | No | Yes (has 'premium') |
74
+ | E | `[]` | No | Yes (empty subset) | No |
75
+
76
+
77
+ ## Decision Guide
78
+
79
+ | Question | Use |
80
+ |----------|-----|
81
+ | "Must have ALL these tags" | `contains` |
82
+ | "Tags must only be from this list" | `containedBy` |
83
+ | "Must have AT LEAST ONE of these tags" | `overlaps` |
84
+
85
+
86
+ ## Empty Array Behavior
87
+
88
+ | Operator | Empty Value `[]` | Behavior |
89
+ |----------|------------------|----------|
90
+ | `contains: []` | Returns **ALL** rows | Everything contains empty set |
91
+ | `containedBy: []` | Returns only rows with **empty arrays** | Only `[]` is subset of `[]` |
92
+ | `overlaps: []` | Returns **NO** rows | Nothing overlaps with empty |
93
+
94
+
95
+ ## Type Handling
96
+
97
+ **String Arrays** (`varchar[]`, `text[]`, `char[]`):
98
+ ```typescript
99
+ { where: { tags: { contains: ['a', 'b'] } } }
100
+ // SQL: "tags"::text[] @> ARRAY['a', 'b']::text[]
101
+ ```
102
+
103
+ **Numeric Arrays** (`integer[]`, `numeric[]`):
104
+ ```typescript
105
+ { where: { scores: { contains: [100, 200] } } }
106
+ // SQL: "scores" @> ARRAY[100, 200]
107
+ ```
108
+
109
+ **Boolean Arrays**:
110
+ ```typescript
111
+ { where: { flags: { contains: [true, false] } } }
112
+ // SQL: "flags" @> ARRAY[true, false]
113
+ ```
114
+
115
+
116
+ ## Defining Array Columns
117
+
118
+ In your Drizzle schema:
119
+
120
+ ```typescript
121
+ import { pgTable, text, varchar, integer } from 'drizzle-orm/pg-core';
122
+
123
+ export const productTable = pgTable('Product', {
124
+ id: text('id').primaryKey(),
125
+ name: text('name').notNull(),
126
+
127
+ // Array columns
128
+ tags: varchar('tags', { length: 100 }).array(), // varchar(100)[]
129
+ categories: text('categories').array(), // text[]
130
+ scores: integer('scores').array(), // integer[]
131
+ });
132
+ ```
@@ -0,0 +1,109 @@
1
+ ---
2
+ title: Comparison Operators
3
+ description: Equality and comparison operators for filtering records
4
+ difficulty: intermediate
5
+ ---
6
+
7
+ # Comparison Operators
8
+
9
+ Equality and comparison operators for filtering records.
10
+
11
+
12
+ ## eq - Equal To
13
+
14
+ Matches records where field equals the value.
15
+
16
+ ```typescript
17
+ // Implicit equality
18
+ { where: { status: 'active' } }
19
+
20
+ // Explicit form
21
+ { where: { status: { eq: 'active' } } }
22
+
23
+ // SQL: WHERE "status" = 'active'
24
+ ```
25
+
26
+ **Special Cases:**
27
+ ```typescript
28
+ // Null equality
29
+ { where: { deletedAt: null } }
30
+ { where: { deletedAt: { eq: null } } }
31
+ // SQL: WHERE "deleted_at" IS NULL
32
+
33
+ // Array shorthand (becomes IN)
34
+ { where: { id: [1, 2, 3] } }
35
+ // SQL: WHERE "id" IN (1, 2, 3)
36
+ ```
37
+
38
+
39
+ ## ne / neq - Not Equal To
40
+
41
+ Matches records where field does NOT equal the value.
42
+
43
+ ```typescript
44
+ { where: { status: { ne: 'deleted' } } }
45
+ { where: { status: { neq: 'deleted' } } } // Alias
46
+
47
+ // SQL: WHERE "status" != 'deleted'
48
+
49
+ // Null handling
50
+ { where: { deletedAt: { ne: null } } }
51
+ // SQL: WHERE "deleted_at" IS NOT NULL
52
+ ```
53
+
54
+
55
+ ## gt - Greater Than
56
+
57
+ ```typescript
58
+ // Numbers
59
+ { where: { price: { gt: 100 } } }
60
+ // SQL: WHERE "price" > 100
61
+
62
+ // Dates
63
+ { where: { createdAt: { gt: new Date('2024-01-01') } } }
64
+ // SQL: WHERE "created_at" > '2024-01-01'
65
+
66
+ // Strings (lexicographic)
67
+ { where: { name: { gt: 'M' } } }
68
+ // SQL: WHERE "name" > 'M'
69
+ ```
70
+
71
+
72
+ ## gte - Greater Than or Equal
73
+
74
+ ```typescript
75
+ { where: { quantity: { gte: 10 } } }
76
+ // SQL: WHERE "quantity" >= 10
77
+
78
+ // Combined with other operators
79
+ { where: { age: { gte: 18, lt: 65 } } }
80
+ // SQL: WHERE "age" >= 18 AND "age" < 65
81
+ ```
82
+
83
+
84
+ ## lt - Less Than
85
+
86
+ ```typescript
87
+ { where: { stock: { lt: 5 } } }
88
+ // SQL: WHERE "stock" < 5
89
+ ```
90
+
91
+
92
+ ## lte - Less Than or Equal
93
+
94
+ ```typescript
95
+ { where: { rating: { lte: 3 } } }
96
+ // SQL: WHERE "rating" <= 3
97
+ ```
98
+
99
+
100
+ ## Summary
101
+
102
+ | Operator | SQL | Description |
103
+ |----------|-----|-------------|
104
+ | `eq` | `=` | Equal to |
105
+ | `ne` / `neq` | `!=` | Not equal to |
106
+ | `gt` | `>` | Greater than |
107
+ | `gte` | `>=` | Greater than or equal |
108
+ | `lt` | `<` | Less than |
109
+ | `lte` | `<=` | Less than or equal |