@venizia/ignis-docs 0.0.1-9 → 0.0.1

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 (32) hide show
  1. package/LICENSE.md +1 -0
  2. package/package.json +2 -2
  3. package/wiki/changelogs/{v0.0.1-7-initial-architecture.md → 2025-12-16-initial-architecture.md} +20 -12
  4. package/wiki/changelogs/2025-12-16-model-repo-datasource-refactor.md +300 -0
  5. package/wiki/changelogs/2025-12-17-refactor.md +80 -12
  6. package/wiki/changelogs/2025-12-18-performance-optimizations.md +28 -90
  7. package/wiki/changelogs/2025-12-18-repository-validation-security.md +101 -297
  8. package/wiki/changelogs/index.md +19 -8
  9. package/wiki/changelogs/planned-transaction-support.md +216 -0
  10. package/wiki/changelogs/template.md +123 -0
  11. package/wiki/get-started/best-practices/api-usage-examples.md +0 -2
  12. package/wiki/get-started/best-practices/architectural-patterns.md +2 -2
  13. package/wiki/get-started/best-practices/common-pitfalls.md +5 -3
  14. package/wiki/get-started/best-practices/contribution-workflow.md +2 -0
  15. package/wiki/get-started/best-practices/data-modeling.md +91 -34
  16. package/wiki/get-started/best-practices/security-guidelines.md +3 -1
  17. package/wiki/get-started/building-a-crud-api.md +3 -3
  18. package/wiki/get-started/core-concepts/application.md +72 -3
  19. package/wiki/get-started/core-concepts/bootstrapping.md +566 -0
  20. package/wiki/get-started/core-concepts/components.md +4 -2
  21. package/wiki/get-started/core-concepts/persistent.md +350 -378
  22. package/wiki/get-started/core-concepts/services.md +21 -27
  23. package/wiki/references/base/bootstrapping.md +789 -0
  24. package/wiki/references/base/components.md +1 -1
  25. package/wiki/references/base/dependency-injection.md +95 -2
  26. package/wiki/references/base/services.md +2 -2
  27. package/wiki/references/components/authentication.md +4 -3
  28. package/wiki/references/components/index.md +1 -1
  29. package/wiki/references/helpers/error.md +2 -2
  30. package/wiki/references/src-details/boot.md +379 -0
  31. package/wiki/references/src-details/core.md +2 -2
  32. package/wiki/changelogs/v0.0.1-8-model-repo-datasource-refactor.md +0 -278
@@ -1,3 +1,8 @@
1
+ ---
2
+ title: Repository Validation & Security
3
+ description: Strict validation for @repository decorator and security fixes for filter operators
4
+ ---
5
+
1
6
  # Changelog - 2025-12-18
2
7
 
3
8
  ## Repository Validation & Security Improvements
@@ -6,18 +11,19 @@ This update adds strict validation to the `@repository` decorator and fixes seve
6
11
 
7
12
  ## Overview
8
13
 
9
- - **@repository Decorator**: Now requires both `model` AND `dataSource` for schema auto-discovery
10
- - **Constructor Validation**: First parameter must extend `AbstractDataSource` (enforced via reflection)
11
- - **DataSource Auto-Discovery**: Schema is automatically built from `@repository` bindings - no manual merging needed!
12
- - **Filter Security**: Fixed empty IN array bypass, invalid column handling, BETWEEN validation
13
- - **PostgreSQL Compatibility**: REGEXP now uses PostgreSQL POSIX operators
14
- - **UUID Generation**: Now uses native PostgreSQL `uuid` type with `gen_random_uuid()`
14
+ - **@repository Decorator**: Now requires both `model` AND `dataSource` for schema auto-discovery.
15
+ - **Constructor Validation**: First parameter must extend `AbstractDataSource` (enforced via reflection).
16
+ - **DataSource Auto-Discovery**: Schema is automatically built from `@repository` bindings.
17
+ - **Filter Security**: Fixed empty IN array bypass, invalid column handling, BETWEEN validation.
18
+ - **PostgreSQL Compatibility**: REGEXP now uses PostgreSQL POSIX operators.
19
+ - **UUID Generation**: Now uses native PostgreSQL `uuid` type with `gen_random_uuid()`.
15
20
 
16
21
  ## Breaking Changes
17
22
 
18
- ### 1. Repository Constructor Signature Changed
23
+ > [!WARNING]
24
+ > This section contains changes that require migration or manual updates to existing code.
19
25
 
20
- **This is a major breaking change.** The constructor signature for all repository classes has changed.
26
+ ### 1. Repository Constructor Signature
21
27
 
22
28
  **Before:**
23
29
  ```typescript
@@ -33,101 +39,49 @@ constructor(opts: {
33
39
  constructor(ds?: IDataSource, opts?: { entityClass?: TClass<BaseEntity<EntitySchema>> })
34
40
  ```
35
41
 
36
- **Key changes:**
37
- - DataSource is now the first parameter (auto-injected from `@repository` decorator)
38
- - `relations` parameter removed - now auto-resolved from entity's static `relations` property
39
- - Both parameters are optional when using `@repository` decorator with `model` and `dataSource`
40
-
41
- **Migration:**
42
- ```typescript
43
- // Before
44
- @repository({})
45
- export class UserRepository extends DefaultCRUDRepository<typeof User.schema> {
46
- constructor(
47
- @inject({ key: 'datasources.PostgresDataSource' }) ds: PostgresDataSource,
48
- ) {
49
- super({
50
- entityClass: User,
51
- relations: userRelations.definitions,
52
- dataSource: ds,
53
- });
54
- }
55
- }
56
-
57
- // After - Zero boilerplate
58
- @repository({ model: User, dataSource: PostgresDataSource })
59
- export class UserRepository extends DefaultCRUDRepository<typeof User.schema> {
60
- // No constructor needed!
61
- }
62
-
63
- // After - With explicit constructor
64
- @repository({ model: User, dataSource: PostgresDataSource })
65
- export class UserRepository extends DefaultCRUDRepository<typeof User.schema> {
66
- constructor(
67
- @inject({ key: 'datasources.PostgresDataSource' }) ds: PostgresDataSource,
68
- ) {
69
- super(ds); // Just pass dataSource, entity and relations auto-resolved
70
- }
71
- }
72
- ```
73
-
74
- ### 2. @repository Decorator Requires Both `model` AND `dataSource`
42
+ ### 2. @repository Decorator Requirements
75
43
 
76
- **Before (would silently fail to register model):**
44
+ **Before:**
77
45
  ```typescript
78
- // This would not register User for schema auto-discovery
46
+ // Would silently fail to register model
79
47
  @repository({ model: User })
80
48
  export class UserRepository extends DefaultCRUDRepository<typeof User.schema> {}
81
49
  ```
82
50
 
83
- **After (throws error):**
51
+ **After:**
84
52
  ```typescript
85
- // Error: [@repository][UserRepository] Invalid metadata | Missing 'dataSource'
53
+ // Throws Error: Invalid metadata | Missing 'dataSource'
86
54
  @repository({ model: User })
87
55
  export class UserRepository extends DefaultCRUDRepository<typeof User.schema> {}
88
56
 
89
- // Correct usage
57
+ // Correct
90
58
  @repository({ model: User, dataSource: PostgresDataSource })
91
59
  export class UserRepository extends DefaultCRUDRepository<typeof User.schema> {}
92
60
  ```
93
61
 
94
- ### 2. Constructor First Parameter Must Be DataSource Type
95
-
96
- When using explicit `@inject` in constructor, the first parameter **must** extend `AbstractDataSource`:
62
+ ### 3. Constructor Parameter Type
97
63
 
98
- **Before (would work with wrong type):**
64
+ **Before:**
99
65
  ```typescript
100
- @repository({ model: User, dataSource: PostgresDataSource })
101
- export class UserRepository extends ReadableRepository<typeof User.schema> {
102
- constructor(
103
- @inject({ key: 'datasources.PostgresDataSource' })
104
- dataSource: any, // ❌ This would compile but is wrong
105
- ) {
106
- super(dataSource);
107
- }
108
- }
66
+ constructor(
67
+ @inject({ key: 'datasources.PostgresDataSource' })
68
+ dataSource: any, // Would compile but is wrong
69
+ )
109
70
  ```
110
71
 
111
- **After (enforced at decorator time):**
72
+ **After:**
112
73
  ```typescript
113
- @repository({ model: User, dataSource: PostgresDataSource })
114
- export class UserRepository extends ReadableRepository<typeof User.schema> {
115
- constructor(
116
- @inject({ key: 'datasources.PostgresDataSource' })
117
- dataSource: PostgresDataSource, // ✅ Must be concrete DataSource type
118
- ) {
119
- super(dataSource);
120
- }
121
- }
74
+ constructor(
75
+ @inject({ key: 'datasources.PostgresDataSource' })
76
+ dataSource: PostgresDataSource, // Must be concrete DataSource type
77
+ )
122
78
  ```
123
79
 
124
- ### 3. Filter Column Validation
125
-
126
- Invalid column names now throw errors instead of being silently ignored:
80
+ ### 4. Filter Column Validation
127
81
 
128
82
  **Before:**
129
83
  ```typescript
130
- // Would silently ignore 'invalidColumn'
84
+ // Silently ignored 'invalidColumn'
131
85
  await repo.find({ filter: { where: { invalidColumn: 'value' } } });
132
86
  ```
133
87
 
@@ -137,68 +91,17 @@ await repo.find({ filter: { where: { invalidColumn: 'value' } } });
137
91
  await repo.find({ filter: { where: { invalidColumn: 'value' } } });
138
92
  ```
139
93
 
140
- ## Security Fixes
141
-
142
- ### Empty IN Array Bypass (CVE-like)
143
-
144
- **Vulnerability:** Empty `IN` arrays would return `true`, bypassing security filters.
145
-
146
- **Fix:** Empty `IN` arrays now return `sql\`false\``, correctly matching no records.
147
-
148
- ```typescript
149
- // Before: WHERE id IN () => true (security bypass!)
150
- // After: WHERE false => no records (correct)
151
- await repo.find({ filter: { where: { id: { IN: [] } } } });
152
- ```
153
-
154
- ### BETWEEN Validation
155
-
156
- **Vulnerability:** Invalid `BETWEEN` values could cause unexpected behavior.
157
-
158
- **Fix:** BETWEEN now validates input is array of exactly 2 elements.
159
-
160
- ```typescript
161
- // Throws: [BETWEEN] Invalid value: expected array of 2 elements
162
- await repo.find({ filter: { where: { age: { BETWEEN: [10] } } } });
163
- ```
164
-
165
- ### PostgreSQL REGEXP Compatibility
166
-
167
- **Issue:** MySQL-style REGEXP operator doesn't work in PostgreSQL.
168
-
169
- **Fix:** Now uses PostgreSQL POSIX regex operators:
170
- - `REGEXP` → `~` (case-sensitive)
171
- - `IREGEXP` → `~*` (case-insensitive, new!)
172
-
173
- ```typescript
174
- // PostgreSQL-compatible regex
175
- await repo.find({ filter: { where: { name: { REGEXP: '^John' } } } });
176
- await repo.find({ filter: { where: { name: { IREGEXP: '^john' } } } }); // Case-insensitive
177
- ```
178
-
179
94
  ## New Features
180
95
 
181
96
  ### DataSource Schema Auto-Discovery
182
97
 
183
- DataSources can now automatically discover their schema from registered `@repository` decorators:
98
+ **File:** `packages/core/src/base/datasources/base.ts`
184
99
 
185
- ```typescript
186
- // Before: Manual schema merging required
187
- @datasource({ driver: 'node-postgres' })
188
- export class PostgresDataSource extends BaseDataSource<...> {
189
- constructor() {
190
- super({
191
- name: PostgresDataSource.name,
192
- config: { /* ... */ },
193
- schema: Object.assign({}, // Manual merge!
194
- { [User.TABLE_NAME]: userTable },
195
- userRelations.relations,
196
- ),
197
- });
198
- }
199
- }
100
+ **Problem:** Manual schema merging was error-prone and verbose.
200
101
 
201
- // After: Auto-discovery - no schema needed!
102
+ **Solution:** DataSources automatically discover their schema from `@repository` bindings.
103
+
104
+ ```typescript
202
105
  @datasource({ driver: 'node-postgres' })
203
106
  export class PostgresDataSource extends BaseDataSource<...> {
204
107
  constructor() {
@@ -211,174 +114,114 @@ export class PostgresDataSource extends BaseDataSource<...> {
211
114
  }
212
115
  ```
213
116
 
214
- When repositories are defined with `@repository({ model: User, dataSource: PostgresDataSource })`, the framework automatically builds the schema.
117
+ ### UUID Type Improvement
215
118
 
216
- ### Schema Key Mismatch Validation
119
+ **File:** `packages/core/src/base/models/enrichers/id.enricher.ts`
217
120
 
218
- Added helpful error when entity name doesn't match schema keys:
121
+ **Problem:** JS-generated UUIDs were stored as text, which is less efficient.
219
122
 
220
- ```typescript
221
- // Error: [UserRepository] Schema key mismatch | Entity name 'User' not found in connector.query | Available keys: [Configuration, Post]
222
- ```
223
-
224
- ### UUID Type Improvement
225
-
226
- Changed from `text` type with JS-generated UUID to native PostgreSQL `uuid`:
123
+ **Solution:** Changed to native PostgreSQL `uuid` type with `gen_random_uuid()`.
227
124
 
228
125
  ```typescript
229
- // Before: text('id').primaryKey().$defaultFn(() => crypto.randomUUID())
230
126
  // After: uuid('id').defaultRandom().primaryKey()
231
127
  ```
232
128
 
233
- Benefits:
234
- - Native PostgreSQL UUID type (16 bytes vs 36 bytes)
235
- - Uses `gen_random_uuid()` - no extension required
236
- - Better indexing performance
237
-
238
129
  ### Case-Insensitive REGEXP (IREGEXP)
239
130
 
240
- Added new `IREGEXP` operator for case-insensitive regex matching:
241
-
242
- ```typescript
243
- // Case-sensitive (existing)
244
- await repo.find({ filter: { where: { name: { REGEXP: '^John' } } } });
245
-
246
- // Case-insensitive (new!)
247
- await repo.find({ filter: { where: { name: { IREGEXP: '^john' } } } });
248
- ```
131
+ **File:** `packages/core/src/base/repositories/operators/query.ts`
249
132
 
250
- ### BaseEntity Static Schema & Relations
133
+ **Problem:** PostgreSQL regex matching is case-sensitive by default.
251
134
 
252
- Models can now define schema and relations as static properties, enabling cleaner syntax:
135
+ **Solution:** Added `IREGEXP` operator for case-insensitive matching (`~*`).
253
136
 
254
137
  ```typescript
255
- // Before - Constructor-based schema
256
- @model({ type: 'entity' })
257
- export class User extends BaseEntity<typeof userTable> {
258
- constructor() {
259
- super({ name: 'User', schema: userTable });
260
- }
261
- }
262
-
263
- // After - Static schema (recommended)
264
- @model({ type: 'entity' })
265
- export class User extends BaseEntity<typeof User.schema> {
266
- static override schema = userTable;
267
- static override relations = () => userRelations.definitions;
268
- static override TABLE_NAME = 'User';
269
- }
138
+ await repo.find({ filter: { where: { name: { IREGEXP: '^john' } } } });
270
139
  ```
271
140
 
272
- Relations are now auto-resolved from the entity's static `relations` property - no need to pass them in repository constructor.
273
-
274
141
  ### Repository Log Option
275
142
 
276
- All CRUD operations now support a `log` option for debugging:
143
+ **File:** `packages/core/src/base/repositories/core/persistable.ts`
144
+
145
+ **Problem:** Debugging repository operations was difficult without logging.
146
+
147
+ **Solution:** Added `log` option to all CRUD operations.
277
148
 
278
149
  ```typescript
279
- // Enable logging for a specific operation
280
150
  await repo.create({
281
151
  data: { name: 'John' },
282
152
  options: {
283
153
  log: { use: true, level: 'debug' }
284
154
  }
285
155
  });
286
-
287
- // Log output: [_create] Executing with opts: { data: [...], options: {...} }
288
156
  ```
289
157
 
290
- **Available on:** `create`, `createAll`, `updateById`, `updateAll`, `deleteById`, `deleteAll`
291
-
292
- ### Improved TypeScript Return Types
158
+ ## Security Fixes
293
159
 
294
- Repository methods now have better type inference based on `shouldReturn`:
160
+ ### Empty IN Array Bypass
295
161
 
296
- ```typescript
297
- // When shouldReturn: false - returns null
298
- const result1 = await repo.create({
299
- data: { name: 'John' },
300
- options: { shouldReturn: false }
301
- });
302
- // Type: Promise<TCount & { data: null }>
162
+ **Vulnerability:** Empty `IN` arrays would return `true`, bypassing security filters.
303
163
 
304
- // When shouldReturn: true (default) - returns the entity
305
- const result2 = await repo.create({
306
- data: { name: 'John' },
307
- options: { shouldReturn: true }
308
- });
309
- // Type: Promise<TCount & { data: User }>
164
+ **Fix:** Empty `IN` arrays now return `sql\`false\``.
310
165
 
311
- // TypeScript now correctly infers the return type!
166
+ ```typescript
167
+ // Before: WHERE id IN () => true (bypass)
168
+ // After: WHERE false => no records
169
+ await repo.find({ filter: { where: { id: { IN: [] } } } });
312
170
  ```
313
171
 
314
- ### IEntity Interface
172
+ ### BETWEEN Validation
173
+
174
+ **Vulnerability:** Invalid `BETWEEN` values could cause unexpected behavior.
315
175
 
316
- New interface for model classes with static schema and relations:
176
+ **Fix:** `BETWEEN` now validates input is an array of exactly 2 elements.
317
177
 
318
178
  ```typescript
319
- interface IEntity<Schema extends TTableSchemaWithId = TTableSchemaWithId> {
320
- TABLE_NAME?: string;
321
- schema: Schema;
322
- relations?: TValueOrResolver<Array<TRelationConfig>>;
323
- }
179
+ // Throws: [BETWEEN] Invalid value: expected array of 2 elements
180
+ await repo.find({ filter: { where: { age: { BETWEEN: [10] } } } });
324
181
  ```
325
182
 
326
183
  ## Files Changed
327
184
 
328
- ### Core Package - Models
329
- - `packages/core/src/base/models/base.ts` - Static schema/relations support, IEntity interface
330
- - `packages/core/src/base/models/common/types.ts` - IEntity interface definition
331
- - `packages/core/src/base/models/enrichers/id.enricher.ts` - Native PostgreSQL UUID type
332
- - `packages/core/src/base/models/enrichers/tz.enricher.ts` - Type naming fix
333
-
334
- ### Core Package - Repositories
335
- - `packages/core/src/base/repositories/core/base.ts` - Constructor signature change, relations auto-resolution
336
- - `packages/core/src/base/repositories/core/readable.ts` - Constructor change, getQueryInterface validation
337
- - `packages/core/src/base/repositories/core/persistable.ts` - Constructor change, log option, TypeScript overloads
338
- - `packages/core/src/base/repositories/core/default-crud.ts` - Documentation update
339
- - `packages/core/src/base/repositories/common/types.ts` - TRepositoryLogOptions, TypeScript overloads
340
- - `packages/core/src/base/repositories/operators/filter.ts` - Column validation, error throwing
341
- - `packages/core/src/base/repositories/operators/query.ts` - REGEXP/IREGEXP fix, BETWEEN validation, IN empty array fix
342
-
343
- ### Core Package - DataSources & Metadata
344
- - `packages/core/src/base/datasources/base.ts` - Schema auto-discovery feature
345
- - `packages/core/src/base/metadata/persistents.ts` - Repository decorator validation, constructor type validation
346
-
347
- ### Examples
348
- - `examples/vert/src/repositories/user.repository.ts` - Updated to proper types
349
- - `examples/vert/src/repositories/configuration.repository.ts` - Updated patterns
350
- - `examples/vert/src/datasources/postgres.datasource.ts` - Using auto-discovery
351
- - `examples/vert/src/models/entities/user.model.ts` - Static schema pattern
352
- - `examples/vert/src/models/entities/configuration.model.ts` - Static schema pattern
185
+ ### Core Package (`packages/core`)
186
+
187
+ | File | Changes |
188
+ |------|---------|
189
+ | `src/base/models/base.ts` | Static schema/relations support, IEntity interface |
190
+ | `src/base/models/common/types.ts` | IEntity interface definition |
191
+ | `src/base/models/enrichers/id.enricher.ts` | Native PostgreSQL UUID type |
192
+ | `src/base/repositories/core/base.ts` | Constructor signature change, relations auto-resolution |
193
+ | `src/base/repositories/core/readable.ts` | Constructor change, getQueryInterface validation |
194
+ | `src/base/repositories/core/persistable.ts` | Constructor change, log option, TypeScript overloads |
195
+ | `src/base/repositories/operators/filter.ts` | Column validation, error throwing |
196
+ | `src/base/repositories/operators/query.ts` | REGEXP/IREGEXP fix, BETWEEN validation, IN empty array fix |
197
+ | `src/base/datasources/base.ts` | Schema auto-discovery feature |
198
+ | `src/base/metadata/persistents.ts` | Repository decorator validation, constructor type validation |
199
+
200
+ ### Examples (`examples/vert`)
201
+
202
+ | File | Changes |
203
+ |------|---------|
204
+ | `src/repositories/user.repository.ts` | Updated to proper types |
205
+ | `src/repositories/configuration.repository.ts` | Updated patterns |
206
+ | `src/datasources/postgres.datasource.ts` | Using auto-discovery |
353
207
 
354
208
  ## Migration Guide
355
209
 
356
- ### Step 1: Update Repository Constructors (BREAKING)
210
+ > [!NOTE]
211
+ > Follow these steps if you're upgrading from a previous version.
357
212
 
358
- The repository constructor signature has changed:
213
+ ### Step 1: Update Repository Constructors
359
214
 
360
- ```typescript
361
- // Before
362
- @repository({})
363
- export class UserRepository extends DefaultCRUDRepository<typeof User.schema> {
364
- constructor(
365
- @inject({ key: 'datasources.PostgresDataSource' }) ds: PostgresDataSource,
366
- ) {
367
- super({
368
- entityClass: User,
369
- relations: userRelations.definitions,
370
- dataSource: ds,
371
- });
372
- }
373
- }
215
+ The repository constructor signature has changed. Update all repository classes.
374
216
 
375
- // After - Option A: Zero boilerplate (recommended)
217
+ ```typescript
218
+ // Option A: Zero boilerplate (recommended)
376
219
  @repository({ model: User, dataSource: PostgresDataSource })
377
220
  export class UserRepository extends DefaultCRUDRepository<typeof User.schema> {
378
221
  // No constructor needed!
379
222
  }
380
223
 
381
- // After - Option B: With explicit constructor
224
+ // Option B: With explicit constructor
382
225
  @repository({ model: User, dataSource: PostgresDataSource })
383
226
  export class UserRepository extends DefaultCRUDRepository<typeof User.schema> {
384
227
  constructor(
@@ -389,57 +232,18 @@ export class UserRepository extends DefaultCRUDRepository<typeof User.schema> {
389
232
  }
390
233
  ```
391
234
 
392
- ### Step 2: Update Model Definitions (Optional but Recommended)
235
+ ### Step 2: Update @repository Decorators
393
236
 
394
- Add static properties to your models for relations auto-resolution:
237
+ Ensure all `@repository` decorators have both `model` and `dataSource`.
395
238
 
396
239
  ```typescript
397
- // Before
398
- @model({ type: 'entity' })
399
- export class User extends BaseEntity<typeof userTable> {
400
- constructor() {
401
- super({ name: 'User', schema: userTable });
402
- }
403
- }
404
-
405
- // After - Static properties
406
- @model({ type: 'entity' })
407
- export class User extends BaseEntity<typeof User.schema> {
408
- static override schema = userTable;
409
- static override relations = () => userRelations.definitions;
410
- static override TABLE_NAME = 'User';
411
- }
412
- ```
413
-
414
- ### Step 3: Update @repository Decorators
415
-
416
- Ensure all `@repository` decorators have both `model` and `dataSource`:
417
-
418
- ```typescript
419
- // Find and update all occurrences
420
240
  @repository({ model: YourModel, dataSource: YourDataSource })
421
241
  ```
422
242
 
423
- ### Step 4: Fix Constructor Types
424
-
425
- If using explicit `@inject`, ensure first parameter has correct type:
426
-
427
- ```typescript
428
- constructor(
429
- @inject({ key: 'datasources.YourDataSource' })
430
- dataSource: YourDataSource, // Not 'any' or 'object'
431
- ) {}
432
- ```
433
-
434
- ### Step 5: Review Filter Queries
435
-
436
- Check for any queries using:
437
- - Empty `IN` arrays (now return no results instead of all)
438
- - Invalid column names (now throw errors)
439
- - `BETWEEN` with non-array or wrong-length values
440
-
441
- ### Step 6: REGEXP Migration (PostgreSQL Users)
243
+ ### Step 3: REGEXP Migration (PostgreSQL Users)
442
244
 
443
245
  Replace MySQL-style REGEXP with PostgreSQL syntax:
444
- - REGEXP already works (uses `~` operator)
445
- - For case-insensitive, use new `IREGEXP` (uses `~*` operator)
246
+ - `REGEXP` uses `~` (case-sensitive)
247
+ - `IREGEXP` uses `~*` (case-insensitive)
248
+
249
+ ```
@@ -1,16 +1,27 @@
1
+ ---
2
+ title: Changelogs
3
+ description: History of significant changes, refactors, and updates to the Ignis framework
4
+ ---
5
+
1
6
  # Changelogs
2
7
 
3
8
  This section tracks the history of significant changes, refactors, and updates to the Ignis framework.
4
9
 
5
- ## Version History
10
+ ## Planned Features
11
+
12
+ | Feature | Description | Priority |
13
+ |---------|-------------|----------|
14
+ | [Transaction Support](./planned-transaction-support) | Loopback 4-style explicit transaction objects with isolation levels | Future |
15
+
16
+ ## Recent Changes
6
17
 
7
- | Version | Date | Description |
8
- |---------|------|-------------|
9
- | [2025-12-18 Performance](./2025-12-18-performance-optimizations.md) | 2025-12-18 | Performance Optimizations (Core API, WeakMap Cache) |
10
- | [2025-12-18](./2025-12-18-repository-validation-security.md) | 2025-12-18 | Repository Validation & Security Improvements |
11
- | [2025-12-17](./2025-12-17-refactor.md) | 2025-12-17 | Inversion of Control Refactor |
12
- | [v0.0.1-8](./v0.0.1-8-model-repo-datasource-refactor.md) | 2025-12-16 | Model-Repository-DataSource Architecture Refactor |
13
- | [v0.0.1-7](./v0.0.1-7-initial-architecture.md) | 2025-12-16 | Initial Architecture (Pre-Refactor) |
18
+ | Date | Title | Type |
19
+ |------|-------|------|
20
+ | 2025-12-18 | [Performance Optimizations](./2025-12-18-performance-optimizations) | Enhancement |
21
+ | 2025-12-18 | [Repository Validation & Security](./2025-12-18-repository-validation-security) | Breaking Change, Security |
22
+ | 2025-12-17 | [Inversion of Control Refactor](./2025-12-17-refactor) | Refactor |
23
+ | 2025-12-16 | [Model-Repository-DataSource Refactor](./2025-12-16-model-repo-datasource-refactor) | Breaking Change |
24
+ | 2025-12-16 | [Initial Architecture](./2025-12-16-initial-architecture) | Documentation |
14
25
 
15
26
  ## How to Read Changelogs
16
27