@venizia/ignis-docs 0.0.3 → 0.0.4-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 (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 +31 -26
  55. package/wiki/references/base/components.md +24 -7
  56. package/wiki/references/base/controllers.md +50 -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 +604 -0
  76. package/wiki/references/base/models.md +215 -23
  77. package/wiki/references/base/providers.md +731 -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,137 @@
1
+ ---
2
+ title: String ID with Custom Generator
3
+ description: Text column with customizable ID generator for maximum database compatibility
4
+ ---
5
+
6
+ # Changelog - 2025-12-31
7
+
8
+ ## String ID with Custom Generator
9
+
10
+ This release changes the string ID implementation from PostgreSQL `uuid` type to `text` column with a customizable ID generator for maximum database compatibility.
11
+
12
+ ## Overview
13
+
14
+ - **Text Column**: String IDs now use `text` column type instead of PostgreSQL `uuid`
15
+ - **Custom Generator**: Optional `generator` function to use any ID format (UUID, nanoid, cuid, etc.)
16
+ - **Default UUID**: Uses `crypto.randomUUID()` by default for backwards compatibility
17
+ - **Consistent Naming**: Renamed `visibleColumns` to `visibleProperties` for consistency with `hiddenProperties`
18
+ - **Removed 'uuid' Option**: Principal enricher now only supports `'number' | 'string'`
19
+
20
+
21
+ ## String ID Changes
22
+
23
+ ### Before
24
+
25
+ ```typescript
26
+ // Used PostgreSQL uuid type
27
+ uuid('id').defaultRandom().primaryKey()
28
+ // Column type: uuid
29
+ ```
30
+
31
+ ### After
32
+
33
+ ```typescript
34
+ // Uses text column with $defaultFn
35
+ text('id').primaryKey().$defaultFn(() => crypto.randomUUID())
36
+ // Column type: text
37
+ ```
38
+
39
+ ### Custom Generator Option
40
+
41
+ ```typescript
42
+ import { nanoid } from 'nanoid';
43
+
44
+ generateIdColumnDefs({
45
+ id: {
46
+ dataType: 'string',
47
+ generator: () => nanoid(), // Custom generator
48
+ },
49
+ })
50
+ ```
51
+
52
+ ### Type Definition
53
+
54
+ ```typescript
55
+ type TIdEnricherOptions = {
56
+ id?: { columnName?: string } & (
57
+ | { dataType: 'string'; generator?: () => string } // NEW: optional generator
58
+ | { dataType: 'number'; sequenceOptions?: PgSequenceOptions }
59
+ | { dataType: 'big-number'; numberMode: 'number' | 'bigint'; sequenceOptions?: PgSequenceOptions }
60
+ );
61
+ };
62
+ ```
63
+
64
+
65
+ ## Naming Consistency
66
+
67
+ Renamed internal properties for consistency:
68
+
69
+ | Before | After |
70
+ |--------|-------|
71
+ | `_visibleColumns` | `_visibleProperties` |
72
+ | `getVisibleColumns()` | `getVisibleProperties()` |
73
+ | `visibleColumns` getter/setter | `visibleProps` getter/setter |
74
+
75
+
76
+ ## Principal Enricher Simplification
77
+
78
+ Removed 'uuid' option since it's now identical to 'string':
79
+
80
+ ```typescript
81
+ // Before
82
+ type IdType = 'number' | 'string' | 'uuid';
83
+
84
+ // After
85
+ type IdType = 'number' | 'string';
86
+ ```
87
+
88
+
89
+ ## Files Changed
90
+
91
+ ### Core Package (`packages/core`)
92
+
93
+ | File | Changes |
94
+ |------|---------|
95
+ | `src/base/models/enrichers/id.enricher.ts` | Text column with custom generator, type aliases |
96
+ | `src/base/models/enrichers/principal.enricher.ts` | Removed 'uuid' option, uses text for string IDs |
97
+ | `src/base/repositories/core/base.ts` | Renamed visibleColumns to visibleProperties |
98
+ | `src/base/repositories/core/readable.ts` | Updated to use getVisibleProperties() |
99
+ | `src/base/repositories/core/persistable.ts` | Updated to use getVisibleProperties() |
100
+ | `src/components/static-asset/models/base.model.ts` | uuid() to text() |
101
+ | `src/components/auth/models/entities/*.ts` | uuid() to text() for all auth models |
102
+
103
+
104
+ ## Migration Guide
105
+
106
+ ### No Breaking Changes for Most Users
107
+
108
+ If you're using `generateIdColumnDefs({ id: { dataType: 'string' } })`, your code continues to work. The only difference is the underlying column type changes from `uuid` to `text`.
109
+
110
+ ### Database Migration
111
+
112
+ If you have existing `uuid` columns and want to migrate to `text`:
113
+
114
+ ```sql
115
+ -- Option 1: Alter column type (data preserved)
116
+ ALTER TABLE "your_table" ALTER COLUMN "id" TYPE TEXT;
117
+
118
+ -- Option 2: Keep uuid type (still works with text-based code)
119
+ -- No migration needed - uuid values are compatible with text operations
120
+ ```
121
+
122
+ ### Custom ID Generator
123
+
124
+ To use a custom generator:
125
+
126
+ ```typescript
127
+ import { nanoid } from 'nanoid';
128
+ // or
129
+ import { createId } from '@paralleldrive/cuid2';
130
+
131
+ generateIdColumnDefs({
132
+ id: {
133
+ dataType: 'string',
134
+ generator: () => nanoid(), // or createId
135
+ },
136
+ })
137
+ ```
@@ -0,0 +1,418 @@
1
+ ---
2
+ title: Default Filter & Repository Mixins
3
+ description: Added default filter support for models and refactored repository architecture with composable mixins
4
+ ---
5
+
6
+ # Changelog - 2026-01-02
7
+
8
+ ## Default Filter & Repository Mixins
9
+
10
+ This release introduces **Default Filter** - a powerful feature that automatically applies predefined filter conditions to all repository queries. Additionally, the repository architecture has been refactored to use composable mixins for better code organization and reusability.
11
+
12
+ ## Overview
13
+
14
+ - **Default Filter**: Configure automatic filter conditions at the model level (e.g., soft delete, tenant isolation)
15
+ - **Skip Default Filter**: Bypass default filters with `shouldSkipDefaultFilter: true` for admin/maintenance operations
16
+ - **Repository Mixins**: Extracted `DefaultFilterMixin` and `FieldsVisibilityMixin` for composable repository features
17
+ - **FilterBuilder Enhancement**: Renamed `DrizzleFilterBuilder` to `FilterBuilder`, added `mergeFilter` method
18
+ - **IExtraOptions Interface**: New interface replacing `TTransactionOption` with `shouldSkipDefaultFilter` support
19
+
20
+ ## New Features
21
+
22
+ ### Default Filter
23
+
24
+ **Files:**
25
+ - `packages/core/src/base/repositories/mixins/default-filter.ts`
26
+ - `packages/core/src/base/repositories/operators/filter.ts`
27
+
28
+ **Problem:** Applications often need to apply the same filter conditions to every query - soft delete (`isDeleted: false`), tenant isolation (`tenantId: 'xxx'`), or active record patterns. Without a centralized solution, developers must manually add these conditions to every repository call.
29
+
30
+ **Solution:** Configure a `defaultFilter` in your model settings. The repository automatically merges this filter with user-provided filters for all read, update, and delete operations.
31
+
32
+ ```typescript
33
+ // Model configuration with default filter
34
+ @model({
35
+ type: 'entity',
36
+ settings: {
37
+ // Automatically applied to all queries
38
+ defaultFilter: {
39
+ where: { isDeleted: false },
40
+ limit: 100, // Prevent unbounded queries
41
+ },
42
+ },
43
+ })
44
+ export class User extends BaseEntity<typeof User.schema> {
45
+ static override schema = userTable;
46
+ }
47
+ ```
48
+
49
+ **Automatic Application:**
50
+
51
+ ```typescript
52
+ // User query - default filter automatically merged
53
+ await userRepo.find({
54
+ filter: { where: { status: 'active' } }
55
+ });
56
+ // Actual query: WHERE isDeleted = false AND status = 'active' LIMIT 100
57
+
58
+ // Default filter also applies to count, update, delete
59
+ await userRepo.count({ where: { role: 'admin' } });
60
+ // Actual query: WHERE isDeleted = false AND role = 'admin'
61
+ ```
62
+
63
+ **Filter Merge Strategy:**
64
+
65
+ | Property | Strategy |
66
+ |----------|----------|
67
+ | `where` | Deep merge (user overrides matching keys) |
68
+ | `limit` | User replaces default (if provided) |
69
+ | `offset`/`skip` | User replaces default (if provided) |
70
+ | `order` | User replaces default (if provided) |
71
+ | `fields` | User replaces default (if provided) |
72
+ | `include` | User replaces default (if provided) |
73
+
74
+ ```typescript
75
+ // Default: { where: { isDeleted: false, status: 'pending' }, limit: 100 }
76
+ // User: { where: { status: 'active' }, limit: 10 }
77
+ // Result: { where: { isDeleted: false, status: 'active' }, limit: 10 }
78
+ ```
79
+
80
+ ### Skip Default Filter
81
+
82
+ **Problem:** Admin users or maintenance scripts sometimes need to query all records, including soft-deleted ones or records from all tenants.
83
+
84
+ **Solution:** Pass `shouldSkipDefaultFilter: true` in the options to bypass the default filter:
85
+
86
+ ```typescript
87
+ // Normal query - default filter applies
88
+ await repo.find({ filter: { where: { role: 'admin' } } });
89
+ // WHERE isDeleted = false AND role = 'admin'
90
+
91
+ // Admin query - bypass default filter
92
+ await repo.find({
93
+ filter: { where: { role: 'admin' } },
94
+ options: { shouldSkipDefaultFilter: true }
95
+ });
96
+ // WHERE role = 'admin' (includes deleted records)
97
+
98
+ // Works with all operations
99
+ await repo.count({ where: {}, options: { shouldSkipDefaultFilter: true } });
100
+ await repo.updateAll({
101
+ where: { status: 'archived' },
102
+ data: { isDeleted: true },
103
+ options: { shouldSkipDefaultFilter: true }
104
+ });
105
+ await repo.deleteAll({
106
+ where: { createdAt: { lt: '2020-01-01' } },
107
+ options: { shouldSkipDefaultFilter: true, force: true }
108
+ });
109
+ ```
110
+
111
+ **Benefits:**
112
+ - Automatic soft-delete filtering without manual `where` additions
113
+ - Multi-tenant isolation at the data layer
114
+ - Consistent query behavior across the application
115
+ - Easy bypass for admin/maintenance operations
116
+
117
+ ### Repository Mixins
118
+
119
+ **Files:**
120
+ - `packages/core/src/base/repositories/mixins/default-filter.ts`
121
+ - `packages/core/src/base/repositories/mixins/fields-visibility.ts`
122
+ - `packages/core/src/base/repositories/mixins/index.ts`
123
+
124
+ **Problem:** Repository base classes were becoming monolithic with multiple concerns (hidden properties, default filters, transaction handling) mixed together.
125
+
126
+ **Solution:** Extract cross-cutting concerns into composable mixins:
127
+
128
+ ```typescript
129
+ // DefaultFilterMixin - Provides default filter functionality
130
+ export const DefaultFilterMixin = <T extends TMixinTarget<object>>(baseClass: T) => {
131
+ abstract class Mixed extends baseClass {
132
+ getDefaultFilter(): TFilter | undefined;
133
+ hasDefaultFilter(): boolean;
134
+ applyDefaultFilter(opts: { userFilter?: TFilter; shouldSkipDefaultFilter?: boolean }): TFilter;
135
+ }
136
+ return Mixed;
137
+ };
138
+
139
+ // FieldsVisibilityMixin - Provides hidden properties functionality
140
+ export const FieldsVisibilityMixin = <T extends TMixinTarget<object>>(baseClass: T) => {
141
+ abstract class Mixed extends baseClass {
142
+ get hiddenProperties(): Set<string>;
143
+ get visibleProperties(): Record<string, any> | undefined;
144
+ getHiddenProperties(): Set<string>;
145
+ hasHiddenProperties(): boolean;
146
+ getVisibleProperties(): Record<string, any> | undefined;
147
+ }
148
+ return Mixed;
149
+ };
150
+ ```
151
+
152
+ **Usage in AbstractRepository:**
153
+
154
+ ```typescript
155
+ export abstract class AbstractRepository<...>
156
+ extends DefaultFilterMixin(FieldsVisibilityMixin(BaseHelper))
157
+ implements IPersistableRepository<...>
158
+ {
159
+ // Mixins provide getDefaultFilter, applyDefaultFilter,
160
+ // getHiddenProperties, getVisibleProperties, etc.
161
+ }
162
+ ```
163
+
164
+ **Benefits:**
165
+ - Separation of concerns
166
+ - Reusable logic across different repository types
167
+ - Easier testing of individual features
168
+ - Clear dependency chain
169
+
170
+ ### IExtraOptions Interface
171
+
172
+ **File:** `packages/core/src/base/repositories/common/types.ts`
173
+
174
+ **Problem:** The `TTransactionOption` type only supported `transaction` option. With the new default filter feature, we need additional options.
175
+
176
+ **Solution:** Introduced `IExtraOptions` interface that extends beyond transactions:
177
+
178
+ ```typescript
179
+ // New interface
180
+ export interface IExtraOptions extends IWithTransaction {
181
+ /**
182
+ * If true, bypass the default filter configured in model settings.
183
+ * Use this when you need to query all records regardless of default filter constraints.
184
+ */
185
+ shouldSkipDefaultFilter?: boolean;
186
+ }
187
+
188
+ // Base transaction interface
189
+ export interface IWithTransaction {
190
+ transaction?: ITransaction;
191
+ }
192
+
193
+ // Deprecated alias for backward compatibility
194
+ /** @deprecated Use IExtraOptions instead */
195
+ export type TTransactionOption = IExtraOptions;
196
+ ```
197
+
198
+ ### FilterBuilder Enhancements
199
+
200
+ **File:** `packages/core/src/base/repositories/operators/filter.ts`
201
+
202
+ **Changes:**
203
+ - Renamed `DrizzleFilterBuilder` to `FilterBuilder`
204
+ - Added `mergeFilter` method for combining default and user filters
205
+ - Added `resolveHiddenProperties` and `resolveRelations` methods
206
+ - Simplified `build` method signature (relations resolved internally)
207
+
208
+ ```typescript
209
+ // New mergeFilter method
210
+ const filterBuilder = new FilterBuilder();
211
+
212
+ const result = filterBuilder.mergeFilter({
213
+ defaultFilter: { where: { isDeleted: false }, limit: 100 },
214
+ userFilter: { where: { status: 'active' }, limit: 10 }
215
+ });
216
+ // Result: { where: { isDeleted: false, status: 'active' }, limit: 10 }
217
+ ```
218
+
219
+ **Internal Changes:**
220
+ - Relations now resolved internally via `resolveRelations` method
221
+ - Hidden properties resolved via `resolveHiddenProperties` method
222
+ - Simplified API for `build` method (no need to pass resolvers)
223
+
224
+ ## Files Changed
225
+
226
+ ### Core Package (`packages/core`)
227
+
228
+ | File | Changes |
229
+ |------|---------|
230
+ | `src/base/repositories/mixins/default-filter.ts` | **NEW** - DefaultFilterMixin implementation |
231
+ | `src/base/repositories/mixins/fields-visibility.ts` | **NEW** - FieldsVisibilityMixin implementation |
232
+ | `src/base/repositories/mixins/index.ts` | **NEW** - Barrel export for mixins |
233
+ | `src/base/repositories/common/types.ts` | Added `IExtraOptions`, `IWithTransaction` interfaces |
234
+ | `src/base/repositories/core/base.ts` | Refactored to use mixins, updated method signatures |
235
+ | `src/base/repositories/core/readable.ts` | Added `applyDefaultFilter` calls to read operations |
236
+ | `src/base/repositories/core/persistable.ts` | Added `applyDefaultFilter` calls to update/delete |
237
+ | `src/base/repositories/core/default-crud.ts` | Updated type parameters |
238
+ | `src/base/repositories/operators/filter.ts` | Renamed to `FilterBuilder`, added `mergeFilter` |
239
+ | `src/helpers/inversion/common/types.ts` | Added `defaultFilter` to model settings type |
240
+
241
+ ### Tests (`packages/core/src/__tests__`)
242
+
243
+ | File | Changes |
244
+ |------|---------|
245
+ | `default-filter/default-filter.test.ts` | **NEW** - Comprehensive test suite (150+ test cases) |
246
+
247
+ ### Examples (`examples/vert`)
248
+
249
+ | File | Changes |
250
+ |------|---------|
251
+ | `src/services/tests/default-filter-test.service.ts` | **NEW** - Integration test service |
252
+ | `src/services/tests/TEST_CASES.md` | **NEW** - Test case documentation |
253
+
254
+ ## Breaking Changes
255
+
256
+ ### DrizzleFilterBuilder Renamed to FilterBuilder
257
+
258
+ **Before:**
259
+ ```typescript
260
+ import { DrizzleFilterBuilder } from '@venizia/ignis';
261
+ const builder = new DrizzleFilterBuilder();
262
+ ```
263
+
264
+ **After:**
265
+ ```typescript
266
+ import { FilterBuilder } from '@venizia/ignis';
267
+ const builder = new FilterBuilder();
268
+ ```
269
+
270
+ ### FilterBuilder.build() Signature Changed
271
+
272
+ **Before:**
273
+ ```typescript
274
+ filterBuilder.build({
275
+ tableName: 'users',
276
+ schema: userSchema,
277
+ relations: { posts: { ... } },
278
+ filter: myFilter,
279
+ relationResolver: (schema) => { ... },
280
+ hiddenPropertiesResolver: (relationName) => { ... },
281
+ });
282
+ ```
283
+
284
+ **After:**
285
+ ```typescript
286
+ // Relations and hidden properties resolved internally
287
+ filterBuilder.build({
288
+ tableName: 'users',
289
+ schema: userSchema,
290
+ filter: myFilter,
291
+ });
292
+ ```
293
+
294
+ ### TTransactionOption Deprecated
295
+
296
+ **Before:**
297
+ ```typescript
298
+ import { TTransactionOption } from '@venizia/ignis';
299
+
300
+ class MyRepo extends AbstractRepository<Schema, Data, Persist, TTransactionOption> {}
301
+ ```
302
+
303
+ **After:**
304
+ ```typescript
305
+ import { IExtraOptions } from '@venizia/ignis';
306
+
307
+ class MyRepo extends AbstractRepository<Schema, Data, Persist, IExtraOptions> {}
308
+ ```
309
+
310
+ ## Migration Guide
311
+
312
+ ### Step 1: Update FilterBuilder Usage
313
+
314
+ If you're using `DrizzleFilterBuilder` directly (rare), rename to `FilterBuilder`:
315
+
316
+ ```typescript
317
+ // Before
318
+ import { DrizzleFilterBuilder } from '@venizia/ignis';
319
+
320
+ // After
321
+ import { FilterBuilder } from '@venizia/ignis';
322
+ ```
323
+
324
+ ### Step 2: Update Custom Repository Generic Types
325
+
326
+ If you have custom repositories with explicit generic types:
327
+
328
+ ```typescript
329
+ // Before
330
+ class MyRepo extends PersistableRepository<Schema, Data, Persist, TTransactionOption> {}
331
+
332
+ // After
333
+ class MyRepo extends PersistableRepository<Schema, Data, Persist, IExtraOptions> {}
334
+ ```
335
+
336
+ ### Step 3: Add Default Filters to Models (Optional)
337
+
338
+ To enable automatic filtering, add `defaultFilter` to your model settings:
339
+
340
+ ```typescript
341
+ @model({
342
+ type: 'entity',
343
+ settings: {
344
+ defaultFilter: {
345
+ where: { isDeleted: false },
346
+ },
347
+ },
348
+ })
349
+ export class User extends BaseEntity<typeof User.schema> {
350
+ static override schema = userTable;
351
+ }
352
+ ```
353
+
354
+ ## Common Use Cases
355
+
356
+ ### Soft Delete Pattern
357
+
358
+ ```typescript
359
+ @model({
360
+ type: 'entity',
361
+ settings: {
362
+ defaultFilter: {
363
+ where: { deletedAt: null }, // or { isDeleted: false }
364
+ },
365
+ },
366
+ })
367
+ export class Post extends BaseEntity<typeof Post.schema> {}
368
+
369
+ // All queries automatically exclude deleted posts
370
+ await postRepo.find({ filter: { where: { published: true } } });
371
+ // WHERE deletedAt IS NULL AND published = true
372
+
373
+ // Restore deleted post (bypass default filter)
374
+ await postRepo.updateById({
375
+ id: postId,
376
+ data: { deletedAt: null },
377
+ options: { shouldSkipDefaultFilter: true }
378
+ });
379
+ ```
380
+
381
+ ### Multi-Tenant Isolation
382
+
383
+ ```typescript
384
+ // Note: tenantId would be injected per-request in real applications
385
+ @model({
386
+ type: 'entity',
387
+ settings: {
388
+ defaultFilter: {
389
+ where: { tenantId: 'current-tenant-id' },
390
+ },
391
+ },
392
+ })
393
+ export class Document extends BaseEntity<typeof Document.schema> {}
394
+ ```
395
+
396
+ ### Active Records Only
397
+
398
+ ```typescript
399
+ @model({
400
+ type: 'entity',
401
+ settings: {
402
+ defaultFilter: {
403
+ where: {
404
+ isActive: true,
405
+ expiresAt: { gt: new Date().toISOString() },
406
+ },
407
+ limit: 50, // Prevent unbounded queries
408
+ },
409
+ },
410
+ })
411
+ export class Subscription extends BaseEntity<typeof Subscription.schema> {}
412
+ ```
413
+
414
+ ## Documentation
415
+
416
+ - [Default Filter Guide](/references/base/filter-system/default-filter) - Full documentation
417
+ - [Repository Mixins](/references/base/repositories/mixins) - Mixin architecture
418
+ - [Advanced Repository Features](/references/base/repositories/advanced) - Updated with shouldSkipDefaultFilter
@@ -17,6 +17,12 @@ This section tracks the history of significant changes, refactors, and updates t
17
17
 
18
18
  | Date | Title | Type |
19
19
  |------|-------|------|
20
+ | 2026-01-02 | [Default Filter & Repository Mixins](./2026-01-02-default-filter-and-repository-mixins) | New Feature |
21
+ | 2025-12-31 | [JSON Path Filtering & Array Operators](./2025-12-31-json-path-filtering-array-operators) | New Feature |
22
+ | 2025-12-31 | [String ID with Custom Generator](./2025-12-31-string-id-custom-generator) | Enhancement |
23
+ | 2025-12-30 | [Repository Enhancements](./2025-12-30-repository-enhancements) | Enhancement |
24
+ | 2025-12-29 | [Snowflake UID Helper](./2025-12-29-snowflake-uid-helper) | New Feature |
25
+ | 2025-12-29 | [Dynamic Binding Registration Fix](./2025-12-29-dynamic-binding-registration) | Bug Fix |
20
26
  | 2025-12-26 | [Transaction Support](./2025-12-26-transaction-support) | Enhancement |
21
27
  | 2025-12-26 | [Nested Relations & Generic Types](./2025-12-26-nested-relations-and-generics) | Enhancement |
22
28
  | 2025-12-18 | [Performance Optimizations](./2025-12-18-performance-optimizations) | Enhancement |
@@ -40,7 +40,6 @@ await migrator.automigrate(); // Drops and recreates all tables
40
40
  | `autoupdate()` | Compares DB ↔ Model, applies ALTER statements | **No** |
41
41
  | `automigrate()` | Drops and recreates tables | **Yes** |
42
42
 
43
- ---
44
43
 
45
44
  ## Implementation Steps
46
45
 
@@ -409,7 +408,6 @@ export abstract class BaseDataSource<...> {
409
408
  }
410
409
  ```
411
410
 
412
- ---
413
411
 
414
412
  ## Files to Create
415
413
 
@@ -428,7 +426,6 @@ export abstract class BaseDataSource<...> {
428
426
  | `packages/core/src/base/datasources/base.ts` | Add `getMigrator()`, `autoupdate()`, `automigrate()` |
429
427
  | `packages/core/src/base/datasources/index.ts` | Export new classes |
430
428
 
431
- ---
432
429
 
433
430
  ## Drizzle to PostgreSQL Type Mapping
434
431
 
@@ -449,7 +446,6 @@ export abstract class BaseDataSource<...> {
449
446
  | `real()` | `real` | 32-bit float |
450
447
  | `doublePrecision()` | `double precision` | 64-bit float |
451
448
 
452
- ---
453
449
 
454
450
  ## Change Detection Matrix
455
451
 
@@ -466,7 +462,6 @@ export abstract class BaseDataSource<...> {
466
462
  | New index | Index not in DB | `CREATE INDEX` |
467
463
  | Removed index | Index not in model | `DROP INDEX` |
468
464
 
469
- ---
470
465
 
471
466
  ## Usage Examples
472
467
 
@@ -515,7 +510,6 @@ if (process.env.NODE_ENV === 'development') {
515
510
  }
516
511
  ```
517
512
 
518
- ---
519
513
 
520
514
  ## Safety Considerations
521
515
 
@@ -536,7 +530,6 @@ if (process.env.NODE_ENV === 'development') {
536
530
  | `ALTER TYPE` | May fail if incompatible | Checks compatibility first |
537
531
  | `automigrate()` | Drops all tables | Requires `force: true` |
538
532
 
539
- ---
540
533
 
541
534
  ## Future Enhancements
542
535
 
@@ -546,7 +539,6 @@ if (process.env.NODE_ENV === 'development') {
546
539
  4. **Multi-Schema Support** - Support for PostgreSQL schemas beyond `public`
547
540
  5. **MySQL/SQLite Support** - Extend beyond PostgreSQL
548
541
 
549
- ---
550
542
 
551
543
  ## Comparison with Alternatives
552
544
 
@@ -558,9 +558,22 @@ npx glob "your-pattern/**/*.controller.js"
558
558
  - Skip subdirectories if you have nested structure
559
559
  - Ignore boot errors (they indicate misconfiguration)
560
560
 
561
- ## Related Documentation
561
+ ## See Also
562
562
 
563
- - [Boot Package Reference](/references/src-details/boot.md)
564
- - [Application Concepts](/get-started/core-concepts/application.md)
565
- - [Dependency Injection](/references/base/dependency-injection.md)
566
- - [Building a CRUD API](/get-started/building-a-crud-api.md)
563
+ - **Related Concepts:**
564
+ - [Application Overview](./index) - Main application class
565
+ - [Controllers](/guides/core-concepts/controllers) - Auto-discovered controllers
566
+ - [Services](/guides/core-concepts/services) - Auto-discovered services
567
+ - [Repositories](/guides/core-concepts/persistent/repositories) - Auto-discovered repositories
568
+
569
+ - **References:**
570
+ - [Bootstrapping API](/references/base/bootstrapping) - Complete API reference
571
+ - [Boot Package](/references/src-details/boot) - Boot system internals
572
+ - [Dependency Injection](/references/base/dependency-injection) - DI container
573
+
574
+ - **Tutorials:**
575
+ - [Complete Installation](/guides/tutorials/complete-installation) - Project structure
576
+ - [Building a CRUD API](/guides/tutorials/building-a-crud-api) - Bootstrapping in action
577
+
578
+ - **Best Practices:**
579
+ - [Architectural Patterns](/best-practices/architectural-patterns) - Project organization patterns