@venizia/ignis-docs 0.0.7 → 0.0.8-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.
- package/dist/mcp-server/common/paths.d.ts +4 -2
- package/dist/mcp-server/common/paths.d.ts.map +1 -1
- package/dist/mcp-server/common/paths.js +8 -6
- package/dist/mcp-server/common/paths.js.map +1 -1
- package/dist/mcp-server/helpers/docs.helper.d.ts.map +1 -1
- package/dist/mcp-server/helpers/docs.helper.js +1 -1
- package/dist/mcp-server/helpers/docs.helper.js.map +1 -1
- package/dist/mcp-server/tools/base.tool.d.ts +1 -1
- package/dist/mcp-server/tools/docs/get-document-content.tool.d.ts +1 -1
- package/dist/mcp-server/tools/docs/get-document-content.tool.d.ts.map +1 -1
- package/dist/mcp-server/tools/docs/get-document-content.tool.js +7 -7
- package/dist/mcp-server/tools/docs/get-document-metadata.tool.js +3 -3
- package/dist/mcp-server/tools/docs/get-package-overview.tool.d.ts +1 -1
- package/dist/mcp-server/tools/docs/get-package-overview.tool.js +1 -1
- package/dist/mcp-server/tools/docs/search-documents.tool.d.ts +1 -1
- package/dist/mcp-server/tools/docs/search-documents.tool.js +1 -1
- package/dist/mcp-server/tools/docs/search-documents.tool.js.map +1 -1
- package/dist/mcp-server/tools/github/list-project-files.tool.d.ts +1 -1
- package/dist/mcp-server/tools/github/list-project-files.tool.js +1 -1
- package/dist/mcp-server/tools/github/list-project-files.tool.js.map +1 -1
- package/dist/mcp-server/tools/github/search-code.tool.d.ts +1 -1
- package/dist/mcp-server/tools/github/search-code.tool.js +1 -1
- package/dist/mcp-server/tools/github/search-code.tool.js.map +1 -1
- package/package.json +9 -9
- package/wiki/best-practices/api-usage-examples.md +9 -9
- package/wiki/best-practices/architectural-patterns.md +19 -3
- package/wiki/best-practices/architecture-decisions.md +6 -6
- package/wiki/best-practices/code-style-standards/advanced-patterns.md +1 -1
- package/wiki/best-practices/code-style-standards/control-flow.md +1 -1
- package/wiki/best-practices/code-style-standards/function-patterns.md +2 -2
- package/wiki/best-practices/code-style-standards/index.md +2 -2
- package/wiki/best-practices/code-style-standards/naming-conventions.md +1 -1
- package/wiki/best-practices/code-style-standards/route-definitions.md +4 -4
- package/wiki/best-practices/data-modeling.md +1 -1
- package/wiki/best-practices/deployment-strategies.md +1 -1
- package/wiki/best-practices/error-handling.md +2 -2
- package/wiki/best-practices/performance-optimization.md +3 -3
- package/wiki/best-practices/security-guidelines.md +2 -2
- package/wiki/best-practices/troubleshooting-tips.md +1 -1
- package/wiki/{references → extensions}/components/authentication/api.md +12 -20
- package/wiki/{references → extensions}/components/authentication/errors.md +1 -1
- package/wiki/{references → extensions}/components/authentication/index.md +5 -8
- package/wiki/{references → extensions}/components/authentication/usage.md +20 -36
- package/wiki/{references → extensions}/components/authorization/api.md +62 -13
- package/wiki/{references → extensions}/components/authorization/errors.md +12 -7
- package/wiki/{references → extensions}/components/authorization/index.md +93 -6
- package/wiki/{references → extensions}/components/authorization/usage.md +42 -4
- package/wiki/{references → extensions}/components/health-check.md +5 -4
- package/wiki/{references → extensions}/components/index.md +2 -0
- package/wiki/{references → extensions}/components/mail/index.md +1 -1
- package/wiki/{references → extensions}/components/request-tracker.md +1 -1
- package/wiki/{references → extensions}/components/socket-io/api.md +2 -2
- package/wiki/{references → extensions}/components/socket-io/errors.md +2 -0
- package/wiki/{references → extensions}/components/socket-io/index.md +24 -20
- package/wiki/{references → extensions}/components/socket-io/usage.md +2 -2
- package/wiki/{references → extensions}/components/static-asset/api.md +14 -15
- package/wiki/{references → extensions}/components/static-asset/errors.md +3 -1
- package/wiki/{references → extensions}/components/static-asset/index.md +158 -89
- package/wiki/{references → extensions}/components/static-asset/usage.md +8 -5
- package/wiki/{references → extensions}/components/swagger.md +3 -3
- package/wiki/{references → extensions}/components/template/index.md +4 -4
- package/wiki/{references → extensions}/components/template/setup-page.md +1 -1
- package/wiki/{references → extensions}/components/template/single-page.md +1 -1
- package/wiki/{references → extensions}/components/websocket/api.md +7 -6
- package/wiki/{references → extensions}/components/websocket/errors.md +17 -3
- package/wiki/{references → extensions}/components/websocket/index.md +17 -11
- package/wiki/{references → extensions}/components/websocket/usage.md +2 -2
- package/wiki/{references → extensions}/helpers/crypto/index.md +1 -1
- package/wiki/{references → extensions}/helpers/env/index.md +9 -5
- package/wiki/{references → extensions}/helpers/error/index.md +2 -7
- package/wiki/{references → extensions}/helpers/index.md +18 -6
- package/wiki/{references → extensions}/helpers/kafka/admin.md +13 -1
- package/wiki/{references → extensions}/helpers/kafka/consumer.md +32 -31
- package/wiki/{references → extensions}/helpers/kafka/examples.md +20 -20
- package/wiki/{references → extensions}/helpers/kafka/index.md +61 -54
- package/wiki/{references → extensions}/helpers/kafka/producer.md +21 -20
- package/wiki/{references → extensions}/helpers/kafka/schema-registry.md +25 -25
- package/wiki/{references → extensions}/helpers/logger/index.md +2 -2
- package/wiki/{references → extensions}/helpers/queue/index.md +400 -4
- package/wiki/{references → extensions}/helpers/storage/api.md +170 -10
- package/wiki/{references → extensions}/helpers/storage/index.md +44 -8
- package/wiki/{references → extensions}/helpers/template/index.md +1 -1
- package/wiki/{references → extensions}/helpers/testing/index.md +4 -4
- package/wiki/{references → extensions}/helpers/types/index.md +63 -16
- package/wiki/{references → extensions}/helpers/websocket/index.md +1 -1
- package/wiki/extensions/index.md +48 -0
- package/wiki/guides/core-concepts/application/bootstrapping.md +55 -37
- package/wiki/guides/core-concepts/application/index.md +95 -35
- package/wiki/guides/core-concepts/components-guide.md +23 -19
- package/wiki/guides/core-concepts/components.md +34 -10
- package/wiki/guides/core-concepts/dependency-injection.md +99 -34
- package/wiki/guides/core-concepts/grpc-controllers.md +295 -0
- package/wiki/guides/core-concepts/persistent/datasources.md +37 -19
- package/wiki/guides/core-concepts/persistent/index.md +6 -6
- package/wiki/guides/core-concepts/persistent/models.md +50 -6
- package/wiki/guides/core-concepts/persistent/repositories.md +83 -8
- package/wiki/guides/core-concepts/persistent/transactions.md +39 -8
- package/wiki/guides/core-concepts/{controllers.md → rest-controllers.md} +32 -35
- package/wiki/guides/core-concepts/services.md +19 -6
- package/wiki/guides/get-started/5-minute-quickstart.md +17 -17
- package/wiki/guides/get-started/philosophy.md +1 -1
- package/wiki/guides/index.md +2 -2
- package/wiki/guides/reference/glossary.md +7 -7
- package/wiki/guides/reference/mcp-docs-server.md +1 -1
- package/wiki/guides/tutorials/building-a-crud-api.md +45 -39
- package/wiki/guides/tutorials/complete-installation.md +74 -51
- package/wiki/guides/tutorials/ecommerce-api.md +39 -30
- package/wiki/guides/tutorials/realtime-chat.md +12 -13
- package/wiki/guides/tutorials/testing.md +2 -2
- package/wiki/index.md +4 -3
- package/wiki/references/base/application.md +341 -21
- package/wiki/references/base/bootstrapping.md +43 -13
- package/wiki/references/base/components.md +259 -8
- package/wiki/references/base/controllers.md +556 -253
- package/wiki/references/base/datasources.md +159 -79
- package/wiki/references/base/dependency-injection.md +299 -48
- package/wiki/references/base/filter-system/application-usage.md +18 -2
- package/wiki/references/base/filter-system/array-operators.md +14 -6
- package/wiki/references/base/filter-system/comparison-operators.md +9 -3
- package/wiki/references/base/filter-system/default-filter.md +28 -3
- package/wiki/references/base/filter-system/fields-order-pagination.md +17 -13
- package/wiki/references/base/filter-system/index.md +169 -11
- package/wiki/references/base/filter-system/json-filtering.md +51 -18
- package/wiki/references/base/filter-system/list-operators.md +4 -3
- package/wiki/references/base/filter-system/logical-operators.md +7 -2
- package/wiki/references/base/filter-system/null-operators.md +50 -0
- package/wiki/references/base/filter-system/quick-reference.md +82 -243
- package/wiki/references/base/filter-system/range-operators.md +7 -1
- package/wiki/references/base/filter-system/tips.md +34 -7
- package/wiki/references/base/filter-system/use-cases.md +6 -5
- package/wiki/references/base/grpc-controllers.md +984 -0
- package/wiki/references/base/index.md +32 -24
- package/wiki/references/base/middleware.md +347 -0
- package/wiki/references/base/models.md +390 -46
- package/wiki/references/base/providers.md +14 -14
- package/wiki/references/base/repositories/advanced.md +195 -69
- package/wiki/references/base/repositories/index.md +447 -12
- package/wiki/references/base/repositories/mixins.md +103 -98
- package/wiki/references/base/repositories/relations.md +129 -45
- package/wiki/references/base/repositories/soft-deletable.md +104 -23
- package/wiki/references/base/services.md +94 -14
- package/wiki/references/index.md +12 -10
- package/wiki/references/quick-reference.md +98 -65
- package/wiki/references/utilities/crypto.md +21 -4
- package/wiki/references/utilities/date.md +25 -7
- package/wiki/references/utilities/index.md +26 -24
- package/wiki/references/utilities/jsx.md +54 -54
- package/wiki/references/utilities/module.md +8 -6
- package/wiki/references/utilities/parse.md +16 -9
- package/wiki/references/utilities/performance.md +22 -7
- package/wiki/references/utilities/promise.md +19 -16
- package/wiki/references/utilities/request.md +48 -26
- package/wiki/references/utilities/schema.md +69 -6
- package/wiki/references/utilities/statuses.md +131 -140
- /package/wiki/{references → extensions}/components/mail/api.md +0 -0
- /package/wiki/{references → extensions}/components/mail/errors.md +0 -0
- /package/wiki/{references → extensions}/components/mail/usage.md +0 -0
- /package/wiki/{references → extensions}/components/template/api-page.md +0 -0
- /package/wiki/{references → extensions}/components/template/errors-page.md +0 -0
- /package/wiki/{references → extensions}/components/template/usage-page.md +0 -0
- /package/wiki/{references → extensions}/helpers/cron/index.md +0 -0
- /package/wiki/{references → extensions}/helpers/inversion/index.md +0 -0
- /package/wiki/{references → extensions}/helpers/network/api.md +0 -0
- /package/wiki/{references → extensions}/helpers/network/index.md +0 -0
- /package/wiki/{references → extensions}/helpers/redis/index.md +0 -0
- /package/wiki/{references → extensions}/helpers/socket-io/api.md +0 -0
- /package/wiki/{references → extensions}/helpers/socket-io/index.md +0 -0
- /package/wiki/{references → extensions}/helpers/template/single-page.md +0 -0
- /package/wiki/{references → extensions}/helpers/uid/index.md +0 -0
- /package/wiki/{references → extensions}/helpers/websocket/api.md +0 -0
- /package/wiki/{references → extensions}/helpers/worker-thread/index.md +0 -0
- /package/wiki/{references → extensions}/src-details/mcp-server.md +0 -0
|
@@ -6,6 +6,13 @@ The Schema utility provides a set of helper functions and predefined schemas for
|
|
|
6
6
|
|
|
7
7
|
The `jsonContent` function creates a standard OpenAPI content object for `application/json` payloads.
|
|
8
8
|
|
|
9
|
+
### `jsonContent(opts)`
|
|
10
|
+
|
|
11
|
+
- `opts` (object):
|
|
12
|
+
- `schema` (ZodType): The Zod schema describing the JSON payload.
|
|
13
|
+
- `description` (string): A description of the content.
|
|
14
|
+
- `required` (boolean, optional): Whether the content is required.
|
|
15
|
+
|
|
9
16
|
```typescript
|
|
10
17
|
import { jsonContent, z } from '@venizia/ignis';
|
|
11
18
|
|
|
@@ -16,13 +23,21 @@ const UserSchema = z.object({
|
|
|
16
23
|
|
|
17
24
|
const userResponse = {
|
|
18
25
|
description: 'A single user object',
|
|
19
|
-
...jsonContent({ schema: UserSchema }),
|
|
26
|
+
...jsonContent({ schema: UserSchema, description: 'User data' }),
|
|
20
27
|
};
|
|
21
28
|
```
|
|
22
29
|
|
|
23
30
|
## `jsonResponse`
|
|
24
31
|
|
|
25
|
-
The `jsonResponse` function generates a standard OpenAPI response object that includes a success (200 OK) response and a default error response for 4xx
|
|
32
|
+
The `jsonResponse` function generates a standard OpenAPI response object that includes a success (200 OK) response and a default error response for `4xx | 5xx` status codes. The error response uses the `ErrorSchema`.
|
|
33
|
+
|
|
34
|
+
### `jsonResponse(opts)`
|
|
35
|
+
|
|
36
|
+
- `opts` (object):
|
|
37
|
+
- `schema` (ZodType): The Zod schema for the success response body.
|
|
38
|
+
- `description` (string, optional): A description for the success response. Defaults to `'Success Response'`.
|
|
39
|
+
- `required` (boolean, optional): Whether the content is required.
|
|
40
|
+
- `headers` (Record<string, THeaderObject>, optional): Custom response headers to include in the success response.
|
|
26
41
|
|
|
27
42
|
```typescript
|
|
28
43
|
import { jsonResponse, z } from '@venizia/ignis';
|
|
@@ -43,11 +58,37 @@ this.defineRoute({
|
|
|
43
58
|
},
|
|
44
59
|
// ...
|
|
45
60
|
});
|
|
61
|
+
|
|
62
|
+
// With custom headers
|
|
63
|
+
this.defineRoute({
|
|
64
|
+
configs: {
|
|
65
|
+
path: '/list',
|
|
66
|
+
method: 'get',
|
|
67
|
+
responses: jsonResponse({
|
|
68
|
+
schema: z.array(UserSchema),
|
|
69
|
+
description: 'User list',
|
|
70
|
+
headers: {
|
|
71
|
+
'x-total-count': {
|
|
72
|
+
description: 'Total number of records',
|
|
73
|
+
schema: { type: 'string', examples: ['100'] },
|
|
74
|
+
},
|
|
75
|
+
},
|
|
76
|
+
}),
|
|
77
|
+
},
|
|
78
|
+
// ...
|
|
79
|
+
});
|
|
46
80
|
```
|
|
47
81
|
|
|
48
82
|
## `requiredString`
|
|
49
83
|
|
|
50
|
-
This function creates a `zod` string schema that is non-empty and can be further constrained by length.
|
|
84
|
+
This function creates a `zod` string schema that is non-empty (`nonempty()`) and can be further constrained by length.
|
|
85
|
+
|
|
86
|
+
### `requiredString(opts?)`
|
|
87
|
+
|
|
88
|
+
- `opts` (object, optional):
|
|
89
|
+
- `min` (number, optional): Minimum string length.
|
|
90
|
+
- `max` (number, optional): Maximum string length.
|
|
91
|
+
- `fixed` (number, optional): Exact string length (uses `.length()`).
|
|
51
92
|
|
|
52
93
|
```typescript
|
|
53
94
|
import { requiredString } from '@venizia/ignis';
|
|
@@ -55,12 +96,13 @@ import { requiredString } from '@venizia/ignis';
|
|
|
55
96
|
const schema = z.object({
|
|
56
97
|
username: requiredString({ min: 3, max: 20 }),
|
|
57
98
|
password: requiredString({ min: 8 }),
|
|
99
|
+
countryCode: requiredString({ fixed: 2 }),
|
|
58
100
|
});
|
|
59
101
|
```
|
|
60
102
|
|
|
61
103
|
## Predefined Schemas
|
|
62
104
|
|
|
63
|
-
- **`AnyObjectSchema`**: A flexible schema for any object (`z.object().catchall(z.any())`)
|
|
105
|
+
- **`AnyObjectSchema`**: A flexible schema for any object (`z.object().catchall(z.any())`), with an OpenAPI description of `'Unknown schema'`.
|
|
64
106
|
|
|
65
107
|
### Type Utilities
|
|
66
108
|
|
|
@@ -73,9 +115,30 @@ import { TAnyObjectSchema, TInferSchema } from '@venizia/ignis';
|
|
|
73
115
|
type UserType = TInferSchema<typeof UserSchema>;
|
|
74
116
|
```
|
|
75
117
|
|
|
76
|
-
|
|
118
|
+
## `snakeToCamel`
|
|
119
|
+
|
|
120
|
+
Transforms a Zod object shape from snake_case keys to camelCase. Uses `.transform()` and `.pipe()` to create a schema that accepts snake_case input but produces camelCase output.
|
|
121
|
+
|
|
122
|
+
```typescript
|
|
123
|
+
import { snakeToCamel } from '@venizia/ignis';
|
|
124
|
+
|
|
125
|
+
const schema = snakeToCamel({
|
|
126
|
+
first_name: z.string(),
|
|
127
|
+
last_name: z.string(),
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
// Input: { first_name: 'John', last_name: 'Doe' }
|
|
131
|
+
// Output: { firstName: 'John', lastName: 'Doe' }
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
## Custom ID Params
|
|
135
|
+
|
|
136
|
+
Use the `idParamsSchema()` helper to generate path parameter schemas for resource IDs:
|
|
137
|
+
|
|
138
|
+
### `idParamsSchema(opts?)`
|
|
77
139
|
|
|
78
|
-
|
|
140
|
+
- `opts` (object, optional):
|
|
141
|
+
- `idType` (string): `'number'` (default) or `'string'`.
|
|
79
142
|
|
|
80
143
|
```typescript
|
|
81
144
|
import { idParamsSchema } from '@venizia/ignis';
|
|
@@ -20,8 +20,8 @@ IGNIS provides a comprehensive system of standardized status codes and constants
|
|
|
20
20
|
| `Statuses` | Universal status codes (0xx-5xx scheme) | General entity lifecycle states |
|
|
21
21
|
| `MigrationStatuses` | Database migration status tracking | Migration success/failure tracking |
|
|
22
22
|
| `CommonStatuses` | Common entity statuses | Users, roles, and general entities |
|
|
23
|
-
| `UserStatuses` | User-specific statuses | User account states |
|
|
24
|
-
| `RoleStatuses` | Role-specific statuses | Role lifecycle states |
|
|
23
|
+
| `UserStatuses` | User-specific statuses | User account states (extends `CommonStatuses`) |
|
|
24
|
+
| `RoleStatuses` | Role-specific statuses | Role lifecycle states (extends `CommonStatuses`) |
|
|
25
25
|
| `UserTypes` | User type classification | System vs linked users |
|
|
26
26
|
|
|
27
27
|
## Table of Contents
|
|
@@ -67,8 +67,10 @@ Initial states for entities being created or in draft mode.
|
|
|
67
67
|
import { Statuses } from '@venizia/ignis';
|
|
68
68
|
|
|
69
69
|
const article = await articleRepository.create({
|
|
70
|
-
|
|
71
|
-
|
|
70
|
+
data: {
|
|
71
|
+
title: 'My Article',
|
|
72
|
+
status: Statuses.DRAFT, // Still being written
|
|
73
|
+
},
|
|
72
74
|
});
|
|
73
75
|
```
|
|
74
76
|
|
|
@@ -88,13 +90,16 @@ States indicating the entity is awaiting action, approval, or processing.
|
|
|
88
90
|
```typescript
|
|
89
91
|
// Job queue
|
|
90
92
|
const job = await jobRepository.create({
|
|
91
|
-
|
|
92
|
-
|
|
93
|
+
data: {
|
|
94
|
+
name: 'send-email',
|
|
95
|
+
status: Statuses.QUEUED,
|
|
96
|
+
},
|
|
93
97
|
});
|
|
94
98
|
|
|
95
99
|
// Approval workflow
|
|
96
|
-
|
|
97
|
-
|
|
100
|
+
await postRepository.updateById({
|
|
101
|
+
id: postId,
|
|
102
|
+
data: { status: Statuses.IN_REVIEW },
|
|
98
103
|
});
|
|
99
104
|
```
|
|
100
105
|
|
|
@@ -114,21 +119,24 @@ States indicating the entity is actively being processed or is currently operati
|
|
|
114
119
|
**Example Usage:**
|
|
115
120
|
```typescript
|
|
116
121
|
// User account activation
|
|
117
|
-
await userRepository.
|
|
118
|
-
|
|
122
|
+
await userRepository.updateById({
|
|
123
|
+
id: userId,
|
|
124
|
+
data: { status: Statuses.ACTIVATED },
|
|
119
125
|
});
|
|
120
126
|
|
|
121
127
|
// Background job
|
|
122
|
-
await jobRepository.
|
|
123
|
-
|
|
124
|
-
startedAt: new Date(),
|
|
128
|
+
await jobRepository.updateById({
|
|
129
|
+
id: jobId,
|
|
130
|
+
data: { status: Statuses.RUNNING, startedAt: new Date() },
|
|
125
131
|
});
|
|
126
132
|
|
|
127
133
|
// Email tracking
|
|
128
134
|
await emailRepository.create({
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
135
|
+
data: {
|
|
136
|
+
to: 'user@example.com',
|
|
137
|
+
subject: 'Welcome',
|
|
138
|
+
status: Statuses.SENT,
|
|
139
|
+
},
|
|
132
140
|
});
|
|
133
141
|
```
|
|
134
142
|
|
|
@@ -148,23 +156,19 @@ Positive terminal states indicating successful completion.
|
|
|
148
156
|
**Example Usage:**
|
|
149
157
|
```typescript
|
|
150
158
|
// Job completion
|
|
151
|
-
await jobRepository.
|
|
152
|
-
|
|
153
|
-
completedAt: new Date(),
|
|
159
|
+
await jobRepository.updateById({
|
|
160
|
+
id: jobId,
|
|
161
|
+
data: { status: Statuses.SUCCESS, completedAt: new Date() },
|
|
154
162
|
});
|
|
155
163
|
|
|
156
164
|
// Approval workflow
|
|
157
|
-
await documentRepository.
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
await batchRepository.update(batchId, {
|
|
165
|
-
status: Statuses.PARTIAL, // Some items succeeded
|
|
166
|
-
processedCount: 75,
|
|
167
|
-
totalCount: 100,
|
|
165
|
+
await documentRepository.updateById({
|
|
166
|
+
id: docId,
|
|
167
|
+
data: {
|
|
168
|
+
status: Statuses.APPROVED,
|
|
169
|
+
approvedBy: userId,
|
|
170
|
+
approvedAt: new Date(),
|
|
171
|
+
},
|
|
168
172
|
});
|
|
169
173
|
```
|
|
170
174
|
|
|
@@ -187,19 +191,15 @@ Negative but reversible states - the entity can be reactivated.
|
|
|
187
191
|
**Example Usage:**
|
|
188
192
|
```typescript
|
|
189
193
|
// User account management
|
|
190
|
-
await userRepository.
|
|
191
|
-
|
|
192
|
-
|
|
194
|
+
await userRepository.updateById({
|
|
195
|
+
id: userId,
|
|
196
|
+
data: { status: Statuses.SUSPENDED },
|
|
193
197
|
});
|
|
194
198
|
|
|
195
199
|
// Feature flags
|
|
196
|
-
await featureRepository.
|
|
197
|
-
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
// Ticket system
|
|
201
|
-
await ticketRepository.update(ticketId, {
|
|
202
|
-
status: Statuses.CLOSED, // Can be reopened if needed
|
|
200
|
+
await featureRepository.updateById({
|
|
201
|
+
id: featureId,
|
|
202
|
+
data: { status: Statuses.DISABLED },
|
|
203
203
|
});
|
|
204
204
|
```
|
|
205
205
|
|
|
@@ -221,30 +221,22 @@ Negative terminal states indicating permanent failure or cancellation.
|
|
|
221
221
|
**Example Usage:**
|
|
222
222
|
```typescript
|
|
223
223
|
// Job failure
|
|
224
|
-
await jobRepository.
|
|
225
|
-
|
|
226
|
-
error: 'Connection timeout',
|
|
227
|
-
failedAt: new Date(),
|
|
228
|
-
});
|
|
229
|
-
|
|
230
|
-
// Token expiration
|
|
231
|
-
await tokenRepository.update(tokenId, {
|
|
232
|
-
status: Statuses.EXPIRED,
|
|
233
|
-
expiredAt: new Date(),
|
|
224
|
+
await jobRepository.updateById({
|
|
225
|
+
id: jobId,
|
|
226
|
+
data: { status: Statuses.FAIL, error: 'Connection timeout', failedAt: new Date() },
|
|
234
227
|
});
|
|
235
228
|
|
|
236
229
|
// Soft delete
|
|
237
|
-
await productRepository.
|
|
238
|
-
|
|
239
|
-
deletedAt: new Date(),
|
|
240
|
-
deletedBy: userId,
|
|
230
|
+
await productRepository.updateById({
|
|
231
|
+
id: productId,
|
|
232
|
+
data: { status: Statuses.DELETED, deletedAt: new Date(), deletedBy: userId },
|
|
241
233
|
});
|
|
242
234
|
```
|
|
243
235
|
|
|
244
236
|
|
|
245
237
|
## Status Groups
|
|
246
238
|
|
|
247
|
-
The `Statuses` class provides static
|
|
239
|
+
The `Statuses` class provides static `Set` instances for grouping related statuses.
|
|
248
240
|
|
|
249
241
|
### Available Groups
|
|
250
242
|
|
|
@@ -333,15 +325,15 @@ const pendingOrders = orders.filter(order => Statuses.isPending(order.status));
|
|
|
333
325
|
|
|
334
326
|
### MigrationStatuses
|
|
335
327
|
|
|
336
|
-
Simplified statuses for database migration tracking.
|
|
328
|
+
Simplified statuses for database migration tracking. References values from `Statuses`.
|
|
337
329
|
|
|
338
330
|
```typescript
|
|
339
331
|
import { MigrationStatuses } from '@venizia/ignis';
|
|
340
332
|
|
|
341
333
|
class MigrationStatuses {
|
|
342
|
-
static readonly UNKNOWN = '000_UNKNOWN';
|
|
343
|
-
static readonly SUCCESS = '302_SUCCESS';
|
|
344
|
-
static readonly FAIL = '500_FAIL';
|
|
334
|
+
static readonly UNKNOWN = '000_UNKNOWN'; // = Statuses.UNKNOWN
|
|
335
|
+
static readonly SUCCESS = '302_SUCCESS'; // = Statuses.SUCCESS
|
|
336
|
+
static readonly FAIL = '500_FAIL'; // = Statuses.FAIL
|
|
345
337
|
|
|
346
338
|
static readonly SCHEME_SET = new Set([
|
|
347
339
|
this.UNKNOWN,
|
|
@@ -356,26 +348,28 @@ class MigrationStatuses {
|
|
|
356
348
|
**Usage:**
|
|
357
349
|
```typescript
|
|
358
350
|
await migrationRepository.create({
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
351
|
+
data: {
|
|
352
|
+
version: '20240103_001',
|
|
353
|
+
name: 'add_users_table',
|
|
354
|
+
status: MigrationStatuses.SUCCESS,
|
|
355
|
+
appliedAt: new Date(),
|
|
356
|
+
},
|
|
363
357
|
});
|
|
364
358
|
```
|
|
365
359
|
|
|
366
360
|
### CommonStatuses
|
|
367
361
|
|
|
368
|
-
Common statuses used across multiple entity types.
|
|
362
|
+
Common statuses used across multiple entity types. References values from `Statuses`.
|
|
369
363
|
|
|
370
364
|
```typescript
|
|
371
365
|
import { CommonStatuses } from '@venizia/ignis';
|
|
372
366
|
|
|
373
367
|
class CommonStatuses {
|
|
374
|
-
static readonly UNKNOWN = '000_UNKNOWN';
|
|
375
|
-
static readonly ACTIVATED = '201_ACTIVATED';
|
|
376
|
-
static readonly DEACTIVATED = '401_DEACTIVATED';
|
|
377
|
-
static readonly BLOCKED = '403_BLOCKED';
|
|
378
|
-
static readonly ARCHIVED = '405_ARCHIVED';
|
|
368
|
+
static readonly UNKNOWN = '000_UNKNOWN'; // = Statuses.UNKNOWN
|
|
369
|
+
static readonly ACTIVATED = '201_ACTIVATED'; // = Statuses.ACTIVATED
|
|
370
|
+
static readonly DEACTIVATED = '401_DEACTIVATED'; // = Statuses.DEACTIVATED
|
|
371
|
+
static readonly BLOCKED = '403_BLOCKED'; // = Statuses.BLOCKED
|
|
372
|
+
static readonly ARCHIVED = '405_ARCHIVED'; // = Statuses.ARCHIVED
|
|
379
373
|
|
|
380
374
|
static readonly SCHEME_SET = new Set([...]);
|
|
381
375
|
static isValid(scheme: string): boolean;
|
|
@@ -385,33 +379,39 @@ class CommonStatuses {
|
|
|
385
379
|
**Usage:**
|
|
386
380
|
```typescript
|
|
387
381
|
// User management
|
|
388
|
-
await userRepository.
|
|
389
|
-
|
|
382
|
+
await userRepository.updateById({
|
|
383
|
+
id: userId,
|
|
384
|
+
data: { status: CommonStatuses.ACTIVATED },
|
|
390
385
|
});
|
|
391
386
|
|
|
392
387
|
// Role management
|
|
393
|
-
await roleRepository.
|
|
394
|
-
|
|
388
|
+
await roleRepository.updateById({
|
|
389
|
+
id: roleId,
|
|
390
|
+
data: { status: CommonStatuses.ARCHIVED },
|
|
395
391
|
});
|
|
396
392
|
```
|
|
397
393
|
|
|
398
394
|
### UserStatuses & RoleStatuses
|
|
399
395
|
|
|
400
|
-
|
|
396
|
+
Both `UserStatuses` and `RoleStatuses` extend `CommonStatuses` directly, inheriting all its statuses and methods.
|
|
401
397
|
|
|
402
398
|
```typescript
|
|
403
399
|
import { UserStatuses, RoleStatuses } from '@venizia/ignis';
|
|
404
400
|
|
|
405
401
|
// UserStatuses extends CommonStatuses
|
|
406
402
|
const user = await userRepository.create({
|
|
407
|
-
|
|
408
|
-
|
|
403
|
+
data: {
|
|
404
|
+
email: 'user@example.com',
|
|
405
|
+
status: UserStatuses.ACTIVATED,
|
|
406
|
+
},
|
|
409
407
|
});
|
|
410
408
|
|
|
411
409
|
// RoleStatuses extends CommonStatuses
|
|
412
410
|
const role = await roleRepository.create({
|
|
413
|
-
|
|
414
|
-
|
|
411
|
+
data: {
|
|
412
|
+
name: 'admin',
|
|
413
|
+
status: RoleStatuses.ACTIVATED,
|
|
414
|
+
},
|
|
415
415
|
});
|
|
416
416
|
```
|
|
417
417
|
|
|
@@ -435,17 +435,21 @@ class UserTypes {
|
|
|
435
435
|
```typescript
|
|
436
436
|
// Create system user
|
|
437
437
|
const systemUser = await userRepository.create({
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
438
|
+
data: {
|
|
439
|
+
email: 'system@app.com',
|
|
440
|
+
type: UserTypes.SYSTEM,
|
|
441
|
+
status: UserStatuses.ACTIVATED,
|
|
442
|
+
},
|
|
441
443
|
});
|
|
442
444
|
|
|
443
445
|
// OAuth linked user
|
|
444
446
|
const oauthUser = await userRepository.create({
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
447
|
+
data: {
|
|
448
|
+
email: 'user@example.com',
|
|
449
|
+
type: UserTypes.LINKED,
|
|
450
|
+
linkedProvider: 'google',
|
|
451
|
+
status: UserStatuses.ACTIVATED,
|
|
452
|
+
},
|
|
449
453
|
});
|
|
450
454
|
```
|
|
451
455
|
|
|
@@ -461,13 +465,13 @@ class OrderService extends BaseService {
|
|
|
461
465
|
async createOrder(data: CreateOrderDto) {
|
|
462
466
|
// Start as NEW
|
|
463
467
|
const order = await this.orderRepository.create({
|
|
464
|
-
...data,
|
|
465
|
-
status: Statuses.NEW,
|
|
468
|
+
data: { ...data, status: Statuses.NEW },
|
|
466
469
|
});
|
|
467
470
|
|
|
468
471
|
// Queue for processing
|
|
469
|
-
await this.orderRepository.
|
|
470
|
-
|
|
472
|
+
await this.orderRepository.updateById({
|
|
473
|
+
id: order.data.id,
|
|
474
|
+
data: { status: Statuses.QUEUED },
|
|
471
475
|
});
|
|
472
476
|
|
|
473
477
|
return order;
|
|
@@ -475,9 +479,9 @@ class OrderService extends BaseService {
|
|
|
475
479
|
|
|
476
480
|
async processOrder(orderId: string) {
|
|
477
481
|
// Mark as processing
|
|
478
|
-
await this.orderRepository.
|
|
479
|
-
|
|
480
|
-
startedAt: new Date(),
|
|
482
|
+
await this.orderRepository.updateById({
|
|
483
|
+
id: orderId,
|
|
484
|
+
data: { status: Statuses.PROCESSING, startedAt: new Date() },
|
|
481
485
|
});
|
|
482
486
|
|
|
483
487
|
try {
|
|
@@ -486,16 +490,15 @@ class OrderService extends BaseService {
|
|
|
486
490
|
await this.inventoryService.reserve(order.items);
|
|
487
491
|
|
|
488
492
|
// Mark as completed
|
|
489
|
-
await this.orderRepository.
|
|
490
|
-
|
|
491
|
-
completedAt: new Date(),
|
|
493
|
+
await this.orderRepository.updateById({
|
|
494
|
+
id: orderId,
|
|
495
|
+
data: { status: Statuses.COMPLETED, completedAt: new Date() },
|
|
492
496
|
});
|
|
493
497
|
} catch (error) {
|
|
494
498
|
// Mark as failed
|
|
495
|
-
await this.orderRepository.
|
|
496
|
-
|
|
497
|
-
error: error.message,
|
|
498
|
-
failedAt: new Date(),
|
|
499
|
+
await this.orderRepository.updateById({
|
|
500
|
+
id: orderId,
|
|
501
|
+
data: { status: Statuses.FAIL, error: error.message, failedAt: new Date() },
|
|
499
502
|
});
|
|
500
503
|
|
|
501
504
|
throw error;
|
|
@@ -503,16 +506,16 @@ class OrderService extends BaseService {
|
|
|
503
506
|
}
|
|
504
507
|
|
|
505
508
|
async cancelOrder(orderId: string) {
|
|
506
|
-
const order = await this.orderRepository.findById(orderId);
|
|
509
|
+
const order = await this.orderRepository.findById({ id: orderId });
|
|
507
510
|
|
|
508
511
|
// Can only cancel pending or active orders
|
|
509
512
|
if (Statuses.isCompleted(order.status) || Statuses.isFailed(order.status)) {
|
|
510
513
|
throw new Error('Cannot cancel completed or failed order');
|
|
511
514
|
}
|
|
512
515
|
|
|
513
|
-
await this.orderRepository.
|
|
514
|
-
|
|
515
|
-
cancelledAt: new Date(),
|
|
516
|
+
await this.orderRepository.updateById({
|
|
517
|
+
id: orderId,
|
|
518
|
+
data: { status: Statuses.CANCELLED, cancelledAt: new Date() },
|
|
516
519
|
});
|
|
517
520
|
}
|
|
518
521
|
}
|
|
@@ -527,9 +530,11 @@ class JobService extends BaseService {
|
|
|
527
530
|
// Get all jobs that can be retried
|
|
528
531
|
async getRetryableJobs() {
|
|
529
532
|
return this.jobRepository.find({
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
+
filter: {
|
|
534
|
+
where: {
|
|
535
|
+
status: { inq: [...Statuses.FAILED_SCHEME_SET] },
|
|
536
|
+
retryCount: { lt: 3 },
|
|
537
|
+
},
|
|
533
538
|
},
|
|
534
539
|
});
|
|
535
540
|
}
|
|
@@ -538,23 +543,7 @@ class JobService extends BaseService {
|
|
|
538
543
|
async getActiveJobsCount() {
|
|
539
544
|
return this.jobRepository.count({
|
|
540
545
|
where: {
|
|
541
|
-
status: {
|
|
542
|
-
},
|
|
543
|
-
});
|
|
544
|
-
}
|
|
545
|
-
|
|
546
|
-
// Archive old completed jobs
|
|
547
|
-
async archiveCompletedJobs(daysOld: number) {
|
|
548
|
-
const cutoffDate = new Date();
|
|
549
|
-
cutoffDate.setDate(cutoffDate.getDate() - daysOld);
|
|
550
|
-
|
|
551
|
-
return this.jobRepository.updateMany({
|
|
552
|
-
where: {
|
|
553
|
-
status: { in: [...Statuses.COMPLETED_SCHEME_SET] },
|
|
554
|
-
completedAt: { lt: cutoffDate },
|
|
555
|
-
},
|
|
556
|
-
data: {
|
|
557
|
-
status: Statuses.ARCHIVED,
|
|
546
|
+
status: { inq: [...Statuses.ACTIVE_SCHEME_SET] },
|
|
558
547
|
},
|
|
559
548
|
});
|
|
560
549
|
}
|
|
@@ -573,14 +562,14 @@ class TaskService extends BaseService {
|
|
|
573
562
|
throw new Error(`Invalid status: ${newStatus}`);
|
|
574
563
|
}
|
|
575
564
|
|
|
576
|
-
const task = await this.taskRepository.findById(taskId);
|
|
565
|
+
const task = await this.taskRepository.findById({ id: taskId });
|
|
577
566
|
|
|
578
567
|
// Validate transition
|
|
579
568
|
this.validateStatusTransition(task.status, newStatus);
|
|
580
569
|
|
|
581
|
-
await this.taskRepository.
|
|
582
|
-
|
|
583
|
-
statusChangedAt: new Date(),
|
|
570
|
+
await this.taskRepository.updateById({
|
|
571
|
+
id: taskId,
|
|
572
|
+
data: { status: newStatus, statusChangedAt: new Date() },
|
|
584
573
|
});
|
|
585
574
|
}
|
|
586
575
|
|
|
@@ -605,7 +594,7 @@ class TaskService extends BaseService {
|
|
|
605
594
|
|
|
606
595
|
## Binding Namespaces
|
|
607
596
|
|
|
608
|
-
The `BindingNamespaces` class organizes dependency injection bindings by type.
|
|
597
|
+
The `BindingNamespaces` class organizes dependency injection bindings by type. It uses `createNamespace()` internally to produce namespace strings.
|
|
609
598
|
|
|
610
599
|
**File:** `packages/core/src/common/bindings.ts`
|
|
611
600
|
|
|
@@ -624,12 +613,14 @@ class BindingNamespaces {
|
|
|
624
613
|
static readonly PROVIDER = 'providers';
|
|
625
614
|
static readonly CONTROLLER = 'controllers';
|
|
626
615
|
static readonly BOOTERS = 'booters';
|
|
616
|
+
|
|
617
|
+
static createNamespace(opts: { name: string }): string;
|
|
627
618
|
}
|
|
628
619
|
```
|
|
629
620
|
|
|
630
621
|
### CoreBindings
|
|
631
622
|
|
|
632
|
-
Application-level binding keys
|
|
623
|
+
Application-level binding keys. Extends `BindingKeys` from the inversion package.
|
|
633
624
|
|
|
634
625
|
```typescript
|
|
635
626
|
import { CoreBindings } from '@venizia/ignis';
|
|
@@ -660,36 +651,36 @@ const config = container.get(CoreBindings.APPLICATION_CONFIG);
|
|
|
660
651
|
### 1. Use Status Constants
|
|
661
652
|
|
|
662
653
|
```typescript
|
|
663
|
-
//
|
|
654
|
+
// Good: Use constants
|
|
664
655
|
order.status = Statuses.COMPLETED;
|
|
665
656
|
|
|
666
|
-
//
|
|
657
|
+
// Bad: Magic strings
|
|
667
658
|
order.status = '303_COMPLETED'; // Prone to typos
|
|
668
659
|
```
|
|
669
660
|
|
|
670
661
|
### 2. Validate Before Updating
|
|
671
662
|
|
|
672
663
|
```typescript
|
|
673
|
-
//
|
|
664
|
+
// Good: Validate transitions
|
|
674
665
|
if (Statuses.isCompleted(order.status)) {
|
|
675
666
|
throw new Error('Cannot modify completed order');
|
|
676
667
|
}
|
|
677
668
|
|
|
678
|
-
//
|
|
669
|
+
// Bad: No validation
|
|
679
670
|
order.status = newStatus; // Could break business rules
|
|
680
671
|
```
|
|
681
672
|
|
|
682
673
|
### 3. Use Helper Methods
|
|
683
674
|
|
|
684
675
|
```typescript
|
|
685
|
-
//
|
|
676
|
+
// Good: Use helper methods
|
|
686
677
|
if (Statuses.isActive(job.status)) {
|
|
687
678
|
// ...
|
|
688
679
|
}
|
|
689
680
|
|
|
690
|
-
//
|
|
681
|
+
// Less readable alternative: Manual set checking
|
|
691
682
|
if (Statuses.ACTIVE_SCHEME_SET.has(job.status)) {
|
|
692
|
-
//
|
|
683
|
+
// ...
|
|
693
684
|
}
|
|
694
685
|
```
|
|
695
686
|
|
|
@@ -698,9 +689,9 @@ if (Statuses.ACTIVE_SCHEME_SET.has(job.status)) {
|
|
|
698
689
|
```typescript
|
|
699
690
|
/**
|
|
700
691
|
* Order Status Flow:
|
|
701
|
-
* NEW
|
|
702
|
-
*
|
|
703
|
-
* CANCELLED
|
|
692
|
+
* NEW -> QUEUED -> PROCESSING -> COMPLETED
|
|
693
|
+
* \ \ \
|
|
694
|
+
* -> CANCELLED <-----
|
|
704
695
|
*/
|
|
705
696
|
class OrderService {
|
|
706
697
|
// Implementation...
|
|
@@ -710,7 +701,7 @@ class OrderService {
|
|
|
710
701
|
### 5. Terminal State Checks
|
|
711
702
|
|
|
712
703
|
```typescript
|
|
713
|
-
//
|
|
704
|
+
// Good: Check for terminal states
|
|
714
705
|
const isTerminal = Statuses.isCompleted(status) || Statuses.isFailed(status);
|
|
715
706
|
|
|
716
707
|
if (isTerminal) {
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|