evo360-types 1.3.505 → 1.3.507

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.
@@ -413,8 +413,8 @@ export declare const zIntegrationsAdapterDocSchema: z.ZodObject<{
413
413
  status: "active" | "disabled" | "beta";
414
414
  category: "clinic-agenda" | "prontuario" | "misc";
415
415
  adapter_version: string;
416
- default_workflow_urls: Partial<Record<"appointment.get" | "appointment.list" | "appointment.create" | "appointment.update" | "appointment.cancel" | "appointment.confirm" | "appointment.revert_confirm" | "appointment.reschedule" | "patient.get" | "patient.list" | "patient.create" | "patient.update" | "patient.document.upload" | "payment.update" | "sync.appointments", string>>;
417
- supported_capabilities: ("appointment.get" | "appointment.list" | "appointment.create" | "appointment.update" | "appointment.cancel" | "appointment.confirm" | "appointment.revert_confirm" | "appointment.reschedule" | "patient.get" | "patient.list" | "patient.create" | "patient.update" | "patient.document.upload" | "payment.update" | "sync.appointments")[];
416
+ default_workflow_urls: Partial<Record<"patient.list" | "patient.get" | "appointment.list" | "appointment.create" | "appointment.get" | "appointment.update" | "appointment.confirm" | "appointment.revert_confirm" | "appointment.cancel" | "patient.create" | "patient.update" | "appointment.reschedule" | "patient.document.upload" | "payment.update" | "sync.appointments", string>>;
417
+ supported_capabilities: ("patient.list" | "patient.get" | "appointment.list" | "appointment.create" | "appointment.get" | "appointment.update" | "appointment.confirm" | "appointment.revert_confirm" | "appointment.cancel" | "patient.create" | "patient.update" | "appointment.reschedule" | "patient.document.upload" | "payment.update" | "sync.appointments")[];
418
418
  ref?: any;
419
419
  created_at?: Date | null | undefined;
420
420
  updated_at?: Date | null | undefined;
@@ -462,14 +462,14 @@ export declare const zIntegrationsAdapterDocSchema: z.ZodObject<{
462
462
  status: "active" | "disabled" | "beta";
463
463
  category: "clinic-agenda" | "prontuario" | "misc";
464
464
  adapter_version: string;
465
- supported_capabilities: ("appointment.get" | "appointment.list" | "appointment.create" | "appointment.update" | "appointment.cancel" | "appointment.confirm" | "appointment.revert_confirm" | "appointment.reschedule" | "patient.get" | "patient.list" | "patient.create" | "patient.update" | "patient.document.upload" | "payment.update" | "sync.appointments")[];
465
+ supported_capabilities: ("patient.list" | "patient.get" | "appointment.list" | "appointment.create" | "appointment.get" | "appointment.update" | "appointment.confirm" | "appointment.revert_confirm" | "appointment.cancel" | "patient.create" | "patient.update" | "appointment.reschedule" | "patient.document.upload" | "payment.update" | "sync.appointments")[];
466
466
  ref?: any;
467
467
  model_ver?: number | undefined;
468
468
  created_at?: Date | null | undefined;
469
469
  updated_at?: Date | null | undefined;
470
470
  deleted_at?: Date | null | undefined;
471
471
  description?: string | undefined;
472
- default_workflow_urls?: Partial<Record<"appointment.get" | "appointment.list" | "appointment.create" | "appointment.update" | "appointment.cancel" | "appointment.confirm" | "appointment.revert_confirm" | "appointment.reschedule" | "patient.get" | "patient.list" | "patient.create" | "patient.update" | "patient.document.upload" | "payment.update" | "sync.appointments", string>> | undefined;
472
+ default_workflow_urls?: Partial<Record<"patient.list" | "patient.get" | "appointment.list" | "appointment.create" | "appointment.get" | "appointment.update" | "appointment.confirm" | "appointment.revert_confirm" | "appointment.cancel" | "patient.create" | "patient.update" | "appointment.reschedule" | "patient.document.upload" | "payment.update" | "sync.appointments", string>> | undefined;
473
473
  default_sync_config?: {
474
474
  hot?: {
475
475
  enabled?: boolean | undefined;
@@ -714,9 +714,10 @@ export declare const zSyncRunEventSchema: z.ZodObject<{
714
714
  tenant: string;
715
715
  status: "success" | "error" | "partial";
716
716
  started_at: Date;
717
+ finished_at: Date;
718
+ duration_ms: number;
717
719
  adapter_id: string;
718
720
  calendar_id: string;
719
- finished_at: Date;
720
721
  run_id: string;
721
722
  window_type: "hot" | "warm" | "recent_reconcile" | "cold";
722
723
  patients_upserted: number;
@@ -724,7 +725,6 @@ export declare const zSyncRunEventSchema: z.ZodObject<{
724
725
  appointments_skipped: number;
725
726
  appointments_restored: number;
726
727
  deletions_detected: number;
727
- duration_ms: number;
728
728
  firestore_reads: number;
729
729
  firestore_writes: number;
730
730
  n8n_calls: number;
@@ -739,11 +739,12 @@ export declare const zSyncRunEventSchema: z.ZodObject<{
739
739
  tenant: string;
740
740
  status: "success" | "error" | "partial";
741
741
  started_at: Date;
742
+ finished_at: Date;
742
743
  adapter_id: string;
743
744
  calendar_id: string;
744
- finished_at: Date;
745
745
  run_id: string;
746
746
  window_type: "hot" | "warm" | "recent_reconcile" | "cold";
747
+ duration_ms?: number | undefined;
747
748
  errors?: {
748
749
  message: string;
749
750
  code?: string | undefined;
@@ -756,7 +757,6 @@ export declare const zSyncRunEventSchema: z.ZodObject<{
756
757
  deletions_detected?: number | undefined;
757
758
  coveredWindow_start?: Date | undefined;
758
759
  coveredWindow_end?: Date | undefined;
759
- duration_ms?: number | undefined;
760
760
  firestore_reads?: number | undefined;
761
761
  firestore_writes?: number | undefined;
762
762
  n8n_calls?: number | undefined;
@@ -984,7 +984,7 @@ export declare const zMedCalendarIntegrationSchema: z.ZodObject<{
984
984
  cadence_minutes?: number | undefined;
985
985
  } | undefined;
986
986
  } | null | undefined;
987
- workflow_overrides?: Partial<Record<"appointment.get" | "appointment.list" | "appointment.create" | "appointment.update" | "appointment.cancel" | "appointment.confirm" | "appointment.revert_confirm" | "appointment.reschedule" | "patient.get" | "patient.list" | "patient.create" | "patient.update" | "patient.document.upload" | "payment.update" | "sync.appointments", string>> | undefined;
987
+ workflow_overrides?: Partial<Record<"patient.list" | "patient.get" | "appointment.list" | "appointment.create" | "appointment.get" | "appointment.update" | "appointment.confirm" | "appointment.revert_confirm" | "appointment.cancel" | "patient.create" | "patient.update" | "appointment.reschedule" | "patient.document.upload" | "payment.update" | "sync.appointments", string>> | undefined;
988
988
  }, {
989
989
  adapter_id: string;
990
990
  credentials_id: string;
@@ -1023,5 +1023,5 @@ export declare const zMedCalendarIntegrationSchema: z.ZodObject<{
1023
1023
  cadence_minutes?: number | undefined;
1024
1024
  } | undefined;
1025
1025
  } | null | undefined;
1026
- workflow_overrides?: Partial<Record<"appointment.get" | "appointment.list" | "appointment.create" | "appointment.update" | "appointment.cancel" | "appointment.confirm" | "appointment.revert_confirm" | "appointment.reschedule" | "patient.get" | "patient.list" | "patient.create" | "patient.update" | "patient.document.upload" | "payment.update" | "sync.appointments", string>> | undefined;
1026
+ workflow_overrides?: Partial<Record<"patient.list" | "patient.get" | "appointment.list" | "appointment.create" | "appointment.get" | "appointment.update" | "appointment.confirm" | "appointment.revert_confirm" | "appointment.cancel" | "patient.create" | "patient.update" | "appointment.reschedule" | "patient.document.upload" | "payment.update" | "sync.appointments", string>> | undefined;
1027
1027
  }>;
@@ -974,7 +974,7 @@ export declare const zMedCalendarSchema: z.ZodObject<{
974
974
  cadence_minutes?: number | undefined;
975
975
  } | undefined;
976
976
  } | null | undefined;
977
- workflow_overrides?: Partial<Record<"appointment.get" | "appointment.list" | "appointment.create" | "appointment.update" | "appointment.cancel" | "appointment.confirm" | "appointment.revert_confirm" | "appointment.reschedule" | "patient.get" | "patient.list" | "patient.create" | "patient.update" | "patient.document.upload" | "payment.update" | "sync.appointments", string>> | undefined;
977
+ workflow_overrides?: Partial<Record<"patient.list" | "patient.get" | "appointment.list" | "appointment.create" | "appointment.get" | "appointment.update" | "appointment.confirm" | "appointment.revert_confirm" | "appointment.cancel" | "patient.create" | "patient.update" | "appointment.reschedule" | "patient.document.upload" | "payment.update" | "sync.appointments", string>> | undefined;
978
978
  }, {
979
979
  adapter_id: string;
980
980
  credentials_id: string;
@@ -1013,7 +1013,7 @@ export declare const zMedCalendarSchema: z.ZodObject<{
1013
1013
  cadence_minutes?: number | undefined;
1014
1014
  } | undefined;
1015
1015
  } | null | undefined;
1016
- workflow_overrides?: Partial<Record<"appointment.get" | "appointment.list" | "appointment.create" | "appointment.update" | "appointment.cancel" | "appointment.confirm" | "appointment.revert_confirm" | "appointment.reschedule" | "patient.get" | "patient.list" | "patient.create" | "patient.update" | "patient.document.upload" | "payment.update" | "sync.appointments", string>> | undefined;
1016
+ workflow_overrides?: Partial<Record<"patient.list" | "patient.get" | "appointment.list" | "appointment.create" | "appointment.get" | "appointment.update" | "appointment.confirm" | "appointment.revert_confirm" | "appointment.cancel" | "patient.create" | "patient.update" | "appointment.reschedule" | "patient.document.upload" | "payment.update" | "sync.appointments", string>> | undefined;
1017
1017
  }>>>;
1018
1018
  notification_config: z.ZodOptional<z.ZodNullable<z.ZodObject<{
1019
1019
  whatsapp: z.ZodOptional<z.ZodNullable<z.ZodObject<{
@@ -1990,7 +1990,7 @@ export declare const zMedCalendarSchema: z.ZodObject<{
1990
1990
  cadence_minutes?: number | undefined;
1991
1991
  } | undefined;
1992
1992
  } | null | undefined;
1993
- workflow_overrides?: Partial<Record<"appointment.get" | "appointment.list" | "appointment.create" | "appointment.update" | "appointment.cancel" | "appointment.confirm" | "appointment.revert_confirm" | "appointment.reschedule" | "patient.get" | "patient.list" | "patient.create" | "patient.update" | "patient.document.upload" | "payment.update" | "sync.appointments", string>> | undefined;
1993
+ workflow_overrides?: Partial<Record<"patient.list" | "patient.get" | "appointment.list" | "appointment.create" | "appointment.get" | "appointment.update" | "appointment.confirm" | "appointment.revert_confirm" | "appointment.cancel" | "patient.create" | "patient.update" | "appointment.reschedule" | "patient.document.upload" | "payment.update" | "sync.appointments", string>> | undefined;
1994
1994
  }, {
1995
1995
  adapter_id: string;
1996
1996
  credentials_id: string;
@@ -2029,7 +2029,7 @@ export declare const zMedCalendarSchema: z.ZodObject<{
2029
2029
  cadence_minutes?: number | undefined;
2030
2030
  } | undefined;
2031
2031
  } | null | undefined;
2032
- workflow_overrides?: Partial<Record<"appointment.get" | "appointment.list" | "appointment.create" | "appointment.update" | "appointment.cancel" | "appointment.confirm" | "appointment.revert_confirm" | "appointment.reschedule" | "patient.get" | "patient.list" | "patient.create" | "patient.update" | "patient.document.upload" | "payment.update" | "sync.appointments", string>> | undefined;
2032
+ workflow_overrides?: Partial<Record<"patient.list" | "patient.get" | "appointment.list" | "appointment.create" | "appointment.get" | "appointment.update" | "appointment.confirm" | "appointment.revert_confirm" | "appointment.cancel" | "patient.create" | "patient.update" | "appointment.reschedule" | "patient.document.upload" | "payment.update" | "sync.appointments", string>> | undefined;
2033
2033
  }>>>;
2034
2034
  notification_config: z.ZodOptional<z.ZodNullable<z.ZodObject<{
2035
2035
  whatsapp: z.ZodOptional<z.ZodNullable<z.ZodObject<{
@@ -3006,7 +3006,7 @@ export declare const zMedCalendarSchema: z.ZodObject<{
3006
3006
  cadence_minutes?: number | undefined;
3007
3007
  } | undefined;
3008
3008
  } | null | undefined;
3009
- workflow_overrides?: Partial<Record<"appointment.get" | "appointment.list" | "appointment.create" | "appointment.update" | "appointment.cancel" | "appointment.confirm" | "appointment.revert_confirm" | "appointment.reschedule" | "patient.get" | "patient.list" | "patient.create" | "patient.update" | "patient.document.upload" | "payment.update" | "sync.appointments", string>> | undefined;
3009
+ workflow_overrides?: Partial<Record<"patient.list" | "patient.get" | "appointment.list" | "appointment.create" | "appointment.get" | "appointment.update" | "appointment.confirm" | "appointment.revert_confirm" | "appointment.cancel" | "patient.create" | "patient.update" | "appointment.reschedule" | "patient.document.upload" | "payment.update" | "sync.appointments", string>> | undefined;
3010
3010
  }, {
3011
3011
  adapter_id: string;
3012
3012
  credentials_id: string;
@@ -3045,7 +3045,7 @@ export declare const zMedCalendarSchema: z.ZodObject<{
3045
3045
  cadence_minutes?: number | undefined;
3046
3046
  } | undefined;
3047
3047
  } | null | undefined;
3048
- workflow_overrides?: Partial<Record<"appointment.get" | "appointment.list" | "appointment.create" | "appointment.update" | "appointment.cancel" | "appointment.confirm" | "appointment.revert_confirm" | "appointment.reschedule" | "patient.get" | "patient.list" | "patient.create" | "patient.update" | "patient.document.upload" | "payment.update" | "sync.appointments", string>> | undefined;
3048
+ workflow_overrides?: Partial<Record<"patient.list" | "patient.get" | "appointment.list" | "appointment.create" | "appointment.get" | "appointment.update" | "appointment.confirm" | "appointment.revert_confirm" | "appointment.cancel" | "patient.create" | "patient.update" | "appointment.reschedule" | "patient.document.upload" | "payment.update" | "sync.appointments", string>> | undefined;
3049
3049
  }>>>;
3050
3050
  notification_config: z.ZodOptional<z.ZodNullable<z.ZodObject<{
3051
3051
  whatsapp: z.ZodOptional<z.ZodNullable<z.ZodObject<{
@@ -3468,21 +3468,6 @@ export declare const zAutomationRoutineSchema: z.ZodObject<{
3468
3468
  created_at: Date;
3469
3469
  updated_at: Date;
3470
3470
  active: boolean;
3471
- trigger: {
3472
- type: "cron";
3473
- cron: {
3474
- expression: string;
3475
- timezone?: string | undefined;
3476
- };
3477
- } | {
3478
- type: "webhook";
3479
- } | {
3480
- type: "event";
3481
- event: {
3482
- types: string[];
3483
- actor_kinds?: ("user" | "system" | "automation")[] | undefined;
3484
- };
3485
- };
3486
3471
  selection: {
3487
3472
  appointment: {
3488
3473
  date_window: {
@@ -3516,6 +3501,21 @@ export declare const zAutomationRoutineSchema: z.ZodObject<{
3516
3501
  };
3517
3502
  target: "patient";
3518
3503
  };
3504
+ trigger: {
3505
+ type: "cron";
3506
+ cron: {
3507
+ expression: string;
3508
+ timezone?: string | undefined;
3509
+ };
3510
+ } | {
3511
+ type: "webhook";
3512
+ } | {
3513
+ type: "event";
3514
+ event: {
3515
+ types: string[];
3516
+ actor_kinds?: ("user" | "system" | "automation")[] | undefined;
3517
+ };
3518
+ };
3519
3519
  branch_mode: "all" | "exclusive";
3520
3520
  branches: {
3521
3521
  name: string;
@@ -3664,21 +3664,6 @@ export declare const zAutomationRoutineSchema: z.ZodObject<{
3664
3664
  id: string;
3665
3665
  created_at: Date;
3666
3666
  updated_at: Date;
3667
- trigger: {
3668
- type: "cron";
3669
- cron: {
3670
- expression: string;
3671
- timezone?: string | undefined;
3672
- };
3673
- } | {
3674
- type: "webhook";
3675
- } | {
3676
- type: "event";
3677
- event: {
3678
- types: string[];
3679
- actor_kinds?: ("user" | "system" | "automation")[] | undefined;
3680
- };
3681
- };
3682
3667
  selection: {
3683
3668
  appointment: {
3684
3669
  date_window: {
@@ -3712,6 +3697,21 @@ export declare const zAutomationRoutineSchema: z.ZodObject<{
3712
3697
  };
3713
3698
  target: "patient";
3714
3699
  };
3700
+ trigger: {
3701
+ type: "cron";
3702
+ cron: {
3703
+ expression: string;
3704
+ timezone?: string | undefined;
3705
+ };
3706
+ } | {
3707
+ type: "webhook";
3708
+ } | {
3709
+ type: "event";
3710
+ event: {
3711
+ types: string[];
3712
+ actor_kinds?: ("user" | "system" | "automation")[] | undefined;
3713
+ };
3714
+ };
3715
3715
  branch_mode: "all" | "exclusive";
3716
3716
  branches: {
3717
3717
  name: string;
@@ -4890,21 +4890,6 @@ export declare const zAutomationRoutineWriteSchema: z.ZodObject<{
4890
4890
  name: string;
4891
4891
  id: string;
4892
4892
  active: boolean;
4893
- trigger: {
4894
- type: "cron";
4895
- cron: {
4896
- expression: string;
4897
- timezone?: string | undefined;
4898
- };
4899
- } | {
4900
- type: "webhook";
4901
- } | {
4902
- type: "event";
4903
- event: {
4904
- types: string[];
4905
- actor_kinds?: ("user" | "system" | "automation")[] | undefined;
4906
- };
4907
- };
4908
4893
  selection: {
4909
4894
  appointment: {
4910
4895
  date_window: {
@@ -4938,6 +4923,21 @@ export declare const zAutomationRoutineWriteSchema: z.ZodObject<{
4938
4923
  };
4939
4924
  target: "patient";
4940
4925
  };
4926
+ trigger: {
4927
+ type: "cron";
4928
+ cron: {
4929
+ expression: string;
4930
+ timezone?: string | undefined;
4931
+ };
4932
+ } | {
4933
+ type: "webhook";
4934
+ } | {
4935
+ type: "event";
4936
+ event: {
4937
+ types: string[];
4938
+ actor_kinds?: ("user" | "system" | "automation")[] | undefined;
4939
+ };
4940
+ };
4941
4941
  branch_mode: "all" | "exclusive";
4942
4942
  branches: {
4943
4943
  name: string;
@@ -5071,21 +5071,6 @@ export declare const zAutomationRoutineWriteSchema: z.ZodObject<{
5071
5071
  }, {
5072
5072
  name: string;
5073
5073
  id: string;
5074
- trigger: {
5075
- type: "cron";
5076
- cron: {
5077
- expression: string;
5078
- timezone?: string | undefined;
5079
- };
5080
- } | {
5081
- type: "webhook";
5082
- } | {
5083
- type: "event";
5084
- event: {
5085
- types: string[];
5086
- actor_kinds?: ("user" | "system" | "automation")[] | undefined;
5087
- };
5088
- };
5089
5074
  selection: {
5090
5075
  appointment: {
5091
5076
  date_window: {
@@ -5119,6 +5104,21 @@ export declare const zAutomationRoutineWriteSchema: z.ZodObject<{
5119
5104
  };
5120
5105
  target: "patient";
5121
5106
  };
5107
+ trigger: {
5108
+ type: "cron";
5109
+ cron: {
5110
+ expression: string;
5111
+ timezone?: string | undefined;
5112
+ };
5113
+ } | {
5114
+ type: "webhook";
5115
+ } | {
5116
+ type: "event";
5117
+ event: {
5118
+ types: string[];
5119
+ actor_kinds?: ("user" | "system" | "automation")[] | undefined;
5120
+ };
5121
+ };
5122
5122
  branch_mode: "all" | "exclusive";
5123
5123
  branches: {
5124
5124
  name: string;
@@ -6284,21 +6284,6 @@ export declare const zAutomationRoutineUpdateRequestSchema: z.ZodObject<{
6284
6284
  name: string;
6285
6285
  id: string;
6286
6286
  active: boolean;
6287
- trigger: {
6288
- type: "cron";
6289
- cron: {
6290
- expression: string;
6291
- timezone?: string | undefined;
6292
- };
6293
- } | {
6294
- type: "webhook";
6295
- } | {
6296
- type: "event";
6297
- event: {
6298
- types: string[];
6299
- actor_kinds?: ("user" | "system" | "automation")[] | undefined;
6300
- };
6301
- };
6302
6287
  selection: {
6303
6288
  appointment: {
6304
6289
  date_window: {
@@ -6332,6 +6317,21 @@ export declare const zAutomationRoutineUpdateRequestSchema: z.ZodObject<{
6332
6317
  };
6333
6318
  target: "patient";
6334
6319
  };
6320
+ trigger: {
6321
+ type: "cron";
6322
+ cron: {
6323
+ expression: string;
6324
+ timezone?: string | undefined;
6325
+ };
6326
+ } | {
6327
+ type: "webhook";
6328
+ } | {
6329
+ type: "event";
6330
+ event: {
6331
+ types: string[];
6332
+ actor_kinds?: ("user" | "system" | "automation")[] | undefined;
6333
+ };
6334
+ };
6335
6335
  branch_mode: "all" | "exclusive";
6336
6336
  branches: {
6337
6337
  name: string;
@@ -6465,21 +6465,6 @@ export declare const zAutomationRoutineUpdateRequestSchema: z.ZodObject<{
6465
6465
  }, {
6466
6466
  name: string;
6467
6467
  id: string;
6468
- trigger: {
6469
- type: "cron";
6470
- cron: {
6471
- expression: string;
6472
- timezone?: string | undefined;
6473
- };
6474
- } | {
6475
- type: "webhook";
6476
- } | {
6477
- type: "event";
6478
- event: {
6479
- types: string[];
6480
- actor_kinds?: ("user" | "system" | "automation")[] | undefined;
6481
- };
6482
- };
6483
6468
  selection: {
6484
6469
  appointment: {
6485
6470
  date_window: {
@@ -6513,6 +6498,21 @@ export declare const zAutomationRoutineUpdateRequestSchema: z.ZodObject<{
6513
6498
  };
6514
6499
  target: "patient";
6515
6500
  };
6501
+ trigger: {
6502
+ type: "cron";
6503
+ cron: {
6504
+ expression: string;
6505
+ timezone?: string | undefined;
6506
+ };
6507
+ } | {
6508
+ type: "webhook";
6509
+ } | {
6510
+ type: "event";
6511
+ event: {
6512
+ types: string[];
6513
+ actor_kinds?: ("user" | "system" | "automation")[] | undefined;
6514
+ };
6515
+ };
6516
6516
  branch_mode: "all" | "exclusive";
6517
6517
  branches: {
6518
6518
  name: string;
@@ -6651,21 +6651,6 @@ export declare const zAutomationRoutineUpdateRequestSchema: z.ZodObject<{
6651
6651
  name: string;
6652
6652
  id: string;
6653
6653
  active: boolean;
6654
- trigger: {
6655
- type: "cron";
6656
- cron: {
6657
- expression: string;
6658
- timezone?: string | undefined;
6659
- };
6660
- } | {
6661
- type: "webhook";
6662
- } | {
6663
- type: "event";
6664
- event: {
6665
- types: string[];
6666
- actor_kinds?: ("user" | "system" | "automation")[] | undefined;
6667
- };
6668
- };
6669
6654
  selection: {
6670
6655
  appointment: {
6671
6656
  date_window: {
@@ -6699,6 +6684,21 @@ export declare const zAutomationRoutineUpdateRequestSchema: z.ZodObject<{
6699
6684
  };
6700
6685
  target: "patient";
6701
6686
  };
6687
+ trigger: {
6688
+ type: "cron";
6689
+ cron: {
6690
+ expression: string;
6691
+ timezone?: string | undefined;
6692
+ };
6693
+ } | {
6694
+ type: "webhook";
6695
+ } | {
6696
+ type: "event";
6697
+ event: {
6698
+ types: string[];
6699
+ actor_kinds?: ("user" | "system" | "automation")[] | undefined;
6700
+ };
6701
+ };
6702
6702
  branch_mode: "all" | "exclusive";
6703
6703
  branches: {
6704
6704
  name: string;
@@ -6835,21 +6835,6 @@ export declare const zAutomationRoutineUpdateRequestSchema: z.ZodObject<{
6835
6835
  routine: {
6836
6836
  name: string;
6837
6837
  id: string;
6838
- trigger: {
6839
- type: "cron";
6840
- cron: {
6841
- expression: string;
6842
- timezone?: string | undefined;
6843
- };
6844
- } | {
6845
- type: "webhook";
6846
- } | {
6847
- type: "event";
6848
- event: {
6849
- types: string[];
6850
- actor_kinds?: ("user" | "system" | "automation")[] | undefined;
6851
- };
6852
- };
6853
6838
  selection: {
6854
6839
  appointment: {
6855
6840
  date_window: {
@@ -6883,6 +6868,21 @@ export declare const zAutomationRoutineUpdateRequestSchema: z.ZodObject<{
6883
6868
  };
6884
6869
  target: "patient";
6885
6870
  };
6871
+ trigger: {
6872
+ type: "cron";
6873
+ cron: {
6874
+ expression: string;
6875
+ timezone?: string | undefined;
6876
+ };
6877
+ } | {
6878
+ type: "webhook";
6879
+ } | {
6880
+ type: "event";
6881
+ event: {
6882
+ types: string[];
6883
+ actor_kinds?: ("user" | "system" | "automation")[] | undefined;
6884
+ };
6885
+ };
6886
6886
  branch_mode: "all" | "exclusive";
6887
6887
  branches: {
6888
6888
  name: string;
@@ -1,4 +1,5 @@
1
1
  export * from "./fb_collections";
2
+ export * from "./test-suite";
2
3
  import type { IFireDoc } from "../shared";
3
4
  export declare const EvoIntegrationsPermissions: {
4
5
  readonly List: "evo_integrations_read";
@@ -18,6 +18,7 @@ exports.OBLIGATORY_CAPABILITIES = exports.SYNC_RUN_HANDLER = exports.SYNC_RUN_PU
18
18
  exports.isInternalCapability = isInternalCapability;
19
19
  exports.splitCapabilityName = splitCapabilityName;
20
20
  __exportStar(require("./fb_collections"), exports);
21
+ __exportStar(require("./test-suite"), exports);
21
22
  // ======================================================
22
23
  // evo-integrations
23
24
  //
@@ -1,4 +1,5 @@
1
1
  export * from "./fb_collections";
2
+ export * from "./test-suite";
2
3
  import type { IFireDoc } from "../shared";
3
4
 
4
5
  // ======================================================
@@ -0,0 +1,211 @@
1
+ import type { IFireDoc } from "../shared";
2
+ export declare const TEST_RUNS_COLLECTION = "test-runs";
3
+ export declare const TEST_RUN_STEPS_COLLECTION = "steps";
4
+ /**
5
+ * O agrupamento é derivado da DEPENDÊNCIA REAL DE ESTADO, não de estética:
6
+ * o `external_id` devolvido pelo create alimenta get/update/confirm/revert/cancel,
7
+ * e o do patient.create alimenta o round-trip e o delete.
8
+ */
9
+ export type TestSuiteId = "reading" | "appointment" | "sync" | "patient" | "cleanup";
10
+ export interface ITestSuiteMeta {
11
+ id: TestSuiteId;
12
+ label: string;
13
+ /** Ordem estrita = o passo N depende do estado produzido pelo N-1. */
14
+ ordered: boolean;
15
+ description: string;
16
+ }
17
+ export declare const TEST_SUITES: readonly ITestSuiteMeta[];
18
+ export type TestStepId = "caps.list" | "ui.config" | "procedure.list" | "status.list" | "dicts.extra" | "patient.list" | "patient.get" | "appointment.list" | "appointment.create" | "appointment.get" | "appointment.update" | "appointment.confirm" | "appointment.revert_confirm" | "appointment.cancel" | "sync.force" | "patient.create" | "patient.roundtrip" | "patient.delete" | "residue.sweep";
19
+ export interface ITestStepMeta {
20
+ id: TestStepId;
21
+ suite: TestSuiteId;
22
+ label: string;
23
+ /**
24
+ * `true` = o passo ESCREVE no PMS de produção.
25
+ *
26
+ * Usado em dois lugares: para o modo somente-leitura e para classificar o custo
27
+ * de REPETIR um passo — repetir leitura é livre, repetir escrita duplica efeito.
28
+ */
29
+ writes: boolean;
30
+ /** Passos que precisam ter passado antes. Vazio = pode rodar sozinho. */
31
+ dependsOn: readonly TestStepId[];
32
+ /** Capability invocada, quando houver. Nem todo passo tem uma. */
33
+ capability?: string;
34
+ }
35
+ /**
36
+ * Ordem do array = ordem de execução. Não é 1:1 com capability:
37
+ * · `residue.sweep` não invoca capability nenhuma (varre a agenda externa);
38
+ * · `sync.force` chama `integrations_sync_monitor`, não uma capability;
39
+ * · `appointment.list` aparece em dois passos (leitura e varredura);
40
+ * · `patient.roundtrip` combina `patient.get` + `patient.update`.
41
+ */
42
+ export declare const TEST_STEPS: readonly ITestStepMeta[];
43
+ /**
44
+ * Suíte padrão (D10) — a LINHA DE BASE COMPARÁVEL: todos os passos.
45
+ *
46
+ * Só uma corrida com exatamente esta seleção é comparável com a anterior. Sem isso
47
+ * o output principal da ferramenta ("nenhum defeito novo") seria infalsificável:
48
+ * bastaria desmarcar o passo que falha.
49
+ *
50
+ * Atenção: a seleção não basta. `comparable` também exige `target.create_patient`
51
+ * ligado — senão `patient.create`/`patient.delete` são pulados e a cobertura real
52
+ * fica menor que a nominal. Quem decide isso é o backend, em `computeComparable`.
53
+ */
54
+ export declare const STANDARD_SUITE_STEP_IDS: readonly TestStepId[];
55
+ export declare const READ_ONLY_STEP_IDS: readonly TestStepId[];
56
+ export type TestCheckStatus = "pass" | "fail" | "skipped";
57
+ export interface ITestCheck {
58
+ /**
59
+ * Id ESTÁVEL no formato `<step_id>:<slug>` — ex. `appointment.update:sem_divergencia`.
60
+ *
61
+ * É a chave que o catálogo de conhecidos referencia. O script antigo casava por
62
+ * REGEX no texto do label, o que quebrava nos dois sentidos: mudar a redação
63
+ * descatalogava um defeito em silêncio, e um regex largo engolia defeito novo de
64
+ * outra causa. Por isso o id vem antes do texto — o label pode ser reescrito à
65
+ * vontade.
66
+ */
67
+ id: string;
68
+ label: string;
69
+ status: TestCheckStatus;
70
+ detail?: string;
71
+ }
72
+ export type TestStepStatus = "pending" | "running" | "pass" | "known" | "fail" | "skipped" | "error";
73
+ export interface ITestSchemaValidation {
74
+ ok: boolean;
75
+ errors?: Array<{
76
+ path: (string | number)[];
77
+ message: string;
78
+ code?: string;
79
+ }>;
80
+ }
81
+ /**
82
+ * O wire — o que o BACKEND mandou para o n8n, lido de
83
+ * `integrations_sync_monitor GET /calls?run_id=`.
84
+ *
85
+ * É a camada que interessa a quem mantém os workflows: a resposta da action mostra
86
+ * o que a UI mandou, não o que saiu na linha. `DocumentReference` vivo no payload
87
+ * (a classe de bug que derrubou produção no revert_confirm) só aparece aqui.
88
+ */
89
+ export interface ITestStepWire {
90
+ request_json?: string;
91
+ response_json?: string;
92
+ n8n_execution_id?: string | null;
93
+ n8n_workflow_id?: string | null;
94
+ workflow_url?: string;
95
+ http_status?: number | null;
96
+ timed_out?: boolean | null;
97
+ error_message?: string | null;
98
+ request_truncated?: boolean | null;
99
+ response_truncated?: boolean | null;
100
+ }
101
+ export interface ITestRunStep extends IFireDoc {
102
+ step_id: TestStepId;
103
+ suite: TestSuiteId;
104
+ order: number;
105
+ status: TestStepStatus;
106
+ started_at?: unknown;
107
+ finished_at?: unknown;
108
+ duration_ms?: number;
109
+ /** Camada 1 — o que a UI mandou para `integrations_actions` e o que voltou. */
110
+ layer1?: {
111
+ request?: unknown;
112
+ response?: unknown;
113
+ };
114
+ /** Correlação com o wire: `transport_metadata.run_id` da resposta da action. */
115
+ n8n_run_id?: string | null;
116
+ /** Camada 2 — o que o BE mandou para o n8n. */
117
+ wire?: ITestStepWire | null;
118
+ schema_validation?: {
119
+ request?: ITestSchemaValidation;
120
+ response?: ITestSchemaValidation;
121
+ } | null;
122
+ checks: ITestCheck[];
123
+ /** Preenchido quando `status === 'known'`: qual defeito catalogado casou. */
124
+ known_defects?: Array<{
125
+ check_id: string;
126
+ description: string;
127
+ ref: string;
128
+ }>;
129
+ error?: string | null;
130
+ }
131
+ export type TestRunStatus = "running" | "finished" | "abandoned";
132
+ /** Dados do paciente novo, quando o usuário liga a criação (D3). */
133
+ export interface ITestNewPatient {
134
+ first_name: string;
135
+ last_name?: string;
136
+ mobile_phone?: string;
137
+ email?: string;
138
+ social_id?: string;
139
+ birth_date?: string;
140
+ }
141
+ export interface ITestRunTarget {
142
+ /** Paciente de teste JÁ EXISTENTE, usado na leitura e no agendamento. */
143
+ patient_id: string;
144
+ /** Só quando `create_patient` está ligado. */
145
+ new_patient?: ITestNewPatient | null;
146
+ create_patient: boolean;
147
+ /** `YYYY-MM-DD`. Recomendado no passado — é aviso, não trava (D2). */
148
+ slot_date: string;
149
+ /** `HH:MM`. */
150
+ slot_time: string;
151
+ /** Dia povoado para o `appointment.list`; sem isso usa `slot_date`. */
152
+ list_date?: string | null;
153
+ }
154
+ /**
155
+ * Diagnóstico de segurança — AVISO, não trava (D2).
156
+ *
157
+ * Os dois avisos têm gravidade diferente e a UI precisa refletir isso: data futura
158
+ * só ativa as varreduras D-2/D-0, que dependem de janela; gatilho de evento ligado
159
+ * dispara na hora do create.
160
+ */
161
+ export interface ITestRunPreflight {
162
+ slot_in_past: boolean;
163
+ /** Quais dos gatilhos de evento estão ligados na agenda-alvo. */
164
+ triggers_enabled: string[];
165
+ /**
166
+ * `notification_config.configs` vazio.
167
+ *
168
+ * Distinguir de "desligado" importa: nada dispara nos dois casos, mas aqui é por
169
+ * AUSÊNCIA DE CONFIGURAÇÃO, não por decisão de alguém.
170
+ */
171
+ notification_config_empty: boolean;
172
+ evaluated_at?: unknown;
173
+ }
174
+ /** O que a corrida criou no PMS — permite enumerar resíduo quando o `Z` é desmarcado (D11). */
175
+ export interface ITestRunInventory {
176
+ appointment_external_ids: string[];
177
+ patient_external_id?: string | null;
178
+ }
179
+ export interface ITestRunVerdict {
180
+ ok: number;
181
+ known: number;
182
+ new_defects: number;
183
+ }
184
+ export interface ITestRun extends IFireDoc {
185
+ adapter_id: string;
186
+ tenant: string;
187
+ calendar_id: string;
188
+ target: ITestRunTarget;
189
+ selection: {
190
+ preset: "standard" | "read-only" | "custom";
191
+ step_ids: TestStepId[];
192
+ };
193
+ /** Quantos passos da suíte padrão esta corrida cobriu. */
194
+ coverage: {
195
+ ran: number;
196
+ total: number;
197
+ };
198
+ /** `true` só quando a seleção é exatamente a suíte padrão (D10). */
199
+ comparable: boolean;
200
+ preflight: ITestRunPreflight;
201
+ inventory: ITestRunInventory;
202
+ verdict: ITestRunVerdict;
203
+ status: TestRunStatus;
204
+ /**
205
+ * Dono da corrida. Quem orquestra é o FE, então duas abas conduzindo a mesma
206
+ * corrida escreveriam na mesma agenda de produção em paralelo — outro usuário
207
+ * abre em modo leitura até assumir explicitamente.
208
+ */
209
+ created_by: string;
210
+ finished_at?: unknown;
211
+ }
@@ -0,0 +1,101 @@
1
+ "use strict";
2
+ // ======================================================
3
+ // evo-integrations — bateria de regressão de adapters (feat-123)
4
+ //
5
+ // Porte do script `_regressao-adapters.cjs` para ferramenta de produto no Nexus.
6
+ //
7
+ // A ferramenta é APARTADA: roda por fora, chamando as APIs (`integrations_actions`,
8
+ // `integrations_admin`, `integrations_sync_monitor`) exatamente como o script faz.
9
+ // Quem orquestra a sequência é o FE; quem persiste o resultado é o BE.
10
+ //
11
+ // Este módulo é o contrato COMPARTILHADO entre os dois lados:
12
+ // · o FE monta a seleção a partir do catálogo de passos;
13
+ // · o BE valida a seleção contra o MESMO catálogo e calcula o veredito.
14
+ //
15
+ // O catálogo de defeitos CONHECIDOS não mora aqui — mora no backend do Nexus,
16
+ // porque só ele calcula veredito (o FE apenas renderiza o que recebe).
17
+ // ======================================================
18
+ Object.defineProperty(exports, "__esModule", { value: true });
19
+ exports.READ_ONLY_STEP_IDS = exports.STANDARD_SUITE_STEP_IDS = exports.TEST_STEPS = exports.TEST_SUITES = exports.TEST_RUN_STEPS_COLLECTION = exports.TEST_RUNS_COLLECTION = void 0;
20
+ // Path: /platform/evo-integrations/test-runs/{run_id}
21
+ exports.TEST_RUNS_COLLECTION = "test-runs";
22
+ // Path: /platform/evo-integrations/test-runs/{run_id}/steps/{step_id}
23
+ exports.TEST_RUN_STEPS_COLLECTION = "steps";
24
+ exports.TEST_SUITES = [
25
+ {
26
+ id: "reading",
27
+ label: "Dicionários e leitura",
28
+ ordered: false,
29
+ description: "Capabilities de consulta. Nenhuma escreve — pode rodar sozinha com efeito colateral zero.",
30
+ },
31
+ {
32
+ id: "appointment",
33
+ label: "Ciclo de vida do agendamento",
34
+ ordered: true,
35
+ description: "create → get → update → confirm → revert_confirm → cancel. Cada passo depende do external_id do create.",
36
+ },
37
+ {
38
+ id: "sync",
39
+ label: "Sync não ressuscita",
40
+ ordered: true,
41
+ description: "Força o sync de 1 dia e confere que o agendamento cancelado NÃO volta. Exige o cancel da suíte anterior.",
42
+ },
43
+ {
44
+ id: "patient",
45
+ label: "Paciente",
46
+ ordered: true,
47
+ description: "create → round-trip (get+update) → delete. O create nunca foi exercitado por nenhuma rodada do script.",
48
+ },
49
+ {
50
+ id: "cleanup",
51
+ label: "Varredura de resíduo",
52
+ ordered: false,
53
+ description: "Lê a agenda EXTERNA e cancela o que tiver o marcador. Selecionável — quem roda é o dev de integrações, que responde pelo que escolhe.",
54
+ },
55
+ ];
56
+ /**
57
+ * Ordem do array = ordem de execução. Não é 1:1 com capability:
58
+ * · `residue.sweep` não invoca capability nenhuma (varre a agenda externa);
59
+ * · `sync.force` chama `integrations_sync_monitor`, não uma capability;
60
+ * · `appointment.list` aparece em dois passos (leitura e varredura);
61
+ * · `patient.roundtrip` combina `patient.get` + `patient.update`.
62
+ */
63
+ exports.TEST_STEPS = [
64
+ // ── S1 — leitura ────────────────────────────────────────────────────────────
65
+ { id: "caps.list", suite: "reading", label: "capabilities", writes: false, dependsOn: [] },
66
+ { id: "ui.config", suite: "reading", label: "ui-config", writes: false, dependsOn: [] },
67
+ { id: "procedure.list", suite: "reading", label: "procedure.list", writes: false, dependsOn: [], capability: "appointment.procedure.list" },
68
+ { id: "status.list", suite: "reading", label: "status.list", writes: false, dependsOn: [], capability: "appointment.status.list" },
69
+ { id: "dicts.extra", suite: "reading", label: "dicionários extra", writes: false, dependsOn: [] },
70
+ { id: "patient.list", suite: "reading", label: "patient.list", writes: false, dependsOn: [], capability: "patient.list" },
71
+ { id: "patient.get", suite: "reading", label: "patient.get", writes: false, dependsOn: [], capability: "patient.get" },
72
+ { id: "appointment.list", suite: "reading", label: "appointment.list", writes: false, dependsOn: [], capability: "appointment.list" },
73
+ // ── S2 — ciclo de vida ──────────────────────────────────────────────────────
74
+ { id: "appointment.create", suite: "appointment", label: "create", writes: true, dependsOn: [], capability: "appointment.create" },
75
+ { id: "appointment.get", suite: "appointment", label: "get", writes: false, dependsOn: ["appointment.create"], capability: "appointment.get" },
76
+ { id: "appointment.update", suite: "appointment", label: "update", writes: true, dependsOn: ["appointment.create"], capability: "appointment.update" },
77
+ { id: "appointment.confirm", suite: "appointment", label: "confirm", writes: true, dependsOn: ["appointment.create"], capability: "appointment.confirm" },
78
+ { id: "appointment.revert_confirm", suite: "appointment", label: "revert_confirm", writes: true, dependsOn: ["appointment.confirm"], capability: "appointment.revert_confirm" },
79
+ { id: "appointment.cancel", suite: "appointment", label: "cancel", writes: true, dependsOn: ["appointment.create"], capability: "appointment.cancel" },
80
+ // ── S3 — sync ───────────────────────────────────────────────────────────────
81
+ { id: "sync.force", suite: "sync", label: "sync (1 dia)", writes: true, dependsOn: ["appointment.cancel"] },
82
+ // ── S4 — paciente ───────────────────────────────────────────────────────────
83
+ { id: "patient.create", suite: "patient", label: "patient.create", writes: true, dependsOn: [], capability: "patient.create" },
84
+ { id: "patient.roundtrip", suite: "patient", label: "round-trip (get+update)", writes: true, dependsOn: [], capability: "patient.update" },
85
+ { id: "patient.delete", suite: "patient", label: "patient.delete", writes: true, dependsOn: ["patient.create"], capability: "patient.delete" },
86
+ // ── Z — limpeza ─────────────────────────────────────────────────────────────
87
+ { id: "residue.sweep", suite: "cleanup", label: "varredura de resíduo", writes: true, dependsOn: [] },
88
+ ];
89
+ /**
90
+ * Suíte padrão (D10) — a LINHA DE BASE COMPARÁVEL: todos os passos.
91
+ *
92
+ * Só uma corrida com exatamente esta seleção é comparável com a anterior. Sem isso
93
+ * o output principal da ferramenta ("nenhum defeito novo") seria infalsificável:
94
+ * bastaria desmarcar o passo que falha.
95
+ *
96
+ * Atenção: a seleção não basta. `comparable` também exige `target.create_patient`
97
+ * ligado — senão `patient.create`/`patient.delete` são pulados e a cobertura real
98
+ * fica menor que a nominal. Quem decide isso é o backend, em `computeComparable`.
99
+ */
100
+ exports.STANDARD_SUITE_STEP_IDS = exports.TEST_STEPS.map((s) => s.id);
101
+ exports.READ_ONLY_STEP_IDS = exports.TEST_STEPS.filter((s) => !s.writes).map((s) => s.id);
@@ -0,0 +1,376 @@
1
+ // ======================================================
2
+ // evo-integrations — bateria de regressão de adapters (feat-123)
3
+ //
4
+ // Porte do script `_regressao-adapters.cjs` para ferramenta de produto no Nexus.
5
+ //
6
+ // A ferramenta é APARTADA: roda por fora, chamando as APIs (`integrations_actions`,
7
+ // `integrations_admin`, `integrations_sync_monitor`) exatamente como o script faz.
8
+ // Quem orquestra a sequência é o FE; quem persiste o resultado é o BE.
9
+ //
10
+ // Este módulo é o contrato COMPARTILHADO entre os dois lados:
11
+ // · o FE monta a seleção a partir do catálogo de passos;
12
+ // · o BE valida a seleção contra o MESMO catálogo e calcula o veredito.
13
+ //
14
+ // O catálogo de defeitos CONHECIDOS não mora aqui — mora no backend do Nexus,
15
+ // porque só ele calcula veredito (o FE apenas renderiza o que recebe).
16
+ // ======================================================
17
+
18
+ import type { IFireDoc } from "../shared";
19
+
20
+ // Path: /platform/evo-integrations/test-runs/{run_id}
21
+ export const TEST_RUNS_COLLECTION = "test-runs";
22
+ // Path: /platform/evo-integrations/test-runs/{run_id}/steps/{step_id}
23
+ export const TEST_RUN_STEPS_COLLECTION = "steps";
24
+
25
+ // ======================================================
26
+ // Suítes
27
+ // ======================================================
28
+
29
+ /**
30
+ * O agrupamento é derivado da DEPENDÊNCIA REAL DE ESTADO, não de estética:
31
+ * o `external_id` devolvido pelo create alimenta get/update/confirm/revert/cancel,
32
+ * e o do patient.create alimenta o round-trip e o delete.
33
+ */
34
+ export type TestSuiteId =
35
+ | "reading" // S1 — dicionários e leitura; independentes, zero efeito colateral
36
+ | "appointment" // S2 — ciclo de vida; ordem estrita
37
+ | "sync" // S3 — depende do cancel da S2
38
+ | "patient" // S4 — ordem estrita; opcional
39
+ | "cleanup"; // Z — limpeza; selecionável (D11)
40
+
41
+ export interface ITestSuiteMeta {
42
+ id: TestSuiteId;
43
+ label: string;
44
+ /** Ordem estrita = o passo N depende do estado produzido pelo N-1. */
45
+ ordered: boolean;
46
+ description: string;
47
+ }
48
+
49
+ export const TEST_SUITES: readonly ITestSuiteMeta[] = [
50
+ {
51
+ id: "reading",
52
+ label: "Dicionários e leitura",
53
+ ordered: false,
54
+ description:
55
+ "Capabilities de consulta. Nenhuma escreve — pode rodar sozinha com efeito colateral zero.",
56
+ },
57
+ {
58
+ id: "appointment",
59
+ label: "Ciclo de vida do agendamento",
60
+ ordered: true,
61
+ description:
62
+ "create → get → update → confirm → revert_confirm → cancel. Cada passo depende do external_id do create.",
63
+ },
64
+ {
65
+ id: "sync",
66
+ label: "Sync não ressuscita",
67
+ ordered: true,
68
+ description:
69
+ "Força o sync de 1 dia e confere que o agendamento cancelado NÃO volta. Exige o cancel da suíte anterior.",
70
+ },
71
+ {
72
+ id: "patient",
73
+ label: "Paciente",
74
+ ordered: true,
75
+ description:
76
+ "create → round-trip (get+update) → delete. O create nunca foi exercitado por nenhuma rodada do script.",
77
+ },
78
+ {
79
+ id: "cleanup",
80
+ label: "Varredura de resíduo",
81
+ ordered: false,
82
+ description:
83
+ "Lê a agenda EXTERNA e cancela o que tiver o marcador. Selecionável — quem roda é o dev de integrações, que responde pelo que escolhe.",
84
+ },
85
+ ] as const;
86
+
87
+ // ======================================================
88
+ // Passos
89
+ // ======================================================
90
+
91
+ export type TestStepId =
92
+ // S1
93
+ | "caps.list"
94
+ | "ui.config"
95
+ | "procedure.list"
96
+ | "status.list"
97
+ | "dicts.extra"
98
+ | "patient.list"
99
+ | "patient.get"
100
+ | "appointment.list"
101
+ // S2
102
+ | "appointment.create"
103
+ | "appointment.get"
104
+ | "appointment.update"
105
+ | "appointment.confirm"
106
+ | "appointment.revert_confirm"
107
+ | "appointment.cancel"
108
+ // S3
109
+ | "sync.force"
110
+ // S4
111
+ | "patient.create"
112
+ | "patient.roundtrip"
113
+ | "patient.delete"
114
+ // Z
115
+ | "residue.sweep";
116
+
117
+ export interface ITestStepMeta {
118
+ id: TestStepId;
119
+ suite: TestSuiteId;
120
+ label: string;
121
+ /**
122
+ * `true` = o passo ESCREVE no PMS de produção.
123
+ *
124
+ * Usado em dois lugares: para o modo somente-leitura e para classificar o custo
125
+ * de REPETIR um passo — repetir leitura é livre, repetir escrita duplica efeito.
126
+ */
127
+ writes: boolean;
128
+ /** Passos que precisam ter passado antes. Vazio = pode rodar sozinho. */
129
+ dependsOn: readonly TestStepId[];
130
+ /** Capability invocada, quando houver. Nem todo passo tem uma. */
131
+ capability?: string;
132
+ }
133
+
134
+ /**
135
+ * Ordem do array = ordem de execução. Não é 1:1 com capability:
136
+ * · `residue.sweep` não invoca capability nenhuma (varre a agenda externa);
137
+ * · `sync.force` chama `integrations_sync_monitor`, não uma capability;
138
+ * · `appointment.list` aparece em dois passos (leitura e varredura);
139
+ * · `patient.roundtrip` combina `patient.get` + `patient.update`.
140
+ */
141
+ export const TEST_STEPS: readonly ITestStepMeta[] = [
142
+ // ── S1 — leitura ────────────────────────────────────────────────────────────
143
+ { id: "caps.list", suite: "reading", label: "capabilities", writes: false, dependsOn: [] },
144
+ { id: "ui.config", suite: "reading", label: "ui-config", writes: false, dependsOn: [] },
145
+ { id: "procedure.list", suite: "reading", label: "procedure.list", writes: false, dependsOn: [], capability: "appointment.procedure.list" },
146
+ { id: "status.list", suite: "reading", label: "status.list", writes: false, dependsOn: [], capability: "appointment.status.list" },
147
+ { id: "dicts.extra", suite: "reading", label: "dicionários extra", writes: false, dependsOn: [] },
148
+ { id: "patient.list", suite: "reading", label: "patient.list", writes: false, dependsOn: [], capability: "patient.list" },
149
+ { id: "patient.get", suite: "reading", label: "patient.get", writes: false, dependsOn: [], capability: "patient.get" },
150
+ { id: "appointment.list", suite: "reading", label: "appointment.list", writes: false, dependsOn: [], capability: "appointment.list" },
151
+
152
+ // ── S2 — ciclo de vida ──────────────────────────────────────────────────────
153
+ { id: "appointment.create", suite: "appointment", label: "create", writes: true, dependsOn: [], capability: "appointment.create" },
154
+ { id: "appointment.get", suite: "appointment", label: "get", writes: false, dependsOn: ["appointment.create"], capability: "appointment.get" },
155
+ { id: "appointment.update", suite: "appointment", label: "update", writes: true, dependsOn: ["appointment.create"], capability: "appointment.update" },
156
+ { id: "appointment.confirm", suite: "appointment", label: "confirm", writes: true, dependsOn: ["appointment.create"], capability: "appointment.confirm" },
157
+ { id: "appointment.revert_confirm", suite: "appointment", label: "revert_confirm", writes: true, dependsOn: ["appointment.confirm"], capability: "appointment.revert_confirm" },
158
+ { id: "appointment.cancel", suite: "appointment", label: "cancel", writes: true, dependsOn: ["appointment.create"], capability: "appointment.cancel" },
159
+
160
+ // ── S3 — sync ───────────────────────────────────────────────────────────────
161
+ { id: "sync.force", suite: "sync", label: "sync (1 dia)", writes: true, dependsOn: ["appointment.cancel"] },
162
+
163
+ // ── S4 — paciente ───────────────────────────────────────────────────────────
164
+ { id: "patient.create", suite: "patient", label: "patient.create", writes: true, dependsOn: [], capability: "patient.create" },
165
+ { id: "patient.roundtrip", suite: "patient", label: "round-trip (get+update)", writes: true, dependsOn: [], capability: "patient.update" },
166
+ { id: "patient.delete", suite: "patient", label: "patient.delete", writes: true, dependsOn: ["patient.create"], capability: "patient.delete" },
167
+
168
+ // ── Z — limpeza ─────────────────────────────────────────────────────────────
169
+ { id: "residue.sweep", suite: "cleanup", label: "varredura de resíduo", writes: true, dependsOn: [] },
170
+ ] as const;
171
+
172
+ /**
173
+ * Suíte padrão (D10) — a LINHA DE BASE COMPARÁVEL: todos os passos.
174
+ *
175
+ * Só uma corrida com exatamente esta seleção é comparável com a anterior. Sem isso
176
+ * o output principal da ferramenta ("nenhum defeito novo") seria infalsificável:
177
+ * bastaria desmarcar o passo que falha.
178
+ *
179
+ * Atenção: a seleção não basta. `comparable` também exige `target.create_patient`
180
+ * ligado — senão `patient.create`/`patient.delete` são pulados e a cobertura real
181
+ * fica menor que a nominal. Quem decide isso é o backend, em `computeComparable`.
182
+ */
183
+ export const STANDARD_SUITE_STEP_IDS: readonly TestStepId[] = TEST_STEPS.map(
184
+ (s) => s.id,
185
+ );
186
+
187
+ export const READ_ONLY_STEP_IDS: readonly TestStepId[] = TEST_STEPS.filter(
188
+ (s) => !s.writes,
189
+ ).map((s) => s.id);
190
+
191
+ // ======================================================
192
+ // Checks
193
+ // ======================================================
194
+
195
+ export type TestCheckStatus = "pass" | "fail" | "skipped";
196
+
197
+ export interface ITestCheck {
198
+ /**
199
+ * Id ESTÁVEL no formato `<step_id>:<slug>` — ex. `appointment.update:sem_divergencia`.
200
+ *
201
+ * É a chave que o catálogo de conhecidos referencia. O script antigo casava por
202
+ * REGEX no texto do label, o que quebrava nos dois sentidos: mudar a redação
203
+ * descatalogava um defeito em silêncio, e um regex largo engolia defeito novo de
204
+ * outra causa. Por isso o id vem antes do texto — o label pode ser reescrito à
205
+ * vontade.
206
+ */
207
+ id: string;
208
+ label: string;
209
+ status: TestCheckStatus;
210
+ detail?: string;
211
+ }
212
+
213
+ // ======================================================
214
+ // Passo executado
215
+ // ======================================================
216
+
217
+ export type TestStepStatus =
218
+ | "pending"
219
+ | "running"
220
+ | "pass"
221
+ | "known" // falhou, mas casa com defeito catalogado — não reprova a corrida
222
+ | "fail" // defeito NOVO
223
+ | "skipped"
224
+ | "error";
225
+
226
+ export interface ITestSchemaValidation {
227
+ ok: boolean;
228
+ errors?: Array<{ path: (string | number)[]; message: string; code?: string }>;
229
+ }
230
+
231
+ /**
232
+ * O wire — o que o BACKEND mandou para o n8n, lido de
233
+ * `integrations_sync_monitor GET /calls?run_id=`.
234
+ *
235
+ * É a camada que interessa a quem mantém os workflows: a resposta da action mostra
236
+ * o que a UI mandou, não o que saiu na linha. `DocumentReference` vivo no payload
237
+ * (a classe de bug que derrubou produção no revert_confirm) só aparece aqui.
238
+ */
239
+ export interface ITestStepWire {
240
+ request_json?: string;
241
+ response_json?: string;
242
+ n8n_execution_id?: string | null;
243
+ n8n_workflow_id?: string | null;
244
+ workflow_url?: string;
245
+ http_status?: number | null;
246
+ timed_out?: boolean | null;
247
+ error_message?: string | null;
248
+ request_truncated?: boolean | null;
249
+ response_truncated?: boolean | null;
250
+ }
251
+
252
+ export interface ITestRunStep extends IFireDoc {
253
+ step_id: TestStepId;
254
+ suite: TestSuiteId;
255
+ order: number;
256
+ status: TestStepStatus;
257
+ started_at?: unknown;
258
+ finished_at?: unknown;
259
+ duration_ms?: number;
260
+
261
+ /** Camada 1 — o que a UI mandou para `integrations_actions` e o que voltou. */
262
+ layer1?: { request?: unknown; response?: unknown };
263
+
264
+ /** Correlação com o wire: `transport_metadata.run_id` da resposta da action. */
265
+ n8n_run_id?: string | null;
266
+
267
+ /** Camada 2 — o que o BE mandou para o n8n. */
268
+ wire?: ITestStepWire | null;
269
+
270
+ schema_validation?: {
271
+ request?: ITestSchemaValidation;
272
+ response?: ITestSchemaValidation;
273
+ } | null;
274
+
275
+ checks: ITestCheck[];
276
+
277
+ /** Preenchido quando `status === 'known'`: qual defeito catalogado casou. */
278
+ known_defects?: Array<{ check_id: string; description: string; ref: string }>;
279
+
280
+ error?: string | null;
281
+ }
282
+
283
+ // ======================================================
284
+ // Corrida
285
+ // ======================================================
286
+
287
+ export type TestRunStatus = "running" | "finished" | "abandoned";
288
+
289
+ /** Dados do paciente novo, quando o usuário liga a criação (D3). */
290
+ export interface ITestNewPatient {
291
+ first_name: string;
292
+ last_name?: string;
293
+ mobile_phone?: string;
294
+ email?: string;
295
+ social_id?: string;
296
+ birth_date?: string;
297
+ }
298
+
299
+ export interface ITestRunTarget {
300
+ /** Paciente de teste JÁ EXISTENTE, usado na leitura e no agendamento. */
301
+ patient_id: string;
302
+ /** Só quando `create_patient` está ligado. */
303
+ new_patient?: ITestNewPatient | null;
304
+ create_patient: boolean;
305
+ /** `YYYY-MM-DD`. Recomendado no passado — é aviso, não trava (D2). */
306
+ slot_date: string;
307
+ /** `HH:MM`. */
308
+ slot_time: string;
309
+ /** Dia povoado para o `appointment.list`; sem isso usa `slot_date`. */
310
+ list_date?: string | null;
311
+ }
312
+
313
+ /**
314
+ * Diagnóstico de segurança — AVISO, não trava (D2).
315
+ *
316
+ * Os dois avisos têm gravidade diferente e a UI precisa refletir isso: data futura
317
+ * só ativa as varreduras D-2/D-0, que dependem de janela; gatilho de evento ligado
318
+ * dispara na hora do create.
319
+ */
320
+ export interface ITestRunPreflight {
321
+ slot_in_past: boolean;
322
+ /** Quais dos gatilhos de evento estão ligados na agenda-alvo. */
323
+ triggers_enabled: string[];
324
+ /**
325
+ * `notification_config.configs` vazio.
326
+ *
327
+ * Distinguir de "desligado" importa: nada dispara nos dois casos, mas aqui é por
328
+ * AUSÊNCIA DE CONFIGURAÇÃO, não por decisão de alguém.
329
+ */
330
+ notification_config_empty: boolean;
331
+ evaluated_at?: unknown;
332
+ }
333
+
334
+ /** O que a corrida criou no PMS — permite enumerar resíduo quando o `Z` é desmarcado (D11). */
335
+ export interface ITestRunInventory {
336
+ appointment_external_ids: string[];
337
+ patient_external_id?: string | null;
338
+ }
339
+
340
+ export interface ITestRunVerdict {
341
+ ok: number;
342
+ known: number;
343
+ new_defects: number;
344
+ }
345
+
346
+ export interface ITestRun extends IFireDoc {
347
+ adapter_id: string;
348
+ tenant: string;
349
+ calendar_id: string;
350
+
351
+ target: ITestRunTarget;
352
+
353
+ selection: {
354
+ preset: "standard" | "read-only" | "custom";
355
+ step_ids: TestStepId[];
356
+ };
357
+
358
+ /** Quantos passos da suíte padrão esta corrida cobriu. */
359
+ coverage: { ran: number; total: number };
360
+ /** `true` só quando a seleção é exatamente a suíte padrão (D10). */
361
+ comparable: boolean;
362
+
363
+ preflight: ITestRunPreflight;
364
+ inventory: ITestRunInventory;
365
+ verdict: ITestRunVerdict;
366
+
367
+ status: TestRunStatus;
368
+
369
+ /**
370
+ * Dono da corrida. Quem orquestra é o FE, então duas abas conduzindo a mesma
371
+ * corrida escreveriam na mesma agenda de produção em paralelo — outro usuário
372
+ * abre em modo leitura até assumir explicitamente.
373
+ */
374
+ created_by: string;
375
+ finished_at?: unknown;
376
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "evo360-types",
3
- "version": "1.3.505",
3
+ "version": "1.3.507",
4
4
  "description": "HREVO360 Shared Types",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",