@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,214 @@
1
+ ---
2
+ title: JSON Path Filtering & Array Operators
3
+ description: Added JSON/JSONB path filtering support and PostgreSQL array column operators
4
+ ---
5
+
6
+ # Changelog - 2025-12-31
7
+
8
+ ## JSON Path Filtering & PostgreSQL Array Operators
9
+
10
+ This release adds powerful query capabilities for JSON/JSONB columns and PostgreSQL array columns, enabling complex filtering patterns without raw SQL.
11
+
12
+ ## Overview
13
+
14
+ - **JSON Path Filtering**: Filter by nested JSON fields using dot notation (e.g., `'jValue.metadata.score': { gt: 80 }`)
15
+ - **Array Column Operators**: PostgreSQL-specific operators `contains`, `containedBy`, `overlaps` for array columns
16
+ - **Safe Numeric Casting**: Automatic type-safe numeric comparison for mixed-type JSON fields
17
+ - **NOT BETWEEN Operator**: Added `notBetween` operator for range exclusion queries
18
+ - **Code Refactoring**: Unified JSON path validation and extraction logic
19
+
20
+ ## New Features
21
+
22
+ ### JSON Path Filtering
23
+
24
+ **Files:**
25
+ - `packages/core/src/base/repositories/operators/filter.ts`
26
+ - `packages/core/src/base/repositories/operators/query.ts`
27
+
28
+ **Problem:** Filtering by nested JSON/JSONB fields required raw SQL or manual extraction, making queries complex and error-prone.
29
+
30
+ **Solution:** Detect JSON paths in filter keys (containing `.` or `[`) and automatically generate PostgreSQL `#>>` extraction expressions with proper type handling.
31
+
32
+ ```typescript
33
+ // Before: Not possible with standard filters
34
+
35
+ // After: Native JSON path support
36
+ await repo.find({
37
+ filter: {
38
+ where: {
39
+ // Simple nested field
40
+ 'jValue.priority': 3,
41
+
42
+ // Deep nesting
43
+ 'jValue.metadata.level': 'high',
44
+
45
+ // Array index access
46
+ 'jValue.tags[0]': 'important',
47
+
48
+ // With operators
49
+ 'jValue.metadata.score': { gte: 70, lte: 90 },
50
+
51
+ // Pattern matching
52
+ 'jValue.metadata.level': { ilike: '%igh%' }
53
+ }
54
+ }
55
+ });
56
+ ```
57
+
58
+ **Generated SQL:**
59
+ ```sql
60
+ WHERE "jValue" #>> '{priority}' = '3'
61
+ AND "jValue" #>> '{metadata,level}' = 'high'
62
+ AND "jValue" #>> '{tags,0}' = 'important'
63
+ AND CASE WHEN ("jValue" #>> '{metadata,score}') ~ '^-?[0-9]+'
64
+ THEN ("jValue" #>> '{metadata,score}')::numeric ELSE NULL END >= 70
65
+ AND CASE WHEN ("jValue" #>> '{metadata,score}') ~ '^-?[0-9]+'
66
+ THEN ("jValue" #>> '{metadata,score}')::numeric ELSE NULL END <= 90
67
+ AND "jValue" #>> '{metadata,level}' ILIKE '%igh%'
68
+ ```
69
+
70
+ **Benefits:**
71
+ - Intuitive dot notation for nested fields
72
+ - Automatic numeric casting for comparison operators
73
+ - Safe handling of mixed-type JSON (non-numeric values become NULL, not errors)
74
+ - SQL injection prevention via path component validation
75
+
76
+ ### Safe Numeric Casting for JSON
77
+
78
+ **Problem:** JSON fields can contain mixed types (`{ score: 85 }` vs `{ score: "high" }`). Casting to numeric would crash on non-numeric values.
79
+
80
+ **Solution:** Safe casting pattern that validates numeric format before casting:
81
+
82
+ ```sql
83
+ CASE WHEN ("jValue" #>> '{score}') ~ '^-?[0-9]+(\.[0-9]+)?$'
84
+ THEN ("jValue" #>> '{score}')::numeric
85
+ ELSE NULL
86
+ END
87
+ ```
88
+
89
+ This ensures:
90
+ - Numeric values: Compared correctly as numbers
91
+ - String values: Treated as NULL (excluded from numeric comparisons)
92
+ - No database errors on mixed-type JSON data
93
+
94
+ ### PostgreSQL Array Column Operators
95
+
96
+ **File:** `packages/core/src/base/repositories/operators/query.ts`
97
+
98
+ **Problem:** PostgreSQL array columns (`varchar[]`, `integer[]`, etc.) require special operators (`@>`, `<@`, `&&`) that weren't available in the filter builder.
99
+
100
+ **Solution:** Added three new operators with automatic type handling:
101
+
102
+ | Operator | PostgreSQL | Description |
103
+ |----------|------------|-------------|
104
+ | `contains` | `@>` | Array contains ALL specified elements |
105
+ | `containedBy` | `<@` | Array is subset of specified elements |
106
+ | `overlaps` | `&&` | Arrays share ANY common element |
107
+
108
+ ```typescript
109
+ // Schema: tags varchar(100)[]
110
+
111
+ // Find products with BOTH 'electronics' AND 'featured'
112
+ await repo.find({
113
+ filter: {
114
+ where: { tags: { contains: ['electronics', 'featured'] } }
115
+ }
116
+ });
117
+ // SQL: "tags"::text[] @> ARRAY['electronics', 'featured']::text[]
118
+
119
+ // Find products where ALL tags are in allowed list
120
+ await repo.find({
121
+ filter: {
122
+ where: { tags: { containedBy: ['sale', 'featured', 'new'] } }
123
+ }
124
+ });
125
+ // SQL: "tags"::text[] <@ ARRAY['sale', 'featured', 'new']::text[]
126
+
127
+ // Find products with 'sale' OR 'premium' tag
128
+ await repo.find({
129
+ filter: {
130
+ where: { tags: { overlaps: ['sale', 'premium'] } }
131
+ }
132
+ });
133
+ // SQL: "tags"::text[] && ARRAY['sale', 'premium']::text[]
134
+ ```
135
+
136
+ **Type Compatibility:**
137
+ - String arrays (`varchar[]`, `text[]`, `char[]`): Both column and value cast to `text[]`
138
+ - Numeric arrays (`integer[]`, `numeric[]`): No casting needed
139
+ - Boolean arrays (`boolean[]`): No casting needed
140
+
141
+ **Empty Array Behavior:**
142
+
143
+ | Operator | Empty `[]` | Result |
144
+ |----------|------------|--------|
145
+ | `contains` | `{ contains: [] }` | `true` - everything contains empty set |
146
+ | `containedBy` | `{ containedBy: [] }` | Only rows with empty arrays |
147
+ | `overlaps` | `{ overlaps: [] }` | `false` - nothing overlaps with empty |
148
+
149
+ ### NOT BETWEEN Operator
150
+
151
+ **File:** `packages/core/src/base/repositories/operators/query.ts`
152
+
153
+ **Problem:** No way to filter for values outside a range.
154
+
155
+ **Solution:** Added `notBetween` operator:
156
+
157
+ ```typescript
158
+ await repo.find({
159
+ filter: {
160
+ where: {
161
+ score: { notBetween: [40, 60] } // Scores < 40 OR > 60
162
+ }
163
+ }
164
+ });
165
+ // SQL: WHERE NOT (score BETWEEN 40 AND 60)
166
+ ```
167
+
168
+ ## Security Enhancements
169
+
170
+ ### JSON Path Validation
171
+
172
+ JSON path components are validated against a strict pattern to prevent SQL injection:
173
+
174
+ ```typescript
175
+ // Valid patterns (allowed)
176
+ /^[a-zA-Z_][a-zA-Z0-9_-]*$|^\d+$/
177
+
178
+ // Examples:
179
+ 'jValue.user_id' // ✅ Valid identifier
180
+ 'jValue.meta-data' // ✅ Kebab-case allowed
181
+ 'jValue.items[0]' // ✅ Array index
182
+ 'jValue.nested[2].field' // ✅ Mixed access
183
+
184
+ // Invalid (throws error)
185
+ 'jValue.field;DROP TABLE' // ❌ SQL injection attempt
186
+ 'jValue.123invalid' // ❌ Starts with number
187
+ ```
188
+
189
+ ## Files Changed
190
+
191
+ ### Core Package (`packages/core`)
192
+
193
+ | File | Changes |
194
+ |------|---------|
195
+ | `src/base/repositories/operators/filter.ts` | Added JSON path filtering (`buildJsonWhereCondition`, `validateJsonColumn`, `isJsonPath`, `isOperatorObject`), refactored `buildJsonOrderBy` to reuse validation |
196
+ | `src/base/repositories/operators/query.ts` | Added array operators (`contains`, `containedBy`, `overlaps`), `notBetween`, `hasNumericComparison` helper, `buildPgArrayComparison` helper |
197
+
198
+ ### Examples (`examples/vert`)
199
+
200
+ | File | Changes |
201
+ |------|---------|
202
+ | `src/models/entities/product.model.ts` | Added array column (`tags varchar(100)[]`) for testing |
203
+ | `src/services/tests/` | New test services for JSON and array operators |
204
+
205
+ ## No Breaking Changes
206
+
207
+ All changes are additive enhancements. Existing filter queries work unchanged.
208
+
209
+ ## Documentation
210
+
211
+ Full documentation with examples available at:
212
+ - [Repositories - JSON Path Filtering](/references/base/repositories#json-path-filtering)
213
+ - [Repositories - Array Column Operators](/references/base/repositories#array-column-operators-postgresql)
214
+ - [Repositories - Query Operators](/references/base/repositories#query-operators)
@@ -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
+ ```