@cullet/erp-core 1.0.2 → 1.0.3

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 (144) hide show
  1. package/README.md +24 -24
  2. package/dist/gate-engine-registry.js.map +1 -1
  3. package/dist/gate-v1-payload.schema.js.map +1 -1
  4. package/dist/index.d.ts +2 -2
  5. package/dist/index.js +1 -1
  6. package/dist/index.js.map +1 -1
  7. package/dist/outcome.js.map +1 -1
  8. package/dist/policies/engines/v1/gate/index.js.map +1 -1
  9. package/dist/policy-service.js.map +1 -1
  10. package/dist/validation-code.js.map +1 -1
  11. package/dist/validation-error.js.map +1 -1
  12. package/dist/validation-field.js.map +1 -1
  13. package/meta.json +67 -67
  14. package/package.json +56 -56
  15. package/src/core/application/commands/command.ts +3 -3
  16. package/src/core/application/commands/requested-by.ts +60 -60
  17. package/src/core/application/index.ts +21 -21
  18. package/src/core/application/policy-error-mapper.ts +54 -54
  19. package/src/core/application/ports/index.ts +6 -6
  20. package/src/core/application/ports/logger.port.ts +4 -4
  21. package/src/core/application/ports/metrics.port.ts +3 -3
  22. package/src/core/application/ports/policy-port.ts +7 -7
  23. package/src/core/application/ports/repository.port.ts +3 -3
  24. package/src/core/application/ports/temporal-repository.port.ts +4 -4
  25. package/src/core/application/ports/tracer.port.ts +7 -7
  26. package/src/core/application/queries/query.ts +13 -13
  27. package/src/core/application/temporal/index.ts +7 -7
  28. package/src/core/application/temporal/temporal-context.ts +20 -20
  29. package/src/core/application/temporal/temporal-use-case.ts +22 -22
  30. package/src/core/application/use-case.ts +10 -10
  31. package/src/core/config/core-config.instance.ts +1 -1
  32. package/src/core/config/core-config.ts +59 -59
  33. package/src/core/config/index.ts +6 -6
  34. package/src/core/config/policy-reporter.ts +31 -31
  35. package/src/core/config/silent-policy-reporter.ts +1 -1
  36. package/src/core/domain/entity.ts +44 -44
  37. package/src/core/domain/rulesets/entity-ruleset.contracts.ts +6 -6
  38. package/src/core/domain/rulesets/ruleset-registry.ts +49 -49
  39. package/src/core/domain/rulesets/ruleset.contracts.ts +6 -6
  40. package/src/core/domain/rulesets/value-object-ruleset.contracts.ts +5 -5
  41. package/src/core/domain/temporal/index.ts +11 -11
  42. package/src/core/domain/temporal/temporal-range.ts +16 -16
  43. package/src/core/domain/temporal/temporal-snapshot.ts +24 -24
  44. package/src/core/domain/temporal/transaction-time.ts +30 -30
  45. package/src/core/domain/temporal/valid-time.ts +29 -29
  46. package/src/core/domain/value-object.ts +16 -16
  47. package/src/core/errors/app-error.ts +64 -64
  48. package/src/core/errors/authentication-error.ts +134 -134
  49. package/src/core/errors/authorization-error.ts +154 -154
  50. package/src/core/errors/business-rule-violation-error.ts +15 -15
  51. package/src/core/errors/conflict-error.ts +202 -201
  52. package/src/core/errors/error-codes.ts +48 -48
  53. package/src/core/errors/idempotency-error.ts +324 -320
  54. package/src/core/errors/index.ts +50 -50
  55. package/src/core/errors/integration-error.ts +120 -120
  56. package/src/core/errors/legacy-incompatible-error.ts +13 -13
  57. package/src/core/errors/not-found-error.ts +14 -14
  58. package/src/core/errors/serialization-error.ts +167 -167
  59. package/src/core/errors/temporal-error.ts +109 -107
  60. package/src/core/errors/types.ts +35 -35
  61. package/src/core/errors/unexpected-error.ts +10 -10
  62. package/src/core/errors/utils/index.ts +2 -2
  63. package/src/core/errors/utils/json-safe.ts +53 -53
  64. package/src/core/errors/validation-error.ts +18 -18
  65. package/src/core/exceptions/business-rule-violation-exception.ts +6 -6
  66. package/src/core/exceptions/domain-exception.ts +5 -5
  67. package/src/core/exceptions/entity-not-found-exception.ts +6 -6
  68. package/src/core/exceptions/invalid-state-transition-exception.ts +8 -8
  69. package/src/core/exceptions/invariant-violation-exception.ts +3 -3
  70. package/src/core/exceptions/validation-code.ts +35 -29
  71. package/src/core/exceptions/validation-exception.ts +19 -19
  72. package/src/core/exceptions/validation-field.ts +20 -19
  73. package/src/core/index.ts +7 -7
  74. package/src/core/policies/asof/asof.ts +47 -47
  75. package/src/core/policies/catalog/catalog.instance.ts +8 -6
  76. package/src/core/policies/catalog/index.ts +4 -4
  77. package/src/core/policies/catalog/policy-catalog-entry.ts +199 -197
  78. package/src/core/policies/catalog/policy-catalog.ts +101 -101
  79. package/src/core/policies/catalog/policy-key.ts +51 -51
  80. package/src/core/policies/context/context-builder.ts +335 -313
  81. package/src/core/policies/context/context-registry.instance.ts +9 -9
  82. package/src/core/policies/context/context-registry.ts +61 -61
  83. package/src/core/policies/context/context-resolver.ts +12 -12
  84. package/src/core/policies/context/context-seed.ts +19 -15
  85. package/src/core/policies/context/index.ts +9 -9
  86. package/src/core/policies/context/path.ts +135 -128
  87. package/src/core/policies/defs/in-memory-policy-definition-repo.ts +56 -55
  88. package/src/core/policies/defs/index.ts +10 -10
  89. package/src/core/policies/defs/policy-definition-repository.ts +3 -3
  90. package/src/core/policies/defs/policy-definition.ts +143 -142
  91. package/src/core/policies/defs/policy-scope.ts +21 -19
  92. package/src/core/policies/defs/policy-semver.ts +51 -51
  93. package/src/core/policies/engines/compute-engine-registry.ts +43 -43
  94. package/src/core/policies/engines/compute-evaluator-registry.ts +20 -20
  95. package/src/core/policies/engines/compute-registry.ts +45 -45
  96. package/src/core/policies/engines/compute-types.ts +15 -15
  97. package/src/core/policies/engines/condition-evaluator-reporter.ts +17 -17
  98. package/src/core/policies/engines/gate-engine-registry.ts +27 -25
  99. package/src/core/policies/engines/gate-types.ts +28 -28
  100. package/src/core/policies/engines/index.ts +28 -28
  101. package/src/core/policies/engines/parse-compute-payload.ts +51 -45
  102. package/src/core/policies/engines/parse-gate-payload.ts +42 -42
  103. package/src/core/policies/engines/v1/compute/compute-engine-v1.ts +39 -37
  104. package/src/core/policies/engines/v1/compute/compute-payload.schema.ts +43 -41
  105. package/src/core/policies/engines/v1/compute/index.ts +6 -6
  106. package/src/core/policies/engines/v1/compute/resolve-decision-table-v1.ts +41 -39
  107. package/src/core/policies/engines/v1/condition-evaluator.ts +547 -505
  108. package/src/core/policies/engines/v1/condition-schema.ts +35 -35
  109. package/src/core/policies/engines/v1/condition-types.ts +21 -21
  110. package/src/core/policies/engines/v1/gate/gate-engine-v1.ts +134 -130
  111. package/src/core/policies/engines/v1/gate/gate-types-v1.ts +5 -5
  112. package/src/core/policies/engines/v1/gate/gate-v1-payload.schema.ts +32 -30
  113. package/src/core/policies/engines/v1/gate/index.ts +4 -4
  114. package/src/core/policies/engines/v1/index.ts +8 -8
  115. package/src/core/policies/index.ts +72 -72
  116. package/src/core/policies/package/policy-package.ts +3 -3
  117. package/src/core/policies/policy-ids.ts +25 -25
  118. package/src/core/policies/resolver/policy-resolver.ts +34 -34
  119. package/src/core/policies/service/index.ts +6 -6
  120. package/src/core/policies/service/policy-evaluation-error.ts +141 -133
  121. package/src/core/policies/service/policy-service.ts +432 -419
  122. package/src/core/policies/utils/date.ts +3 -3
  123. package/src/core/policies/utils/hash.ts +61 -61
  124. package/src/core/result/outcome.ts +131 -126
  125. package/src/core/result/result.ts +130 -127
  126. package/src/core/shared/aggregate-version.ts +5 -5
  127. package/src/core/shared/hashing.ts +18 -18
  128. package/src/core/shared/immutable.ts +29 -29
  129. package/src/core/shared/temporal-guards.ts +9 -9
  130. package/src/core/versioning/domain-event-contracts.ts +40 -40
  131. package/src/core/versioning/version.ts +19 -19
  132. package/src/examples/rulesets/entity/order-creation-rules-v1.ts +18 -18
  133. package/src/examples/rulesets/entity/order-invariants-v1.ts +31 -29
  134. package/src/examples/rulesets/entity/order-invariants-v2.ts +12 -12
  135. package/src/examples/rulesets/entity/order.ts +127 -127
  136. package/src/examples/rulesets/value-object/cpf-rules-v1.ts +41 -39
  137. package/src/examples/rulesets/value-object/cpf-rules-v2.ts +14 -12
  138. package/src/examples/rulesets/value-object/cpf.ts +24 -24
  139. package/src/examples/rulesets/value-object/customer.ts +42 -39
  140. package/src/examples/rulesets/value-object/person-name-rules-v1.ts +27 -27
  141. package/src/examples/rulesets/value-object/person-name-rules-v2.ts +13 -13
  142. package/src/examples/rulesets/value-object/person-name.ts +29 -26
  143. package/src/index.ts +2 -2
  144. package/src/version.ts +1 -1
@@ -13,9 +13,9 @@ type ErrorSeverity = "low" | "medium" | "high" | "critical";
13
13
  type JsonSafePrimitive = string | number | boolean | null;
14
14
 
15
15
  type JsonSafeValue =
16
- | JsonSafePrimitive
17
- | JsonSafeValue[]
18
- | { [key: string]: JsonSafeValue };
16
+ | JsonSafePrimitive
17
+ | JsonSafeValue[]
18
+ | { [key: string]: JsonSafeValue };
19
19
 
20
20
  type JsonSafeRecord = Record<string, JsonSafeValue>;
21
21
 
@@ -28,47 +28,47 @@ type JsonSafeRecord = Record<string, JsonSafeValue>;
28
28
  * Subclasses can extend or pick from this type.
29
29
  */
30
30
  type AppErrorOptions = {
31
- /** Original error or exception that caused this error. */
32
- cause?: unknown;
31
+ /** Original error or exception that caused this error. */
32
+ cause?: unknown;
33
33
 
34
- /** Arbitrary key-value metadata (will be sanitized to JSON-safe values). */
35
- metadata?: Record<string, unknown>;
34
+ /** Arbitrary key-value metadata (will be sanitized to JSON-safe values). */
35
+ metadata?: Record<string, unknown>;
36
36
 
37
- /** Error category/type for grouping (e.g., "authentication", "validation"). */
38
- type?: string;
37
+ /** Error category/type for grouping (e.g., "authentication", "validation"). */
38
+ type?: string;
39
39
 
40
- /** severity level for alerting/logging prioritization. */
41
- severity?: ErrorSeverity;
40
+ /** severity level for alerting/logging prioritization. */
41
+ severity?: ErrorSeverity;
42
42
 
43
- /**
44
- * Identifies a single execution "story" in the system. All operations
45
- * related to the same logical flow must share the same correlationId.
46
- */
47
- correlationId?: string;
43
+ /**
44
+ * Identifies a single execution "story" in the system. All operations
45
+ * related to the same logical flow must share the same correlationId.
46
+ */
47
+ correlationId?: string;
48
48
 
49
- /**
50
- * Identifies a specific technical request attempt (each retry may produce
51
- * a new requestId), even when the correlationId stays the same.
52
- */
53
- requestId?: string;
49
+ /**
50
+ * Identifies a specific technical request attempt (each retry may produce
51
+ * a new requestId), even when the correlationId stays the same.
52
+ */
53
+ requestId?: string;
54
54
 
55
- /**
56
- * Identifies a unique business intent (idempotency key); stays the same
57
- * across technical retries and multiple requests that represent the same intent.
58
- */
59
- commandId?: string;
55
+ /**
56
+ * Identifies a unique business intent (idempotency key); stays the same
57
+ * across technical retries and multiple requests that represent the same intent.
58
+ */
59
+ commandId?: string;
60
60
 
61
- /** ISO timestamp of when the error was created (defaults to now). */
62
- createdAtIso?: string;
61
+ /** ISO timestamp of when the error was created (defaults to now). */
62
+ createdAtIso?: string;
63
63
 
64
- /** Safe message that can be exposed to end users (no internal details). */
65
- publicMessage?: string;
64
+ /** Safe message that can be exposed to end users (no internal details). */
65
+ publicMessage?: string;
66
66
  };
67
67
 
68
68
  export type {
69
- AppErrorOptions,
70
- ErrorSeverity,
71
- JsonSafePrimitive,
72
- JsonSafeRecord,
73
- JsonSafeValue,
69
+ AppErrorOptions,
70
+ ErrorSeverity,
71
+ JsonSafePrimitive,
72
+ JsonSafeRecord,
73
+ JsonSafeValue,
74
74
  };
@@ -7,16 +7,16 @@ import type { AppErrorOptions } from "./types";
7
7
  // ─────────────────────────────────────────────────────────────────────────────
8
8
 
9
9
  class UnexpectedError extends AppError {
10
- constructor(
11
- message = "Unexpected error",
12
- cause?: unknown,
13
- options?: Omit<AppErrorOptions, "cause">,
14
- ) {
15
- super(message, ErrorCodes.unexpected, {
16
- cause,
17
- ...options,
18
- });
19
- }
10
+ constructor(
11
+ message = "Unexpected error",
12
+ cause?: unknown,
13
+ options?: Omit<AppErrorOptions, "cause">,
14
+ ) {
15
+ super(message, ErrorCodes.unexpected, {
16
+ cause,
17
+ ...options,
18
+ });
19
+ }
20
20
  }
21
21
 
22
22
  export { UnexpectedError };
@@ -1,4 +1,4 @@
1
1
  export {
2
- assertJsonSafeMetadata,
3
- NON_SERIALIZABLE_PLACEHOLDER,
2
+ assertJsonSafeMetadata,
3
+ NON_SERIALIZABLE_PLACEHOLDER,
4
4
  } from "./json-safe";
@@ -13,53 +13,53 @@ const NON_SERIALIZABLE_PLACEHOLDER = "[NonSerializable]";
13
13
  // ─────────────────────────────────────────────────────────────────────────────
14
14
 
15
15
  function isPlainObject(value: unknown): value is Record<string, unknown> {
16
- if (value === null || typeof value !== "object") return false;
17
- const proto = Object.getPrototypeOf(value);
18
- return proto === Object.prototype || proto === null;
16
+ if (value === null || typeof value !== "object") return false;
17
+ const proto = Object.getPrototypeOf(value);
18
+ return proto === Object.prototype || proto === null;
19
19
  }
20
20
 
21
21
  function sanitizeValue(value: unknown): JsonSafeValue {
22
- // Null passthrough
23
- if (value === null) return null;
24
-
25
- const type = typeof value;
26
-
27
- // Primitives
28
- if (type === "string" || type === "number" || type === "boolean") {
29
- return value as JsonSafeValue;
30
- }
31
-
32
- // Non-serializable primitives
33
- if (
34
- type === "bigint" ||
35
- type === "function" ||
36
- type === "symbol" ||
37
- value === undefined
38
- ) {
39
- return NON_SERIALIZABLE_PLACEHOLDER;
40
- }
41
-
42
- // Arrays (recursive)
43
- if (Array.isArray(value)) {
44
- return value.map(sanitizeValue);
45
- }
46
-
47
- // Date → placeholder (could also use .toISOString() if preferred)
48
- if (value instanceof Date) {
49
- return NON_SERIALIZABLE_PLACEHOLDER;
50
- }
51
-
52
- // Class instances and non-plain objects → placeholder
53
- if (!isPlainObject(value)) {
54
- return NON_SERIALIZABLE_PLACEHOLDER;
55
- }
56
-
57
- // Plain object (recursive)
58
- const result: Record<string, JsonSafeValue> = {};
59
- for (const [key, val] of Object.entries(value)) {
60
- result[key] = sanitizeValue(val);
61
- }
62
- return result;
22
+ // Null passthrough
23
+ if (value === null) return null;
24
+
25
+ const type = typeof value;
26
+
27
+ // Primitives
28
+ if (type === "string" || type === "number" || type === "boolean") {
29
+ return value as JsonSafeValue;
30
+ }
31
+
32
+ // Non-serializable primitives
33
+ if (
34
+ type === "bigint" ||
35
+ type === "function" ||
36
+ type === "symbol" ||
37
+ value === undefined
38
+ ) {
39
+ return NON_SERIALIZABLE_PLACEHOLDER;
40
+ }
41
+
42
+ // Arrays (recursive)
43
+ if (Array.isArray(value)) {
44
+ return value.map(sanitizeValue);
45
+ }
46
+
47
+ // Date → placeholder (could also use .toISOString() if preferred)
48
+ if (value instanceof Date) {
49
+ return NON_SERIALIZABLE_PLACEHOLDER;
50
+ }
51
+
52
+ // Class instances and non-plain objects → placeholder
53
+ if (!isPlainObject(value)) {
54
+ return NON_SERIALIZABLE_PLACEHOLDER;
55
+ }
56
+
57
+ // Plain object (recursive)
58
+ const result: Record<string, JsonSafeValue> = {};
59
+ for (const [key, val] of Object.entries(value)) {
60
+ result[key] = sanitizeValue(val);
61
+ }
62
+ return result;
63
63
  }
64
64
 
65
65
  // ─────────────────────────────────────────────────────────────────────────────
@@ -77,17 +77,17 @@ function sanitizeValue(value: unknown): JsonSafeValue {
77
77
  * @throws {TypeError} If `input` is not a plain object at the root level.
78
78
  */
79
79
  function assertJsonSafeMetadata(input: unknown): JsonSafeRecord {
80
- if (input === undefined) {
81
- return {};
82
- }
80
+ if (input === undefined) {
81
+ return {};
82
+ }
83
83
 
84
- if (!isPlainObject(input)) {
85
- throw new TypeError(
86
- "metadata must be a plain object (Record<string, unknown>).",
87
- );
88
- }
84
+ if (!isPlainObject(input)) {
85
+ throw new TypeError(
86
+ "metadata must be a plain object (Record<string, unknown>).",
87
+ );
88
+ }
89
89
 
90
- return sanitizeValue(input) as JsonSafeRecord;
90
+ return sanitizeValue(input) as JsonSafeRecord;
91
91
  }
92
92
 
93
93
  export { assertJsonSafeMetadata, NON_SERIALIZABLE_PLACEHOLDER };
@@ -10,25 +10,25 @@ import type { AppErrorOptions } from "./types";
10
10
  // ─────────────────────────────────────────────────────────────────────────────
11
11
 
12
12
  class ValidationError extends AppError {
13
- constructor(
14
- field: ValidationField,
15
- code: ValidationCode,
16
- message: string,
17
- options?: AppErrorOptions,
18
- ) {
19
- const baseMetadata = {
20
- field: field.value,
21
- validationCode: code.value,
22
- };
23
- const mergedMetadata = options?.metadata
24
- ? { ...baseMetadata, ...options.metadata }
25
- : baseMetadata;
13
+ constructor(
14
+ field: ValidationField,
15
+ code: ValidationCode,
16
+ message: string,
17
+ options?: AppErrorOptions,
18
+ ) {
19
+ const baseMetadata = {
20
+ field: field.value,
21
+ validationCode: code.value,
22
+ };
23
+ const mergedMetadata = options?.metadata
24
+ ? { ...baseMetadata, ...options.metadata }
25
+ : baseMetadata;
26
26
 
27
- super(message, ErrorCodes.validation, {
28
- ...options,
29
- metadata: mergedMetadata,
30
- });
31
- }
27
+ super(message, ErrorCodes.validation, {
28
+ ...options,
29
+ metadata: mergedMetadata,
30
+ });
31
+ }
32
32
  }
33
33
 
34
34
  export { ValidationError };
@@ -1,12 +1,12 @@
1
1
  import { DomainException } from "./domain-exception";
2
2
 
3
3
  class BusinessRuleViolationException extends DomainException {
4
- constructor(
5
- public readonly rule: string,
6
- message: string,
7
- ) {
8
- super(message);
9
- }
4
+ constructor(
5
+ public readonly rule: string,
6
+ message: string,
7
+ ) {
8
+ super(message);
9
+ }
10
10
  }
11
11
 
12
12
  export { BusinessRuleViolationException };
@@ -1,9 +1,9 @@
1
1
  abstract class DomainException extends Error {
2
- constructor(message: string) {
3
- super(message);
4
- Object.setPrototypeOf(this, new.target.prototype);
5
- this.name = new.target.name;
6
- }
2
+ constructor(message: string) {
3
+ super(message);
4
+ Object.setPrototypeOf(this, new.target.prototype);
5
+ this.name = new.target.name;
6
+ }
7
7
  }
8
8
 
9
9
  export { DomainException };
@@ -1,12 +1,12 @@
1
1
  import { DomainException } from "./domain-exception";
2
2
 
3
3
  class EntityNotFoundException extends DomainException {
4
- constructor(
5
- public readonly entityName: string,
6
- public readonly identifier: string,
7
- ) {
8
- super(`${entityName} with identifier ${identifier} was not found.`);
9
- }
4
+ constructor(
5
+ public readonly entityName: string,
6
+ public readonly identifier: string,
7
+ ) {
8
+ super(`${entityName} with identifier ${identifier} was not found.`);
9
+ }
10
10
  }
11
11
 
12
12
  export { EntityNotFoundException };
@@ -1,15 +1,15 @@
1
1
  import { DomainException } from "./domain-exception";
2
2
 
3
3
  class InvalidStateTransitionException<
4
- TState extends string = string,
4
+ TState extends string = string,
5
5
  > extends DomainException {
6
- constructor(
7
- public readonly from: TState,
8
- public readonly to: TState,
9
- message: string,
10
- ) {
11
- super(message);
12
- }
6
+ constructor(
7
+ public readonly from: TState,
8
+ public readonly to: TState,
9
+ message: string,
10
+ ) {
11
+ super(message);
12
+ }
13
13
  }
14
14
 
15
15
  export { InvalidStateTransitionException };
@@ -1,9 +1,9 @@
1
1
  import { DomainException } from "./domain-exception";
2
2
 
3
3
  class InvariantViolationException extends DomainException {
4
- constructor(message: string) {
5
- super(message);
6
- }
4
+ constructor(message: string) {
5
+ super(message);
6
+ }
7
7
  }
8
8
 
9
9
  export { InvariantViolationException };
@@ -2,38 +2,44 @@
2
2
  // Provides common reusable codes while allowing custom codes via `of`.
3
3
 
4
4
  class ValidationCode {
5
- public readonly value: string;
5
+ public readonly value: string;
6
6
 
7
- private constructor(value: string) {
8
- this.value = value;
9
- }
7
+ private constructor(value: string) {
8
+ this.value = value;
9
+ }
10
10
 
11
- // Factory for custom codes
12
- public static of(value: string): ValidationCode {
13
- return new ValidationCode(value);
14
- }
11
+ // Factory for custom codes
12
+ public static of(value: string): ValidationCode {
13
+ return new ValidationCode(value);
14
+ }
15
15
 
16
- // Common, domain-friendly codes
17
- public static readonly BLANK = new ValidationCode("blank");
18
- public static readonly REQUIRED = new ValidationCode("required");
19
- public static readonly INVALID_FORMAT = new ValidationCode("invalid_format");
20
- public static readonly INVALID_CHARACTERS = new ValidationCode(
21
- "invalid_characters",
22
- );
23
- public static readonly INVALID_LENGTH = new ValidationCode("invalid_length");
24
- public static readonly TOO_SHORT = new ValidationCode("too_short");
25
- public static readonly TOO_LONG = new ValidationCode("too_long");
26
- public static readonly OUT_OF_RANGE = new ValidationCode("out_of_range");
27
- public static readonly INVALID_CHECKSUM = new ValidationCode(
28
- "invalid_checksum",
29
- );
30
- public static readonly INVALID_CHECKING_DIGIT = new ValidationCode(
31
- "invalid_checking_digit",
32
- );
33
- public static readonly ALREADY_EXISTS = new ValidationCode("already_exists");
34
- public static readonly NOT_FOUND = new ValidationCode("not_found");
35
- public static readonly NOT_ALLOWED = new ValidationCode("not_allowed");
36
- public static readonly UNEXPECTED = new ValidationCode("unexpected");
16
+ // Common, domain-friendly codes
17
+ public static readonly BLANK = new ValidationCode("blank");
18
+ public static readonly REQUIRED = new ValidationCode("required");
19
+ public static readonly INVALID_FORMAT = new ValidationCode(
20
+ "invalid_format",
21
+ );
22
+ public static readonly INVALID_CHARACTERS = new ValidationCode(
23
+ "invalid_characters",
24
+ );
25
+ public static readonly INVALID_LENGTH = new ValidationCode(
26
+ "invalid_length",
27
+ );
28
+ public static readonly TOO_SHORT = new ValidationCode("too_short");
29
+ public static readonly TOO_LONG = new ValidationCode("too_long");
30
+ public static readonly OUT_OF_RANGE = new ValidationCode("out_of_range");
31
+ public static readonly INVALID_CHECKSUM = new ValidationCode(
32
+ "invalid_checksum",
33
+ );
34
+ public static readonly INVALID_CHECKING_DIGIT = new ValidationCode(
35
+ "invalid_checking_digit",
36
+ );
37
+ public static readonly ALREADY_EXISTS = new ValidationCode(
38
+ "already_exists",
39
+ );
40
+ public static readonly NOT_FOUND = new ValidationCode("not_found");
41
+ public static readonly NOT_ALLOWED = new ValidationCode("not_allowed");
42
+ public static readonly UNEXPECTED = new ValidationCode("unexpected");
37
43
  }
38
44
 
39
45
  export { ValidationCode };
@@ -3,37 +3,37 @@ import { ValidationCode } from "./validation-code";
3
3
  import { ValidationField } from "./validation-field";
4
4
 
5
5
  export interface ValidationViolation {
6
- readonly field: ValidationField;
7
- readonly code: ValidationCode;
8
- readonly message: string;
6
+ readonly field: ValidationField;
7
+ readonly code: ValidationCode;
8
+ readonly message: string;
9
9
  }
10
10
 
11
11
  class ValidationException extends DomainException {
12
- constructor(
13
- public readonly field: ValidationField,
14
- public readonly code: ValidationCode,
15
- message: string,
16
- ) {
17
- super(message);
18
- }
12
+ constructor(
13
+ public readonly field: ValidationField,
14
+ public readonly code: ValidationCode,
15
+ message: string,
16
+ ) {
17
+ super(message);
18
+ }
19
19
  }
20
20
 
21
21
  // Carries multiple validation violations from a single operation (e.g. bulk validation).
22
22
  // Use when you need to report all field errors at once rather than failing on the first.
23
23
  class MultipleValidationException extends DomainException {
24
- constructor(public readonly violations: readonly ValidationViolation[]) {
25
- super(violations.map((v) => v.message).join("; "));
26
- }
24
+ constructor(public readonly violations: readonly ValidationViolation[]) {
25
+ super(violations.map((v) => v.message).join("; "));
26
+ }
27
27
  }
28
28
 
29
29
  class InvalidValueException extends ValidationException {
30
- constructor(field: ValidationField, code: ValidationCode, message: string) {
31
- super(field, code, message);
32
- }
30
+ constructor(field: ValidationField, code: ValidationCode, message: string) {
31
+ super(field, code, message);
32
+ }
33
33
  }
34
34
 
35
35
  export {
36
- InvalidValueException,
37
- MultipleValidationException,
38
- ValidationException,
36
+ InvalidValueException,
37
+ MultipleValidationException,
38
+ ValidationException,
39
39
  };
@@ -3,30 +3,31 @@
3
3
  // This is a minimal base class — field catalogs are defined per domain/module.
4
4
 
5
5
  class ValidationField {
6
- public readonly value: string;
6
+ public readonly value: string;
7
7
 
8
- private constructor(value: string) {
9
- this.value = value;
10
- }
8
+ private constructor(value: string) {
9
+ this.value = value;
10
+ }
11
11
 
12
- // Factory for custom or domain-specific fields
13
- public static of(value: string): ValidationField {
14
- return new ValidationField(value);
15
- }
12
+ // Factory for custom or domain-specific fields
13
+ public static of(value: string): ValidationField {
14
+ return new ValidationField(value);
15
+ }
16
16
 
17
- // Creates a nested field path: parent.nested('child') -> 'parent.child'
18
- public nested(child: string | ValidationField): ValidationField {
19
- const childValue = child instanceof ValidationField ? child.value : child;
20
- return new ValidationField(`${this.value}.${childValue}`);
21
- }
17
+ // Creates a nested field path: parent.nested('child') -> 'parent.child'
18
+ public nested(child: string | ValidationField): ValidationField {
19
+ const childValue =
20
+ child instanceof ValidationField ? child.value : child;
21
+ return new ValidationField(`${this.value}.${childValue}`);
22
+ }
22
23
 
23
- public toString(): string {
24
- return this.value;
25
- }
24
+ public toString(): string {
25
+ return this.value;
26
+ }
26
27
 
27
- public equals(other: ValidationField): boolean {
28
- return this.value === other.value;
29
- }
28
+ public equals(other: ValidationField): boolean {
29
+ return this.value === other.value;
30
+ }
30
31
  }
31
32
 
32
33
  export { ValidationField };
package/src/core/index.ts CHANGED
@@ -1,13 +1,13 @@
1
1
  export * from "./errors";
2
2
  export * from "./exceptions/validation-field";
3
3
  export type {
4
- LogPayload,
5
- LoggerPort,
6
- MetricLabels,
7
- MetricsPort,
8
- TraceAttributeValue,
9
- TraceSpan,
10
- TracerPort,
4
+ LogPayload,
5
+ LoggerPort,
6
+ MetricLabels,
7
+ MetricsPort,
8
+ TraceAttributeValue,
9
+ TraceSpan,
10
+ TracerPort,
11
11
  } from "./application";
12
12
  export { mapPolicyEvaluationError } from "./application/policy-error-mapper";
13
13
  export { Entity, type EntityState } from "./domain/entity";