evo360-types 1.3.659 → 1.3.664

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 (30) hide show
  1. package/dist/apps/evo-core/zod-schemas.d.ts +157 -8
  2. package/dist/apps/evo-core/zod-schemas.js +15 -2
  3. package/dist/apps/evo-core/zod-schemas.ts +15 -1
  4. package/dist/apps/evo-crm/lead/zod-schemas.d.ts +6 -6
  5. package/dist/apps/evo-csq/zod-schemas.d.ts +8 -8
  6. package/dist/apps/evo-finops/zod-schemas.d.ts +67 -24
  7. package/dist/apps/evo-finops/zod-schemas.js +23 -1
  8. package/dist/apps/evo-finops/zod-schemas.ts +25 -0
  9. package/dist/apps/evo-med/insurance/zod-schemas.d.ts +6 -6
  10. package/dist/apps/evo-med/people/zod-schemas.d.ts +12 -12
  11. package/dist/apps/evo-task/zod-schemas.d.ts +201 -4
  12. package/dist/apps/evo-task/zod-schemas.js +22 -2
  13. package/dist/apps/evo-task/zod-schemas.ts +23 -1
  14. package/dist/apps/shared/zod-schemas.d.ts +2 -2
  15. package/dist/types/evo-core/index.d.ts +14 -2
  16. package/dist/types/evo-core/index.ts +20 -2
  17. package/dist/types/evo-finops/common/contract.d.ts +2 -0
  18. package/dist/types/evo-finops/common/contract.ts +3 -0
  19. package/dist/types/evo-finops/common/nfse-fee-reimbursement.d.ts +105 -0
  20. package/dist/types/evo-finops/common/nfse-fee-reimbursement.js +34 -0
  21. package/dist/types/evo-finops/common/nfse-fee-reimbursement.ts +134 -0
  22. package/dist/types/evo-finops/index.d.ts +1 -0
  23. package/dist/types/evo-finops/index.js +1 -0
  24. package/dist/types/evo-finops/index.ts +1 -0
  25. package/dist/types/evo-task/index.d.ts +14 -0
  26. package/dist/types/evo-task/index.js +3 -0
  27. package/dist/types/evo-task/index.ts +25 -0
  28. package/dist/types/evo-task-runner/index.d.ts +2 -1
  29. package/dist/types/evo-task-runner/index.ts +5 -1
  30. package/package.json +1 -1
@@ -54,14 +54,26 @@ export interface INexusModuleChatPermissions {
54
54
  }
55
55
  export interface INexusReports {
56
56
  }
57
+ /**
58
+ * Sub-claims do módulo financeiro do Nexus. `finance === true` é o formato
59
+ * legado; não herda `reimbursements` (feat-264: movimenta dinheiro, exige TOTP).
60
+ */
61
+ export interface INexusModuleFinancePermissions {
62
+ customers?: boolean;
63
+ contracts?: boolean;
64
+ billing?: boolean;
65
+ reports?: boolean;
66
+ /** feat-264 — reembolso da taxa de NFS-e. Sem bypass de admin. */
67
+ reimbursements?: boolean;
68
+ }
57
69
  export interface INexusModules {
58
70
  chat?: INexusModuleChatPermissions | boolean;
59
71
  tenants?: boolean;
60
- finance?: boolean;
72
+ finance?: INexusModuleFinancePermissions | boolean;
61
73
  notifications?: boolean;
62
74
  waba?: boolean;
63
75
  reports?: INexusReports | boolean;
64
- [key: string]: INexusModuleChatPermissions | INexusReports | boolean | undefined;
76
+ [key: string]: INexusModuleChatPermissions | INexusModuleFinancePermissions | INexusReports | boolean | undefined;
65
77
  }
66
78
  export interface INexusClaims {
67
79
  nexus_access: boolean;
@@ -66,14 +66,32 @@ export interface INexusModuleChatPermissions {
66
66
 
67
67
  export interface INexusReports {}
68
68
 
69
+ /**
70
+ * Sub-claims do módulo financeiro do Nexus. `finance === true` é o formato
71
+ * legado; não herda `reimbursements` (feat-264: movimenta dinheiro, exige TOTP).
72
+ */
73
+ export interface INexusModuleFinancePermissions {
74
+ customers?: boolean;
75
+ contracts?: boolean;
76
+ billing?: boolean;
77
+ reports?: boolean;
78
+ /** feat-264 — reembolso da taxa de NFS-e. Sem bypass de admin. */
79
+ reimbursements?: boolean;
80
+ }
81
+
69
82
  export interface INexusModules {
70
83
  chat?: INexusModuleChatPermissions | boolean;
71
84
  tenants?: boolean;
72
- finance?: boolean;
85
+ finance?: INexusModuleFinancePermissions | boolean;
73
86
  notifications?: boolean;
74
87
  waba?: boolean;
75
88
  reports?: INexusReports | boolean;
76
- [key: string]: INexusModuleChatPermissions | INexusReports | boolean | undefined;
89
+ [key: string]:
90
+ | INexusModuleChatPermissions
91
+ | INexusModuleFinancePermissions
92
+ | INexusReports
93
+ | boolean
94
+ | undefined;
77
95
  }
78
96
 
79
97
  export interface INexusClaims {
@@ -179,6 +179,8 @@ export interface INexFinopsContract extends IFireGlobalDoc {
179
179
  * `INexFinopsUsageAlertDefaults.thresholds`.
180
180
  */
181
181
  alert_thresholds?: number[] | null;
182
+ /** feat-264 D4 — reembolsar a taxa de NFS-e ao cliente. ⚠️ Ausente/null = TRUE (reembolsa). */
183
+ nfse_fee_reimbursement?: boolean | null;
182
184
  }
183
185
  export declare const NEX_FINOPS_CONTRACT_STATUS_TRANSITIONS: Record<NexFinopsContractStatus, NexFinopsContractStatus[]>;
184
186
  /**
@@ -219,6 +219,9 @@ export interface INexFinopsContract extends IFireGlobalDoc {
219
219
  * `INexFinopsUsageAlertDefaults.thresholds`.
220
220
  */
221
221
  alert_thresholds?: number[] | null;
222
+
223
+ /** feat-264 D4 — reembolsar a taxa de NFS-e ao cliente. ⚠️ Ausente/null = TRUE (reembolsa). */
224
+ nfse_fee_reimbursement?: boolean | null;
222
225
  }
223
226
 
224
227
  // ── Status transitions ──
@@ -0,0 +1,105 @@
1
+ /** Coleção dos registros de reembolso. */
2
+ export declare const NEX_FINOPS_NFSE_FEE_REIMBURSEMENTS_COLLECTION = "nfse_fee_reimbursements";
3
+ /** `externalReference` da transferência Asaas = `"nexnfr:{id}"`. */
4
+ export declare const NFSE_FEE_REIMBURSEMENT_EXTERNAL_REF_PREFIX = "nexnfr:";
5
+ export type NfseFeeReimbursementState = 'awaiting_authorization' | 'pending' | 'done' | 'failed' | 'canceled' | 'refused';
6
+ /**
7
+ * `failed`/`canceled`/`refused` -> `done` existe só para a REALIDADE do Asaas: um
8
+ * `TRANSFER_DONE` do `transfer_id` vinculado significa que o dinheiro saiu; o
9
+ * registro vira `done` (as notas passam a ser consumidas e nunca são pagas duas
10
+ * vezes) e gera alerta CRITICAL. Nenhum fluxo nosso faz essa transição.
11
+ */
12
+ export declare const NFSE_FEE_REIMBURSEMENT_TRANSITIONS: Record<NfseFeeReimbursementState, NfseFeeReimbursementState[]>;
13
+ /** Estados que consomem as notas do snapshot (não podem ser reembolsadas de novo). */
14
+ export declare const NFSE_FEE_REIMBURSEMENT_CONSUMING_STATES: readonly string[];
15
+ /** Estados em voo: bloqueiam nova execução para o mesmo tenant/competência. */
16
+ export declare const NFSE_FEE_REIMBURSEMENT_IN_FLIGHT_STATES: readonly string[];
17
+ /** D1: plugável. Só `asaas_internal_transfer` é implementado; `pix` fica para depois. */
18
+ export type NfseFeeReimbursementPayoutMethod = 'asaas_internal_transfer';
19
+ export interface INfseFeeReimbursement {
20
+ /** `{tenant}_{YYYY-MM}[_{seq}]` */
21
+ id: string;
22
+ tenant: string;
23
+ /** `"YYYY-MM"` (mês de `authorized_at` em America/Sao_Paulo). */
24
+ competencia: string;
25
+ /** 1, 2, … */
26
+ seq: number;
27
+ state: NfseFeeReimbursementState;
28
+ state_reason?: string | null;
29
+ provider: {
30
+ id: string;
31
+ type: 'asaas_subaccount';
32
+ env: 'production';
33
+ asaas_account_id: string;
34
+ wallet_id: string;
35
+ };
36
+ /** Snapshot do que foi reembolsado. */
37
+ invoices: {
38
+ count: number;
39
+ ids: string[];
40
+ };
41
+ fee: {
42
+ value: number;
43
+ source: 'asaas_myaccount_fees';
44
+ fetched_at: string;
45
+ };
46
+ /** `round2(count * fee.value)` */
47
+ amount: number;
48
+ currency: 'BRL';
49
+ contract: {
50
+ customer_id: string | null;
51
+ contract_ids: string[];
52
+ };
53
+ payout: {
54
+ method: NfseFeeReimbursementPayoutMethod;
55
+ /** `"nexnfr:{id}"` */
56
+ external_reference: string;
57
+ /** Ex.: `"Reembolso taxa NFS-e 09/2026 - 10 notas"` */
58
+ description: string;
59
+ /** Id Asaas — vinculado SÓ pela resposta do nosso POST /v3/transfers/ (validação e eventos nunca vinculam). */
60
+ transfer_id?: string | null;
61
+ /** PENDING | BANK_PROCESSING | DONE | CANCELLED | FAILED | BLOCKED */
62
+ asaas_status?: string | null;
63
+ transfer_fee?: number | null;
64
+ effective_date?: string | null;
65
+ fail_reason?: string | null;
66
+ };
67
+ validation: {
68
+ decision: 'APPROVED' | 'REFUSED' | null;
69
+ decided_at?: string | null;
70
+ attempts: number;
71
+ last_reason?: string | null;
72
+ };
73
+ last_event?: string | null;
74
+ last_event_at?: string | null;
75
+ requested_by: {
76
+ login_id: string;
77
+ email?: string | null;
78
+ second_factor: 'totp';
79
+ auth_time: string;
80
+ };
81
+ created_at: string;
82
+ updated_at: string;
83
+ done_at?: string | null;
84
+ }
85
+ export type NfseFeeReimbursementEligibility = 'eligible' | 'nothing_to_reimburse' | 'in_flight' | 'open_competencia' | 'not_eligible_own_account' | 'not_eligible_contract_flag' | 'no_contract' | 'subaccount_not_ready' | 'fee_unavailable';
86
+ export interface INfseFeeReimbursementPreviewRow {
87
+ tenant: string;
88
+ tenant_name?: string | null;
89
+ competencia: string;
90
+ eligibility: NfseFeeReimbursementEligibility;
91
+ reason?: string | null;
92
+ provider_id?: string | null;
93
+ provider_type?: string | null;
94
+ wallet_id?: string | null;
95
+ /** Autorizadas na competência, do provider. */
96
+ invoice_count_total: number;
97
+ invoice_count_already_reimbursed: number;
98
+ invoice_count_to_reimburse: number;
99
+ fee_value: number | null;
100
+ amount: number | null;
101
+ next_record_id?: string | null;
102
+ records: Array<Pick<INfseFeeReimbursement, 'id' | 'state' | 'amount' | 'seq'> & {
103
+ invoice_count: number;
104
+ }>;
105
+ }
@@ -0,0 +1,34 @@
1
+ "use strict";
2
+ // ── Nexus FinOps — reembolso da taxa de NFS-e (feat-264) ──
3
+ //
4
+ // A Asaas debita da subconta do cliente a taxa de cada NFS-e autorizada. O
5
+ // Nexus apura, por competência, quantas notas nossas foram autorizadas e
6
+ // devolve `count × fee` por transferência interna (walletId) a partir da conta
7
+ // master. Cada apuração vira um registro de controle do backend.
8
+ //
9
+ // Runtime `lib: es6`: as constantes abaixo são só dados.
10
+ Object.defineProperty(exports, "__esModule", { value: true });
11
+ exports.NFSE_FEE_REIMBURSEMENT_IN_FLIGHT_STATES = exports.NFSE_FEE_REIMBURSEMENT_CONSUMING_STATES = exports.NFSE_FEE_REIMBURSEMENT_TRANSITIONS = exports.NFSE_FEE_REIMBURSEMENT_EXTERNAL_REF_PREFIX = exports.NEX_FINOPS_NFSE_FEE_REIMBURSEMENTS_COLLECTION = void 0;
12
+ /** Coleção dos registros de reembolso. */
13
+ exports.NEX_FINOPS_NFSE_FEE_REIMBURSEMENTS_COLLECTION = 'nfse_fee_reimbursements';
14
+ // path: core/nexus/apps/nex-finops/nfse_fee_reimbursements/{id}
15
+ /** `externalReference` da transferência Asaas = `"nexnfr:{id}"`. */
16
+ exports.NFSE_FEE_REIMBURSEMENT_EXTERNAL_REF_PREFIX = 'nexnfr:';
17
+ /**
18
+ * `failed`/`canceled`/`refused` -> `done` existe só para a REALIDADE do Asaas: um
19
+ * `TRANSFER_DONE` do `transfer_id` vinculado significa que o dinheiro saiu; o
20
+ * registro vira `done` (as notas passam a ser consumidas e nunca são pagas duas
21
+ * vezes) e gera alerta CRITICAL. Nenhum fluxo nosso faz essa transição.
22
+ */
23
+ exports.NFSE_FEE_REIMBURSEMENT_TRANSITIONS = {
24
+ awaiting_authorization: ['pending', 'failed', 'refused', 'canceled', 'done'],
25
+ pending: ['done', 'failed', 'canceled'],
26
+ done: [],
27
+ failed: ['done'],
28
+ canceled: ['done'],
29
+ refused: ['done'],
30
+ };
31
+ /** Estados que consomem as notas do snapshot (não podem ser reembolsadas de novo). */
32
+ exports.NFSE_FEE_REIMBURSEMENT_CONSUMING_STATES = ['awaiting_authorization', 'pending', 'done'];
33
+ /** Estados em voo: bloqueiam nova execução para o mesmo tenant/competência. */
34
+ exports.NFSE_FEE_REIMBURSEMENT_IN_FLIGHT_STATES = ['awaiting_authorization', 'pending'];
@@ -0,0 +1,134 @@
1
+ // ── Nexus FinOps — reembolso da taxa de NFS-e (feat-264) ──
2
+ //
3
+ // A Asaas debita da subconta do cliente a taxa de cada NFS-e autorizada. O
4
+ // Nexus apura, por competência, quantas notas nossas foram autorizadas e
5
+ // devolve `count × fee` por transferência interna (walletId) a partir da conta
6
+ // master. Cada apuração vira um registro de controle do backend.
7
+ //
8
+ // Runtime `lib: es6`: as constantes abaixo são só dados.
9
+
10
+ /** Coleção dos registros de reembolso. */
11
+ export const NEX_FINOPS_NFSE_FEE_REIMBURSEMENTS_COLLECTION = 'nfse_fee_reimbursements';
12
+ // path: core/nexus/apps/nex-finops/nfse_fee_reimbursements/{id}
13
+
14
+ /** `externalReference` da transferência Asaas = `"nexnfr:{id}"`. */
15
+ export const NFSE_FEE_REIMBURSEMENT_EXTERNAL_REF_PREFIX = 'nexnfr:';
16
+
17
+ export type NfseFeeReimbursementState =
18
+ | 'awaiting_authorization' // intenção gravada; POST /v3/transfers chamado ou a chamar; aguarda validação
19
+ | 'pending' // validação APROVADA por nós (ou Asaas confirmou PENDING com id vinculado)
20
+ | 'done' // TRANSFER_DONE
21
+ | 'failed' // POST rejeitado/erro de rede, ou TRANSFER_FAILED
22
+ | 'canceled' // TRANSFER_CANCELLED (inclui 3 falhas da validação)
23
+ | 'refused'; // nosso webhook recusou (divergência) — terminal
24
+
25
+ /**
26
+ * `failed`/`canceled`/`refused` -> `done` existe só para a REALIDADE do Asaas: um
27
+ * `TRANSFER_DONE` do `transfer_id` vinculado significa que o dinheiro saiu; o
28
+ * registro vira `done` (as notas passam a ser consumidas e nunca são pagas duas
29
+ * vezes) e gera alerta CRITICAL. Nenhum fluxo nosso faz essa transição.
30
+ */
31
+ export const NFSE_FEE_REIMBURSEMENT_TRANSITIONS: Record<NfseFeeReimbursementState, NfseFeeReimbursementState[]> = {
32
+ awaiting_authorization: ['pending', 'failed', 'refused', 'canceled', 'done'],
33
+ pending: ['done', 'failed', 'canceled'],
34
+ done: [],
35
+ failed: ['done'],
36
+ canceled: ['done'],
37
+ refused: ['done'],
38
+ };
39
+
40
+ /** Estados que consomem as notas do snapshot (não podem ser reembolsadas de novo). */
41
+ export const NFSE_FEE_REIMBURSEMENT_CONSUMING_STATES: readonly string[] = ['awaiting_authorization', 'pending', 'done'];
42
+
43
+ /** Estados em voo: bloqueiam nova execução para o mesmo tenant/competência. */
44
+ export const NFSE_FEE_REIMBURSEMENT_IN_FLIGHT_STATES: readonly string[] = ['awaiting_authorization', 'pending'];
45
+
46
+ /** D1: plugável. Só `asaas_internal_transfer` é implementado; `pix` fica para depois. */
47
+ export type NfseFeeReimbursementPayoutMethod = 'asaas_internal_transfer';
48
+
49
+ export interface INfseFeeReimbursement {
50
+ /** `{tenant}_{YYYY-MM}[_{seq}]` */
51
+ id: string;
52
+ tenant: string;
53
+ /** `"YYYY-MM"` (mês de `authorized_at` em America/Sao_Paulo). */
54
+ competencia: string;
55
+ /** 1, 2, … */
56
+ seq: number;
57
+ state: NfseFeeReimbursementState;
58
+ state_reason?: string | null;
59
+ provider: {
60
+ id: string;
61
+ type: 'asaas_subaccount';
62
+ env: 'production';
63
+ asaas_account_id: string;
64
+ wallet_id: string;
65
+ };
66
+ /** Snapshot do que foi reembolsado. */
67
+ invoices: { count: number; ids: string[] };
68
+ fee: { value: number; source: 'asaas_myaccount_fees'; fetched_at: string };
69
+ /** `round2(count * fee.value)` */
70
+ amount: number;
71
+ currency: 'BRL';
72
+ contract: { customer_id: string | null; contract_ids: string[] };
73
+ payout: {
74
+ method: NfseFeeReimbursementPayoutMethod;
75
+ /** `"nexnfr:{id}"` */
76
+ external_reference: string;
77
+ /** Ex.: `"Reembolso taxa NFS-e 09/2026 - 10 notas"` */
78
+ description: string;
79
+ /** Id Asaas — vinculado SÓ pela resposta do nosso POST /v3/transfers/ (validação e eventos nunca vinculam). */
80
+ transfer_id?: string | null;
81
+ /** PENDING | BANK_PROCESSING | DONE | CANCELLED | FAILED | BLOCKED */
82
+ asaas_status?: string | null;
83
+ transfer_fee?: number | null;
84
+ effective_date?: string | null;
85
+ fail_reason?: string | null;
86
+ };
87
+ validation: {
88
+ decision: 'APPROVED' | 'REFUSED' | null;
89
+ decided_at?: string | null;
90
+ attempts: number;
91
+ last_reason?: string | null;
92
+ };
93
+ last_event?: string | null;
94
+ last_event_at?: string | null;
95
+ requested_by: {
96
+ login_id: string;
97
+ email?: string | null;
98
+ second_factor: 'totp';
99
+ auth_time: string;
100
+ };
101
+ created_at: string;
102
+ updated_at: string;
103
+ done_at?: string | null;
104
+ }
105
+
106
+ export type NfseFeeReimbursementEligibility =
107
+ | 'eligible'
108
+ | 'nothing_to_reimburse'
109
+ | 'in_flight'
110
+ | 'open_competencia'
111
+ | 'not_eligible_own_account' // provider type 'asaas' (conta própria) — D1
112
+ | 'not_eligible_contract_flag'
113
+ | 'no_contract'
114
+ | 'subaccount_not_ready' // subconta inativa/sem wallet_id/sem env production
115
+ | 'fee_unavailable'; // GET /v3/myAccount/fees falhou ou sem invoice.feeValue
116
+
117
+ export interface INfseFeeReimbursementPreviewRow {
118
+ tenant: string;
119
+ tenant_name?: string | null;
120
+ competencia: string;
121
+ eligibility: NfseFeeReimbursementEligibility;
122
+ reason?: string | null;
123
+ provider_id?: string | null;
124
+ provider_type?: string | null;
125
+ wallet_id?: string | null;
126
+ /** Autorizadas na competência, do provider. */
127
+ invoice_count_total: number;
128
+ invoice_count_already_reimbursed: number;
129
+ invoice_count_to_reimburse: number;
130
+ fee_value: number | null;
131
+ amount: number | null;
132
+ next_record_id?: string | null;
133
+ records: Array<Pick<INfseFeeReimbursement, 'id' | 'state' | 'amount' | 'seq'> & { invoice_count: number }>;
134
+ }
@@ -5,6 +5,7 @@ export * from "./common/contract";
5
5
  export * from "./common/proposal";
6
6
  export * from "./common/billing";
7
7
  export * from "./common/payment-method";
8
+ export * from "./common/nfse-fee-reimbursement";
8
9
  export * from "./providers";
9
10
  export * from "./providers/provider_fiscal_types";
10
11
  export * from "./providers/asaas/asaas_provider";
@@ -22,6 +22,7 @@ __exportStar(require("./common/contract"), exports);
22
22
  __exportStar(require("./common/proposal"), exports);
23
23
  __exportStar(require("./common/billing"), exports);
24
24
  __exportStar(require("./common/payment-method"), exports);
25
+ __exportStar(require("./common/nfse-fee-reimbursement"), exports);
25
26
  __exportStar(require("./providers"), exports);
26
27
  __exportStar(require("./providers/provider_fiscal_types"), exports);
27
28
  __exportStar(require("./providers/asaas/asaas_provider"), exports);
@@ -7,6 +7,7 @@ export * from "./common/contract";
7
7
  export * from "./common/proposal";
8
8
  export * from "./common/billing";
9
9
  export * from "./common/payment-method";
10
+ export * from "./common/nfse-fee-reimbursement";
10
11
  export * from "./providers";
11
12
  export * from "./providers/provider_fiscal_types";
12
13
  export * from "./providers/asaas/asaas_provider";
@@ -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
  };
@@ -357,6 +357,10 @@ export interface IAutoTask extends ITaskBase {
357
357
  // Runtime state populated by the Task Runner
358
358
  runner_state?: ITaskRunnerState;
359
359
 
360
+ // Why the handler decided not to deliver (suppressed | failed by defect).
361
+ // Reset to null when the task completes or is retried manually.
362
+ outcome?: ITaskOutcome | null;
363
+
360
364
  // What to execute
361
365
  auto: ITaskAutoSpec;
362
366
  }
@@ -369,11 +373,29 @@ export const TaskExecutionStatusEnum = {
369
373
  Success: "success",
370
374
  Error: "error",
371
375
  Retry: "retry",
376
+ // Handler ran and decided not to deliver; `outcome` says why. The runner
377
+ // finalizes the task directly (no retry, fallback or handoff).
378
+ Suppressed: "suppressed",
372
379
  } as const;
373
380
 
374
381
  export type TaskExecutionStatus =
375
382
  (typeof TaskExecutionStatusEnum)[keyof typeof TaskExecutionStatusEnum];
376
383
 
384
+ export type TaskOutcomeClass = "legitimate" | "defect";
385
+
386
+ // Outcome of an execution that did not deliver. `legitimate` ends the task as
387
+ // `suppressed`; `defect` ends it as `failed` (actionable problem).
388
+ export interface ITaskOutcome {
389
+ class: TaskOutcomeClass;
390
+ reason: string;
391
+ label: string;
392
+ message: string;
393
+ action_hint?: string;
394
+ scope?: string;
395
+ details?: Record<string, unknown>;
396
+ at: Date;
397
+ }
398
+
377
399
  export interface ITaskExecution extends IFireDoc {
378
400
  taskId: string;
379
401
  handler: TaskAutoHandler;
@@ -391,6 +413,9 @@ export interface ITaskExecution extends IFireDoc {
391
413
  details?: Record<string, unknown>;
392
414
  };
393
415
 
416
+ // Present when status is suppressed
417
+ outcome?: ITaskOutcome;
418
+
394
419
  // Optional provider metadata (e.g. WhatsApp provider message id)
395
420
  provider?: {
396
421
  name?: string;
@@ -1,6 +1,6 @@
1
1
  export * from "./fb_collections";
2
2
  import type { IFireDoc } from "../shared";
3
- import type { TaskAutoHandler, TaskExecutionStatus, TaskRetryStrategy } from "../evo-task";
3
+ import type { TaskAutoHandler, ITaskOutcome, TaskExecutionStatus, TaskRetryStrategy } from "../evo-task";
4
4
  export declare const EvoTaskRunnerPermissions: {
5
5
  readonly List: "evo_task_runner_read";
6
6
  readonly Get: "evo_task_runner_read";
@@ -55,6 +55,7 @@ export interface ITaskExecutionReport {
55
55
  attempt: number;
56
56
  correlation_id?: string;
57
57
  status: TaskExecutionStatus;
58
+ outcome?: ITaskOutcome;
58
59
  started_at: Date;
59
60
  completed_at: Date;
60
61
  suggested_retry?: {
@@ -2,6 +2,7 @@ export * from "./fb_collections";
2
2
  import type { IFireDoc } from "../shared";
3
3
  import type {
4
4
  TaskAutoHandler,
5
+ ITaskOutcome,
5
6
  TaskExecutionStatus,
6
7
  TaskRetryStrategy,
7
8
  } from "../evo-task";
@@ -115,7 +116,10 @@ export interface ITaskExecutionReport {
115
116
  correlation_id?: string;
116
117
 
117
118
  // Status/result
118
- status: TaskExecutionStatus; // success | error | retry
119
+ status: TaskExecutionStatus; // success | error | retry | suppressed
120
+
121
+ // Required when status is suppressed: why nothing was delivered
122
+ outcome?: ITaskOutcome;
119
123
 
120
124
  started_at: Date;
121
125
  completed_at: Date;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "evo360-types",
3
- "version": "1.3.659",
3
+ "version": "1.3.664",
4
4
  "description": "HREVO360 Shared Types",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",