evo360-types 1.3.408 → 1.3.411

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.
@@ -1,10 +1,10 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.zAutomationDryRunRequestSchema = exports.zHubAutomationConfigSchema = exports.zAutomationRoutineSchema = exports.zAutomationBranchModeSchema = exports.zAutomationBranchSchema = exports.zAutomationOutputSchema = exports.zAutomationHumanTaskOutputSchema = exports.zAutomationAutoTaskOutputSchema = exports.zAutomationExecuteAtSchema = exports.zAutomationConditionGroupSchema = exports.zAutomationConditionSchema = exports.zAutomationOperatorSchema = exports.zAutomationSelectionSchema = exports.zAutomationAppointmentSelectionSchema = exports.zAutomationDateWindowSchema = exports.zAutomationDateOffsetModeSchema = exports.zAutomationTriggerSchema = exports.zAutomationCronTriggerSchema = void 0;
3
+ exports.zAutomationTriggerRequestSchema = exports.zAutomationDryRunRequestSchema = exports.zHubAutomationConfigSchema = exports.zAutomationRoutineUpdateRequestSchema = exports.zAutomationRoutineWriteSchema = exports.zAutomationRoutineSchema = exports.zAutomationBranchModeSchema = exports.zAutomationBranchSchema = exports.zAutomationOutputSchema = exports.zAutomationHumanTaskOutputSchema = exports.zAutomationAutoTaskOutputSchema = exports.zAutomationExecuteAtSchema = exports.zAutomationConditionGroupSchema = exports.zAutomationConditionSchema = exports.zAutomationOperatorSchema = exports.zAutomationSelectionSchema = exports.zAutomationAppointmentSelectionSchema = exports.zAutomationDateWindowSchema = exports.zAutomationDateOffsetModeSchema = exports.zAutomationTriggerSchema = exports.zAutomationWebhookTriggerSchema = exports.zAutomationCronTriggerSchema = void 0;
4
4
  const zod_1 = require("zod");
5
5
  const zod_schemas_1 = require("../evo-task/zod-schemas");
6
6
  // ------------------------------------------------------
7
- // Trigger (F1: cron only)
7
+ // Trigger (cron sweep | webhook reverse-trigger)
8
8
  // ------------------------------------------------------
9
9
  exports.zAutomationCronTriggerSchema = zod_1.z.object({
10
10
  type: zod_1.z.literal("cron"),
@@ -13,7 +13,14 @@ exports.zAutomationCronTriggerSchema = zod_1.z.object({
13
13
  timezone: zod_1.z.string().optional(),
14
14
  }),
15
15
  });
16
- exports.zAutomationTriggerSchema = exports.zAutomationCronTriggerSchema;
16
+ // F2: fired only by POST /routines/:id/trigger; invisible to the sweep.
17
+ exports.zAutomationWebhookTriggerSchema = zod_1.z.object({
18
+ type: zod_1.z.literal("webhook"),
19
+ });
20
+ exports.zAutomationTriggerSchema = zod_1.z.discriminatedUnion("type", [
21
+ exports.zAutomationCronTriggerSchema,
22
+ exports.zAutomationWebhookTriggerSchema,
23
+ ]);
17
24
  // ------------------------------------------------------
18
25
  // Selection (F1: appointment target only)
19
26
  // ------------------------------------------------------
@@ -27,9 +34,16 @@ exports.zAutomationAppointmentSelectionSchema = zod_1.z.object({
27
34
  appointment: zod_1.z.object({
28
35
  calendar_ids: zod_1.z.array(zod_1.z.string()).optional(),
29
36
  date_window: exports.zAutomationDateWindowSchema,
37
+ // String filters accept the wildcard `*` (case-insensitive glob); without
38
+ // `*` = exact match (Q21). Sourced from the appointment embeds.
30
39
  status_in: zod_1.z.array(zod_1.z.string()).optional(),
31
40
  status_base_in: zod_1.z.array(zod_1.z.string()).optional(),
32
41
  appointment_type_not_in: zod_1.z.array(zod_1.z.string()).optional(),
42
+ professional_names: zod_1.z.array(zod_1.z.string()).optional(),
43
+ procedure_names: zod_1.z.array(zod_1.z.string()).optional(),
44
+ insurance_names: zod_1.z.array(zod_1.z.string()).optional(),
45
+ address_names: zod_1.z.array(zod_1.z.string()).optional(),
46
+ payment_status_in: zod_1.z.array(zod_1.z.string()).optional(),
33
47
  }),
34
48
  });
35
49
  exports.zAutomationSelectionSchema = exports.zAutomationAppointmentSelectionSchema;
@@ -65,6 +79,11 @@ exports.zAutomationExecuteAtSchema = zod_1.z.discriminatedUnion("rule", [
65
79
  time: zod_1.z.string().regex(/^([01]\d|2[0-3]):[0-5]\d$/, "expected HH:mm"),
66
80
  base: zod_1.z.enum(["target_date", "run_date"]),
67
81
  }),
82
+ // Q20.7: appointment.startDate + offset_minutes (negative = before).
83
+ zod_1.z.object({
84
+ rule: zod_1.z.literal("relative_to_appointment"),
85
+ offset_minutes: zod_1.z.number().int(),
86
+ }),
68
87
  ]);
69
88
  exports.zAutomationAutoTaskOutputSchema = zod_1.z.object({
70
89
  type: zod_1.z.literal("auto_task"),
@@ -135,6 +154,32 @@ exports.zAutomationRoutineSchema = zod_1.z.object({
135
154
  updated_at: zod_1.z.coerce.date(),
136
155
  });
137
156
  // ------------------------------------------------------
157
+ // Routine write payload (CRUD via POST/PUT — F3)
158
+ // Same structure as zAutomationRoutineSchema WITHOUT the server-managed fields
159
+ // (version/dry_run_stamp/trigger_state/stats/created_at/updated_at), which the
160
+ // backend owns. `active` defaults false (create) — activation is a separate
161
+ // endpoint that also enforces the Q11 dry-run gate.
162
+ // ------------------------------------------------------
163
+ exports.zAutomationRoutineWriteSchema = zod_1.z.object({
164
+ id: zod_1.z.string(),
165
+ name: zod_1.z.string().min(1),
166
+ description: zod_1.z.string().optional(),
167
+ active: zod_1.z.boolean().default(false),
168
+ trigger: exports.zAutomationTriggerSchema,
169
+ selection: exports.zAutomationSelectionSchema,
170
+ branch_mode: exports.zAutomationBranchModeSchema,
171
+ branches: zod_1.z.array(exports.zAutomationBranchSchema),
172
+ guards: zod_1.z.object({
173
+ max_tasks_per_run: zod_1.z.number().int().positive(),
174
+ }),
175
+ });
176
+ // PUT /routines/:id body — optimistic concurrency: expected_version must match
177
+ // the stored routine's version or the backend returns 409.
178
+ exports.zAutomationRoutineUpdateRequestSchema = zod_1.z.object({
179
+ routine: exports.zAutomationRoutineWriteSchema,
180
+ expected_version: zod_1.z.number().int().positive(),
181
+ });
182
+ // ------------------------------------------------------
138
183
  // Module config (mirrors zTaskRunnerConfigSchema: active default false, passthrough)
139
184
  // ------------------------------------------------------
140
185
  exports.zHubAutomationConfigSchema = zod_1.z
@@ -157,3 +202,14 @@ exports.zAutomationDryRunRequestSchema = zod_1.z.object({
157
202
  .regex(/^\d{4}-\d{2}-\d{2}$/, "expected yyyy-MM-dd")
158
203
  .optional(),
159
204
  });
205
+ // ------------------------------------------------------
206
+ // Trigger request (endpoint POST /routines/:id/trigger)
207
+ // Same shape as the dry-run request — only an optional run_date; no
208
+ // calendar_ids override or arbitrary payload (F2 scope, see plan-f2 §1).
209
+ // ------------------------------------------------------
210
+ exports.zAutomationTriggerRequestSchema = zod_1.z.object({
211
+ run_date: zod_1.z
212
+ .string()
213
+ .regex(/^\d{4}-\d{2}-\d{2}$/, "expected yyyy-MM-dd")
214
+ .optional(),
215
+ });
@@ -6,7 +6,7 @@ import {
6
6
  } from "../evo-task/zod-schemas";
7
7
 
8
8
  // ------------------------------------------------------
9
- // Trigger (F1: cron only)
9
+ // Trigger (cron sweep | webhook reverse-trigger)
10
10
  // ------------------------------------------------------
11
11
  export const zAutomationCronTriggerSchema = z.object({
12
12
  type: z.literal("cron"),
@@ -16,7 +16,15 @@ export const zAutomationCronTriggerSchema = z.object({
16
16
  }),
17
17
  });
18
18
 
19
- export const zAutomationTriggerSchema = zAutomationCronTriggerSchema;
19
+ // F2: fired only by POST /routines/:id/trigger; invisible to the sweep.
20
+ export const zAutomationWebhookTriggerSchema = z.object({
21
+ type: z.literal("webhook"),
22
+ });
23
+
24
+ export const zAutomationTriggerSchema = z.discriminatedUnion("type", [
25
+ zAutomationCronTriggerSchema,
26
+ zAutomationWebhookTriggerSchema,
27
+ ]);
20
28
 
21
29
  // ------------------------------------------------------
22
30
  // Selection (F1: appointment target only)
@@ -33,9 +41,16 @@ export const zAutomationAppointmentSelectionSchema = z.object({
33
41
  appointment: z.object({
34
42
  calendar_ids: z.array(z.string()).optional(),
35
43
  date_window: zAutomationDateWindowSchema,
44
+ // String filters accept the wildcard `*` (case-insensitive glob); without
45
+ // `*` = exact match (Q21). Sourced from the appointment embeds.
36
46
  status_in: z.array(z.string()).optional(),
37
47
  status_base_in: z.array(z.string()).optional(),
38
48
  appointment_type_not_in: z.array(z.string()).optional(),
49
+ professional_names: z.array(z.string()).optional(),
50
+ procedure_names: z.array(z.string()).optional(),
51
+ insurance_names: z.array(z.string()).optional(),
52
+ address_names: z.array(z.string()).optional(),
53
+ payment_status_in: z.array(z.string()).optional(),
39
54
  }),
40
55
  });
41
56
 
@@ -89,6 +104,11 @@ export const zAutomationExecuteAtSchema = z.discriminatedUnion("rule", [
89
104
  time: z.string().regex(/^([01]\d|2[0-3]):[0-5]\d$/, "expected HH:mm"),
90
105
  base: z.enum(["target_date", "run_date"]),
91
106
  }),
107
+ // Q20.7: appointment.startDate + offset_minutes (negative = before).
108
+ z.object({
109
+ rule: z.literal("relative_to_appointment"),
110
+ offset_minutes: z.number().int(),
111
+ }),
92
112
  ]);
93
113
 
94
114
  export const zAutomationAutoTaskOutputSchema = z.object({
@@ -165,6 +185,34 @@ export const zAutomationRoutineSchema = z.object({
165
185
  updated_at: z.coerce.date(),
166
186
  });
167
187
 
188
+ // ------------------------------------------------------
189
+ // Routine write payload (CRUD via POST/PUT — F3)
190
+ // Same structure as zAutomationRoutineSchema WITHOUT the server-managed fields
191
+ // (version/dry_run_stamp/trigger_state/stats/created_at/updated_at), which the
192
+ // backend owns. `active` defaults false (create) — activation is a separate
193
+ // endpoint that also enforces the Q11 dry-run gate.
194
+ // ------------------------------------------------------
195
+ export const zAutomationRoutineWriteSchema = z.object({
196
+ id: z.string(),
197
+ name: z.string().min(1),
198
+ description: z.string().optional(),
199
+ active: z.boolean().default(false),
200
+ trigger: zAutomationTriggerSchema,
201
+ selection: zAutomationSelectionSchema,
202
+ branch_mode: zAutomationBranchModeSchema,
203
+ branches: z.array(zAutomationBranchSchema),
204
+ guards: z.object({
205
+ max_tasks_per_run: z.number().int().positive(),
206
+ }),
207
+ });
208
+
209
+ // PUT /routines/:id body — optimistic concurrency: expected_version must match
210
+ // the stored routine's version or the backend returns 409.
211
+ export const zAutomationRoutineUpdateRequestSchema = z.object({
212
+ routine: zAutomationRoutineWriteSchema,
213
+ expected_version: z.number().int().positive(),
214
+ });
215
+
168
216
  // ------------------------------------------------------
169
217
  // Module config (mirrors zTaskRunnerConfigSchema: active default false, passthrough)
170
218
  // ------------------------------------------------------
@@ -189,3 +237,15 @@ export const zAutomationDryRunRequestSchema = z.object({
189
237
  .regex(/^\d{4}-\d{2}-\d{2}$/, "expected yyyy-MM-dd")
190
238
  .optional(),
191
239
  });
240
+
241
+ // ------------------------------------------------------
242
+ // Trigger request (endpoint POST /routines/:id/trigger)
243
+ // Same shape as the dry-run request — only an optional run_date; no
244
+ // calendar_ids override or arbitrary payload (F2 scope, see plan-f2 §1).
245
+ // ------------------------------------------------------
246
+ export const zAutomationTriggerRequestSchema = z.object({
247
+ run_date: z
248
+ .string()
249
+ .regex(/^\d{4}-\d{2}-\d{2}$/, "expected yyyy-MM-dd")
250
+ .optional(),
251
+ });
@@ -12,7 +12,10 @@ export interface IAutomationCronTrigger {
12
12
  timezone?: string;
13
13
  };
14
14
  }
15
- export type IAutomationTrigger = IAutomationCronTrigger;
15
+ export interface IAutomationWebhookTrigger {
16
+ type: "webhook";
17
+ }
18
+ export type IAutomationTrigger = IAutomationCronTrigger | IAutomationWebhookTrigger;
16
19
  export type AutomationDateOffsetMode = "calendar" | "business";
17
20
  export interface IAutomationDateWindow {
18
21
  offset_days: number;
@@ -26,10 +29,24 @@ export interface IAutomationAppointmentSelection {
26
29
  status_in?: string[];
27
30
  status_base_in?: string[];
28
31
  appointment_type_not_in?: string[];
32
+ professional_names?: string[];
33
+ procedure_names?: string[];
34
+ insurance_names?: string[];
35
+ address_names?: string[];
36
+ payment_status_in?: string[];
29
37
  };
30
38
  }
31
39
  export type IAutomationSelection = IAutomationAppointmentSelection;
32
- export declare const AUTOMATION_APPOINTMENT_FACTS: readonly ["appointment.status", "appointment.status_base", "appointment.appointment_type", "appointment.appointment_base_type", "appointment.appointment_mode", "appointment.professional_id", "appointment.procedure_ids", "appointment.payment_status", "appointment.calendar_id"];
40
+ export interface IAutomationFilterValues {
41
+ professionals: string[];
42
+ procedures: string[];
43
+ insurances: string[];
44
+ addresses: string[];
45
+ statuses: string[];
46
+ status_bases: string[];
47
+ appointment_types: string[];
48
+ }
49
+ export declare const AUTOMATION_APPOINTMENT_FACTS: readonly ["appointment.status", "appointment.status_base", "appointment.appointment_type", "appointment.appointment_base_type", "appointment.appointment_mode", "appointment.professional_id", "appointment.procedure_ids", "appointment.professional_name", "appointment.procedure_names", "appointment.insurance_name", "appointment.address_name", "appointment.payment_status", "appointment.calendar_id"];
33
50
  export type AutomationAppointmentFact = (typeof AUTOMATION_APPOINTMENT_FACTS)[number];
34
51
  export type AutomationFact = AutomationAppointmentFact;
35
52
  export declare const AutomationOperatorEnum: {
@@ -64,6 +81,9 @@ export type IAutomationExecuteAt = {
64
81
  rule: "send_at_local";
65
82
  time: string;
66
83
  base: "target_date" | "run_date";
84
+ } | {
85
+ rule: "relative_to_appointment";
86
+ offset_minutes: number;
67
87
  };
68
88
  export interface IAutomationAutoTaskOutput {
69
89
  type: "auto_task";
@@ -118,6 +138,19 @@ export interface IAutomationRoutine {
118
138
  created_at: Date;
119
139
  updated_at: Date;
120
140
  }
141
+ export interface IAutomationRoutineWrite {
142
+ id: string;
143
+ name: string;
144
+ description?: string;
145
+ active: boolean;
146
+ trigger: IAutomationTrigger;
147
+ selection: IAutomationSelection;
148
+ branch_mode: AutomationBranchMode;
149
+ branches: IAutomationBranch[];
150
+ guards: {
151
+ max_tasks_per_run: number;
152
+ };
153
+ }
121
154
  export interface IHubAutomationConfig {
122
155
  active: boolean;
123
156
  limits?: {
@@ -147,10 +180,12 @@ export interface IAutomationRunSample {
147
180
  appointment_id: string;
148
181
  branch_id?: string;
149
182
  decision: string;
183
+ task_id?: string;
150
184
  conditions?: IAutomationConditionResult[];
151
185
  [key: string]: unknown;
152
186
  }
153
187
  export interface IAutomationRunTrace {
188
+ run_id?: string;
154
189
  routine_id: string;
155
190
  routine_version: number;
156
191
  trigger: {
@@ -47,9 +47,16 @@ exports.AUTOMATION_APPOINTMENT_FACTS = [
47
47
  "appointment.appointment_base_type",
48
48
  // 'telemedicine' | 'in_person'
49
49
  "appointment.appointment_mode",
50
- // Derived from professional.professionalRef.id
50
+ // Derived from professional.professionalRef.id. On external calendars the
51
+ // reliable value is the name (Q21) — professional_id kept for internal.
51
52
  "appointment.professional_id",
52
53
  "appointment.procedure_ids",
54
+ // Embed-sourced names (Q20-C passthrough); reliable across adapters.
55
+ "appointment.professional_name",
56
+ // string[] — matches if ANY procedure name matches.
57
+ "appointment.procedure_names",
58
+ "appointment.insurance_name",
59
+ "appointment.address_name",
53
60
  "appointment.payment_status",
54
61
  "appointment.calendar_id",
55
62
  ];
@@ -27,7 +27,7 @@ export type HubAutomationPermissions =
27
27
  (typeof HubAutomationPermissions)[keyof typeof HubAutomationPermissions];
28
28
 
29
29
  // ------------------------------------------------------
30
- // Trigger (F1: cron only)
30
+ // Trigger (cron sweep | webhook reverse-trigger)
31
31
  // ------------------------------------------------------
32
32
  export interface IAutomationCronTrigger {
33
33
  type: "cron";
@@ -39,7 +39,15 @@ export interface IAutomationCronTrigger {
39
39
  };
40
40
  }
41
41
 
42
- export type IAutomationTrigger = IAutomationCronTrigger;
42
+ // F2: fired only by POST /routines/:id/trigger (n8n as a client of the engine);
43
+ // invisible to the sweep (listActiveCronRoutines filters type === 'cron').
44
+ export interface IAutomationWebhookTrigger {
45
+ type: "webhook";
46
+ }
47
+
48
+ export type IAutomationTrigger =
49
+ | IAutomationCronTrigger
50
+ | IAutomationWebhookTrigger;
43
51
 
44
52
  // ------------------------------------------------------
45
53
  // Selection (F1: appointment target only)
@@ -60,18 +68,47 @@ export interface IAutomationDateWindow {
60
68
  export interface IAutomationAppointmentSelection {
61
69
  target: "appointment";
62
70
  appointment: {
63
- // Empty/omitted = all calendars of the tenant.
71
+ // Empty/omitted = all calendars of the tenant. GUI enforces exactly 1
72
+ // (Q21-A: single-calendar unlocks rich filter-values); calendar_ids[] kept
73
+ // for engine/seed compat (multi-calendar = N routines).
64
74
  calendar_ids?: string[];
65
75
  date_window: IAutomationDateWindow;
66
- // Filters applied in memory over the day window (no server-side status query).
76
+ // Filters applied in memory over the day window (no server-side query).
77
+ // String filters accept the wildcard `*` (case-insensitive glob); without
78
+ // `*` they are exact matches (Q21). Sourced from the appointment embeds
79
+ // (passthrough from the sync, per the Q20-C investigation).
67
80
  status_in?: string[];
68
81
  status_base_in?: string[];
69
82
  appointment_type_not_in?: string[];
83
+ // professional.display_name
84
+ professional_names?: string[];
85
+ // matches if ANY procedures[].name matches
86
+ procedure_names?: string[];
87
+ // insurance.name
88
+ insurance_names?: string[];
89
+ // address.address_name (note: NOT address.Name of the legacy n8n shape)
90
+ address_names?: string[];
91
+ // payment.status — fixed local enum (pending/partial/paid/not_informed)
92
+ payment_status_in?: string[];
70
93
  };
71
94
  }
72
95
 
73
96
  export type IAutomationSelection = IAutomationAppointmentSelection;
74
97
 
98
+ // Distinct filter values for a calendar, built from a limited window of local
99
+ // appointments (GET /routines/filter-values?calendar_id=). Feeds the GUI's
100
+ // selection filters and branch conditions with real, per-calendar suggestions
101
+ // (Q20-C: distinct-local, no adapter capability). Sorted pt-BR, capped per field.
102
+ export interface IAutomationFilterValues {
103
+ professionals: string[];
104
+ procedures: string[];
105
+ insurances: string[];
106
+ addresses: string[];
107
+ statuses: string[];
108
+ status_bases: string[];
109
+ appointment_types: string[];
110
+ }
111
+
75
112
  // ------------------------------------------------------
76
113
  // Fact catalog (F1: appointment domain facts only — Q15: no patient.* facts)
77
114
  // ------------------------------------------------------
@@ -83,9 +120,16 @@ export const AUTOMATION_APPOINTMENT_FACTS = [
83
120
  "appointment.appointment_base_type",
84
121
  // 'telemedicine' | 'in_person'
85
122
  "appointment.appointment_mode",
86
- // Derived from professional.professionalRef.id
123
+ // Derived from professional.professionalRef.id. On external calendars the
124
+ // reliable value is the name (Q21) — professional_id kept for internal.
87
125
  "appointment.professional_id",
88
126
  "appointment.procedure_ids",
127
+ // Embed-sourced names (Q20-C passthrough); reliable across adapters.
128
+ "appointment.professional_name",
129
+ // string[] — matches if ANY procedure name matches.
130
+ "appointment.procedure_names",
131
+ "appointment.insurance_name",
132
+ "appointment.address_name",
89
133
  "appointment.payment_status",
90
134
  "appointment.calendar_id",
91
135
  ] as const;
@@ -143,6 +187,11 @@ export type AutomationOutputType =
143
187
  // - immediate: now (Task Runner picks it up on the next tick)
144
188
  // - send_at_local: HH:mm resolved in the tenant timezone, anchored to the
145
189
  // target date or the run date.
190
+ // - relative_to_appointment: appointment.startDate + offset_minutes (Q20.7).
191
+ // Negative = before the appointment (e.g. -120 = 2h before). The routine
192
+ // runs once (e.g. 6am); each task is scheduled relative to its own target.
193
+ // If the computed time already passed at run time, the materializer clamps
194
+ // it to "now" (with a log).
146
195
  export type IAutomationExecuteAt =
147
196
  | { rule: "immediate" }
148
197
  | {
@@ -150,6 +199,11 @@ export type IAutomationExecuteAt =
150
199
  // "HH:mm" (24h)
151
200
  time: string;
152
201
  base: "target_date" | "run_date";
202
+ }
203
+ | {
204
+ rule: "relative_to_appointment";
205
+ // Signed minutes offset from appointment.startDate (negative = before).
206
+ offset_minutes: number;
153
207
  };
154
208
 
155
209
  export interface IAutomationAutoTaskOutput {
@@ -230,6 +284,27 @@ export interface IAutomationRoutine {
230
284
  updated_at: Date;
231
285
  }
232
286
 
287
+ // ------------------------------------------------------
288
+ // Routine write payload (CRUD via POST/PUT on hub_automation_admin — F3)
289
+ // The routine WITHOUT server-managed fields: `version`, `dry_run_stamp`,
290
+ // `trigger_state`, `stats`, `created_at`, `updated_at` are set by the backend
291
+ // (version bookkeeping, Q11 gate, cursor, run stats, timestamps). The FE never
292
+ // writes them. Written by hand (no utility types) to keep the contract explicit.
293
+ // ------------------------------------------------------
294
+ export interface IAutomationRoutineWrite {
295
+ id: string;
296
+ name: string;
297
+ description?: string;
298
+ active: boolean;
299
+ trigger: IAutomationTrigger;
300
+ selection: IAutomationSelection;
301
+ branch_mode: AutomationBranchMode;
302
+ branches: IAutomationBranch[];
303
+ guards: {
304
+ max_tasks_per_run: number;
305
+ };
306
+ }
307
+
233
308
  // ------------------------------------------------------
234
309
  // Module config (Firestore doc: tenants/{t}/apps/hub-automation/config/config)
235
310
  // ------------------------------------------------------
@@ -275,11 +350,17 @@ export interface IAutomationRunSample {
275
350
  branch_id?: string;
276
351
  // e.g. 'created' | 'already_existed' | 'not_matched' | 'suppressed_by_limit'
277
352
  decision: string;
353
+ // Set by the materializer when decision === 'created'; lets the run viewer
354
+ // deep-link from a sample to the materialized Task (F3).
355
+ task_id?: string;
278
356
  conditions?: IAutomationConditionResult[];
279
357
  [key: string]: unknown;
280
358
  }
281
359
 
282
360
  export interface IAutomationRunTrace {
361
+ // Engine-generated run id; surfaced in the webhook trigger response (F2) so
362
+ // the caller can deep-link to this run. Optional for backward compatibility.
363
+ run_id?: string;
283
364
  routine_id: string;
284
365
  routine_version: number;
285
366
  trigger: {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "evo360-types",
3
- "version": "1.3.408",
3
+ "version": "1.3.411",
4
4
  "description": "HREVO360 Shared Types",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",