evo360-types 1.3.656 → 1.3.662

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 (31) hide show
  1. package/dist/apps/evo-csq/zod-schemas.d.ts +40 -40
  2. package/dist/apps/evo-modules/zod-schemas.d.ts +446 -0
  3. package/dist/apps/evo-modules/zod-schemas.js +143 -0
  4. package/dist/apps/evo-modules/zod-schemas.ts +153 -0
  5. package/dist/apps/evo-task/zod-schemas.d.ts +201 -4
  6. package/dist/apps/evo-task/zod-schemas.js +22 -2
  7. package/dist/apps/evo-task/zod-schemas.ts +23 -1
  8. package/dist/index.d.ts +2 -0
  9. package/dist/index.js +2 -0
  10. package/dist/index.ts +2 -0
  11. package/dist/types/evo-modules/activation.d.ts +46 -0
  12. package/dist/types/evo-modules/activation.js +131 -0
  13. package/dist/types/evo-modules/activation.ts +150 -0
  14. package/dist/types/evo-modules/catalog.d.ts +28 -0
  15. package/dist/types/evo-modules/catalog.js +130 -0
  16. package/dist/types/evo-modules/catalog.ts +131 -0
  17. package/dist/types/evo-modules/index.d.ts +227 -0
  18. package/dist/types/evo-modules/index.js +75 -0
  19. package/dist/types/evo-modules/index.ts +329 -0
  20. package/dist/types/evo-task/index.d.ts +14 -0
  21. package/dist/types/evo-task/index.js +3 -0
  22. package/dist/types/evo-task/index.ts +25 -0
  23. package/dist/types/evo-task-runner/index.d.ts +2 -1
  24. package/dist/types/evo-task-runner/index.ts +5 -1
  25. package/dist/types/evo-telemedicine/fb_collections.js +1 -1
  26. package/dist/types/evo-telemedicine/fb_collections.ts +1 -1
  27. package/dist/types/evo-telemedicine/index.d.ts +8 -12
  28. package/dist/types/evo-telemedicine/index.ts +8 -12
  29. package/dist/types/evo-tenant/index.ts +3 -1
  30. package/fixtures/tenant-modules/is-module-active.parity.json +364 -0
  31. package/package.json +7 -4
@@ -0,0 +1,227 @@
1
+ import type { IFireDoc, IFireGlobalDoc } from "../shared";
2
+ import type { ITenantModuleEntitlement, TenantModuleSource, TenantModuleStatus } from "../evo-tenant";
3
+ import type { EntitlementAuditAction, IEntitlementAuditActor } from "../evo-telemedicine";
4
+ export * from "./catalog";
5
+ export * from "./activation";
6
+ export declare const EVO_MODULES_APP = "evo-modules";
7
+ export declare const MODULES_ENTITLEMENT_AUDIT_COLLECTION = "entitlement-audit";
8
+ export declare const MODULES_PROVISIONING_COLLECTION = "provisioning";
9
+ export declare const MODULES_ROLLOUT_PLATFORM_PATH = "platform/evo-modules/rollout";
10
+ /** TTL do lock por tenant+módulo durante um apply. */
11
+ export declare const MODULES_LOCK_TTL_MS: number;
12
+ /** Regex da chave de módulo (`tenants/{t}.modules[key]`). */
13
+ export declare const MODULE_KEY_PATTERN: RegExp;
14
+ export type ModuleAction = "enable" | "disable" | "trial" | "override";
15
+ export declare const ModuleActionEnum: {
16
+ readonly Enable: "enable";
17
+ readonly Disable: "disable";
18
+ readonly Trial: "trial";
19
+ readonly Override: "override";
20
+ };
21
+ export type ModuleStepKind = "entitlement" | "rbac_group" | "rbac_recompute" | "contract_allowance" | "contract_check" | "rollout_check";
22
+ export declare const ModuleStepKindEnum: {
23
+ readonly Entitlement: "entitlement";
24
+ readonly RbacGroup: "rbac_group";
25
+ readonly RbacRecompute: "rbac_recompute";
26
+ readonly ContractAllowance: "contract_allowance";
27
+ readonly ContractCheck: "contract_check";
28
+ readonly RolloutCheck: "rollout_check";
29
+ };
30
+ export declare const MODULE_STEP_KINDS: readonly ModuleStepKind[];
31
+ export interface IModuleRolloutDescriptor {
32
+ /** Path completo do doc (4 segmentos: `platform/<app>/<col>/<doc>`). */
33
+ path: string;
34
+ /**
35
+ * `flags_map`: doc genérico `{ flags: { [flag]: boolean }, emergency_kill }`.
36
+ * `legacy_fields`: doc com um campo booleano por flag (telemedicina).
37
+ */
38
+ layout: "flags_map" | "legacy_fields";
39
+ /** flag -> campo do doc (`legacy_fields`) ou chave em `flags` (`flags_map`). */
40
+ flags: Record<string, string>;
41
+ }
42
+ export interface IModuleCapabilityDefinition {
43
+ label: string;
44
+ default: boolean | number | string;
45
+ }
46
+ export interface IModuleAllowanceMetric {
47
+ /** Chave de `NexFinopsMetricCatalog`. */
48
+ metric: string;
49
+ /** Gravado no contrato vigente quando a chave está ausente (Q6). */
50
+ default_included: number;
51
+ }
52
+ export interface IPlatformModuleDefinition {
53
+ /** `MODULE_KEY_PATTERN`; é a chave em `tenants/{t}.modules`. */
54
+ key: string;
55
+ label: string;
56
+ description?: string;
57
+ /** App do Firestore onde vivem os dados do módulo (`evo-telemedicine`, `evo-csq`). */
58
+ app_id: string;
59
+ capabilities: Record<string, IModuleCapabilityDefinition>;
60
+ /** Status/origem gravados no `enable` de um tenant sem entitlement. */
61
+ default_entitlement: {
62
+ status: TenantModuleStatus;
63
+ source: TenantModuleSource;
64
+ };
65
+ /** Tenant novo nasce com o módulo (`createTenant`). */
66
+ default_for_new_tenants: boolean;
67
+ /** Grupos RBAC globais que tornam os papéis do módulo atribuíveis. */
68
+ rbac_groups: string[];
69
+ allowance_metrics: IModuleAllowanceMetric[];
70
+ rollout: IModuleRolloutDescriptor | null;
71
+ depends_on: string[];
72
+ provisioning: {
73
+ enable: ModuleStepKind[];
74
+ disable: ModuleStepKind[];
75
+ };
76
+ legacy?: {
77
+ /** Trilhas antigas (relativas a `tenants/{t}/`), lidas pelo histórico e nunca escritas. */
78
+ audit_collections?: string[];
79
+ };
80
+ }
81
+ export type ModuleStepStatus = "pending" | "noop" | "change" | "done" | "failed" | "blocked" | "skipped";
82
+ export interface IModuleProvisioningStep {
83
+ kind: ModuleStepKind;
84
+ status: ModuleStepStatus;
85
+ summary: string;
86
+ before?: unknown;
87
+ after?: unknown;
88
+ error?: string | null;
89
+ started_at?: Date | null;
90
+ finished_at?: Date | null;
91
+ }
92
+ export type ModuleRunMode = "plan" | "apply";
93
+ export type ModuleRunStatus = "planned" | "running" | "done" | "failed" | "blocked" | "superseded";
94
+ export interface IModuleChangeParams {
95
+ /** `trial`: obrigatório. */
96
+ expires_at?: Date | null;
97
+ /** `override`: obrigatório. */
98
+ override_until?: Date | null;
99
+ /** `enable`: libera o passo `contract_allowance` quando ele vem `blocked` (Q6). */
100
+ allow_without_contract?: boolean;
101
+ /** `disable`: remove o grupo RBAC se nenhum outro módulo ativo o declara (Q7). */
102
+ purge_rbac?: boolean;
103
+ /** `disable`: grava `suspended` em vez de `cancelled`. */
104
+ suspend?: boolean;
105
+ }
106
+ export interface IModuleRunActor extends IEntitlementAuditActor {
107
+ login_id?: string;
108
+ }
109
+ export interface IModuleProvisioningRun extends IFireDoc {
110
+ tenant: string;
111
+ module: string;
112
+ action: ModuleAction;
113
+ mode: ModuleRunMode;
114
+ status: ModuleRunStatus;
115
+ params: IModuleChangeParams;
116
+ /** Hash estável dos passos planejados (kind+status+after). Muda ⇒ `PLAN_DRIFT`. */
117
+ plan_hash: string;
118
+ /** `PLATFORM_MODULE_CATALOG_VERSION` de quem planejou/aplicou. */
119
+ types_version: string;
120
+ steps: IModuleProvisioningStep[];
121
+ actor: IModuleRunActor;
122
+ reason: string;
123
+ /** Run `apply` que este retoma. */
124
+ resumed_from?: string | null;
125
+ /** Run `plan` que originou este `apply`. */
126
+ plan_run_id?: string | null;
127
+ error?: string | null;
128
+ finished_at?: Date | null;
129
+ }
130
+ /** Lock no doc `tenants/{t}/apps/evo-modules`, campo `locks.{module}`. */
131
+ export interface IModuleLock {
132
+ run_id: string;
133
+ expires_at: Date;
134
+ }
135
+ export interface IModuleRolloutDoc extends IFireGlobalDoc {
136
+ flags: Record<string, boolean>;
137
+ emergency_kill: boolean;
138
+ updated_at: Date;
139
+ updated_by: string;
140
+ }
141
+ /** Estado de rollout normalizado (o mesmo para os dois layouts). */
142
+ export interface IModuleRolloutState {
143
+ module: string;
144
+ path: string;
145
+ /** `false` ⇒ doc ausente/ilegível: tudo negado. */
146
+ exists: boolean;
147
+ flags: Record<string, boolean>;
148
+ emergency_kill: boolean;
149
+ updated_at: Date | null;
150
+ updated_by: string | null;
151
+ }
152
+ export interface IModuleEntitlementAudit extends IFireDoc {
153
+ module: string;
154
+ action: EntitlementAuditAction;
155
+ before?: ITenantModuleEntitlement | null;
156
+ after: ITenantModuleEntitlement;
157
+ actor: IEntitlementAuditActor;
158
+ reason: string;
159
+ occurred_at: Date;
160
+ correlation_id?: string;
161
+ run_id?: string;
162
+ }
163
+ export interface IModuleStepContext {
164
+ tenant: string;
165
+ module: IPlatformModuleDefinition;
166
+ action: ModuleAction;
167
+ params: IModuleChangeParams;
168
+ actor_user_id: string | null;
169
+ /** Passos anteriores do mesmo run (estado corrente). */
170
+ previous_steps?: IModuleProvisioningStep[];
171
+ }
172
+ export type ModuleStepPlanResult = Pick<IModuleProvisioningStep, "status" | "summary" | "before" | "after">;
173
+ export type ModuleStepApplyResult = Pick<IModuleProvisioningStep, "status" | "summary" | "after">;
174
+ export interface IModuleStepExecutor {
175
+ plan(ctx: IModuleStepContext): Promise<ModuleStepPlanResult>;
176
+ apply(ctx: IModuleStepContext): Promise<ModuleStepApplyResult>;
177
+ }
178
+ export interface IModuleChangeRequest {
179
+ tenant: string;
180
+ module: string;
181
+ action: ModuleAction;
182
+ params?: IModuleChangeParams;
183
+ reason: string;
184
+ }
185
+ export interface IModuleApplyRequest {
186
+ tenant: string;
187
+ /** Aplica o plano deste run (`mode: 'plan'`). Exclusivo com `resume_run_id`. */
188
+ plan_run_id?: string;
189
+ /** Retoma um run `apply` em `failed`/`blocked`. */
190
+ resume_run_id?: string;
191
+ /** Sobrepõe params do plano (só `allow_without_contract` faz sentido aqui). */
192
+ params?: Pick<IModuleChangeParams, "allow_without_contract">;
193
+ }
194
+ export interface IModuleOverviewRequest {
195
+ tenant: string;
196
+ }
197
+ export interface IModuleOverviewEntry {
198
+ definition: IPlatformModuleDefinition;
199
+ entitlement: ITenantModuleEntitlement | null;
200
+ active: boolean;
201
+ rollout: IModuleRolloutState | null;
202
+ }
203
+ export interface IModuleOverviewResponse {
204
+ ok: true;
205
+ tenant: string;
206
+ catalog_version: string;
207
+ modules: IModuleOverviewEntry[];
208
+ /** Últimos 10 runs (plan e apply), mais recentes primeiro. */
209
+ runs: IModuleProvisioningRun[];
210
+ /** Últimas 30 entradas de auditoria (caminho genérico + legados), por `occurred_at` desc. */
211
+ audit: IModuleEntitlementAudit[];
212
+ }
213
+ export interface IModulePlanResponse {
214
+ ok: true;
215
+ run: IModuleProvisioningRun;
216
+ }
217
+ export type ModuleApplyErrorCode = "PLAN_DRIFT" | "MODULE_LOCKED" | "RUN_NOT_FOUND" | "RUN_NOT_RESUMABLE";
218
+ export type IModuleApplyResponse = {
219
+ ok: true;
220
+ run: IModuleProvisioningRun;
221
+ }
222
+ /** O estado mudou desde o plano: `plan` é o run novo (`mode: 'plan'`) para revisar. */
223
+ | {
224
+ ok: false;
225
+ error: "PLAN_DRIFT";
226
+ plan: IModuleProvisioningRun;
227
+ };
@@ -0,0 +1,75 @@
1
+ "use strict";
2
+ // ======================================================
3
+ // evo-modules (feat-263 — Módulos da plataforma)
4
+ //
5
+ // Entitlement de módulos por tenant: "este cliente tem direito ao módulo X?".
6
+ // NÃO é feature flag: o kill switch operacional de cada módulo é o `rollout`
7
+ // (doc de plataforma), um gate independente.
8
+ //
9
+ // Storage do estado continua em `tenants/{t}.modules[key]`
10
+ // (`ITenantModuleEntitlement`, feat-160 D5). Este namespace acrescenta:
11
+ // - o catálogo em código (`PLATFORM_MODULE_CATALOG`), que carrega
12
+ // comportamento (passos de provisionamento, grupos RBAC, métricas de franquia);
13
+ // - a decisão única `isModuleActive` / `hasModuleCapability`, usada por
14
+ // backend, web-app e Nexus (o Flutter espelha pela fixture de paridade);
15
+ // - os tipos do run de provisionamento, do doc de rollout genérico e da
16
+ // auditoria genérica.
17
+ //
18
+ // Firestore (por tenant):
19
+ // - App doc (locks): /tenants/{t}/apps/evo-modules campo `locks.{module}`
20
+ // - Auditoria: /tenants/{t}/apps/evo-modules/entitlement-audit/{id}
21
+ // - Provisionamento: /tenants/{t}/apps/evo-modules/provisioning/{runId}
22
+ //
23
+ // Plataforma (só backend):
24
+ // - Rollout genérico: /platform/evo-modules/rollout/{module}
25
+ // (a telemedicina continua em `platform/evo-telemedicine/config/rollout`,
26
+ // lida pelo mesmo reader via `rollout.layout = 'legacy_fields'`).
27
+ // ======================================================
28
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
29
+ if (k2 === undefined) k2 = k;
30
+ var desc = Object.getOwnPropertyDescriptor(m, k);
31
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
32
+ desc = { enumerable: true, get: function() { return m[k]; } };
33
+ }
34
+ Object.defineProperty(o, k2, desc);
35
+ }) : (function(o, m, k, k2) {
36
+ if (k2 === undefined) k2 = k;
37
+ o[k2] = m[k];
38
+ }));
39
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
40
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
41
+ };
42
+ Object.defineProperty(exports, "__esModule", { value: true });
43
+ exports.MODULE_STEP_KINDS = exports.ModuleStepKindEnum = exports.ModuleActionEnum = exports.MODULE_KEY_PATTERN = exports.MODULES_LOCK_TTL_MS = exports.MODULES_ROLLOUT_PLATFORM_PATH = exports.MODULES_PROVISIONING_COLLECTION = exports.MODULES_ENTITLEMENT_AUDIT_COLLECTION = exports.EVO_MODULES_APP = void 0;
44
+ __exportStar(require("./catalog"), exports);
45
+ __exportStar(require("./activation"), exports);
46
+ exports.EVO_MODULES_APP = "evo-modules";
47
+ exports.MODULES_ENTITLEMENT_AUDIT_COLLECTION = "entitlement-audit";
48
+ exports.MODULES_PROVISIONING_COLLECTION = "provisioning";
49
+ exports.MODULES_ROLLOUT_PLATFORM_PATH = "platform/evo-modules/rollout";
50
+ /** TTL do lock por tenant+módulo durante um apply. */
51
+ exports.MODULES_LOCK_TTL_MS = 10 * 60 * 1000;
52
+ /** Regex da chave de módulo (`tenants/{t}.modules[key]`). */
53
+ exports.MODULE_KEY_PATTERN = /^[a-z][a-z0-9_]{1,40}$/;
54
+ exports.ModuleActionEnum = {
55
+ Enable: "enable",
56
+ Disable: "disable",
57
+ Trial: "trial",
58
+ Override: "override",
59
+ };
60
+ exports.ModuleStepKindEnum = {
61
+ Entitlement: "entitlement",
62
+ RbacGroup: "rbac_group",
63
+ RbacRecompute: "rbac_recompute",
64
+ ContractAllowance: "contract_allowance",
65
+ ContractCheck: "contract_check",
66
+ RolloutCheck: "rollout_check",
67
+ };
68
+ exports.MODULE_STEP_KINDS = [
69
+ "entitlement",
70
+ "rbac_group",
71
+ "rbac_recompute",
72
+ "contract_allowance",
73
+ "contract_check",
74
+ "rollout_check",
75
+ ];
@@ -0,0 +1,329 @@
1
+ // ======================================================
2
+ // evo-modules (feat-263 — Módulos da plataforma)
3
+ //
4
+ // Entitlement de módulos por tenant: "este cliente tem direito ao módulo X?".
5
+ // NÃO é feature flag: o kill switch operacional de cada módulo é o `rollout`
6
+ // (doc de plataforma), um gate independente.
7
+ //
8
+ // Storage do estado continua em `tenants/{t}.modules[key]`
9
+ // (`ITenantModuleEntitlement`, feat-160 D5). Este namespace acrescenta:
10
+ // - o catálogo em código (`PLATFORM_MODULE_CATALOG`), que carrega
11
+ // comportamento (passos de provisionamento, grupos RBAC, métricas de franquia);
12
+ // - a decisão única `isModuleActive` / `hasModuleCapability`, usada por
13
+ // backend, web-app e Nexus (o Flutter espelha pela fixture de paridade);
14
+ // - os tipos do run de provisionamento, do doc de rollout genérico e da
15
+ // auditoria genérica.
16
+ //
17
+ // Firestore (por tenant):
18
+ // - App doc (locks): /tenants/{t}/apps/evo-modules campo `locks.{module}`
19
+ // - Auditoria: /tenants/{t}/apps/evo-modules/entitlement-audit/{id}
20
+ // - Provisionamento: /tenants/{t}/apps/evo-modules/provisioning/{runId}
21
+ //
22
+ // Plataforma (só backend):
23
+ // - Rollout genérico: /platform/evo-modules/rollout/{module}
24
+ // (a telemedicina continua em `platform/evo-telemedicine/config/rollout`,
25
+ // lida pelo mesmo reader via `rollout.layout = 'legacy_fields'`).
26
+ // ======================================================
27
+
28
+ import type { IFireDoc, IFireGlobalDoc } from "../shared";
29
+ import type {
30
+ ITenantModuleEntitlement,
31
+ TenantModuleSource,
32
+ TenantModuleStatus,
33
+ } from "../evo-tenant";
34
+ import type {
35
+ EntitlementAuditAction,
36
+ IEntitlementAuditActor,
37
+ } from "../evo-telemedicine";
38
+
39
+ export * from "./catalog";
40
+ export * from "./activation";
41
+
42
+ export const EVO_MODULES_APP = "evo-modules";
43
+ export const MODULES_ENTITLEMENT_AUDIT_COLLECTION = "entitlement-audit";
44
+ export const MODULES_PROVISIONING_COLLECTION = "provisioning";
45
+ export const MODULES_ROLLOUT_PLATFORM_PATH = "platform/evo-modules/rollout";
46
+ /** TTL do lock por tenant+módulo durante um apply. */
47
+ export const MODULES_LOCK_TTL_MS = 10 * 60 * 1000;
48
+
49
+ /** Regex da chave de módulo (`tenants/{t}.modules[key]`). */
50
+ export const MODULE_KEY_PATTERN = /^[a-z][a-z0-9_]{1,40}$/;
51
+
52
+ export type ModuleAction = "enable" | "disable" | "trial" | "override";
53
+ export const ModuleActionEnum = {
54
+ Enable: "enable",
55
+ Disable: "disable",
56
+ Trial: "trial",
57
+ Override: "override",
58
+ } as const;
59
+
60
+ export type ModuleStepKind =
61
+ | "entitlement"
62
+ | "rbac_group"
63
+ | "rbac_recompute"
64
+ | "contract_allowance"
65
+ | "contract_check"
66
+ | "rollout_check";
67
+ export const ModuleStepKindEnum = {
68
+ Entitlement: "entitlement",
69
+ RbacGroup: "rbac_group",
70
+ RbacRecompute: "rbac_recompute",
71
+ ContractAllowance: "contract_allowance",
72
+ ContractCheck: "contract_check",
73
+ RolloutCheck: "rollout_check",
74
+ } as const;
75
+ export const MODULE_STEP_KINDS: readonly ModuleStepKind[] = [
76
+ "entitlement",
77
+ "rbac_group",
78
+ "rbac_recompute",
79
+ "contract_allowance",
80
+ "contract_check",
81
+ "rollout_check",
82
+ ];
83
+
84
+ // ----- Catálogo
85
+
86
+ export interface IModuleRolloutDescriptor {
87
+ /** Path completo do doc (4 segmentos: `platform/<app>/<col>/<doc>`). */
88
+ path: string;
89
+ /**
90
+ * `flags_map`: doc genérico `{ flags: { [flag]: boolean }, emergency_kill }`.
91
+ * `legacy_fields`: doc com um campo booleano por flag (telemedicina).
92
+ */
93
+ layout: "flags_map" | "legacy_fields";
94
+ /** flag -> campo do doc (`legacy_fields`) ou chave em `flags` (`flags_map`). */
95
+ flags: Record<string, string>;
96
+ }
97
+
98
+ export interface IModuleCapabilityDefinition {
99
+ label: string;
100
+ default: boolean | number | string;
101
+ }
102
+
103
+ export interface IModuleAllowanceMetric {
104
+ /** Chave de `NexFinopsMetricCatalog`. */
105
+ metric: string;
106
+ /** Gravado no contrato vigente quando a chave está ausente (Q6). */
107
+ default_included: number;
108
+ }
109
+
110
+ export interface IPlatformModuleDefinition {
111
+ /** `MODULE_KEY_PATTERN`; é a chave em `tenants/{t}.modules`. */
112
+ key: string;
113
+ label: string;
114
+ description?: string;
115
+ /** App do Firestore onde vivem os dados do módulo (`evo-telemedicine`, `evo-csq`). */
116
+ app_id: string;
117
+ capabilities: Record<string, IModuleCapabilityDefinition>;
118
+ /** Status/origem gravados no `enable` de um tenant sem entitlement. */
119
+ default_entitlement: { status: TenantModuleStatus; source: TenantModuleSource };
120
+ /** Tenant novo nasce com o módulo (`createTenant`). */
121
+ default_for_new_tenants: boolean;
122
+ /** Grupos RBAC globais que tornam os papéis do módulo atribuíveis. */
123
+ rbac_groups: string[];
124
+ allowance_metrics: IModuleAllowanceMetric[];
125
+ rollout: IModuleRolloutDescriptor | null;
126
+ depends_on: string[];
127
+ provisioning: { enable: ModuleStepKind[]; disable: ModuleStepKind[] };
128
+ legacy?: {
129
+ /** Trilhas antigas (relativas a `tenants/{t}/`), lidas pelo histórico e nunca escritas. */
130
+ audit_collections?: string[];
131
+ };
132
+ }
133
+
134
+ // ----- Run de provisionamento: tenants/{t}/apps/evo-modules/provisioning/{runId}
135
+
136
+ export type ModuleStepStatus =
137
+ | "pending"
138
+ | "noop"
139
+ | "change"
140
+ | "done"
141
+ | "failed"
142
+ | "blocked"
143
+ | "skipped";
144
+
145
+ export interface IModuleProvisioningStep {
146
+ kind: ModuleStepKind;
147
+ status: ModuleStepStatus;
148
+ summary: string;
149
+ before?: unknown;
150
+ after?: unknown;
151
+ error?: string | null;
152
+ started_at?: Date | null;
153
+ finished_at?: Date | null;
154
+ }
155
+
156
+ export type ModuleRunMode = "plan" | "apply";
157
+ export type ModuleRunStatus =
158
+ | "planned"
159
+ | "running"
160
+ | "done"
161
+ | "failed"
162
+ | "blocked"
163
+ | "superseded";
164
+
165
+ export interface IModuleChangeParams {
166
+ /** `trial`: obrigatório. */
167
+ expires_at?: Date | null;
168
+ /** `override`: obrigatório. */
169
+ override_until?: Date | null;
170
+ /** `enable`: libera o passo `contract_allowance` quando ele vem `blocked` (Q6). */
171
+ allow_without_contract?: boolean;
172
+ /** `disable`: remove o grupo RBAC se nenhum outro módulo ativo o declara (Q7). */
173
+ purge_rbac?: boolean;
174
+ /** `disable`: grava `suspended` em vez de `cancelled`. */
175
+ suspend?: boolean;
176
+ }
177
+
178
+ export interface IModuleRunActor extends IEntitlementAuditActor {
179
+ login_id?: string;
180
+ }
181
+
182
+ export interface IModuleProvisioningRun extends IFireDoc {
183
+ tenant: string;
184
+ module: string;
185
+ action: ModuleAction;
186
+ mode: ModuleRunMode;
187
+ status: ModuleRunStatus;
188
+ params: IModuleChangeParams;
189
+ /** Hash estável dos passos planejados (kind+status+after). Muda ⇒ `PLAN_DRIFT`. */
190
+ plan_hash: string;
191
+ /** `PLATFORM_MODULE_CATALOG_VERSION` de quem planejou/aplicou. */
192
+ types_version: string;
193
+ steps: IModuleProvisioningStep[];
194
+ actor: IModuleRunActor;
195
+ reason: string;
196
+ /** Run `apply` que este retoma. */
197
+ resumed_from?: string | null;
198
+ /** Run `plan` que originou este `apply`. */
199
+ plan_run_id?: string | null;
200
+ error?: string | null;
201
+ finished_at?: Date | null;
202
+ }
203
+
204
+ /** Lock no doc `tenants/{t}/apps/evo-modules`, campo `locks.{module}`. */
205
+ export interface IModuleLock {
206
+ run_id: string;
207
+ expires_at: Date;
208
+ }
209
+
210
+ // ----- Rollout genérico: platform/evo-modules/rollout/{module}
211
+
212
+ export interface IModuleRolloutDoc extends IFireGlobalDoc {
213
+ flags: Record<string, boolean>;
214
+ emergency_kill: boolean;
215
+ updated_at: Date;
216
+ updated_by: string;
217
+ }
218
+
219
+ /** Estado de rollout normalizado (o mesmo para os dois layouts). */
220
+ export interface IModuleRolloutState {
221
+ module: string;
222
+ path: string;
223
+ /** `false` ⇒ doc ausente/ilegível: tudo negado. */
224
+ exists: boolean;
225
+ flags: Record<string, boolean>;
226
+ emergency_kill: boolean;
227
+ updated_at: Date | null;
228
+ updated_by: string | null;
229
+ }
230
+
231
+ // ----- Auditoria genérica: tenants/{t}/apps/evo-modules/entitlement-audit/{id}
232
+
233
+ export interface IModuleEntitlementAudit extends IFireDoc {
234
+ module: string;
235
+ action: EntitlementAuditAction;
236
+ before?: ITenantModuleEntitlement | null;
237
+ after: ITenantModuleEntitlement;
238
+ actor: IEntitlementAuditActor;
239
+ reason: string;
240
+ occurred_at: Date;
241
+ correlation_id?: string;
242
+ run_id?: string;
243
+ }
244
+
245
+ // ----- Executor de passo injetável
246
+ //
247
+ // Permite que um passo seja implementado fora do `@evo/model` (ex.: a franquia
248
+ // no `@evo/nex-model`) sem dependência entre os packages: quem roda o runner
249
+ // (functions-nexus, CLI) registra o executor.
250
+
251
+ export interface IModuleStepContext {
252
+ tenant: string;
253
+ module: IPlatformModuleDefinition;
254
+ action: ModuleAction;
255
+ params: IModuleChangeParams;
256
+ actor_user_id: string | null;
257
+ /** Passos anteriores do mesmo run (estado corrente). */
258
+ previous_steps?: IModuleProvisioningStep[];
259
+ }
260
+
261
+ export type ModuleStepPlanResult = Pick<
262
+ IModuleProvisioningStep,
263
+ "status" | "summary" | "before" | "after"
264
+ >;
265
+ export type ModuleStepApplyResult = Pick<
266
+ IModuleProvisioningStep,
267
+ "status" | "summary" | "after"
268
+ >;
269
+
270
+ export interface IModuleStepExecutor {
271
+ plan(ctx: IModuleStepContext): Promise<ModuleStepPlanResult>;
272
+ apply(ctx: IModuleStepContext): Promise<ModuleStepApplyResult>;
273
+ }
274
+
275
+ // ----- Callables do Nexus (`nex_tenants-*`)
276
+ //
277
+ // Datas atravessam o callable como ISO string.
278
+
279
+ export interface IModuleChangeRequest {
280
+ tenant: string;
281
+ module: string;
282
+ action: ModuleAction;
283
+ params?: IModuleChangeParams;
284
+ reason: string;
285
+ }
286
+
287
+ export interface IModuleApplyRequest {
288
+ tenant: string;
289
+ /** Aplica o plano deste run (`mode: 'plan'`). Exclusivo com `resume_run_id`. */
290
+ plan_run_id?: string;
291
+ /** Retoma um run `apply` em `failed`/`blocked`. */
292
+ resume_run_id?: string;
293
+ /** Sobrepõe params do plano (só `allow_without_contract` faz sentido aqui). */
294
+ params?: Pick<IModuleChangeParams, "allow_without_contract">;
295
+ }
296
+
297
+ export interface IModuleOverviewRequest {
298
+ tenant: string;
299
+ }
300
+
301
+ export interface IModuleOverviewEntry {
302
+ definition: IPlatformModuleDefinition;
303
+ entitlement: ITenantModuleEntitlement | null;
304
+ active: boolean;
305
+ rollout: IModuleRolloutState | null;
306
+ }
307
+
308
+ export interface IModuleOverviewResponse {
309
+ ok: true;
310
+ tenant: string;
311
+ catalog_version: string;
312
+ modules: IModuleOverviewEntry[];
313
+ /** Últimos 10 runs (plan e apply), mais recentes primeiro. */
314
+ runs: IModuleProvisioningRun[];
315
+ /** Últimas 30 entradas de auditoria (caminho genérico + legados), por `occurred_at` desc. */
316
+ audit: IModuleEntitlementAudit[];
317
+ }
318
+
319
+ export interface IModulePlanResponse {
320
+ ok: true;
321
+ run: IModuleProvisioningRun;
322
+ }
323
+
324
+ export type ModuleApplyErrorCode = "PLAN_DRIFT" | "MODULE_LOCKED" | "RUN_NOT_FOUND" | "RUN_NOT_RESUMABLE";
325
+
326
+ export type IModuleApplyResponse =
327
+ | { ok: true; run: IModuleProvisioningRun }
328
+ /** O estado mudou desde o plano: `plan` é o run novo (`mode: 'plan'`) para revisar. */
329
+ | { ok: false; error: "PLAN_DRIFT"; plan: IModuleProvisioningRun };
@@ -191,6 +191,7 @@ export interface IAutoTask extends ITaskBase {
191
191
  retry?: ITaskRetryPolicy;
192
192
  on_failure?: ITaskOnFailure;
193
193
  runner_state?: ITaskRunnerState;
194
+ outcome?: ITaskOutcome | null;
194
195
  auto: ITaskAutoSpec;
195
196
  }
196
197
  export type ITask = IHumanTask | IAutoTask;
@@ -198,8 +199,20 @@ export declare const TaskExecutionStatusEnum: {
198
199
  readonly Success: "success";
199
200
  readonly Error: "error";
200
201
  readonly Retry: "retry";
202
+ readonly Suppressed: "suppressed";
201
203
  };
202
204
  export type TaskExecutionStatus = (typeof TaskExecutionStatusEnum)[keyof typeof TaskExecutionStatusEnum];
205
+ export type TaskOutcomeClass = "legitimate" | "defect";
206
+ export interface ITaskOutcome {
207
+ class: TaskOutcomeClass;
208
+ reason: string;
209
+ label: string;
210
+ message: string;
211
+ action_hint?: string;
212
+ scope?: string;
213
+ details?: Record<string, unknown>;
214
+ at: Date;
215
+ }
203
216
  export interface ITaskExecution extends IFireDoc {
204
217
  taskId: string;
205
218
  handler: TaskAutoHandler;
@@ -214,6 +227,7 @@ export interface ITaskExecution extends IFireDoc {
214
227
  code?: string | number;
215
228
  details?: Record<string, unknown>;
216
229
  };
230
+ outcome?: ITaskOutcome;
217
231
  provider?: {
218
232
  name?: string;
219
233
  message_id?: string;
@@ -167,4 +167,7 @@ exports.TaskExecutionStatusEnum = {
167
167
  Success: "success",
168
168
  Error: "error",
169
169
  Retry: "retry",
170
+ // Handler ran and decided not to deliver; `outcome` says why. The runner
171
+ // finalizes the task directly (no retry, fallback or handoff).
172
+ Suppressed: "suppressed",
170
173
  };