@venizia/ignis-docs 0.2.0 → 0.2.1-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.
- package/README.md +14 -14
- package/content/best-practices/api-usage-examples.md +39 -19
- package/content/best-practices/architectural-patterns.md +22 -11
- package/content/best-practices/architecture-decisions.md +29 -16
- package/content/best-practices/code-style-standards/advanced-patterns.md +43 -31
- package/content/best-practices/code-style-standards/constants-configuration.md +19 -4
- package/content/best-practices/code-style-standards/control-flow.md +33 -1
- package/content/best-practices/code-style-standards/documentation.md +28 -8
- package/content/best-practices/code-style-standards/function-patterns.md +15 -4
- package/content/best-practices/code-style-standards/index.md +7 -2
- package/content/best-practices/code-style-standards/naming-conventions.md +26 -2
- package/content/best-practices/code-style-standards/route-definitions.md +9 -5
- package/content/best-practices/code-style-standards/tooling.md +14 -1
- package/content/best-practices/code-style-standards/type-safety.md +39 -6
- package/content/best-practices/common-pitfalls.md +59 -35
- package/content/best-practices/contribution-workflow.md +6 -2
- package/content/best-practices/data-modeling.md +78 -62
- package/content/best-practices/deployment-strategies.md +56 -19
- package/content/best-practices/error-handling.md +182 -93
- package/content/best-practices/index.md +6 -0
- package/content/best-practices/performance-optimization.md +26 -13
- package/content/best-practices/security-guidelines.md +35 -9
- package/content/best-practices/testing-strategies.md +7 -2
- package/content/best-practices/troubleshooting-tips.md +27 -17
- package/content/extensions/components/api-reference.md +107 -322
- package/content/extensions/components/authentication/api.md +454 -603
- package/content/extensions/components/authentication/errors.md +121 -498
- package/content/extensions/components/authentication/index.md +88 -801
- package/content/extensions/components/authentication/usage.md +207 -956
- package/content/extensions/components/authorization/api.md +736 -656
- package/content/extensions/components/authorization/errors.md +168 -206
- package/content/extensions/components/authorization/index.md +82 -797
- package/content/extensions/components/authorization/usage.md +194 -527
- package/content/extensions/components/health-check.md +71 -243
- package/content/extensions/components/mail/api.md +504 -287
- package/content/extensions/components/mail/errors.md +73 -61
- package/content/extensions/components/mail/index.md +96 -467
- package/content/extensions/components/mail/usage.md +130 -172
- package/content/extensions/components/request-tracker.md +66 -173
- package/content/extensions/components/socket-io/api.md +195 -13
- package/content/extensions/components/socket-io/errors.md +3 -3
- package/content/extensions/components/socket-io/index.md +50 -337
- package/content/extensions/components/socket-io/usage.md +143 -26
- package/content/extensions/components/static-asset/api.md +410 -142
- package/content/extensions/components/static-asset/errors.md +110 -53
- package/content/extensions/components/static-asset/index.md +79 -608
- package/content/extensions/components/static-asset/usage.md +180 -300
- package/content/extensions/components/websocket/api.md +275 -399
- package/content/extensions/components/websocket/errors.md +47 -56
- package/content/extensions/components/websocket/index.md +74 -407
- package/content/extensions/components/websocket/usage.md +110 -341
- package/content/extensions/helpers/cron/index.md +51 -160
- package/content/extensions/helpers/crypto/index.md +62 -483
- package/content/extensions/helpers/crypto/reference.md +456 -0
- package/content/extensions/helpers/env/index.md +60 -178
- package/content/extensions/helpers/error/index.md +221 -207
- package/content/extensions/helpers/inversion/index.md +65 -556
- package/content/extensions/helpers/inversion/reference.md +522 -0
- package/content/extensions/helpers/kafka/admin.md +20 -1
- package/content/extensions/helpers/kafka/compile-binary.md +41 -35
- package/content/extensions/helpers/kafka/consumer.md +54 -20
- package/content/extensions/helpers/kafka/examples.md +21 -16
- package/content/extensions/helpers/kafka/index.md +80 -610
- package/content/extensions/helpers/kafka/producer.md +134 -5
- package/content/extensions/helpers/kafka/schema-registry.md +45 -70
- package/content/extensions/helpers/logger/hf-logger.md +193 -0
- package/content/extensions/helpers/logger/index.md +64 -563
- package/content/extensions/helpers/logger/pino.md +85 -0
- package/content/extensions/helpers/logger/reference.md +746 -0
- package/content/extensions/helpers/network/api.md +241 -195
- package/content/extensions/helpers/network/index.md +72 -530
- package/content/extensions/helpers/queue/index.md +72 -900
- package/content/extensions/helpers/queue/reference.md +467 -0
- package/content/extensions/helpers/redis/index.md +73 -645
- package/content/extensions/helpers/redis/reference.md +727 -0
- package/content/extensions/helpers/secrets/index.md +66 -0
- package/content/extensions/helpers/socket-io/api.md +305 -203
- package/content/extensions/helpers/socket-io/index.md +66 -432
- package/content/extensions/helpers/storage/api.md +564 -462
- package/content/extensions/helpers/storage/index.md +77 -573
- package/content/extensions/helpers/types/index.md +66 -499
- package/content/extensions/helpers/types/reference.md +650 -0
- package/content/extensions/helpers/uid/index.md +58 -227
- package/content/extensions/helpers/websocket/api.md +329 -216
- package/content/extensions/helpers/websocket/index.md +65 -503
- package/content/extensions/helpers/worker-thread/index.md +58 -396
- package/content/extensions/helpers/worker-thread/reference.md +428 -0
- package/content/guides/core-concepts/persistent/models.md +1 -1
- package/content/guides/core-concepts/persistent/search-typesense.md +3 -3
- package/content/guides/core-concepts/persistent/transactions.md +1 -1
- package/content/guides/core-concepts/secrets-vault.md +177 -0
- package/content/guides/core-concepts/services.md +1 -1
- package/content/guides/migrations/redis-helpers-migration.md +1 -1
- package/content/guides/migrations/unified-connectors-migration.md +2 -2
- package/content/guides/tutorials/ecommerce-api.md +3 -8
- package/content/references/base/application.md +1 -1
- package/content/references/base/connectors.md +79 -136
- package/content/references/base/datasources-reference.md +599 -0
- package/content/references/base/datasources.md +84 -444
- package/content/references/base/dependency-injection.md +17 -39
- package/content/references/base/filter-system/application-usage.md +69 -121
- package/content/references/base/filter-system/array-operators.md +12 -0
- package/content/references/base/filter-system/comparison-operators.md +12 -0
- package/content/references/base/filter-system/default-filter.md +136 -348
- package/content/references/base/filter-system/fields-order-pagination.md +38 -16
- package/content/references/base/filter-system/index.md +106 -257
- package/content/references/base/filter-system/json-filtering.md +12 -2
- package/content/references/base/filter-system/list-operators.md +16 -2
- package/content/references/base/filter-system/logical-operators.md +13 -0
- package/content/references/base/filter-system/null-operators.md +13 -0
- package/content/references/base/filter-system/pattern-matching.md +12 -0
- package/content/references/base/filter-system/quick-reference.md +11 -2
- package/content/references/base/filter-system/range-operators.md +12 -0
- package/content/references/base/filter-system/tips.md +70 -133
- package/content/references/base/filter-system/use-cases.md +156 -233
- package/content/references/base/middlewares.md +35 -21
- package/content/references/base/models-reference.md +886 -0
- package/content/references/base/models.md +80 -1452
- package/content/references/base/repositories/advanced.md +156 -192
- package/content/references/base/repositories/index.md +77 -650
- package/content/references/base/repositories/mixins.md +22 -18
- package/content/references/base/repositories/relations.md +123 -171
- package/content/references/base/repositories/soft-deletable.md +58 -56
- package/content/references/base/secrets.md +263 -0
- package/content/references/base/services.md +2 -2
- package/content/references/configuration/environment-variables.md +48 -4
- package/content/references/configuration/index.md +49 -31
- package/content/references/quick-reference.md +3 -16
- package/content/references/utilities/crypto.md +35 -76
- package/content/references/utilities/date.md +33 -73
- package/content/references/utilities/index.md +1 -1
- package/content/references/utilities/jsx-reference.md +298 -0
- package/content/references/utilities/jsx.md +82 -525
- package/content/references/utilities/module.md +29 -62
- package/content/references/utilities/parse.md +34 -64
- package/content/references/utilities/performance.md +33 -58
- package/content/references/utilities/promise.md +28 -62
- package/content/references/utilities/request.md +57 -218
- package/content/references/utilities/schema.md +43 -137
- package/content/references/utilities/statuses-reference.md +361 -0
- package/content/references/utilities/statuses.md +63 -667
- package/package.json +8 -8
|
@@ -1,726 +1,122 @@
|
|
|
1
1
|
---
|
|
2
|
-
title:
|
|
3
|
-
description:
|
|
2
|
+
title: Statuses
|
|
3
|
+
description: A shared catalog of lifecycle status codes and binding-namespace constants
|
|
4
4
|
difficulty: beginner
|
|
5
|
-
lastUpdated: 2026-
|
|
5
|
+
lastUpdated: 2026-07-16
|
|
6
6
|
---
|
|
7
7
|
|
|
8
|
-
#
|
|
8
|
+
# Statuses
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
`Statuses` is a static catalog of lifecycle status codes - a shared vocabulary so every entity in an app uses the same strings for "draft", "active", "failed", and so on.
|
|
11
11
|
|
|
12
|
-
|
|
13
|
-
- `packages/core/src/common/statuses.ts`
|
|
14
|
-
- `packages/core/src/common/bindings.ts`
|
|
15
|
-
|
|
16
|
-
## Quick Reference
|
|
17
|
-
|
|
18
|
-
| Class | Purpose | Use Case |
|
|
19
|
-
|-------|---------|----------|
|
|
20
|
-
| `Statuses` | Universal status codes (0xx-5xx scheme) | General entity lifecycle states |
|
|
21
|
-
| `MigrationStatuses` | Database migration status tracking | Migration success/failure tracking |
|
|
22
|
-
| `CommonStatuses` | Common entity statuses | Users, roles, and general entities |
|
|
23
|
-
| `UserStatuses` | User-specific statuses | User account states (extends `CommonStatuses`) |
|
|
24
|
-
| `RoleStatuses` | Role-specific statuses | Role lifecycle states (extends `CommonStatuses`) |
|
|
25
|
-
| `UserTypes` | User type classification | System vs linked users |
|
|
26
|
-
|
|
27
|
-
## Table of Contents
|
|
28
|
-
|
|
29
|
-
- [Statuses Class](#statuses-class)
|
|
30
|
-
- [Status Code Scheme](#status-code-scheme)
|
|
31
|
-
- [Status Groups](#status-groups)
|
|
32
|
-
- [Validation Methods](#validation-methods)
|
|
33
|
-
- [Specialized Status Classes](#specialized-status-classes)
|
|
34
|
-
- [Usage Examples](#usage-examples)
|
|
35
|
-
- [Binding Namespaces](#binding-namespaces)
|
|
36
|
-
- [Best Practices](#best-practices)
|
|
37
|
-
- [See Also](#see-also)
|
|
38
|
-
|
|
39
|
-
## Statuses Class
|
|
40
|
-
|
|
41
|
-
The `Statuses` class provides a comprehensive, HTTP-inspired status code system for tracking entity lifecycle states.
|
|
42
|
-
|
|
43
|
-
### Status Code Scheme
|
|
44
|
-
|
|
45
|
-
Status codes follow a numerical prefix pattern inspired by HTTP status codes:
|
|
46
|
-
|
|
47
|
-
| Prefix | Category | Meaning | Reversibility |
|
|
48
|
-
|--------|----------|---------|---------------|
|
|
49
|
-
| **0xx** | Initial | Entity creation/draft state | N/A |
|
|
50
|
-
| **1xx** | Pending | Awaiting action or decision | Reversible |
|
|
51
|
-
| **2xx** | Active | In progress or running | Reversible |
|
|
52
|
-
| **3xx** | Completed | Positive terminal state | Terminal |
|
|
53
|
-
| **4xx** | Inactive | Negative but reversible | Reversible |
|
|
54
|
-
| **5xx** | Failed | Negative terminal state | Terminal |
|
|
55
|
-
|
|
56
|
-
### 0xx - Initial States
|
|
57
|
-
|
|
58
|
-
Initial states for entities being created or in draft mode.
|
|
59
|
-
|
|
60
|
-
| Constant | Value | Description |
|
|
61
|
-
|----------|-------|-------------|
|
|
62
|
-
| `UNKNOWN` | `'000_UNKNOWN'` | Unknown or uninitialized state |
|
|
63
|
-
| `DRAFT` | `'001_DRAFT'` | Draft state, not yet finalized |
|
|
12
|
+
## In one example
|
|
64
13
|
|
|
65
|
-
**Example Usage:**
|
|
66
14
|
```typescript
|
|
67
15
|
import { Statuses } from '@venizia/ignis';
|
|
68
16
|
|
|
69
|
-
const article = await articleRepository.create({
|
|
70
|
-
data: {
|
|
71
|
-
title: 'My Article',
|
|
72
|
-
status: Statuses.DRAFT, // Still being written
|
|
73
|
-
},
|
|
74
|
-
});
|
|
75
|
-
```
|
|
76
|
-
|
|
77
|
-
### 1xx - Pending/Waiting States
|
|
78
|
-
|
|
79
|
-
States indicating the entity is awaiting action, approval, or processing.
|
|
80
|
-
|
|
81
|
-
| Constant | Value | Description |
|
|
82
|
-
|----------|-------|-------------|
|
|
83
|
-
| `NEW` | `'100_NEW'` | Newly created, not yet processed |
|
|
84
|
-
| `QUEUED` | `'101_QUEUED'` | Queued for processing |
|
|
85
|
-
| `SCHEDULED` | `'102_SCHEDULED'` | Scheduled for future execution |
|
|
86
|
-
| `PENDING` | `'103_PENDING'` | Awaiting action or decision |
|
|
87
|
-
| `IN_REVIEW` | `'104_IN_REVIEW'` | Under review or approval process |
|
|
88
|
-
|
|
89
|
-
**Example Usage:**
|
|
90
|
-
```typescript
|
|
91
|
-
// Job queue
|
|
92
17
|
const job = await jobRepository.create({
|
|
93
|
-
data: {
|
|
94
|
-
name: 'send-email',
|
|
95
|
-
status: Statuses.QUEUED,
|
|
96
|
-
},
|
|
97
|
-
});
|
|
98
|
-
|
|
99
|
-
// Approval workflow
|
|
100
|
-
await postRepository.updateById({
|
|
101
|
-
id: postId,
|
|
102
|
-
data: { status: Statuses.IN_REVIEW },
|
|
103
|
-
});
|
|
104
|
-
```
|
|
105
|
-
|
|
106
|
-
### 2xx - Active/Running States
|
|
107
|
-
|
|
108
|
-
States indicating the entity is actively being processed or is currently operational.
|
|
109
|
-
|
|
110
|
-
| Constant | Value | Description |
|
|
111
|
-
|----------|-------|-------------|
|
|
112
|
-
| `ENABLED` | `'200_ENABLED'` | Feature or entity is enabled |
|
|
113
|
-
| `ACTIVATED` | `'201_ACTIVATED'` | Account or service is active |
|
|
114
|
-
| `RUNNING` | `'202_RUNNING'` | Process is currently running |
|
|
115
|
-
| `PROCESSING` | `'203_PROCESSING'` | Being actively processed |
|
|
116
|
-
| `SENT` | `'204_SENT'` | Message/item has been sent |
|
|
117
|
-
| `RECEIVED` | `'205_RECEIVED'` | Message/item has been received |
|
|
118
|
-
|
|
119
|
-
**Example Usage:**
|
|
120
|
-
```typescript
|
|
121
|
-
// User account activation
|
|
122
|
-
await userRepository.updateById({
|
|
123
|
-
id: userId,
|
|
124
|
-
data: { status: Statuses.ACTIVATED },
|
|
125
|
-
});
|
|
126
|
-
|
|
127
|
-
// Background job
|
|
128
|
-
await jobRepository.updateById({
|
|
129
|
-
id: jobId,
|
|
130
|
-
data: { status: Statuses.RUNNING, startedAt: new Date() },
|
|
18
|
+
data: { name: 'send-email', status: Statuses.QUEUED },
|
|
131
19
|
});
|
|
132
20
|
|
|
133
|
-
//
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
},
|
|
140
|
-
});
|
|
21
|
+
// Later, react to the current lifecycle phase
|
|
22
|
+
if (Statuses.isActive(job.status)) {
|
|
23
|
+
console.log('Job is running');
|
|
24
|
+
} else if (Statuses.isFailed(job.status)) {
|
|
25
|
+
console.log('Job failed permanently');
|
|
26
|
+
}
|
|
141
27
|
```
|
|
142
28
|
|
|
143
|
-
|
|
29
|
+
## How it works
|
|
144
30
|
|
|
145
|
-
|
|
31
|
+
- **HTTP-inspired numeric prefix.** Each status is a `'NNN_NAME'` string (e.g. `'302_SUCCESS'`). The leading digit groups statuses into six phases.
|
|
32
|
+
- **Group sets for classification.** Every phase has a matching `*_SCHEME_SET` (a `Set<string>`) plus a validator method (`isActive`, `isFailed`, etc.) that just checks set membership.
|
|
33
|
+
- **Specialized classes narrow the catalog.** `MigrationStatuses`, `CommonStatuses`, `UserStatuses`, and `RoleStatuses` each expose a small, named subset of `Statuses` values for a specific use case - they don't invent new status strings.
|
|
34
|
+
- **A separate constant catalog for DI.** `BindingNamespaces` and `CoreBindings` (in the same file area) are unrelated to entity lifecycle - they're the namespace/key strings the container uses for dependency injection.
|
|
146
35
|
|
|
147
|
-
|
|
148
|
-
|----------|-------|-------------|
|
|
149
|
-
| `PARTIAL` | `'300_PARTIAL'` | Partially completed |
|
|
150
|
-
| `APPROVED` | `'301_APPROVED'` | Approved by reviewer |
|
|
151
|
-
| `SUCCESS` | `'302_SUCCESS'` | Successfully completed |
|
|
152
|
-
| `COMPLETED` | `'303_COMPLETED'` | Fully completed |
|
|
153
|
-
| `SETTLED` | `'304_SETTLED'` | Finalized or settled |
|
|
154
|
-
| `CONFIRMED` | `'305_CONFIRMED'` | Confirmed by user or system |
|
|
36
|
+
**The six phases**
|
|
155
37
|
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
38
|
+
| Prefix | Phase | Meaning | Reversibility |
|
|
39
|
+
|--------|-------|---------|----------------|
|
|
40
|
+
| `0xx` | Initial | Entity creation/draft state | N/A |
|
|
41
|
+
| `1xx` | Pending | Awaiting action or decision | Reversible |
|
|
42
|
+
| `2xx` | Active | In progress or running | Reversible |
|
|
43
|
+
| `3xx` | Completed | Positive terminal state | Terminal |
|
|
44
|
+
| `4xx` | Inactive | Negative but reversible | Reversible |
|
|
45
|
+
| `5xx` | Failed | Negative terminal state | Terminal |
|
|
163
46
|
|
|
164
|
-
|
|
165
|
-
await documentRepository.updateById({
|
|
166
|
-
id: docId,
|
|
167
|
-
data: {
|
|
168
|
-
status: Statuses.APPROVED,
|
|
169
|
-
approvedBy: userId,
|
|
170
|
-
approvedAt: new Date(),
|
|
171
|
-
},
|
|
172
|
-
});
|
|
173
|
-
```
|
|
47
|
+
**Specialized classes**
|
|
174
48
|
|
|
175
|
-
|
|
49
|
+
| Class | Scope |
|
|
50
|
+
|-------|-------|
|
|
51
|
+
| `MigrationStatuses` | `UNKNOWN` / `SUCCESS` / `FAIL` - database migration tracking |
|
|
52
|
+
| `CommonStatuses` | `UNKNOWN` / `ACTIVATED` / `DEACTIVATED` / `BLOCKED` / `ARCHIVED` - shared entity states |
|
|
53
|
+
| `UserStatuses` | Extends `CommonStatuses` with no additions - user account states |
|
|
54
|
+
| `RoleStatuses` | Extends `CommonStatuses` with no additions - role lifecycle states |
|
|
176
55
|
|
|
177
|
-
|
|
56
|
+
## Common tasks
|
|
178
57
|
|
|
179
|
-
|
|
180
|
-
|----------|-------|-------------|
|
|
181
|
-
| `DISABLED` | `'400_DISABLED'` | Feature or entity is disabled |
|
|
182
|
-
| `DEACTIVATED` | `'401_DEACTIVATED'` | Account or service is deactivated |
|
|
183
|
-
| `SUSPENDED` | `'402_SUSPENDED'` | Temporarily suspended |
|
|
184
|
-
| `BLOCKED` | `'403_BLOCKED'` | Access blocked (e.g., banned user) |
|
|
185
|
-
| `CLOSED` | `'404_CLOSED'` | Closed but can be reopened |
|
|
186
|
-
| `ARCHIVED` | `'405_ARCHIVED'` | Archived for record keeping |
|
|
187
|
-
| `PAUSED` | `'406_PAUSED'` | Paused, can be resumed |
|
|
188
|
-
| `REVOKED` | `'407_REVOKED'` | Permission or access revoked |
|
|
189
|
-
| `REFUNDED` | `'408_REFUNDED'` | Payment or transaction refunded |
|
|
58
|
+
**Set a status on create or update.** Use the `Statuses` constant, never a raw string literal.
|
|
190
59
|
|
|
191
|
-
**Example Usage:**
|
|
192
60
|
```typescript
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
data: { status: Statuses.SUSPENDED },
|
|
197
|
-
});
|
|
198
|
-
|
|
199
|
-
// Feature flags
|
|
200
|
-
await featureRepository.updateById({
|
|
201
|
-
id: featureId,
|
|
202
|
-
data: { status: Statuses.DISABLED },
|
|
61
|
+
await orderRepository.updateById({
|
|
62
|
+
id: orderId,
|
|
63
|
+
data: { status: Statuses.PROCESSING },
|
|
203
64
|
});
|
|
204
65
|
```
|
|
205
66
|
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
Negative terminal states indicating permanent failure or cancellation.
|
|
209
|
-
|
|
210
|
-
| Constant | Value | Description |
|
|
211
|
-
|----------|-------|-------------|
|
|
212
|
-
| `FAIL` | `'500_FAIL'` | General failure |
|
|
213
|
-
| `EXPIRED` | `'501_EXPIRED'` | Expired and no longer valid |
|
|
214
|
-
| `TIMEOUT` | `'502_TIMEOUT'` | Operation timed out |
|
|
215
|
-
| `SKIPPED` | `'503_SKIPPED'` | Intentionally skipped |
|
|
216
|
-
| `ABORTED` | `'504_ABORTED'` | Aborted by system |
|
|
217
|
-
| `CANCELLED` | `'505_CANCELLED'` | Cancelled by user/admin |
|
|
218
|
-
| `DELETED` | `'506_DELETED'` | Soft deleted |
|
|
219
|
-
| `REJECTED` | `'507_REJECTED'` | Rejected by reviewer |
|
|
67
|
+
**Check whether a status belongs to a phase.** Each phase has an `is*` helper.
|
|
220
68
|
|
|
221
|
-
**Example Usage:**
|
|
222
69
|
```typescript
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
id: jobId,
|
|
226
|
-
data: { status: Statuses.FAIL, error: 'Connection timeout', failedAt: new Date() },
|
|
227
|
-
});
|
|
228
|
-
|
|
229
|
-
// Soft delete
|
|
230
|
-
await productRepository.updateById({
|
|
231
|
-
id: productId,
|
|
232
|
-
data: { status: Statuses.DELETED, deletedAt: new Date(), deletedBy: userId },
|
|
233
|
-
});
|
|
234
|
-
```
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
## Status Groups
|
|
238
|
-
|
|
239
|
-
The `Statuses` class provides static `Set` instances for grouping related statuses.
|
|
240
|
-
|
|
241
|
-
### Available Groups
|
|
242
|
-
|
|
243
|
-
| Group | Set Name | Included Statuses |
|
|
244
|
-
|-------|----------|-------------------|
|
|
245
|
-
| Initial | `INITIAL_SCHEME_SET` | `UNKNOWN`, `DRAFT` |
|
|
246
|
-
| Pending | `PENDING_SCHEME_SET` | `NEW`, `QUEUED`, `SCHEDULED`, `PENDING`, `IN_REVIEW` |
|
|
247
|
-
| Active | `ACTIVE_SCHEME_SET` | `ENABLED`, `ACTIVATED`, `RUNNING`, `PROCESSING`, `SENT`, `RECEIVED` |
|
|
248
|
-
| Completed | `COMPLETED_SCHEME_SET` | `PARTIAL`, `APPROVED`, `SUCCESS`, `COMPLETED`, `SETTLED`, `CONFIRMED` |
|
|
249
|
-
| Inactive | `INACTIVE_SCHEME_SET` | `DISABLED`, `DEACTIVATED`, `SUSPENDED`, `BLOCKED`, `CLOSED`, `ARCHIVED`, `PAUSED`, `REVOKED`, `REFUNDED` |
|
|
250
|
-
| Failed | `FAILED_SCHEME_SET` | `FAIL`, `EXPIRED`, `TIMEOUT`, `SKIPPED`, `ABORTED`, `CANCELLED`, `DELETED`, `REJECTED` |
|
|
251
|
-
| All | `SCHEME_SET` | All statuses combined |
|
|
252
|
-
|
|
253
|
-
### Usage
|
|
254
|
-
|
|
255
|
-
```typescript
|
|
256
|
-
import { Statuses } from '@venizia/ignis';
|
|
257
|
-
|
|
258
|
-
// Check if status is in a group
|
|
259
|
-
if (Statuses.ACTIVE_SCHEME_SET.has(order.status)) {
|
|
260
|
-
console.log('Order is being processed');
|
|
70
|
+
if (Statuses.isCompleted(order.status) || Statuses.isFailed(order.status)) {
|
|
71
|
+
throw getError({ message: 'Cannot modify a terminal order' });
|
|
261
72
|
}
|
|
262
|
-
|
|
263
|
-
// Filter active jobs
|
|
264
|
-
const activeJobs = jobs.filter(job =>
|
|
265
|
-
Statuses.ACTIVE_SCHEME_SET.has(job.status)
|
|
266
|
-
);
|
|
267
|
-
|
|
268
|
-
// Check if operation can proceed
|
|
269
|
-
const canRetry = !Statuses.FAILED_SCHEME_SET.has(task.status);
|
|
270
73
|
```
|
|
271
74
|
|
|
272
|
-
|
|
273
|
-
## Validation Methods
|
|
274
|
-
|
|
275
|
-
The `Statuses` class provides helper methods for checking status categories.
|
|
276
|
-
|
|
277
|
-
### Available Methods
|
|
278
|
-
|
|
279
|
-
| Method | Parameters | Returns | Description |
|
|
280
|
-
|--------|------------|---------|-------------|
|
|
281
|
-
| `isInitial(status)` | `status: string` | `boolean` | Check if status is in initial group |
|
|
282
|
-
| `isPending(status)` | `status: string` | `boolean` | Check if status is in pending group |
|
|
283
|
-
| `isActive(status)` | `status: string` | `boolean` | Check if status is in active group |
|
|
284
|
-
| `isCompleted(status)` | `status: string` | `boolean` | Check if status is in completed group |
|
|
285
|
-
| `isInactive(status)` | `status: string` | `boolean` | Check if status is in inactive group |
|
|
286
|
-
| `isFailed(status)` | `status: string` | `boolean` | Check if status is in failed group |
|
|
287
|
-
| `isValid(status)` | `status: string` | `boolean` | Check if status is a valid status code |
|
|
288
|
-
|
|
289
|
-
### Examples
|
|
75
|
+
**Filter a query by phase.** Spread a `*_SCHEME_SET` into an `inq` operator.
|
|
290
76
|
|
|
291
77
|
```typescript
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
if (Statuses.isActive(user.status)) {
|
|
296
|
-
// User can log in
|
|
297
|
-
await processLogin(user);
|
|
298
|
-
} else if (Statuses.isInactive(user.status)) {
|
|
299
|
-
throw new Error('Account is inactive. Please contact support.');
|
|
300
|
-
} else if (Statuses.isFailed(user.status)) {
|
|
301
|
-
throw new Error('Account has been permanently closed.');
|
|
302
|
-
}
|
|
303
|
-
|
|
304
|
-
// Validation
|
|
305
|
-
function validateStatusTransition(from: string, to: string) {
|
|
306
|
-
if (!Statuses.isValid(to)) {
|
|
307
|
-
throw new Error(`Invalid status: ${to}`);
|
|
308
|
-
}
|
|
309
|
-
|
|
310
|
-
// Don't allow transitions from terminal states
|
|
311
|
-
if (Statuses.isCompleted(from) || Statuses.isFailed(from)) {
|
|
312
|
-
throw new Error('Cannot transition from terminal state');
|
|
313
|
-
}
|
|
314
|
-
|
|
315
|
-
return true;
|
|
316
|
-
}
|
|
317
|
-
|
|
318
|
-
// Filter entities
|
|
319
|
-
const activeUsers = users.filter(user => Statuses.isActive(user.status));
|
|
320
|
-
const pendingOrders = orders.filter(order => Statuses.isPending(order.status));
|
|
78
|
+
const retryableJobs = await jobRepository.find({
|
|
79
|
+
filter: { where: { status: { inq: [...Statuses.FAILED_SCHEME_SET] } } },
|
|
80
|
+
});
|
|
321
81
|
```
|
|
322
82
|
|
|
323
|
-
|
|
324
|
-
## Specialized Status Classes
|
|
325
|
-
|
|
326
|
-
### MigrationStatuses
|
|
327
|
-
|
|
328
|
-
Simplified statuses for database migration tracking. References values from `Statuses`.
|
|
83
|
+
**Validate an incoming status string.** `isValid` guards against typos before a write.
|
|
329
84
|
|
|
330
85
|
```typescript
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
class MigrationStatuses {
|
|
334
|
-
static readonly UNKNOWN = '000_UNKNOWN'; // = Statuses.UNKNOWN
|
|
335
|
-
static readonly SUCCESS = '302_SUCCESS'; // = Statuses.SUCCESS
|
|
336
|
-
static readonly FAIL = '500_FAIL'; // = Statuses.FAIL
|
|
337
|
-
|
|
338
|
-
static readonly SCHEME_SET = new Set([
|
|
339
|
-
this.UNKNOWN,
|
|
340
|
-
this.SUCCESS,
|
|
341
|
-
this.FAIL,
|
|
342
|
-
]);
|
|
343
|
-
|
|
344
|
-
static isValid(scheme: string): boolean;
|
|
86
|
+
if (!Statuses.isValid(newStatus)) {
|
|
87
|
+
throw getError({ message: `Invalid status: ${newStatus}` });
|
|
345
88
|
}
|
|
346
89
|
```
|
|
347
90
|
|
|
348
|
-
**
|
|
349
|
-
```typescript
|
|
350
|
-
await migrationRepository.create({
|
|
351
|
-
data: {
|
|
352
|
-
version: '20240103_001',
|
|
353
|
-
name: 'add_users_table',
|
|
354
|
-
status: MigrationStatuses.SUCCESS,
|
|
355
|
-
appliedAt: new Date(),
|
|
356
|
-
},
|
|
357
|
-
});
|
|
358
|
-
```
|
|
359
|
-
|
|
360
|
-
### CommonStatuses
|
|
361
|
-
|
|
362
|
-
Common statuses used across multiple entity types. References values from `Statuses`.
|
|
91
|
+
**Use a narrowed catalog for a specific domain.** `CommonStatuses` (and `UserStatuses`/`RoleStatuses`, which extend it) expose only the values relevant to users and roles.
|
|
363
92
|
|
|
364
93
|
```typescript
|
|
365
|
-
import {
|
|
366
|
-
|
|
367
|
-
class CommonStatuses {
|
|
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
|
|
373
|
-
|
|
374
|
-
static readonly SCHEME_SET = new Set([...]);
|
|
375
|
-
static isValid(scheme: string): boolean;
|
|
376
|
-
}
|
|
377
|
-
```
|
|
94
|
+
import { UserStatuses } from '@venizia/ignis';
|
|
378
95
|
|
|
379
|
-
**Usage:**
|
|
380
|
-
```typescript
|
|
381
|
-
// User management
|
|
382
96
|
await userRepository.updateById({
|
|
383
97
|
id: userId,
|
|
384
|
-
data: { status:
|
|
385
|
-
});
|
|
386
|
-
|
|
387
|
-
// Role management
|
|
388
|
-
await roleRepository.updateById({
|
|
389
|
-
id: roleId,
|
|
390
|
-
data: { status: CommonStatuses.ARCHIVED },
|
|
391
|
-
});
|
|
392
|
-
```
|
|
393
|
-
|
|
394
|
-
### UserStatuses & RoleStatuses
|
|
395
|
-
|
|
396
|
-
Both `UserStatuses` and `RoleStatuses` extend `CommonStatuses` directly, inheriting all its statuses and methods.
|
|
397
|
-
|
|
398
|
-
```typescript
|
|
399
|
-
import { UserStatuses, RoleStatuses } from '@venizia/ignis';
|
|
400
|
-
|
|
401
|
-
// UserStatuses extends CommonStatuses
|
|
402
|
-
const user = await userRepository.create({
|
|
403
|
-
data: {
|
|
404
|
-
email: 'user@example.com',
|
|
405
|
-
status: UserStatuses.ACTIVATED,
|
|
406
|
-
},
|
|
407
|
-
});
|
|
408
|
-
|
|
409
|
-
// RoleStatuses extends CommonStatuses
|
|
410
|
-
const role = await roleRepository.create({
|
|
411
|
-
data: {
|
|
412
|
-
name: 'admin',
|
|
413
|
-
status: RoleStatuses.ACTIVATED,
|
|
414
|
-
},
|
|
98
|
+
data: { status: UserStatuses.ACTIVATED },
|
|
415
99
|
});
|
|
416
100
|
```
|
|
417
101
|
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
Classification of user types in the system.
|
|
102
|
+
**Classify a user by type.** `UserTypes` is a separate, unrelated catalog (`SYSTEM` vs `LINKED`), not a status.
|
|
421
103
|
|
|
422
104
|
```typescript
|
|
423
105
|
import { UserTypes } from '@venizia/ignis';
|
|
424
106
|
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
static readonly LINKED = 'LINKED'; // External auth (OAuth, SAML)
|
|
428
|
-
|
|
429
|
-
static readonly SCHEME_SET = new Set([this.SYSTEM, this.LINKED]);
|
|
430
|
-
static isValid(orgType: string): boolean;
|
|
431
|
-
}
|
|
432
|
-
```
|
|
433
|
-
|
|
434
|
-
**Usage:**
|
|
435
|
-
```typescript
|
|
436
|
-
// Create system user
|
|
437
|
-
const systemUser = await userRepository.create({
|
|
438
|
-
data: {
|
|
439
|
-
email: 'system@app.com',
|
|
440
|
-
type: UserTypes.SYSTEM,
|
|
441
|
-
status: UserStatuses.ACTIVATED,
|
|
442
|
-
},
|
|
107
|
+
await userRepository.create({
|
|
108
|
+
data: { email: 'system@app.com', type: UserTypes.SYSTEM, status: UserStatuses.ACTIVATED },
|
|
443
109
|
});
|
|
444
|
-
|
|
445
|
-
// OAuth linked user
|
|
446
|
-
const oauthUser = await userRepository.create({
|
|
447
|
-
data: {
|
|
448
|
-
email: 'user@example.com',
|
|
449
|
-
type: UserTypes.LINKED,
|
|
450
|
-
linkedProvider: 'google',
|
|
451
|
-
status: UserStatuses.ACTIVATED,
|
|
452
|
-
},
|
|
453
|
-
});
|
|
454
|
-
```
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
## Usage Examples
|
|
458
|
-
|
|
459
|
-
### Entity Lifecycle Management
|
|
460
|
-
|
|
461
|
-
```typescript
|
|
462
|
-
import { Statuses } from '@venizia/ignis';
|
|
463
|
-
|
|
464
|
-
class OrderService extends BaseService {
|
|
465
|
-
async createOrder(data: CreateOrderDto) {
|
|
466
|
-
// Start as NEW
|
|
467
|
-
const order = await this.orderRepository.create({
|
|
468
|
-
data: { ...data, status: Statuses.NEW },
|
|
469
|
-
});
|
|
470
|
-
|
|
471
|
-
// Queue for processing
|
|
472
|
-
await this.orderRepository.updateById({
|
|
473
|
-
id: order.data.id,
|
|
474
|
-
data: { status: Statuses.QUEUED },
|
|
475
|
-
});
|
|
476
|
-
|
|
477
|
-
return order;
|
|
478
|
-
}
|
|
479
|
-
|
|
480
|
-
async processOrder(orderId: string) {
|
|
481
|
-
// Mark as processing
|
|
482
|
-
await this.orderRepository.updateById({
|
|
483
|
-
id: orderId,
|
|
484
|
-
data: { status: Statuses.PROCESSING, startedAt: new Date() },
|
|
485
|
-
});
|
|
486
|
-
|
|
487
|
-
try {
|
|
488
|
-
// Process order logic...
|
|
489
|
-
await this.paymentService.charge(order);
|
|
490
|
-
await this.inventoryService.reserve(order.items);
|
|
491
|
-
|
|
492
|
-
// Mark as completed
|
|
493
|
-
await this.orderRepository.updateById({
|
|
494
|
-
id: orderId,
|
|
495
|
-
data: { status: Statuses.COMPLETED, completedAt: new Date() },
|
|
496
|
-
});
|
|
497
|
-
} catch (error) {
|
|
498
|
-
// Mark as failed
|
|
499
|
-
await this.orderRepository.updateById({
|
|
500
|
-
id: orderId,
|
|
501
|
-
data: { status: Statuses.FAIL, error: error.message, failedAt: new Date() },
|
|
502
|
-
});
|
|
503
|
-
|
|
504
|
-
throw error;
|
|
505
|
-
}
|
|
506
|
-
}
|
|
507
|
-
|
|
508
|
-
async cancelOrder(orderId: string) {
|
|
509
|
-
const order = await this.orderRepository.findById({ id: orderId });
|
|
510
|
-
|
|
511
|
-
// Can only cancel pending or active orders
|
|
512
|
-
if (Statuses.isCompleted(order.status) || Statuses.isFailed(order.status)) {
|
|
513
|
-
throw new Error('Cannot cancel completed or failed order');
|
|
514
|
-
}
|
|
515
|
-
|
|
516
|
-
await this.orderRepository.updateById({
|
|
517
|
-
id: orderId,
|
|
518
|
-
data: { status: Statuses.CANCELLED, cancelledAt: new Date() },
|
|
519
|
-
});
|
|
520
|
-
}
|
|
521
|
-
}
|
|
522
110
|
```
|
|
523
111
|
|
|
524
|
-
|
|
112
|
+
## See also
|
|
525
113
|
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
// Get all jobs that can be retried
|
|
531
|
-
async getRetryableJobs() {
|
|
532
|
-
return this.jobRepository.find({
|
|
533
|
-
filter: {
|
|
534
|
-
where: {
|
|
535
|
-
status: { inq: [...Statuses.FAILED_SCHEME_SET] },
|
|
536
|
-
retryCount: { lt: 3 },
|
|
537
|
-
},
|
|
538
|
-
},
|
|
539
|
-
});
|
|
540
|
-
}
|
|
541
|
-
|
|
542
|
-
// Get active jobs count
|
|
543
|
-
async getActiveJobsCount() {
|
|
544
|
-
return this.jobRepository.count({
|
|
545
|
-
where: {
|
|
546
|
-
status: { inq: [...Statuses.ACTIVE_SCHEME_SET] },
|
|
547
|
-
},
|
|
548
|
-
});
|
|
549
|
-
}
|
|
550
|
-
}
|
|
551
|
-
```
|
|
552
|
-
|
|
553
|
-
### Validation & State Transitions
|
|
554
|
-
|
|
555
|
-
```typescript
|
|
556
|
-
import { Statuses } from '@venizia/ignis';
|
|
557
|
-
|
|
558
|
-
class TaskService extends BaseService {
|
|
559
|
-
async updateTaskStatus(taskId: string, newStatus: string) {
|
|
560
|
-
// Validate status
|
|
561
|
-
if (!Statuses.isValid(newStatus)) {
|
|
562
|
-
throw new Error(`Invalid status: ${newStatus}`);
|
|
563
|
-
}
|
|
564
|
-
|
|
565
|
-
const task = await this.taskRepository.findById({ id: taskId });
|
|
566
|
-
|
|
567
|
-
// Validate transition
|
|
568
|
-
this.validateStatusTransition(task.status, newStatus);
|
|
569
|
-
|
|
570
|
-
await this.taskRepository.updateById({
|
|
571
|
-
id: taskId,
|
|
572
|
-
data: { status: newStatus, statusChangedAt: new Date() },
|
|
573
|
-
});
|
|
574
|
-
}
|
|
575
|
-
|
|
576
|
-
private validateStatusTransition(from: string, to: string) {
|
|
577
|
-
// Cannot transition from terminal states
|
|
578
|
-
if (Statuses.isCompleted(from) || Statuses.isFailed(from)) {
|
|
579
|
-
throw new Error('Cannot change status from terminal state');
|
|
580
|
-
}
|
|
581
|
-
|
|
582
|
-
// Can only move to COMPLETED from ACTIVE or PENDING
|
|
583
|
-
if (to === Statuses.COMPLETED) {
|
|
584
|
-
if (!Statuses.isActive(from) && !Statuses.isPending(from)) {
|
|
585
|
-
throw new Error('Can only complete active or pending tasks');
|
|
586
|
-
}
|
|
587
|
-
}
|
|
588
|
-
|
|
589
|
-
// Additional transition rules...
|
|
590
|
-
}
|
|
591
|
-
}
|
|
592
|
-
```
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
## Binding Namespaces
|
|
596
|
-
|
|
597
|
-
The `BindingNamespaces` class organizes dependency injection bindings by type. It uses `createNamespace()` internally to produce namespace strings.
|
|
598
|
-
|
|
599
|
-
**File:** `packages/core/src/common/bindings.ts`
|
|
600
|
-
|
|
601
|
-
### Available Namespaces
|
|
602
|
-
|
|
603
|
-
```typescript
|
|
604
|
-
import { BindingNamespaces } from '@venizia/ignis';
|
|
114
|
+
- [Full reference](/references/utilities/statuses-reference) - every status code, group set, specialized class, and binding constant
|
|
115
|
+
- [Models](/references/base/models) - entity definitions that carry a `status` column
|
|
116
|
+
- [Repositories](/references/base/repositories/) - querying and updating by status
|
|
117
|
+
- [Filter System](/references/base/filter-system/) - `inq`/`nin` operators used with `*_SCHEME_SET`
|
|
605
118
|
|
|
606
|
-
|
|
607
|
-
static readonly COMPONENT = 'components';
|
|
608
|
-
static readonly DATASOURCE = 'datasources';
|
|
609
|
-
static readonly REPOSITORY = 'repositories';
|
|
610
|
-
static readonly MODEL = 'models';
|
|
611
|
-
static readonly SERVICE = 'services';
|
|
612
|
-
static readonly MIDDLEWARE = 'middlewares';
|
|
613
|
-
static readonly PROVIDER = 'providers';
|
|
614
|
-
static readonly CONTROLLER = 'controllers';
|
|
615
|
-
static readonly BOOTERS = 'booters';
|
|
616
|
-
|
|
617
|
-
static createNamespace(opts: { name: string }): string;
|
|
618
|
-
}
|
|
619
|
-
```
|
|
620
|
-
|
|
621
|
-
### CoreBindings
|
|
622
|
-
|
|
623
|
-
Application-level binding keys. Extends `BindingKeys` from the inversion package.
|
|
624
|
-
|
|
625
|
-
```typescript
|
|
626
|
-
import { CoreBindings } from '@venizia/ignis';
|
|
627
|
-
|
|
628
|
-
class CoreBindings {
|
|
629
|
-
static readonly APPLICATION_INSTANCE = '@app/instance';
|
|
630
|
-
static readonly APPLICATION_SERVER = '@app/server';
|
|
631
|
-
static readonly APPLICATION_CONFIG = '@app/config';
|
|
632
|
-
static readonly APPLICATION_PROJECT_ROOT = '@app/project_root';
|
|
633
|
-
static readonly APPLICATION_ROOT_ROUTER = '@app/router/root';
|
|
634
|
-
static readonly APPLICATION_ENVIRONMENTS = '@app/environments';
|
|
635
|
-
static readonly APPLICATION_MIDDLEWARE_OPTIONS = '@app/middleware_options';
|
|
636
|
-
}
|
|
637
|
-
```
|
|
638
|
-
|
|
639
|
-
**Usage:**
|
|
640
|
-
```typescript
|
|
641
|
-
// Access application instance
|
|
642
|
-
const app = container.get(CoreBindings.APPLICATION_INSTANCE);
|
|
643
|
-
|
|
644
|
-
// Access configuration
|
|
645
|
-
const config = container.get(CoreBindings.APPLICATION_CONFIG);
|
|
646
|
-
```
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
## Best Practices
|
|
650
|
-
|
|
651
|
-
### 1. Use Status Constants
|
|
652
|
-
|
|
653
|
-
```typescript
|
|
654
|
-
// Good: Use constants
|
|
655
|
-
order.status = Statuses.COMPLETED;
|
|
656
|
-
|
|
657
|
-
// Bad: Magic strings
|
|
658
|
-
order.status = '303_COMPLETED'; // Prone to typos
|
|
659
|
-
```
|
|
660
|
-
|
|
661
|
-
### 2. Validate Before Updating
|
|
662
|
-
|
|
663
|
-
```typescript
|
|
664
|
-
// Good: Validate transitions
|
|
665
|
-
if (Statuses.isCompleted(order.status)) {
|
|
666
|
-
throw new Error('Cannot modify completed order');
|
|
667
|
-
}
|
|
668
|
-
|
|
669
|
-
// Bad: No validation
|
|
670
|
-
order.status = newStatus; // Could break business rules
|
|
671
|
-
```
|
|
672
|
-
|
|
673
|
-
### 3. Use Helper Methods
|
|
674
|
-
|
|
675
|
-
```typescript
|
|
676
|
-
// Good: Use helper methods
|
|
677
|
-
if (Statuses.isActive(job.status)) {
|
|
678
|
-
// ...
|
|
679
|
-
}
|
|
680
|
-
|
|
681
|
-
// Less readable alternative: Manual set checking
|
|
682
|
-
if (Statuses.ACTIVE_SCHEME_SET.has(job.status)) {
|
|
683
|
-
// ...
|
|
684
|
-
}
|
|
685
|
-
```
|
|
686
|
-
|
|
687
|
-
### 4. Document State Machines
|
|
688
|
-
|
|
689
|
-
```typescript
|
|
690
|
-
/**
|
|
691
|
-
* Order Status Flow:
|
|
692
|
-
* NEW -> QUEUED -> PROCESSING -> COMPLETED
|
|
693
|
-
* \ \ \
|
|
694
|
-
* -> CANCELLED <-----
|
|
695
|
-
*/
|
|
696
|
-
class OrderService {
|
|
697
|
-
// Implementation...
|
|
698
|
-
}
|
|
699
|
-
```
|
|
700
|
-
|
|
701
|
-
### 5. Terminal State Checks
|
|
702
|
-
|
|
703
|
-
```typescript
|
|
704
|
-
// Good: Check for terminal states
|
|
705
|
-
const isTerminal = Statuses.isCompleted(status) || Statuses.isFailed(status);
|
|
706
|
-
|
|
707
|
-
if (isTerminal) {
|
|
708
|
-
throw new Error('Cannot modify entity in terminal state');
|
|
709
|
-
}
|
|
710
|
-
```
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
## See Also
|
|
714
|
-
|
|
715
|
-
- **Related References:**
|
|
716
|
-
- [Models](../base/models.md) - Entity definitions using statuses
|
|
717
|
-
- [Repositories](../base/repositories/) - Querying by status
|
|
718
|
-
- [Services](../base/services.md) - Business logic with status transitions
|
|
719
|
-
|
|
720
|
-
- **Guides:**
|
|
721
|
-
- [Data Modeling](/guides/core-concepts/persistent/models)
|
|
722
|
-
- [Working with Repositories](/guides/core-concepts/persistent/repositories)
|
|
119
|
+
**Files:**
|
|
723
120
|
|
|
724
|
-
-
|
|
725
|
-
|
|
726
|
-
- [Data Modeling Best Practices](/best-practices/data-modeling)
|
|
121
|
+
- [`packages/core/src/common/statuses.ts`](https://github.com/VENIZIA-AI/ignis/blob/main/packages/core/src/common/statuses.ts)
|
|
122
|
+
- [`packages/core/src/common/bindings.ts`](https://github.com/VENIZIA-AI/ignis/blob/main/packages/core/src/common/bindings.ts)
|