@cullet/erp-core 1.0.11 → 1.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.
Files changed (51) hide show
  1. package/KIT_CONTEXT.md +67 -0
  2. package/README.md +128 -1
  3. package/dist/app-error.d.ts +108 -0
  4. package/dist/application/index.d.ts +2 -0
  5. package/dist/application/index.js +2 -0
  6. package/dist/errors/index.d.ts +2 -1
  7. package/dist/errors/index.js +4 -2
  8. package/dist/gate-engine-registry.d.ts +80 -0
  9. package/dist/gate-v1-payload.schema.js +2 -28
  10. package/dist/gate-v1-payload.schema.js.map +1 -1
  11. package/dist/hashing.js +49 -0
  12. package/dist/hashing.js.map +1 -0
  13. package/dist/index.d.ts +11 -45
  14. package/dist/index.js +12 -85
  15. package/dist/index.js.map +1 -1
  16. package/dist/not-found-error.js +54 -0
  17. package/dist/not-found-error.js.map +1 -0
  18. package/dist/outcome.js +1 -1
  19. package/dist/parse-gate-payload.d.ts +3 -78
  20. package/dist/path.d.ts +89 -0
  21. package/dist/policies/engines/index.d.ts +2 -1
  22. package/dist/policies/index.d.ts +4 -2
  23. package/dist/policy-service.d.ts +3 -86
  24. package/dist/policy-service.js +5 -16
  25. package/dist/policy-service.js.map +1 -1
  26. package/dist/temporal-guards.js +30 -0
  27. package/dist/temporal-guards.js.map +1 -0
  28. package/dist/temporal-use-case.d.ts +309 -0
  29. package/dist/temporal-use-case.js +284 -0
  30. package/dist/temporal-use-case.js.map +1 -0
  31. package/dist/validation-code.js +1 -47
  32. package/dist/validation-code.js.map +1 -1
  33. package/dist/validation-error.d.ts +2 -107
  34. package/dist/validation-error.js +2 -52
  35. package/dist/validation-error.js.map +1 -1
  36. package/dist/validation-exception.js +18 -0
  37. package/dist/validation-exception.js.map +1 -0
  38. package/meta.json +3 -2
  39. package/package.json +5 -1
  40. package/src/application/index.ts +1 -0
  41. package/src/core/application/commands/index.ts +1 -0
  42. package/src/core/application/index.ts +12 -3
  43. package/src/core/application/ports/index.ts +2 -2
  44. package/src/core/application/ports/policy-port.ts +13 -3
  45. package/src/core/application/ports/repository.port.ts +37 -1
  46. package/src/core/application/temporal/temporal-use-case.ts +14 -2
  47. package/src/core/application/use-case.ts +133 -2
  48. package/src/core/index.ts +1 -10
  49. package/src/examples/application/cancel-order.example.ts +124 -0
  50. package/src/examples/application/in-memory-account-repository.example.ts +73 -0
  51. package/src/version.ts +1 -1
package/KIT_CONTEXT.md CHANGED
@@ -23,6 +23,73 @@ Núcleo arquitetural para sistemas ERP (e domínios transacionais com temporalid
23
23
  - **Policies permitem disable sem remover código**: `PolicyDefinition` aceita `enabled: false` e o repositório ignora definições desabilitadas.
24
24
  - **Composição isolada é de primeira classe**: use `new CoreConfig()`, `new ContextResolverRegistry()` e `registerNamespacedContextResolversIn(...)` quando precisar evitar singletons compartilhados.
25
25
 
26
+ ## [example] Exemplo end-to-end (Command + Repository + PolicyPort)
27
+
28
+ Um `Command` carrega o agregado por um `ResultRepository`, consulta um
29
+ `PolicyPort` (gate `ALLOW`/`DENY`) e persiste. Falhas recuperáveis voltam como
30
+ `Result.err`, nunca como exceção.
31
+
32
+ ```ts
33
+ class CancelOrder extends Command<
34
+ CancelOrderInput,
35
+ Result<Order, CancelOrderError>
36
+ > {
37
+ constructor(
38
+ private readonly orders: ResultRepository<
39
+ Order,
40
+ string,
41
+ CancelOrderError
42
+ >,
43
+ private readonly policies: PolicyPort,
44
+ ) {
45
+ super();
46
+ }
47
+
48
+ protected async execute(input: CancelOrderInput) {
49
+ const found = await this.orders.findById(input.orderId);
50
+ if (found.isErr()) return found;
51
+ const order = found.getOrThrow();
52
+ if (!order)
53
+ return Result.err(
54
+ new NotFoundError("Order", { id: input.orderId }),
55
+ );
56
+
57
+ const evaluated = await this.policies.evaluate({
58
+ decisionId: asPolicyDecisionId(input.orderId),
59
+ policyKey: "order.cancel",
60
+ scopeChain: [],
61
+ contextVersion: 1,
62
+ seed: {
63
+ tenantId: asTenantId(input.tenantId),
64
+ schoolId: asSchoolId(input.schoolId),
65
+ fields: { orderStatus: order.status },
66
+ },
67
+ });
68
+ if (evaluated.isErr()) return evaluated;
69
+
70
+ const result = evaluated.getOrThrow();
71
+ if (result.kind === "GATE" && result.decision.status === "DENY") {
72
+ return Result.err(
73
+ AuthorizationError.policyDenied({
74
+ action: "order.cancel",
75
+ policyId: result.ref.definitionId,
76
+ policyVersion: Number(result.ref.policyVersion),
77
+ evaluatedAtIso: result.evaluatedAt.toISOString(),
78
+ }),
79
+ );
80
+ }
81
+
82
+ const saved = await this.orders.save({ ...order, status: "CANCELLED" });
83
+ if (saved.isErr()) return saved;
84
+ return Result.ok({ ...order, status: "CANCELLED" });
85
+ }
86
+ }
87
+ ```
88
+
89
+ - **Imports**: tudo do root `@cullet/erp-core`.
90
+ - **`Repository` vs `ResultRepository`**: `Repository` (`save`/`delete` → `Promise<void>`) é o estilo imperativo; `ResultRepository` devolve `Result` para sinalizar not-found / concorrência otimista sem quebrar o fluxo.
91
+ - **Referência compilada/testada**: `src/examples/application/cancel-order.example.ts` (+ `.spec.ts`).
92
+
26
93
  ## [extension-points] Pontos de extensão
27
94
 
28
95
  Implemente as portas em `application/ports/` para conectar a stack real:
package/README.md CHANGED
@@ -13,7 +13,7 @@ Para o sumário prompt-friendly veja [`KIT_CONTEXT.md`](./KIT_CONTEXT.md). Para
13
13
  - **Erros de aplicação** — `AppError` discriminada por `code`: `ValidationError`, `NotFoundError`, `ConflictError`, `AuthorizationError`, `IntegrationError`.
14
14
  - **Result** — `Result<T, E>` e `Outcome` para retorno tipado da aplicação.
15
15
  - **Policies** — `PolicyCatalog`, `PolicyDefinition`, `PolicyResolver`, `PolicyService` e tipos associados para avaliação declarativa.
16
- - **Application** — portas de observabilidade (`LoggerPort`, `MetricsPort`, `TracerPort`) e `mapPolicyEvaluationError` para integrar a camada de aplicação.
16
+ - **Application** — `UseCase`/`Command` (CQS, entrada `CommandInput` com `RequestedBy`), portas de persistência (`Repository` e a variante `ResultRepository`), `PolicyPort`, portas de observabilidade (`LoggerPort`, `MetricsPort`, `TracerPort`) e `mapPolicyEvaluationError`. Veja o [exemplo end-to-end](#exemplo-end-to-end).
17
17
  - **Exemplos** — rulesets de referência em `examples/rulesets/`, fora da superfície principal de domínio.
18
18
 
19
19
  ## Como começa
@@ -46,6 +46,133 @@ npx cullet fc erp-core@1.0.0
46
46
 
47
47
  O argumento do `fc` é o nome do kit no registry (`erp-core`), não o nome npm com escopo. O comando instala `@cullet/erp-core`, copia o `src/` para `./cullet/erp-core@1.0.0/` e registra o alias `@cullet/erp-core` no `tsconfig.json`.
48
48
 
49
+ ## Exemplo end-to-end
50
+
51
+ Um `Command` concreto que orquestra um `ResultRepository` e um `PolicyPort`.
52
+ O fluxo carrega o agregado, consulta uma policy declarativa (gate `ALLOW`/`DENY`)
53
+ e só então persiste — toda falha recuperável (erro de infra no repositório,
54
+ policy negando, agregado inexistente, conflito de concorrência otimista no
55
+ `save`) volta como `Result.err(...)`, nunca como exceção atravessando a
56
+ fronteira. O código abaixo é a versão consumidora do exemplo testado em
57
+ [`src/examples/application/cancel-order.example.ts`](./src/examples/application/cancel-order.example.ts).
58
+
59
+ ```ts
60
+ import {
61
+ AuthorizationError,
62
+ Command,
63
+ NotFoundError,
64
+ RequestedBy,
65
+ Result,
66
+ asPolicyDecisionId,
67
+ asSchoolId,
68
+ asTenantId,
69
+ type CommandInput,
70
+ type PolicyPort,
71
+ type ResultRepository,
72
+ } from "@cullet/erp-core";
73
+
74
+ type OrderStatus = "OPEN" | "CANCELLED";
75
+ interface Order {
76
+ readonly id: string;
77
+ readonly status: OrderStatus;
78
+ }
79
+
80
+ // `CommandInput` obriga toda mutação a registrar quem a disparou.
81
+ interface CancelOrderInput extends CommandInput {
82
+ readonly orderId: string;
83
+ readonly tenantId: string;
84
+ readonly schoolId: string;
85
+ }
86
+
87
+ type CancelOrderError = NotFoundError | AuthorizationError;
88
+
89
+ class CancelOrder extends Command<
90
+ CancelOrderInput,
91
+ Result<Order, CancelOrderError>
92
+ > {
93
+ constructor(
94
+ private readonly orders: ResultRepository<
95
+ Order,
96
+ string,
97
+ CancelOrderError
98
+ >,
99
+ private readonly policies: PolicyPort,
100
+ ) {
101
+ super();
102
+ }
103
+
104
+ protected async execute(
105
+ input: CancelOrderInput,
106
+ ): Promise<Result<Order, CancelOrderError>> {
107
+ // 1. Carrega o agregado; falhas de infra ficam in-band no Result.
108
+ const found = await this.orders.findById(input.orderId);
109
+ if (found.isErr()) return found;
110
+
111
+ const order = found.getOrThrow();
112
+ if (!order) {
113
+ return Result.err(
114
+ new NotFoundError("Order", { id: input.orderId }),
115
+ );
116
+ }
117
+
118
+ // 2. Decide via policy declarativa (um GATE retorna ALLOW/DENY).
119
+ const evaluated = await this.policies.evaluate({
120
+ decisionId: asPolicyDecisionId(input.orderId),
121
+ policyKey: "order.cancel",
122
+ scopeChain: [],
123
+ contextVersion: 1,
124
+ seed: {
125
+ tenantId: asTenantId(input.tenantId),
126
+ schoolId: asSchoolId(input.schoolId),
127
+ fields: { orderStatus: order.status },
128
+ },
129
+ });
130
+ if (evaluated.isErr()) return evaluated;
131
+
132
+ const result = evaluated.getOrThrow();
133
+ if (result.kind === "GATE" && result.decision.status === "DENY") {
134
+ return Result.err(
135
+ AuthorizationError.policyDenied({
136
+ action: "order.cancel",
137
+ resource: { type: "Order", id: order.id },
138
+ policyId: result.ref.definitionId,
139
+ policyVersion: Number(result.ref.policyVersion),
140
+ evaluatedAtIso: result.evaluatedAt.toISOString(),
141
+ }),
142
+ );
143
+ }
144
+
145
+ // 3. Muta e persiste; um conflito de versão no save também volta como
146
+ // Result.err — nunca uma exceção atravessando a fronteira.
147
+ const cancelled: Order = { ...order, status: "CANCELLED" };
148
+ const saved = await this.orders.save(cancelled);
149
+ if (saved.isErr()) return saved;
150
+
151
+ return Result.ok(cancelled);
152
+ }
153
+ }
154
+
155
+ // Chamada — `run` recebe a entrada e devolve o Result tipado.
156
+ const result = await new CancelOrder(orderRepository, policyPort).run({
157
+ orderId: "order-42",
158
+ tenantId: "tenant-1",
159
+ schoolId: "school-1",
160
+ requestedBy: RequestedBy.fromUser("550e8400-e29b-41d4-a716-446655440000"),
161
+ });
162
+
163
+ result.match({
164
+ ok: (order) => console.log("cancelado", order.id),
165
+ err: (error) => console.error(error.code, error.message),
166
+ });
167
+ ```
168
+
169
+ `Repository<TEntity, TId>` (estilo imperativo, `save`/`delete` retornam
170
+ `Promise<void>`) continua disponível quando você prefere lançar exceções;
171
+ `ResultRepository` é a variante alinhada à filosofia "erros como valor" e
172
+ permite sinalizar not-found / concorrência otimista sem quebrar o fluxo. Uma
173
+ implementação in-memory de referência está em
174
+ [`src/examples/application/in-memory-account-repository.example.ts`](./src/examples/application/in-memory-account-repository.example.ts).
175
+
49
176
  ## Composicao sem singletons
50
177
 
51
178
  Para isolamento por tenant, request ou teste, prefira instancias locais em vez
@@ -0,0 +1,108 @@
1
+ //#region src/core/errors/types.d.ts
2
+ type ErrorSeverity = "low" | "medium" | "high" | "critical";
3
+ type JsonSafePrimitive = string | number | boolean | null;
4
+ type JsonSafeValue = JsonSafePrimitive | JsonSafeValue[] | {
5
+ [key: string]: JsonSafeValue;
6
+ };
7
+ type JsonSafeRecord = Record<string, JsonSafeValue>;
8
+ /**
9
+ * Options accepted by the AppError constructor.
10
+ * Subclasses can extend or pick from this type.
11
+ */
12
+ type AppErrorOptions = {
13
+ /** Original error or exception that caused this error. */
14
+ cause?: unknown;
15
+ /** Arbitrary key-value metadata (will be sanitized to JSON-safe values). */
16
+ metadata?: Record<string, unknown>;
17
+ /** Error category/type for grouping (e.g., "authentication", "validation"). */
18
+ type?: string;
19
+ /** severity level for alerting/logging prioritization. */
20
+ severity?: ErrorSeverity;
21
+ /**
22
+ * Identifies a single execution "story" in the system. All operations
23
+ * related to the same logical flow must share the same correlationId.
24
+ */
25
+ correlationId?: string;
26
+ /**
27
+ * Identifies a specific technical request attempt (each retry may produce
28
+ * a new requestId), even when the correlationId stays the same.
29
+ */
30
+ requestId?: string;
31
+ /**
32
+ * Identifies a unique business intent (idempotency key); stays the same
33
+ * across technical retries and multiple requests that represent the same intent.
34
+ */
35
+ commandId?: string;
36
+ /** ISO timestamp of when the error was created (defaults to now). */
37
+ createdAtIso?: string;
38
+ /** Safe message that can be exposed to end users (no internal details). */
39
+ publicMessage?: string;
40
+ };
41
+ //#endregion
42
+ //#region src/core/errors/app-error.d.ts
43
+ /**
44
+ * Root of the application/domain error hierarchy. Every error the system raises
45
+ * on purpose extends `AppError`, which gives callers a single `instanceof` to
46
+ * catch and a uniform, serializable shape to log and transport.
47
+ *
48
+ * Beyond the native `Error` message it carries a stable `code` (the contract the
49
+ * outside world matches on), an optional non-leaking `publicMessage`, a
50
+ * severity, JSON-safe `metadata`, and the correlation/request/command ids that
51
+ * stitch an error back to the request that produced it. The metadata is
52
+ * validated as JSON-safe on construction, so a logger can serialize any
53
+ * `AppError` without hitting a circular reference or a non-serializable value.
54
+ *
55
+ * Abstract on purpose: callers should throw a specific subclass (e.g.
56
+ * {@link ValidationError}, {@link NotFoundError}) so the `code` and shape are
57
+ * meaningful, never a bare `AppError`.
58
+ */
59
+ declare abstract class AppError extends Error {
60
+ readonly code: string;
61
+ readonly cause?: unknown;
62
+ readonly metadata?: JsonSafeRecord;
63
+ readonly type?: string;
64
+ readonly severity?: ErrorSeverity;
65
+ readonly createdAtIso: string;
66
+ readonly publicMessage?: string;
67
+ /**
68
+ * Identifies a single execution "story" in the system. All operations
69
+ * related to the same logical flow must share the same correlationId.
70
+ */
71
+ readonly correlationId?: string;
72
+ /**
73
+ * Identifies a specific technical request attempt (each retry may produce
74
+ * a new requestId), even when the correlationId stays the same.
75
+ */
76
+ readonly requestId?: string;
77
+ /**
78
+ * Marks the business intent / idempotency key; stays the same across
79
+ * technical retries and multiple requests that represent the same intent.
80
+ */
81
+ readonly commandId?: string;
82
+ /**
83
+ * Builds the common error envelope shared by every subclass.
84
+ *
85
+ * `name` is taken from `new.target` so the thrown instance reports its
86
+ * concrete subclass name (not `"AppError"`), and the prototype is re-pinned
87
+ * via `setPrototypeOf` so `instanceof` keeps working after transpilation to
88
+ * older targets where extending built-ins breaks the chain. `createdAtIso`
89
+ * defaults to now, and `metadata` is validated as JSON-safe so the error is
90
+ * always serializable.
91
+ *
92
+ * Declared `protected`: instantiate a concrete subclass, never `AppError`.
93
+ *
94
+ * @param message - The internal, developer-facing message.
95
+ * @param code - The stable machine-readable code callers match on.
96
+ * @param options - Optional cause, metadata, severity, and correlation ids.
97
+ * @throws When `options.metadata` contains a value that is not JSON-safe.
98
+ */
99
+ protected constructor(message: string, code: string, options?: AppErrorOptions);
100
+ /**
101
+ * Returns a JSON-safe representation of the error.
102
+ * Does NOT include `cause` by default (to avoid leaking internal details).
103
+ */
104
+ toJSON(): Record<string, unknown>;
105
+ }
106
+ //#endregion
107
+ export { JsonSafeRecord as a, JsonSafePrimitive as i, AppErrorOptions as n, JsonSafeValue as o, ErrorSeverity as r, AppError as t };
108
+ //# sourceMappingURL=app-error.d.ts.map
@@ -0,0 +1,2 @@
1
+ import { A as TracerPort, C as RequestedBy, D as UseCaseObservability, E as UseCase, M as MetricsPort, N as LogPayload, O as TraceAttributeValue, P as LoggerPort, S as CommandInput, T as MaybePromise, _ as PolicyEvaluationInput, a as TemporalContext, b as PolicyPortError, c as CacheStrategy, d as mapPolicyEvaluationError, f as TemporalHistory, g as ResultRepository, h as Repository, i as CreateTemporalContextInput, j as MetricLabels, k as TraceSpan, l as Page, n as TemporalUseCaseInput, o as assertTemporalContext, p as TemporalRepository, r as TemporalizedContextSeed, s as createTemporalContext, t as TemporalUseCase, u as Query, v as PolicyEvaluationOutput, w as RequestedByKind, x as Command, y as PolicyPort } from "../temporal-use-case.js";
2
+ export { CacheStrategy, Command, CommandInput, CreateTemporalContextInput, LogPayload, LoggerPort, MaybePromise, MetricLabels, MetricsPort, Page, PolicyEvaluationInput, PolicyEvaluationOutput, PolicyPort, PolicyPortError, Query, Repository, RequestedBy, RequestedByKind, ResultRepository, TemporalContext, TemporalHistory, TemporalRepository, TemporalUseCase, TemporalUseCaseInput, TemporalizedContextSeed, TraceAttributeValue, TraceSpan, TracerPort, UseCase, UseCaseObservability, assertTemporalContext, createTemporalContext, mapPolicyEvaluationError };
@@ -0,0 +1,2 @@
1
+ import { a as Query, c as RequestedBy, l as UseCase, n as assertTemporalContext, o as mapPolicyEvaluationError, r as createTemporalContext, s as Command, t as TemporalUseCase } from "../temporal-use-case.js";
2
+ export { Command, Query, RequestedBy, TemporalUseCase, UseCase, assertTemporalContext, createTemporalContext, mapPolicyEvaluationError };
@@ -1,2 +1,3 @@
1
- import { $ as ErrorCodes, A as IdempotencyPayloadMismatchError, B as UniqueConstraintViolation, C as IntegrationErrorMetadata, D as IdempotencyFailureKind, E as IdempotencyErrorMetadata, F as AlreadyExistsError, G as AuthorizationErrorMetadata, H as translateUniqueViolationToDuplicate, I as ConflictError, J as AuthenticationError, K as AuthorizationErrorReason, L as ConflictErrorMetadata, M as payloadHash, N as sha256Hex, O as IdempotencyInProgressError, P as stableStringify, Q as assertJsonSafeMetadata, R as ConflictKind, S as IntegrationError, T as IdempotencyError, U as BusinessRuleViolationError, V as UniqueConstraintViolationError, W as AuthorizationError, X as AuthenticationErrorReason, Y as AuthenticationErrorMetadata, Z as AppError, _ as SerializationMessages, a as TemporalError, at as JsonSafeValue, b as NotFoundError, c as TemporalPrecision, d as SerializationCodes, et as serializationErrorCode, f as SerializationDirection, g as SerializationInError, h as SerializationFailureCategory, i as NotYetValidError, it as JsonSafeRecord, j as IdempotencyReplayNotSupportedError, k as IdempotencyKeyMissingError, l as evaluateTemporalWindow, m as SerializationErrorMetadata, n as UnexpectedError, nt as ErrorSeverity, o as TemporalErrorMetadata, p as SerializationError, q as AuthorizationRequirement, r as ExpiredError, rt as JsonSafePrimitive, s as TemporalKind, t as ValidationError, tt as AppErrorOptions, u as SerializationBoundary, v as SerializationOutError, w as IntegrationErrorReason, x as LegacyIncompatibleError, y as safePreview, z as DuplicateError } from "../validation-error.js";
1
+ import { a as JsonSafeRecord, i as JsonSafePrimitive, n as AppErrorOptions, o as JsonSafeValue, r as ErrorSeverity, t as AppError } from "../app-error.js";
2
+ import { $ as serializationErrorCode, A as IdempotencyPayloadMismatchError, B as UniqueConstraintViolation, C as IntegrationErrorMetadata, D as IdempotencyFailureKind, E as IdempotencyErrorMetadata, F as AlreadyExistsError, G as AuthorizationErrorMetadata, H as translateUniqueViolationToDuplicate, I as ConflictError, J as AuthenticationError, K as AuthorizationErrorReason, L as ConflictErrorMetadata, M as payloadHash, N as sha256Hex, O as IdempotencyInProgressError, P as stableStringify, Q as ErrorCodes, R as ConflictKind, S as IntegrationError, T as IdempotencyError, U as BusinessRuleViolationError, V as UniqueConstraintViolationError, W as AuthorizationError, X as AuthenticationErrorReason, Y as AuthenticationErrorMetadata, Z as assertJsonSafeMetadata, _ as SerializationMessages, a as TemporalError, b as NotFoundError, c as TemporalPrecision, d as SerializationCodes, f as SerializationDirection, g as SerializationInError, h as SerializationFailureCategory, i as NotYetValidError, j as IdempotencyReplayNotSupportedError, k as IdempotencyKeyMissingError, l as evaluateTemporalWindow, m as SerializationErrorMetadata, n as UnexpectedError, o as TemporalErrorMetadata, p as SerializationError, q as AuthorizationRequirement, r as ExpiredError, s as TemporalKind, t as ValidationError, u as SerializationBoundary, v as SerializationOutError, w as IntegrationErrorReason, x as LegacyIncompatibleError, y as safePreview, z as DuplicateError } from "../validation-error.js";
2
3
  export { AlreadyExistsError, AppError, AppErrorOptions, AuthenticationError, AuthenticationErrorMetadata, AuthenticationErrorReason, AuthorizationError, AuthorizationErrorMetadata, AuthorizationErrorReason, AuthorizationRequirement, BusinessRuleViolationError, ConflictError, ConflictErrorMetadata, ConflictKind, SerializationInError as DeserializationError, SerializationInError, DuplicateError, ErrorCodes, ErrorSeverity, ExpiredError, TemporalErrorMetadata as ExpiredErrorMetadata, TemporalErrorMetadata, TemporalPrecision as ExpiredErrorPrecision, TemporalPrecision, IdempotencyError, IdempotencyErrorMetadata, IdempotencyFailureKind, IdempotencyInProgressError, IdempotencyKeyMissingError, IdempotencyPayloadMismatchError, IdempotencyReplayNotSupportedError, IntegrationError, IntegrationErrorMetadata, IntegrationErrorReason, JsonSafePrimitive, JsonSafeRecord, JsonSafeValue, LegacyIncompatibleError, NotFoundError, NotYetValidError, SerializationBoundary, SerializationCodes, SerializationDirection, SerializationError, SerializationErrorMetadata, SerializationFailureCategory, SerializationMessages, SerializationOutError, TemporalError, TemporalKind, UnexpectedError, UniqueConstraintViolation, UniqueConstraintViolationError, ValidationError, assertJsonSafeMetadata, evaluateTemporalWindow, payloadHash, safePreview, serializationErrorCode, sha256Hex, stableStringify, translateUniqueViolationToDuplicate };
@@ -1,3 +1,5 @@
1
- import { a as stableStringify, c as ErrorCodes, i as sha256Hex, l as serializationErrorCode, n as UnexpectedError, o as AppError, r as payloadHash, s as assertJsonSafeMetadata } from "../validation-code.js";
2
- import { C as UniqueConstraintViolationError, D as AuthenticationError, E as AuthorizationError, S as DuplicateError, T as BusinessRuleViolationError, _ as IdempotencyKeyMissingError, a as evaluateTemporalWindow, b as AlreadyExistsError, c as SerializationInError, d as safePreview, f as NotFoundError, g as IdempotencyInProgressError, h as IdempotencyError, i as TemporalError, l as SerializationMessages, m as IntegrationError, n as ExpiredError, o as SerializationCodes, p as LegacyIncompatibleError, r as NotYetValidError, s as SerializationError, t as ValidationError, u as SerializationOutError, v as IdempotencyPayloadMismatchError, w as translateUniqueViolationToDuplicate, x as ConflictError, y as IdempotencyReplayNotSupportedError } from "../validation-error.js";
1
+ import { a as ErrorCodes, i as assertJsonSafeMetadata, n as UnexpectedError, o as serializationErrorCode, r as AppError } from "../validation-code.js";
2
+ import { C as translateUniqueViolationToDuplicate, S as UniqueConstraintViolationError, T as AuthenticationError, _ as IdempotencyPayloadMismatchError, a as evaluateTemporalWindow, b as ConflictError, c as SerializationInError, d as safePreview, f as LegacyIncompatibleError, g as IdempotencyKeyMissingError, h as IdempotencyInProgressError, i as TemporalError, l as SerializationMessages, m as IdempotencyError, n as ExpiredError, o as SerializationCodes, p as IntegrationError, r as NotYetValidError, s as SerializationError, t as ValidationError, u as SerializationOutError, v as IdempotencyReplayNotSupportedError, w as AuthorizationError, x as DuplicateError, y as AlreadyExistsError } from "../validation-error.js";
3
+ import { n as BusinessRuleViolationError, t as NotFoundError } from "../not-found-error.js";
4
+ import { n as sha256Hex, r as stableStringify, t as payloadHash } from "../hashing.js";
3
5
  export { AlreadyExistsError, AppError, AuthenticationError, AuthorizationError, BusinessRuleViolationError, ConflictError, SerializationInError as DeserializationError, SerializationInError, DuplicateError, ErrorCodes, ExpiredError, IdempotencyError, IdempotencyInProgressError, IdempotencyKeyMissingError, IdempotencyPayloadMismatchError, IdempotencyReplayNotSupportedError, IntegrationError, LegacyIncompatibleError, NotFoundError, NotYetValidError, SerializationCodes, SerializationError, SerializationMessages, SerializationOutError, TemporalError, UnexpectedError, UniqueConstraintViolationError, ValidationError, assertJsonSafeMetadata, evaluateTemporalWindow, payloadHash, safePreview, serializationErrorCode, sha256Hex, stableStringify, translateUniqueViolationToDuplicate };
@@ -0,0 +1,80 @@
1
+ import { I as Result, c as PolicyViolation, g as CoreConfig, h as Outcome, l as VersionedGateEngine, p as ConditionNode, s as PolicyContext, t as GateOutcome } from "./gate-types.js";
2
+ import { z } from "zod";
3
+
4
+ //#region src/core/policies/engines/v1/compute/compute-payload.schema.d.ts
5
+ interface ComputeParamsPayload {
6
+ readonly type: "params";
7
+ readonly data: Readonly<Record<string, unknown>>;
8
+ }
9
+ interface ComputeDecisionTableRule<R = unknown> {
10
+ readonly conditions: ConditionNode;
11
+ readonly result: R;
12
+ }
13
+ interface ComputeDecisionTablePayload<R = unknown> {
14
+ readonly type: "decision-table";
15
+ readonly rules: readonly ComputeDecisionTableRule<R>[];
16
+ readonly default: R;
17
+ }
18
+ type ComputePayloadV1 = ComputeDecisionTablePayload<unknown> | ComputeParamsPayload;
19
+ //#endregion
20
+ //#region src/core/policies/engines/compute-payload.d.ts
21
+ type ComputePayload = ComputePayloadV1;
22
+ //#endregion
23
+ //#region src/core/policies/engines/compute-types.d.ts
24
+ type ComputeStatus = "OK" | "NOT_APPLICABLE" | "ERROR";
25
+ interface ComputeOutcomeData {
26
+ readonly values: unknown | null;
27
+ readonly violations: readonly PolicyViolation[];
28
+ }
29
+ /** Semantic outcome of a COMPUTE policy evaluation. */
30
+ type ComputeOutcome = Outcome<ComputeStatus, ComputeOutcomeData>;
31
+ /**
32
+ * Pure compute operation: receives a resolved value + context, returns a
33
+ * business decision. Registration metadata (policy key/version) lives outside
34
+ * this contract.
35
+ *
36
+ * The engine resolves the structural payload before calling the evaluator:
37
+ * - `params` -> `payload.data`
38
+ * - `decision-table` -> matching `rule.result` or `default`
39
+ *
40
+ * Result wraps technical failures (invalid value shape).
41
+ * Outcome carries the semantic business decision.
42
+ */
43
+ interface ComputeEvaluator {
44
+ evaluate(resolvedValue: unknown, context: Record<string, unknown>): Result<ComputeOutcome, string>;
45
+ }
46
+ interface ComputeEvaluatorRegistration {
47
+ readonly policyKey: string;
48
+ readonly version: number;
49
+ readonly evaluator: ComputeEvaluator;
50
+ }
51
+ interface VersionedComputeEngine {
52
+ readonly version: number;
53
+ evaluate(payload: ComputePayload, context: PolicyContext, evaluator: ComputeEvaluator): Result<ComputeOutcome, string>;
54
+ }
55
+ //#endregion
56
+ //#region src/core/policies/engines/compute-registry.d.ts
57
+ interface ComputeRegistryOptions {
58
+ readonly coreConfig?: CoreConfig;
59
+ }
60
+ declare class ComputeRegistry {
61
+ private readonly engines;
62
+ private readonly evaluators;
63
+ constructor(params?: ComputeRegistryOptions);
64
+ register(registration: ComputeEvaluatorRegistration): void;
65
+ registerEngine(engine: VersionedComputeEngine): void;
66
+ getEngine(version: number): VersionedComputeEngine | undefined;
67
+ getEvaluator(policyKey: string, version: number): ComputeEvaluator | undefined;
68
+ evaluate(policyKey: string, computeEngineVersion: number, payloadSchemaVersion: number, payload: unknown, context: PolicyContext): Result<ComputeOutcome, string>;
69
+ }
70
+ //#endregion
71
+ //#region src/core/policies/engines/gate-engine-registry.d.ts
72
+ declare class GateEngineRegistry {
73
+ private readonly engines;
74
+ register(engine: VersionedGateEngine): void;
75
+ get(version: number): VersionedGateEngine | undefined;
76
+ evaluate(version: number, payload: unknown, context: PolicyContext): Result<GateOutcome, string>;
77
+ }
78
+ //#endregion
79
+ export { ComputeOutcome as a, VersionedComputeEngine as c, ComputeDecisionTableRule as d, ComputeParamsPayload as f, ComputeEvaluatorRegistration as i, ComputePayload as l, ComputeRegistry as n, ComputeOutcomeData as o, ComputePayloadV1 as p, ComputeEvaluator as r, ComputeStatus as s, GateEngineRegistry as t, ComputeDecisionTablePayload as u };
80
+ //# sourceMappingURL=gate-engine-registry.d.ts.map
@@ -1,31 +1,5 @@
1
+ import { r as isValidDate } from "./temporal-guards.js";
1
2
  import { z } from "zod";
2
- //#region src/core/exceptions/domain-exception.ts
3
- var DomainException = class extends Error {
4
- constructor(message) {
5
- super(message);
6
- Object.setPrototypeOf(this, new.target.prototype);
7
- this.name = new.target.name;
8
- }
9
- };
10
- //#endregion
11
- //#region src/core/exceptions/invariant-violation-exception.ts
12
- var InvariantViolationException = class extends DomainException {
13
- constructor(message) {
14
- super(message);
15
- }
16
- };
17
- //#endregion
18
- //#region src/core/shared/temporal-guards.ts
19
- function isValidDate(value) {
20
- return value instanceof Date && !Number.isNaN(value.getTime());
21
- }
22
- function cloneDate(date) {
23
- return new Date(date.getTime());
24
- }
25
- function assertValidDate(fieldName, value) {
26
- if (!isValidDate(value)) throw new InvariantViolationException(`${fieldName} must be a valid Date instance`);
27
- }
28
- //#endregion
29
3
  //#region src/core/config/silent-policy-reporter.ts
30
4
  var SilentPolicyReporter = class {
31
5
  report(_event) {}
@@ -720,6 +694,6 @@ var GatePayloadSchemaV1 = class GatePayloadSchemaV1 {
720
694
  };
721
695
  const gatePayloadSchema = GatePayloadSchemaV1.schema;
722
696
  //#endregion
723
- export { DomainException as _, conditionNodeSchema as a, Ok as c, CoreConfig as d, SilentPolicyReporter as f, InvariantViolationException as g, isValidDate as h, conditionLeafNodeSchema as i, Result as l, cloneDate as m, gatePayloadSchema as n, PolicyContextPath as o, assertValidDate as p, ConditionEvaluatorV1 as r, Err as s, GatePayloadSchemaV1 as t, coreConfig as u };
697
+ export { conditionNodeSchema as a, Ok as c, CoreConfig as d, SilentPolicyReporter as f, conditionLeafNodeSchema as i, Result as l, gatePayloadSchema as n, PolicyContextPath as o, ConditionEvaluatorV1 as r, Err as s, GatePayloadSchemaV1 as t, coreConfig as u };
724
698
 
725
699
  //# sourceMappingURL=gate-v1-payload.schema.js.map