@cullet/erp-core 1.0.2 → 1.0.4

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 (146) 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 +5 -0
  4. package/dist/gate-v1-payload.schema.js.map +1 -1
  5. package/dist/index.d.ts +2 -2
  6. package/dist/index.js +1 -1
  7. package/dist/index.js.map +1 -1
  8. package/dist/outcome.js.map +1 -1
  9. package/dist/policies/engines/v1/gate/index.d.ts +1 -0
  10. package/dist/policies/engines/v1/gate/index.js.map +1 -1
  11. package/dist/policy-service.js.map +1 -1
  12. package/dist/validation-code.js.map +1 -1
  13. package/dist/validation-error.js.map +1 -1
  14. package/dist/validation-field.js.map +1 -1
  15. package/meta.json +67 -67
  16. package/package.json +56 -56
  17. package/src/core/application/commands/command.ts +3 -3
  18. package/src/core/application/commands/requested-by.ts +60 -60
  19. package/src/core/application/index.ts +21 -21
  20. package/src/core/application/policy-error-mapper.ts +54 -54
  21. package/src/core/application/ports/index.ts +6 -6
  22. package/src/core/application/ports/logger.port.ts +4 -4
  23. package/src/core/application/ports/metrics.port.ts +3 -3
  24. package/src/core/application/ports/policy-port.ts +7 -7
  25. package/src/core/application/ports/repository.port.ts +3 -3
  26. package/src/core/application/ports/temporal-repository.port.ts +4 -4
  27. package/src/core/application/ports/tracer.port.ts +7 -7
  28. package/src/core/application/queries/query.ts +13 -13
  29. package/src/core/application/temporal/index.ts +7 -7
  30. package/src/core/application/temporal/temporal-context.ts +20 -20
  31. package/src/core/application/temporal/temporal-use-case.ts +22 -22
  32. package/src/core/application/use-case.ts +10 -10
  33. package/src/core/config/core-config.instance.ts +1 -1
  34. package/src/core/config/core-config.ts +59 -59
  35. package/src/core/config/index.ts +6 -6
  36. package/src/core/config/policy-reporter.ts +31 -31
  37. package/src/core/config/silent-policy-reporter.ts +1 -1
  38. package/src/core/domain/entity.ts +44 -44
  39. package/src/core/domain/rulesets/entity-ruleset.contracts.ts +6 -6
  40. package/src/core/domain/rulesets/ruleset-registry.ts +49 -49
  41. package/src/core/domain/rulesets/ruleset.contracts.ts +6 -6
  42. package/src/core/domain/rulesets/value-object-ruleset.contracts.ts +5 -5
  43. package/src/core/domain/temporal/index.ts +11 -11
  44. package/src/core/domain/temporal/temporal-range.ts +16 -16
  45. package/src/core/domain/temporal/temporal-snapshot.ts +24 -24
  46. package/src/core/domain/temporal/transaction-time.ts +30 -30
  47. package/src/core/domain/temporal/valid-time.ts +29 -29
  48. package/src/core/domain/value-object.ts +16 -16
  49. package/src/core/errors/app-error.ts +64 -64
  50. package/src/core/errors/authentication-error.ts +134 -134
  51. package/src/core/errors/authorization-error.ts +154 -154
  52. package/src/core/errors/business-rule-violation-error.ts +15 -15
  53. package/src/core/errors/conflict-error.ts +202 -201
  54. package/src/core/errors/error-codes.ts +48 -48
  55. package/src/core/errors/idempotency-error.ts +324 -320
  56. package/src/core/errors/index.ts +50 -50
  57. package/src/core/errors/integration-error.ts +120 -120
  58. package/src/core/errors/legacy-incompatible-error.ts +13 -13
  59. package/src/core/errors/not-found-error.ts +14 -14
  60. package/src/core/errors/serialization-error.ts +167 -167
  61. package/src/core/errors/temporal-error.ts +109 -107
  62. package/src/core/errors/types.ts +35 -35
  63. package/src/core/errors/unexpected-error.ts +10 -10
  64. package/src/core/errors/utils/index.ts +2 -2
  65. package/src/core/errors/utils/json-safe.ts +53 -53
  66. package/src/core/errors/validation-error.ts +18 -18
  67. package/src/core/exceptions/business-rule-violation-exception.ts +6 -6
  68. package/src/core/exceptions/domain-exception.ts +5 -5
  69. package/src/core/exceptions/entity-not-found-exception.ts +6 -6
  70. package/src/core/exceptions/invalid-state-transition-exception.ts +8 -8
  71. package/src/core/exceptions/invariant-violation-exception.ts +3 -3
  72. package/src/core/exceptions/validation-code.ts +35 -29
  73. package/src/core/exceptions/validation-exception.ts +19 -19
  74. package/src/core/exceptions/validation-field.ts +20 -19
  75. package/src/core/index.ts +7 -7
  76. package/src/core/policies/asof/asof.ts +47 -47
  77. package/src/core/policies/catalog/catalog.instance.ts +8 -6
  78. package/src/core/policies/catalog/index.ts +4 -4
  79. package/src/core/policies/catalog/policy-catalog-entry.ts +199 -197
  80. package/src/core/policies/catalog/policy-catalog.ts +101 -101
  81. package/src/core/policies/catalog/policy-key.ts +51 -51
  82. package/src/core/policies/context/context-builder.ts +335 -313
  83. package/src/core/policies/context/context-registry.instance.ts +9 -9
  84. package/src/core/policies/context/context-registry.ts +61 -61
  85. package/src/core/policies/context/context-resolver.ts +12 -12
  86. package/src/core/policies/context/context-seed.ts +19 -15
  87. package/src/core/policies/context/index.ts +9 -9
  88. package/src/core/policies/context/path.ts +135 -128
  89. package/src/core/policies/defs/in-memory-policy-definition-repo.ts +56 -55
  90. package/src/core/policies/defs/index.ts +10 -10
  91. package/src/core/policies/defs/policy-definition-repository.ts +3 -3
  92. package/src/core/policies/defs/policy-definition.ts +143 -142
  93. package/src/core/policies/defs/policy-scope.ts +21 -19
  94. package/src/core/policies/defs/policy-semver.ts +51 -51
  95. package/src/core/policies/engines/compute-engine-registry.ts +43 -43
  96. package/src/core/policies/engines/compute-evaluator-registry.ts +20 -20
  97. package/src/core/policies/engines/compute-registry.ts +45 -45
  98. package/src/core/policies/engines/compute-types.ts +15 -15
  99. package/src/core/policies/engines/condition-evaluator-reporter.ts +17 -17
  100. package/src/core/policies/engines/gate-engine-registry.ts +27 -25
  101. package/src/core/policies/engines/gate-types.ts +28 -28
  102. package/src/core/policies/engines/index.ts +28 -28
  103. package/src/core/policies/engines/parse-compute-payload.ts +51 -45
  104. package/src/core/policies/engines/parse-gate-payload.ts +42 -42
  105. package/src/core/policies/engines/v1/compute/compute-engine-v1.ts +39 -37
  106. package/src/core/policies/engines/v1/compute/compute-payload.schema.ts +43 -41
  107. package/src/core/policies/engines/v1/compute/index.ts +6 -6
  108. package/src/core/policies/engines/v1/compute/resolve-decision-table-v1.ts +41 -39
  109. package/src/core/policies/engines/v1/condition-evaluator.ts +557 -504
  110. package/src/core/policies/engines/v1/condition-schema.ts +35 -35
  111. package/src/core/policies/engines/v1/condition-types.ts +21 -21
  112. package/src/core/policies/engines/v1/gate/gate-engine-v1.ts +134 -130
  113. package/src/core/policies/engines/v1/gate/gate-types-v1.ts +5 -5
  114. package/src/core/policies/engines/v1/gate/gate-v1-payload.schema.ts +32 -30
  115. package/src/core/policies/engines/v1/gate/index.ts +4 -4
  116. package/src/core/policies/engines/v1/index.ts +8 -8
  117. package/src/core/policies/index.ts +72 -72
  118. package/src/core/policies/package/policy-package.ts +3 -3
  119. package/src/core/policies/policy-ids.ts +25 -25
  120. package/src/core/policies/resolver/policy-resolver.ts +34 -34
  121. package/src/core/policies/service/index.ts +6 -6
  122. package/src/core/policies/service/policy-evaluation-error.ts +141 -133
  123. package/src/core/policies/service/policy-service.ts +432 -419
  124. package/src/core/policies/utils/date.ts +3 -3
  125. package/src/core/policies/utils/hash.ts +61 -61
  126. package/src/core/result/outcome.ts +131 -126
  127. package/src/core/result/result.ts +130 -127
  128. package/src/core/shared/aggregate-version.ts +5 -5
  129. package/src/core/shared/hashing.ts +18 -18
  130. package/src/core/shared/immutable.ts +29 -29
  131. package/src/core/shared/temporal-guards.ts +9 -9
  132. package/src/core/versioning/domain-event-contracts.ts +40 -40
  133. package/src/core/versioning/version.ts +19 -19
  134. package/src/examples/rulesets/entity/order-creation-rules-v1.ts +18 -18
  135. package/src/examples/rulesets/entity/order-invariants-v1.ts +31 -29
  136. package/src/examples/rulesets/entity/order-invariants-v2.ts +12 -12
  137. package/src/examples/rulesets/entity/order.ts +127 -127
  138. package/src/examples/rulesets/value-object/cpf-rules-v1.ts +41 -39
  139. package/src/examples/rulesets/value-object/cpf-rules-v2.ts +14 -12
  140. package/src/examples/rulesets/value-object/cpf.ts +24 -24
  141. package/src/examples/rulesets/value-object/customer.ts +42 -39
  142. package/src/examples/rulesets/value-object/person-name-rules-v1.ts +27 -27
  143. package/src/examples/rulesets/value-object/person-name-rules-v2.ts +13 -13
  144. package/src/examples/rulesets/value-object/person-name.ts +29 -26
  145. package/src/index.ts +2 -2
  146. package/src/version.ts +1 -1
@@ -8,117 +8,117 @@ import { PolicyCatalogEntry } from "./policy-catalog-entry";
8
8
  * The catalog defines the universe of policies; the database cannot invent new ones.
9
9
  */
10
10
  export class PolicyCatalog {
11
- private readonly versionedEntries: ReadonlyMap<string, PolicyCatalogEntry>;
12
- private readonly entriesByKey: ReadonlyMap<
13
- string,
14
- readonly PolicyCatalogEntry[]
15
- >;
16
-
17
- constructor(entries: readonly PolicyCatalogEntry[]) {
18
- const families = new Map<string, PolicyCatalogEntry[]>();
19
- const versionedMap = new Map<string, PolicyCatalogEntry>();
20
-
21
- for (const rawEntry of entries) {
22
- const entry = PolicyCatalogEntry.from(rawEntry);
23
- const key = entry.key.toString();
24
- const variantKey = entry.toVariantKey();
25
-
26
- if (versionedMap.has(variantKey)) {
27
- throw new UnexpectedError(
28
- `Duplicate PolicyCatalog entry for key "${key}" and variant "${variantKey}"`,
29
- );
30
- }
31
-
32
- const family = families.get(key) ?? [];
33
- family.push(entry);
34
- families.set(key, family);
35
- versionedMap.set(variantKey, entry);
36
- }
37
-
38
- for (const family of families.values()) {
39
- PolicyCatalogEntry.assertFamilyConsistency(family);
11
+ private readonly versionedEntries: ReadonlyMap<string, PolicyCatalogEntry>;
12
+ private readonly entriesByKey: ReadonlyMap<
13
+ string,
14
+ readonly PolicyCatalogEntry[]
15
+ >;
16
+
17
+ constructor(entries: readonly PolicyCatalogEntry[]) {
18
+ const families = new Map<string, PolicyCatalogEntry[]>();
19
+ const versionedMap = new Map<string, PolicyCatalogEntry>();
20
+
21
+ for (const rawEntry of entries) {
22
+ const entry = PolicyCatalogEntry.from(rawEntry);
23
+ const key = entry.key.toString();
24
+ const variantKey = entry.toVariantKey();
25
+
26
+ if (versionedMap.has(variantKey)) {
27
+ throw new UnexpectedError(
28
+ `Duplicate PolicyCatalog entry for key "${key}" and variant "${variantKey}"`,
29
+ );
30
+ }
31
+
32
+ const family = families.get(key) ?? [];
33
+ family.push(entry);
34
+ families.set(key, family);
35
+ versionedMap.set(variantKey, entry);
36
+ }
37
+
38
+ for (const family of families.values()) {
39
+ PolicyCatalogEntry.assertFamilyConsistency(family);
40
+ }
41
+
42
+ this.versionedEntries = versionedMap;
43
+ this.entriesByKey = families;
40
44
  }
41
45
 
42
- this.versionedEntries = versionedMap;
43
- this.entriesByKey = families;
44
- }
45
-
46
- get(key: string): Result<PolicyCatalogEntry, string> {
47
- const familyResult = this.getFamily(key);
48
- if (familyResult.isErr()) {
49
- return Result.err(familyResult.errorOrNull()!);
46
+ get(key: string): Result<PolicyCatalogEntry, string> {
47
+ const familyResult = this.getFamily(key);
48
+ if (familyResult.isErr()) {
49
+ return Result.err(familyResult.errorOrNull()!);
50
+ }
51
+
52
+ const family = familyResult.getOrNull()!;
53
+ if (family.length > 1) {
54
+ return Result.err(
55
+ `Policy key "${key}" has multiple catalog variants; use getVersioned(...) or getFamily(...)`,
56
+ );
57
+ }
58
+
59
+ const [entry] = family;
60
+ if (!entry) {
61
+ return Result.err(`Policy not found in catalog: "${key}"`);
62
+ }
63
+
64
+ return Result.ok(entry);
50
65
  }
51
66
 
52
- const family = familyResult.getOrNull()!;
53
- if (family.length > 1) {
54
- return Result.err(
55
- `Policy key "${key}" has multiple catalog variants; use getVersioned(...) or getFamily(...)`,
56
- );
57
- }
67
+ getFamily(key: string): Result<readonly PolicyCatalogEntry[], string> {
68
+ const family = this.entriesByKey.get(key);
69
+ if (!family) {
70
+ return Result.err(`Policy not found in catalog: "${key}"`);
71
+ }
58
72
 
59
- const [entry] = family;
60
- if (!entry) {
61
- return Result.err(`Policy not found in catalog: "${key}"`);
73
+ return Result.ok(family);
62
74
  }
63
75
 
64
- return Result.ok(entry);
65
- }
66
-
67
- getFamily(key: string): Result<readonly PolicyCatalogEntry[], string> {
68
- const family = this.entriesByKey.get(key);
69
- if (!family) {
70
- return Result.err(`Policy not found in catalog: "${key}"`);
71
- }
72
-
73
- return Result.ok(family);
74
- }
75
-
76
- getVersioned(params: {
77
- readonly key: string;
78
- readonly kind: "GATE" | "COMPUTE";
79
- readonly gateEngineVersion?: number;
80
- readonly computeEngineVersion?: number;
81
- readonly payloadSchemaVersion?: number;
82
- }): Result<PolicyCatalogEntry, string> {
83
- const family = this.entriesByKey.get(params.key);
84
- if (!family || family.length === 0) {
85
- return Result.err(`Policy not found in catalog: "${params.key}"`);
76
+ getVersioned(params: {
77
+ readonly key: string;
78
+ readonly kind: "GATE" | "COMPUTE";
79
+ readonly gateEngineVersion?: number;
80
+ readonly computeEngineVersion?: number;
81
+ readonly payloadSchemaVersion?: number;
82
+ }): Result<PolicyCatalogEntry, string> {
83
+ const family = this.entriesByKey.get(params.key);
84
+ if (!family || family.length === 0) {
85
+ return Result.err(`Policy not found in catalog: "${params.key}"`);
86
+ }
87
+
88
+ const exactMatch = family.find((entry) => entry.matchesVersion(params));
89
+ if (exactMatch) {
90
+ return Result.ok(exactMatch);
91
+ }
92
+
93
+ if (family.length === 1 && !family[0].hasExplicitVersionSelector()) {
94
+ return Result.ok(family[0]);
95
+ }
96
+
97
+ const versionDetails = [
98
+ params.kind,
99
+ params.gateEngineVersion !== undefined
100
+ ? `gateEngineVersion=${params.gateEngineVersion}`
101
+ : null,
102
+ params.computeEngineVersion !== undefined
103
+ ? `computeEngineVersion=${params.computeEngineVersion}`
104
+ : null,
105
+ params.payloadSchemaVersion !== undefined
106
+ ? `payloadSchemaVersion=${params.payloadSchemaVersion}`
107
+ : null,
108
+ ]
109
+ .filter((part): part is string => part !== null)
110
+ .join(", ");
111
+
112
+ return Result.err(
113
+ `Policy variant not found in catalog: "${params.key}" (${versionDetails})`,
114
+ );
86
115
  }
87
116
 
88
- const exactMatch = family.find((entry) => entry.matchesVersion(params));
89
- if (exactMatch) {
90
- return Result.ok(exactMatch);
117
+ list(): readonly PolicyCatalogEntry[] {
118
+ return Array.from(this.versionedEntries.values());
91
119
  }
92
120
 
93
- if (family.length === 1 && !family[0].hasExplicitVersionSelector()) {
94
- return Result.ok(family[0]);
121
+ has(key: string): boolean {
122
+ return this.entriesByKey.has(key);
95
123
  }
96
-
97
- const versionDetails = [
98
- params.kind,
99
- params.gateEngineVersion !== undefined
100
- ? `gateEngineVersion=${params.gateEngineVersion}`
101
- : null,
102
- params.computeEngineVersion !== undefined
103
- ? `computeEngineVersion=${params.computeEngineVersion}`
104
- : null,
105
- params.payloadSchemaVersion !== undefined
106
- ? `payloadSchemaVersion=${params.payloadSchemaVersion}`
107
- : null,
108
- ]
109
- .filter((part): part is string => part !== null)
110
- .join(", ");
111
-
112
- return Result.err(
113
- `Policy variant not found in catalog: "${params.key}" (${versionDetails})`,
114
- );
115
- }
116
-
117
- list(): readonly PolicyCatalogEntry[] {
118
- return Array.from(this.versionedEntries.values());
119
- }
120
-
121
- has(key: string): boolean {
122
- return this.entriesByKey.has(key);
123
- }
124
124
  }
@@ -13,66 +13,66 @@ const SEGMENT_PATTERN = /^[a-z][a-z0-9_]*$/;
13
13
  const MAX_POLICY_KEY_LENGTH = 255;
14
14
 
15
15
  export class PolicyKey {
16
- public readonly module: string;
17
- public readonly area: string;
18
- public readonly name: string;
16
+ public readonly module: string;
17
+ public readonly area: string;
18
+ public readonly name: string;
19
19
 
20
- private constructor(module: string, area: string, name: string) {
21
- this.module = module;
22
- this.area = area;
23
- this.name = name;
24
- Object.freeze(this);
25
- }
26
-
27
- static parse(raw: string): Result<PolicyKey, string> {
28
- if (!raw || typeof raw !== "string") {
29
- return Result.err("PolicyKey cannot be empty");
20
+ private constructor(module: string, area: string, name: string) {
21
+ this.module = module;
22
+ this.area = area;
23
+ this.name = name;
24
+ Object.freeze(this);
30
25
  }
31
26
 
32
- if (raw.length > MAX_POLICY_KEY_LENGTH) {
33
- return Result.err(
34
- `PolicyKey cannot exceed ${MAX_POLICY_KEY_LENGTH} characters, got ${raw.length}`,
35
- );
36
- }
27
+ static parse(raw: string): Result<PolicyKey, string> {
28
+ if (!raw || typeof raw !== "string") {
29
+ return Result.err("PolicyKey cannot be empty");
30
+ }
37
31
 
38
- const segments = raw.split(".");
39
- if (segments.length !== 3) {
40
- return Result.err(
41
- `PolicyKey must have exactly 3 segments (module.area.name), got ${segments.length}: "${raw}"`,
42
- );
43
- }
32
+ if (raw.length > MAX_POLICY_KEY_LENGTH) {
33
+ return Result.err(
34
+ `PolicyKey cannot exceed ${MAX_POLICY_KEY_LENGTH} characters, got ${raw.length}`,
35
+ );
36
+ }
44
37
 
45
- const [rawModule, rawArea, name] = segments;
38
+ const segments = raw.split(".");
39
+ if (segments.length !== 3) {
40
+ return Result.err(
41
+ `PolicyKey must have exactly 3 segments (module.area.name), got ${segments.length}: "${raw}"`,
42
+ );
43
+ }
46
44
 
47
- if (!SEGMENT_PATTERN.test(rawModule)) {
48
- return Result.err(
49
- `PolicyKey segment "module" is invalid: "${rawModule}". ` +
50
- "Must start with a lowercase letter and contain only [a-z0-9_].",
51
- );
52
- }
45
+ const [rawModule, rawArea, name] = segments;
53
46
 
54
- if (!SEGMENT_PATTERN.test(rawArea)) {
55
- return Result.err(
56
- `PolicyKey segment "area" is invalid: "${rawArea}". ` +
57
- "Must start with a lowercase letter and contain only [a-z0-9_].",
58
- );
59
- }
47
+ if (!SEGMENT_PATTERN.test(rawModule)) {
48
+ return Result.err(
49
+ `PolicyKey segment "module" is invalid: "${rawModule}". ` +
50
+ "Must start with a lowercase letter and contain only [a-z0-9_].",
51
+ );
52
+ }
60
53
 
61
- if (!SEGMENT_PATTERN.test(name)) {
62
- return Result.err(
63
- `PolicyKey segment "name" is invalid: "${name}". ` +
64
- "Must start with a lowercase letter and contain only [a-z0-9_].",
65
- );
66
- }
54
+ if (!SEGMENT_PATTERN.test(rawArea)) {
55
+ return Result.err(
56
+ `PolicyKey segment "area" is invalid: "${rawArea}". ` +
57
+ "Must start with a lowercase letter and contain only [a-z0-9_].",
58
+ );
59
+ }
67
60
 
68
- return Result.ok(new PolicyKey(rawModule, rawArea, name));
69
- }
61
+ if (!SEGMENT_PATTERN.test(name)) {
62
+ return Result.err(
63
+ `PolicyKey segment "name" is invalid: "${name}". ` +
64
+ "Must start with a lowercase letter and contain only [a-z0-9_].",
65
+ );
66
+ }
70
67
 
71
- toString(): string {
72
- return `${this.module}.${this.area}.${this.name}`;
73
- }
68
+ return Result.ok(new PolicyKey(rawModule, rawArea, name));
69
+ }
74
70
 
75
- equals(other: PolicyKey): boolean {
76
- return this.toString() === other.toString();
77
- }
71
+ toString(): string {
72
+ return `${this.module}.${this.area}.${this.name}`;
73
+ }
74
+
75
+ equals(other: PolicyKey): boolean {
76
+ return this.toString() === other.toString();
77
+ }
78
78
  }