evo360-types 1.3.574 → 1.3.581

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 (47) hide show
  1. package/dist/apps/evo-chat/channel/zod-schemas.d.ts +273 -0
  2. package/dist/apps/evo-chat/channel/zod-schemas.js +17 -1
  3. package/dist/apps/evo-chat/channel/zod-schemas.ts +19 -0
  4. package/dist/apps/evo-chat/thread-message/zod-schemas.d.ts +24 -0
  5. package/dist/apps/evo-chat/thread-message/zod-schemas.js +2 -0
  6. package/dist/apps/evo-chat/thread-message/zod-schemas.ts +2 -0
  7. package/dist/apps/evo-chat/waba-template/zod-schemas.d.ts +6 -0
  8. package/dist/apps/evo-chat/waba-template/zod-schemas.js +2 -0
  9. package/dist/apps/evo-chat/waba-template/zod-schemas.ts +2 -0
  10. package/dist/apps/evo-crm/lead/zod-schemas.d.ts +9 -0
  11. package/dist/apps/evo-med/calendar/zod-schemas.d.ts +4215 -1256
  12. package/dist/apps/evo-med/calendar/zod-schemas.js +61 -1
  13. package/dist/apps/evo-med/calendar/zod-schemas.ts +64 -0
  14. package/dist/apps/evo-med/insurance/zod-schemas.d.ts +9 -0
  15. package/dist/apps/evo-med/people/zod-schemas.d.ts +18 -0
  16. package/dist/apps/evo-notifications/zod-schemas.d.ts +110 -0
  17. package/dist/apps/evo-notifications/zod-schemas.js +8 -1
  18. package/dist/apps/evo-notifications/zod-schemas.ts +9 -0
  19. package/dist/apps/evo-telemedicine/zod-schemas.d.ts +161 -13
  20. package/dist/apps/evo-telemedicine/zod-schemas.js +93 -2
  21. package/dist/apps/evo-telemedicine/zod-schemas.ts +96 -0
  22. package/dist/apps/shared/zod-schemas.d.ts +3 -0
  23. package/dist/apps/shared/zod-schemas.js +2 -0
  24. package/dist/apps/shared/zod-schemas.ts +2 -0
  25. package/dist/types/evo-chat/channel/index.d.ts +19 -0
  26. package/dist/types/evo-chat/channel/index.ts +24 -0
  27. package/dist/types/evo-chat/thread-message/index.d.ts +4 -0
  28. package/dist/types/evo-chat/thread-message/index.ts +4 -0
  29. package/dist/types/evo-chat/waba-template/index.d.ts +6 -0
  30. package/dist/types/evo-chat/waba-template/index.js +3 -1
  31. package/dist/types/evo-chat/waba-template/index.ts +7 -0
  32. package/dist/types/evo-finops/common/contract.d.ts +8 -0
  33. package/dist/types/evo-finops/common/contract.js +7 -0
  34. package/dist/types/evo-finops/common/contract.ts +7 -0
  35. package/dist/types/evo-med/calendar/index.d.ts +124 -1
  36. package/dist/types/evo-med/calendar/index.js +60 -1
  37. package/dist/types/evo-med/calendar/index.ts +167 -1
  38. package/dist/types/evo-notifications/index.d.ts +11 -0
  39. package/dist/types/evo-notifications/index.ts +13 -0
  40. package/dist/types/evo-reports/index.d.ts +27 -0
  41. package/dist/types/evo-reports/index.ts +28 -0
  42. package/dist/types/evo-telemedicine/index.d.ts +421 -6
  43. package/dist/types/evo-telemedicine/index.js +69 -1
  44. package/dist/types/evo-telemedicine/index.ts +454 -6
  45. package/dist/types/shared/index.d.ts +1 -0
  46. package/dist/types/shared/index.ts +2 -0
  47. package/package.json +1 -1
@@ -61,6 +61,30 @@ export interface IMedCalendarNotificationConfig {
61
61
  * `email` legados (que os consumidores atuais ainda leem).
62
62
  */
63
63
  configs?: { [configKey: string]: IMedCalendarNotificationEntry } | null;
64
+
65
+ /**
66
+ * feat-160 (§10.2) — MESMA forma de `configs`, mas só para agendamento com
67
+ * `appointmentMode === 'telemedicine'`.
68
+ *
69
+ * **Semântica de HERANÇA, resolvida em UM lugar** (`@evo/model`
70
+ * `calendar-notification-config.ts` → `resolveNotificationConfigEntry(config,
71
+ * configKey, mode)`); nenhum leitor decide sozinho:
72
+ *
73
+ * - modo `telemedicine` e a chave EXISTE aqui ⇒ vale esta entrada, inclusive
74
+ * com `enabled: false` (é exatamente assim que a clínica desliga um aviso
75
+ * SÓ na telemedicina sem mexer no presencial);
76
+ * - modo `telemedicine` e a chave NÃO existe aqui ⇒ HERDA `configs[configKey]`;
77
+ * - modo presencial (ou ausente) ⇒ `configs[configKey]`, este bloco é ignorado.
78
+ *
79
+ * Chave ausente ≠ chave com `enabled:false`: a primeira herda, a segunda
80
+ * desliga. É a única distinção que o editor do FE precisa expressar ("herdar
81
+ * do presencial" = remover a chave).
82
+ *
83
+ * Ausência do bloco inteiro = comportamento pré-feat-160 (toda agenda hoje).
84
+ */
85
+ telemedicine_configs?:
86
+ | { [configKey: string]: IMedCalendarNotificationEntry }
87
+ | null;
64
88
  }
65
89
 
66
90
  /** Uma config de notificação (feat-092): um evento/momento × seus canais. */
@@ -90,8 +114,10 @@ export interface IMedCalendarNotificationChannelEntry {
90
114
  department_id?: string | null;
91
115
  /** Template principal da mensagem (HSM name no WA / template_id lógico no email). */
92
116
  template_id?: string | null;
93
- /** Tipo do template principal: 'hsm' | 'email' | … O leitor pode inferir pelo canal. */
117
+ /** Tipo do template principal: 'hsm' | 'quick_reply' | 'direct_send' | 'email' | … O leitor pode inferir pelo canal. */
94
118
  template_type?: string | null;
119
+ /** feat-165 — texto (com tokens) enviado quando `template_type === 'direct_send'`. */
120
+ direct_send_text?: string | null;
95
121
  /** Botões/ações da mensagem → artefato de resposta de cada um. */
96
122
  ctas?: IMedCalendarNotificationCta[] | null;
97
123
  }
@@ -152,6 +178,135 @@ export const MedCalendarNotificationConfigKeys = {
152
178
  export type MedCalendarNotificationConfigKey =
153
179
  (typeof MedCalendarNotificationConfigKeys)[keyof typeof MedCalendarNotificationConfigKeys];
154
180
 
181
+ // ----- Virtual Care (inline no calendar doc) — feat-160 F16
182
+ // Config por-agenda do módulo de telemedicina ("Hub Médica Virtual Care"), lida
183
+ // pelo backend no `join`/`admit`/sweep e editada na seção própria do Calendar V2
184
+ // (visível só com o entitlement `modules.telemedicine`).
185
+ //
186
+ // Bloco e campos são TODOS opcionais: agenda sem o bloco (a maioria) vale
187
+ // exatamente `CALENDAR_VIRTUAL_CARE_DEFAULTS`, sem migração de dado (plan §12).
188
+ // Por isso existem DOIS tipos: `IMedCalendarVirtualCareConfig` é o que está
189
+ // gravado (parcial), e `IMedCalendarVirtualCareSettings` é o resultado de
190
+ // aplicar os defaults sobre ele — o que o backend efetivamente decide com.
191
+ //
192
+ // `| null` em todo campo, como no `notification_config`: o editor do FE grava
193
+ // "não escolhido" como `null` explícito e `.passthrough()` não cobre null em
194
+ // chave declarada — sem `.nullable()` o doc inteiro do calendário reprovaria.
195
+
196
+ /** `recording.mode` da agenda (feat-160 F15). `off` esconde "Solicitar gravação". */
197
+ export const VirtualCareRecordingModeEnum = {
198
+ /** Gravação indisponível nesta agenda. */
199
+ Off: "off",
200
+ /** Médico solicita em sala e o paciente aceita ali (comportamento do MVP). */
201
+ Manual: "manual",
202
+ /** Inicia sozinha, só áudio; o aceite é colhido ANTES de o paciente entrar. */
203
+ AutoAudio: "auto_audio",
204
+ /** Idem, com vídeo. */
205
+ AutoVideo: "auto_video",
206
+ } as const;
207
+
208
+ export type VirtualCareRecordingMode =
209
+ (typeof VirtualCareRecordingModeEnum)[keyof typeof VirtualCareRecordingModeEnum];
210
+
211
+ /** Limites de `recording.retention_days` (D32; D13 mantém 7 como default). */
212
+ export const VIRTUAL_CARE_RETENTION_DAYS_MIN = 7;
213
+ export const VIRTUAL_CARE_RETENTION_DAYS_MAX = 730;
214
+
215
+ /** Limites de `max_duration_minutes`. */
216
+ export const VIRTUAL_CARE_MAX_DURATION_MINUTES_MIN = 15;
217
+ export const VIRTUAL_CARE_MAX_DURATION_MINUTES_MAX = 480;
218
+
219
+ /** O que está GRAVADO no doc da agenda — tudo parcial (ausente = default). */
220
+ export interface IMedCalendarVirtualCareConfig {
221
+ /**
222
+ * Admite o paciente sozinho quando o médico já está em sala
223
+ * (`waiting_policy` default `auto_when_doctor_present`). Exige a capability
224
+ * `auto_admit` do entitlement e NUNCA vale sem identidade verificada (D9).
225
+ */
226
+ auto_admit?: boolean | null;
227
+ recording?: {
228
+ mode?: VirtualCareRecordingMode | null;
229
+ /** Transcrição da gravação. Gate D12 + capability `transcription`. */
230
+ transcription?: boolean | null;
231
+ /**
232
+ * Retenção de gravação/transcrição em dias, 7..730 (D32). O sweep é a
233
+ * verdade (`artifact.expires_at` = fim + N dias); o lifecycle do bucket é
234
+ * só defesa de último caso. O prazo escolhido entra no texto de gravação
235
+ * mostrado ao paciente (`{{retention}}`).
236
+ */
237
+ retention_days?: number | null;
238
+ } | null;
239
+ identity?: {
240
+ require_name?: boolean | null;
241
+ /** Só é exigível quando o cadastro TEM data de nascimento (spec §8.3). */
242
+ require_birth_date?: boolean | null;
243
+ /** `true` ⇒ `identity_level: 'weak'`; nunca habilita auto-admit (D9). */
244
+ skip?: boolean | null;
245
+ } | null;
246
+ /** Antecedência de acesso à sala, por papel, em minutos. */
247
+ allow_early_start_minutes?: {
248
+ doctor?: number | null;
249
+ patient?: number | null;
250
+ } | null;
251
+ /** `true` = passar do fim previsto não encerra a consulta (comportamento atual). */
252
+ allow_late_end?: boolean | null;
253
+ /** Teto absoluto; o sweep encerra ao exceder (`reason: max_duration`). 15..480. */
254
+ max_duration_minutes?: number | null;
255
+ /** Aviso ao médico no SPA quando faltar N min para o fim. 0 = sem aviso. */
256
+ end_warning_minutes?: number | null;
257
+ }
258
+
259
+ /** Config já RESOLVIDA (doc + defaults) — é com isto que o backend decide. */
260
+ export interface IMedCalendarVirtualCareSettings {
261
+ auto_admit: boolean;
262
+ recording: {
263
+ mode: VirtualCareRecordingMode;
264
+ transcription: boolean;
265
+ retention_days: number;
266
+ };
267
+ identity: {
268
+ require_name: boolean;
269
+ require_birth_date: boolean;
270
+ skip: boolean;
271
+ };
272
+ allow_early_start_minutes: {
273
+ doctor: number;
274
+ patient: number;
275
+ };
276
+ allow_late_end: boolean;
277
+ max_duration_minutes: number;
278
+ end_warning_minutes: number;
279
+ }
280
+
281
+ /**
282
+ * Defaults da spec (plan §12 / D13 / D32). Agenda sem `virtual_care` vale
283
+ * exatamente isto — é o que faz "sem migração de dado" ser verdade.
284
+ *
285
+ * Congelado (`as const` + `Readonly`) de propósito: é referência compartilhada,
286
+ * e um consumidor que mutasse um nível aninhado mudaria o default de todos.
287
+ * Para resolver, faça merge por nível (`{ ...DEFAULTS.recording, ...cfg.recording }`).
288
+ */
289
+ export const CALENDAR_VIRTUAL_CARE_DEFAULTS: IMedCalendarVirtualCareSettings = {
290
+ auto_admit: false,
291
+ recording: {
292
+ mode: VirtualCareRecordingModeEnum.Manual,
293
+ transcription: false,
294
+ retention_days: VIRTUAL_CARE_RETENTION_DAYS_MIN,
295
+ },
296
+ identity: {
297
+ require_name: true,
298
+ require_birth_date: true,
299
+ skip: false,
300
+ },
301
+ allow_early_start_minutes: {
302
+ doctor: 30,
303
+ patient: 15,
304
+ },
305
+ allow_late_end: true,
306
+ max_duration_minutes: 120,
307
+ end_warning_minutes: 5,
308
+ } as const;
309
+
155
310
  // ----- MedCalendarTypes
156
311
  export interface IMedCalendar extends IFireDoc {
157
312
  calendarId: string;
@@ -187,5 +342,16 @@ export interface IMedCalendar extends IFireDoc {
187
342
  integration?: IMedCalendarIntegration | null;
188
343
  // Config de notificações por-agenda (feat-048). Opcional — agendas sem lembrete não têm o bloco.
189
344
  notification_config?: IMedCalendarNotificationConfig | null;
345
+ /**
346
+ * Config de telemedicina por-agenda (feat-160 F16). Ausente = defaults de
347
+ * `CALENDAR_VIRTUAL_CARE_DEFAULTS`; só tem efeito com `modules.telemedicine`.
348
+ */
349
+ virtual_care?: IMedCalendarVirtualCareConfig | null;
350
+ /**
351
+ * Profissional (médico) padrão da agenda — feat-160 F16, fora do módulo de
352
+ * telemedicina (pedido do usuário, mesmo editor). Ref para
353
+ * `tenants/{t}/apps/evo-med/professionals/{id}`; `null` = sem padrão.
354
+ */
355
+ default_professional_ref?: FirestoreDocumentReference | null;
190
356
  [key: string]: unknown; // index signature
191
357
  }
@@ -113,6 +113,11 @@ export interface IQuickReplyActionIntent {
113
113
  url_secret?: string;
114
114
  [key: string]: unknown;
115
115
  }
116
+ /** feat-165 — Meta Direct Send. `ttl_seconds`: 30..43200 (utility). */
117
+ export interface INotificationDirectSend {
118
+ category: 'utility';
119
+ ttl_seconds?: number;
120
+ }
116
121
  export interface INotificationSendPayload {
117
122
  kind: "notification.send";
118
123
  classification?: string;
@@ -126,6 +131,12 @@ export interface INotificationSendPayload {
126
131
  * Mutuamente exclusivo com `template.template_id` para `channel.type === 'whatsapp'`.
127
132
  */
128
133
  body_text?: string;
134
+ /**
135
+ * feat-165 — intencao de envio via Meta Direct Send (utilidade, sem template).
136
+ * So e honrada se o canal tiver `direct_send.enabled` e nao estiver restrito;
137
+ * caso contrario o envio segue o comportamento atual.
138
+ */
139
+ direct_send?: INotificationDirectSend;
129
140
  /**
130
141
  * Quick-reply actions (actionable WhatsApp buttons / email links).
131
142
  * Channel-agnostic intents; the provider renders them per channel.
@@ -196,6 +196,12 @@ export interface IQuickReplyActionIntent {
196
196
  // Payload schema for Task Runner (task.auto.kind = "notification.send")
197
197
  // ======================================================
198
198
 
199
+ /** feat-165 — Meta Direct Send. `ttl_seconds`: 30..43200 (utility). */
200
+ export interface INotificationDirectSend {
201
+ category: 'utility';
202
+ ttl_seconds?: number;
203
+ }
204
+
199
205
  export interface INotificationSendPayload {
200
206
  kind: "notification.send";
201
207
 
@@ -217,6 +223,13 @@ export interface INotificationSendPayload {
217
223
  */
218
224
  body_text?: string;
219
225
 
226
+ /**
227
+ * feat-165 — intencao de envio via Meta Direct Send (utilidade, sem template).
228
+ * So e honrada se o canal tiver `direct_send.enabled` e nao estiver restrito;
229
+ * caso contrario o envio segue o comportamento atual.
230
+ */
231
+ direct_send?: INotificationDirectSend;
232
+
220
233
  /**
221
234
  * Quick-reply actions (actionable WhatsApp buttons / email links).
222
235
  * Channel-agnostic intents; the provider renders them per channel.
@@ -21,6 +21,17 @@ export interface IUsageCapabilities {
21
21
  * antes dessa data: ausência de medição não é consumo zero.
22
22
  */
23
23
  llm_since: string | null;
24
+ /**
25
+ * feat-160 F18 — entitlement `modules.telemedicine` ativo OU uso de
26
+ * teleconsulta medido na janela.
27
+ */
28
+ telemedicine: boolean;
29
+ /**
30
+ * Data (`YYYY-MM-DD`) a partir da qual existe medição de teleconsulta — o
31
+ * emissor não tem backfill. `null` antes do deploy dele; a série não é
32
+ * desenhada antes dessa data, porque ausência de medição não é consumo zero.
33
+ */
34
+ telemedicine_since: string | null;
24
35
  }
25
36
  /**
26
37
  * Uma linha da abertura por departamento dentro de um mês.
@@ -84,6 +95,21 @@ export interface IUsageLlm {
84
95
  tokens_cache_write: number;
85
96
  tokens_cache_read: number;
86
97
  }
98
+ /**
99
+ * Teleconsultas REALIZADAS no mês (feat-160 F18 / D33). Realizada = a consulta
100
+ * começou (`started_at`) E o paciente esteve conectado (`connected_at`): médico
101
+ * entrando em sala vazia não conta.
102
+ *
103
+ * Os dois campos são DISJUNTOS — uma consulta cai em exatamente um. O total é a
104
+ * soma; não há campo de total, para não haver duas verdades.
105
+ *
106
+ * `com_gravacao` = teve ao menos um artifact `recording_*` em `ready`. Bloco
107
+ * inteiro `null` = capability desligada (não é consumo zero).
108
+ */
109
+ export interface IUsageTelemedicine {
110
+ realizadas_sem_gravacao: number;
111
+ realizadas_com_gravacao: number;
112
+ }
87
113
  export interface IMonthlyUsageRow {
88
114
  /** Primeiro dia do mês em UTC, `YYYY-MM-DD`. */
89
115
  mes: string;
@@ -92,6 +118,7 @@ export interface IMonthlyUsageRow {
92
118
  contatos: IUsageContacts;
93
119
  notificacoes: IUsageNotifications;
94
120
  ia: IUsageLlm | null;
121
+ telemedicina: IUsageTelemedicine | null;
95
122
  }
96
123
  export interface IMonthlyUsageResponse {
97
124
  ok: true;
@@ -37,6 +37,17 @@ export interface IUsageCapabilities {
37
37
  * antes dessa data: ausência de medição não é consumo zero.
38
38
  */
39
39
  llm_since: string | null;
40
+ /**
41
+ * feat-160 F18 — entitlement `modules.telemedicine` ativo OU uso de
42
+ * teleconsulta medido na janela.
43
+ */
44
+ telemedicine: boolean;
45
+ /**
46
+ * Data (`YYYY-MM-DD`) a partir da qual existe medição de teleconsulta — o
47
+ * emissor não tem backfill. `null` antes do deploy dele; a série não é
48
+ * desenhada antes dessa data, porque ausência de medição não é consumo zero.
49
+ */
50
+ telemedicine_since: string | null;
40
51
  }
41
52
 
42
53
  /**
@@ -105,6 +116,22 @@ export interface IUsageLlm {
105
116
  tokens_cache_read: number;
106
117
  }
107
118
 
119
+ /**
120
+ * Teleconsultas REALIZADAS no mês (feat-160 F18 / D33). Realizada = a consulta
121
+ * começou (`started_at`) E o paciente esteve conectado (`connected_at`): médico
122
+ * entrando em sala vazia não conta.
123
+ *
124
+ * Os dois campos são DISJUNTOS — uma consulta cai em exatamente um. O total é a
125
+ * soma; não há campo de total, para não haver duas verdades.
126
+ *
127
+ * `com_gravacao` = teve ao menos um artifact `recording_*` em `ready`. Bloco
128
+ * inteiro `null` = capability desligada (não é consumo zero).
129
+ */
130
+ export interface IUsageTelemedicine {
131
+ realizadas_sem_gravacao: number;
132
+ realizadas_com_gravacao: number;
133
+ }
134
+
108
135
  export interface IMonthlyUsageRow {
109
136
  /** Primeiro dia do mês em UTC, `YYYY-MM-DD`. */
110
137
  mes: string;
@@ -113,6 +140,7 @@ export interface IMonthlyUsageRow {
113
140
  contatos: IUsageContacts;
114
141
  notificacoes: IUsageNotifications;
115
142
  ia: IUsageLlm | null;
143
+ telemedicina: IUsageTelemedicine | null;
116
144
  }
117
145
 
118
146
  export interface IMonthlyUsageResponse {