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
@@ -1,6 +1,7 @@
1
1
  export * from "./fb_collections";
2
2
  import type { IFireDoc, IFireGlobalDoc } from "../shared";
3
3
  import type { ITenantModuleEntitlement } from "../evo-tenant";
4
+ import type { VirtualCareRecordingMode } from "../evo-med/calendar";
4
5
  export declare const EvoTelemedicinePermissions: {
5
6
  /** Ver estado e dados operacionais básicos. */
6
7
  readonly Read: "evo_telemedicine_read";
@@ -171,6 +172,18 @@ export declare const AccessGrantKindEnum: {
171
172
  readonly LaunchCode: "launch_code";
172
173
  /** Sessão do browser (cookie `__session`), 15 min, rotativa. */
173
174
  readonly BrowserSession: "browser_session";
175
+ /**
176
+ * feat-160 F7 — `kind` de uma ENTRADA A MAIS no `grant-index`, apontando
177
+ * para o MESMO grant `qr_capability`, para o link do calendário (ICS)
178
+ * resolver o caminho da teleconsulta (T56/P1).
179
+ *
180
+ * ⚠️ NENHUM grant tem este kind: `ITeleconsultationAccessGrant.kind` nunca
181
+ * vale `ics_capability`. O poder de entrar continua amarrado ao
182
+ * `secret_hash` do grant, que é o HMAC do `cap` e não do `ics_cap`. Está no
183
+ * mesmo enum porque é o `kind` do índice e o índice é endereçado pelo mesmo
184
+ * espaço de nomes — não para virar um grant.
185
+ */
186
+ readonly IcsCapability: "ics_capability";
174
187
  };
175
188
  export type AccessGrantKind = (typeof AccessGrantKindEnum)[keyof typeof AccessGrantKindEnum];
176
189
  export declare const AccessGrantStateEnum: {
@@ -218,6 +231,12 @@ export declare const TeleconsultationEventTypeEnum: {
218
231
  /** Alteração tardia na agenda com consulta já iniciada — tratamento operacional, não apaga o encontro. */
219
232
  readonly TeleconsultationDiverged: "teleconsultation.diverged";
220
233
  readonly AccessCreated: "access.created";
234
+ /**
235
+ * feat-160 F13/D31 — alguém REVELOU/copiou o link do paciente no painel. Um
236
+ * evento por revelação (é o ato do usuário que fica registrado, não a
237
+ * abertura da tela). Distinto de `access.created`, que é a emissão do grant.
238
+ */
239
+ readonly AccessLinkRevealed: "access.link_revealed";
221
240
  readonly AccessRevoked: "access.revoked";
222
241
  readonly AccessExchanged: "access.exchanged";
223
242
  readonly AccessVerificationFailed: "access.verification_failed";
@@ -241,8 +260,22 @@ export declare const TeleconsultationEventTypeEnum: {
241
260
  readonly RecordingConsentRequested: "recording.consent_requested";
242
261
  readonly RecordingConsentAccepted: "recording.consent_accepted";
243
262
  readonly RecordingConsentDeclined: "recording.consent_declined";
263
+ /**
264
+ * feat-160 F15 — o paciente RECUSOU a gravação automática ANTES de entrar.
265
+ * Não é `recording.consent_declined`: aquela é a recusa de uma solicitação
266
+ * feita em sala (a consulta segue sem gravar); esta IMPEDE a entrada, porque
267
+ * em `auto_*` o aceite é condição do join (D21).
268
+ */
269
+ readonly RecordingConsentDeclinedPreJoin: "recording.consent_declined_pre_join";
244
270
  readonly RecordingConsentWithdrawn: "recording.consent_withdrawn";
245
271
  readonly RecordingStarted: "recording.started";
272
+ /**
273
+ * feat-160 F15 — gravação iniciada pela POLÍTICA da agenda (`auto_audio`/
274
+ * `auto_video`), não por comando do médico. Trilha própria porque
275
+ * `recording.started` sem um `recording.consent_requested` antes pareceria
276
+ * gravação sem solicitação na auditoria.
277
+ */
278
+ readonly RecordingAutoStarted: "recording.auto_started";
246
279
  readonly RecordingStopped: "recording.stopped";
247
280
  readonly RecordingFailed: "recording.failed";
248
281
  readonly TranscriptionQueued: "transcription.queued";
@@ -252,6 +285,15 @@ export declare const TeleconsultationEventTypeEnum: {
252
285
  readonly ConsultationStarted: "consultation.started";
253
286
  readonly ConsultationReconnecting: "consultation.reconnecting";
254
287
  readonly ConsultationEnded: "consultation.ended";
288
+ /**
289
+ * feat-160 F18 — consulta encerrada e MEDIDA como "não contada" (paciente
290
+ * não atendeu, sem gravação elegível, franquia). Existe porque
291
+ * `usage_metered_at` é carimbado nos DOIS casos: sem este evento a
292
+ * reconciliação "quantas `ended` carimbadas × quantas linhas no BigQuery"
293
+ * acusaria diferença em toda consulta não contada, indistinguível de evento
294
+ * perdido.
295
+ */
296
+ readonly UsageSkipped: "teleconsultation.usage_skipped";
255
297
  readonly ArtifactAccessed: "artifact.accessed";
256
298
  readonly ArtifactDeleted: "artifact.deleted";
257
299
  readonly EntitlementDenied: "entitlement.denied";
@@ -325,7 +367,33 @@ export interface ITeleconsultation extends IFireDoc {
325
367
  provider_meeting_id?: string;
326
368
  active_provider_session_id?: string;
327
369
  recording_status: RecordingStatus;
370
+ /**
371
+ * Gravação — campos de OPERAÇÃO escritos por F8 e lidos pelo `GET /session`
372
+ * (feat-160). Nenhum id do provedor entra aqui: o id da gravação no
373
+ * provedor vive em `private/provider.active_provider_recording_id` (T52).
374
+ */
375
+ recording_request_id?: string;
376
+ /** Versão do texto legal `recording` referenciada na solicitação (D21). */
377
+ recording_terms_version?: string;
378
+ recording_requested_at?: Date | null;
379
+ /** `userId` do médico que solicitou. */
380
+ recording_requested_by?: string;
381
+ recording_started_at?: Date | null;
382
+ recording_stopped_at?: Date | null;
383
+ /** Código estável, sem PII, quando `recording_status === 'failed'`. */
384
+ recording_failure_code?: string | null;
385
+ /** Segmento corrente (1..n) — mais de uma sessão física = vários segmentos. */
386
+ recording_segment?: number;
328
387
  transcription_status: TranscriptionStatus;
388
+ /**
389
+ * feat-160 F10 — desmonte do meeting no provedor ainda pendente; o sweep lê e
390
+ * limpa. Escrito FORA do comando transacional de propósito: não é estado
391
+ * clínico e um `version + 1` por housekeeping faria o `expected_version` que
392
+ * o painel acabou de ler virar 409.
393
+ */
394
+ provider_teardown_pending?: boolean;
395
+ /** feat-160 F10 — até quando o metadado sensível sobrevive à retenção. */
396
+ metadata_retention_until?: Date | null;
329
397
  entitlement_snapshot: ITeleconsultationEntitlementSnapshot;
330
398
  /**
331
399
  * Geração no `appointment-index`: incrementa quando o appointment volta a ser
@@ -337,11 +405,63 @@ export interface ITeleconsultation extends IFireDoc {
337
405
  /** Última versão/data do appointment aplicada — descarta evento de reconciliação antigo. */
338
406
  last_reconciled_appointment_version?: number | string | null;
339
407
  last_reconciled_at?: Date | null;
408
+ /**
409
+ * feat-160 F18 — quando a passada de bilhetagem do sweep pode contar esta
410
+ * consulta. Carimbado por `endForAll` (`ended_at + 15 min`): o `ready` das
411
+ * gravações só chega pelo webhook DEPOIS do fim, então contar no `end`
412
+ * classificaria toda consulta gravada como "sem gravação".
413
+ */
414
+ usage_metering_due_at?: Date | null;
415
+ /**
416
+ * Quando o evento de uso foi emitido. Presente = já contada; é o que torna a
417
+ * bilhetagem idempotente no doc (a dedup em BigQuery, por `target.entityId`,
418
+ * é a segunda camada) e a trilha para reconciliar contra o BigQuery — o
419
+ * publish é best-effort e pode se perder.
420
+ */
421
+ usage_metered_at?: Date | null;
340
422
  /** Concorrência otimista: todo comando de estado é transação + `version`. */
341
423
  version: number;
342
424
  created_at: Date;
343
425
  updated_at: Date;
344
426
  }
427
+ /**
428
+ * `.../teleconsultations/{teleconsultationId}/private/provider` (data-model §7;
429
+ * threat model P1/T52).
430
+ *
431
+ * Tudo o que identifica o encontro NO PROVEDOR mora aqui, e só aqui: o subdoc
432
+ * `private/**` é negado a todo mundo nas rules, inclusive super admin, enquanto
433
+ * `teleconsultations/{id}` e `participants/{id}` são legíveis pelo FE com
434
+ * `evo_telemedicine_read`. Um id de provedor na mão do browser é exatamente o
435
+ * que T52 proíbe — e `runTeleconsultationCommand` LANÇA se um patch do doc
436
+ * principal carregar `provider_meeting_id`/`active_provider_session_id`, para
437
+ * que o invariante não dependa de alguém lembrar em cada PR.
438
+ */
439
+ export interface ITeleconsultationPrivateProvider {
440
+ readonly id: string;
441
+ tenant: string;
442
+ teleconsultation_id: string;
443
+ provider: TeleconsultationProvider;
444
+ /** Id do meeting no provider — nunca sai deste doc para o FE nem para o SPA. */
445
+ provider_meeting_id?: string;
446
+ active_provider_session_id?: string;
447
+ /** Sessões físicas já vistas (mais de uma = segmentos do mesmo encontro). */
448
+ provider_session_ids?: string[];
449
+ /** Id do participante no provider, por id LÓGICO (`doctor`/`patient`). */
450
+ provider_participant_ids?: Record<string, string>;
451
+ /**
452
+ * Gravação ativa no provedor. O artefato guarda o mesmo valor em
453
+ * `provider_artifact_id` (é por ele que o webhook casa), mas o `stop` precisa
454
+ * do id sem depender de qual segmento é o corrente.
455
+ */
456
+ active_provider_recording_id?: string | null;
457
+ created_at?: Date | null;
458
+ updated_at?: Date | null;
459
+ }
460
+ /**
461
+ * Campos que o doc PRINCIPAL da teleconsulta jamais carrega — a asserção do
462
+ * `runTeleconsultationCommand` e do teste de sanidade itera esta lista.
463
+ */
464
+ export declare const TELECONSULTATION_PROVIDER_ONLY_FIELDS: readonly ["provider_meeting_id", "active_provider_session_id"];
345
465
  /** `.../participants/{participantId}` (data-model §2). Id lógico estável; reconexão reutiliza o mesmo participante. */
346
466
  export interface ITeleconsultationParticipant extends IFireDoc {
347
467
  teleconsultation_id: string;
@@ -404,6 +524,11 @@ export interface ITeleconsultationArtifact extends IFireDoc {
404
524
  ended_at?: Date | null;
405
525
  /** Retenção: o sweep deleta o objeto e só então marca `deleted` (auditoria preservada). */
406
526
  expires_at?: Date | null;
527
+ /**
528
+ * feat-160 F10 — quando o CONTEÚDO foi apagado. O doc sobrevive (status
529
+ * `deleted`) porque a auditoria da deleção é preservada (D13).
530
+ */
531
+ deleted_at?: Date | null;
407
532
  error_code?: string;
408
533
  created_at: Date;
409
534
  updated_at: Date;
@@ -491,6 +616,21 @@ export interface ITelemedicineAppointmentIndex extends IFireDoc {
491
616
  active_teleconsultation_id: string | null;
492
617
  generation: number;
493
618
  last_reconciled_appointment_version?: number | string | null;
619
+ /**
620
+ * feat-160 F3 — instante do write do appointment já aplicado. A marca d'água
621
+ * mora AQUI, e não só na teleconsulta, porque o índice sobrevive ao que ela
622
+ * precisa cobrir: um `denied` não cria doc nenhum e um terminal deixa de ser
623
+ * a teleconsulta ativa. Sem isto, um evento antigo redelivered depois de um
624
+ * `denied` seria reavaliado como novo.
625
+ */
626
+ last_reconciled_at?: Date | null;
627
+ /**
628
+ * Última teleconsulta deste appointment, ativa ou não. Gravada quando o
629
+ * índice é liberado (terminal) para o painel continuar mostrando a
630
+ * teleconsulta expirada/encerrada em vez de "não tem teleconsulta". NÃO é
631
+ * fonte de verdade de ativo — isso é `active_teleconsultation_id`.
632
+ */
633
+ last_teleconsultation_id?: string | null;
494
634
  updated_at: Date;
495
635
  }
496
636
  /**
@@ -539,6 +679,12 @@ export interface ITelemedicineGrantIndex extends IFireGlobalDoc {
539
679
  tenant: string;
540
680
  teleconsultation_id: string;
541
681
  grant_id: string;
682
+ /**
683
+ * Qual segredo esta entrada resolve. Ausente = a capability do `/qr`
684
+ * (comportamento original); `ics_capability` = o segredo derivado do link do
685
+ * calendário, que aponta para o MESMO grant `qr_capability` (F7).
686
+ */
687
+ kind?: AccessGrantKind;
542
688
  /** TTL nativo. */
543
689
  expires_at: Date;
544
690
  }
@@ -696,6 +842,73 @@ export interface IRoomConsentRefDto {
696
842
  subject: ConsentSubject;
697
843
  terms_version: string;
698
844
  }
845
+ /**
846
+ * Projeção SANITIZADA do estado de gravação no `GET /session` (feat-160 F8).
847
+ * Nunca traz id do provider, path do objeto no GCS nem URL assinada — só o que
848
+ * a UI dos dois papéis precisa.
849
+ */
850
+ export interface IRoomRecordingStateDto {
851
+ /** Mesma origem do `recording_status` do DTO da sessão. */
852
+ status: RecordingStatus;
853
+ /** Início do segmento ativo — única origem do cronômetro; `null` fora de gravação. */
854
+ started_at: string | null;
855
+ /** Idempotência do comando e vínculo do consentimento (T19). */
856
+ recording_request_id?: string;
857
+ /** Versão do texto legal `recording` referenciada na solicitação (D21). */
858
+ terms_version?: string;
859
+ /** Código estável, sem PII, quando `status === 'failed'`. */
860
+ failure_code?: string;
861
+ /** feat-160 F15 — presente só nos modos `auto_*` (aviso pré-join). */
862
+ auto?: IRoomRecordingAutoDto;
863
+ }
864
+ /**
865
+ * feat-160 F15 — aviso PRÉ-JOIN da gravação automática (`auto_audio`/
866
+ * `auto_video`). Presente só nesses modos: é o que o SPA usa para explicar o
867
+ * que vai ser gravado e por quanto tempo ANTES do aceite.
868
+ */
869
+ export interface IRoomRecordingAutoDto {
870
+ /** `auto_audio` ou `auto_video`; os outros modos não têm este bloco. */
871
+ mode: VirtualCareRecordingMode;
872
+ /**
873
+ * `true` em `auto_audio`. Hoje é INTENÇÃO declarada: o `POST /recordings` do
874
+ * provedor não expõe flag de áudio-only, então o arquivo sai A/V. O SPA usa o
875
+ * campo para o texto do aviso; quando o provedor ganhar a flag, só o adapter
876
+ * muda.
877
+ */
878
+ audio_only: boolean;
879
+ /** Retenção que o texto mostrado ao paciente promete (`{{retention}}`, D32). */
880
+ retention_days: number;
881
+ /**
882
+ * Versão vigente do texto `recording` que o `POST /consents` tem de
883
+ * referenciar. `null` = não há texto publicado ⇒ sem aceite possível (D21) e
884
+ * a gravação automática NÃO acontece.
885
+ */
886
+ terms_version: string | null;
887
+ }
888
+ /**
889
+ * feat-160 F16 — política EFETIVA da agenda nesta sessão (`virtual_care` já
890
+ * com os defaults aplicados). É projeção de decisão, não de config gravada:
891
+ * agenda sem o bloco devolve os defaults.
892
+ */
893
+ export interface IRoomSessionPolicyDto {
894
+ recording_mode: VirtualCareRecordingMode;
895
+ auto_admit: boolean;
896
+ identity: {
897
+ require_name: boolean;
898
+ require_birth_date: boolean;
899
+ skip: boolean;
900
+ };
901
+ /**
902
+ * Prazo duro da consulta. `end_at`/`warning_at` são `null` quando não há
903
+ * prazo (consulta não iniciada com `allow_late_end`), e `reason` diz qual
904
+ * limite venceu — o MESMO `reason` com que o sweep encerra.
905
+ */
906
+ deadline: {
907
+ end_at: string | null;
908
+ warning_at: string | null;
909
+ reason: "scheduled_end" | "max_duration" | null;
910
+ };
911
+ }
699
912
  /**
700
913
  * `GET /api/room/v1/session` — estado SANITIZADO: sem tenant id, sem ids do
701
914
  * provider; nome do profissional/clínica só depois da verificação.
@@ -712,13 +925,62 @@ export interface IRoomSessionDto {
712
925
  identity_level: IdentityLevel;
713
926
  /** Paciente precisa passar por `POST /identity/verify` antes do join. */
714
927
  identity_required: boolean;
928
+ /**
929
+ * Quais campos o formulário de identidade deve pedir (spec §8.3): a data de
930
+ * nascimento só é pedida quando EXISTE no cadastro. Para o médico vem sempre
931
+ * `{ birth_date: false }`.
932
+ */
933
+ identity_required_fields: {
934
+ birth_date: boolean;
935
+ /**
936
+ * feat-160 F16 — `virtual_care.identity.require_name`: a agenda pode exigir
937
+ * o nome também. OPCIONAL no contrato porque SPA anterior à F16 não o
938
+ * conhece e deve seguir pedindo só a data (comportamento de antes).
939
+ */
940
+ name?: boolean;
941
+ };
942
+ /**
943
+ * Contador do lockout, lido do GRANT raiz — e a ÚNICA fonte dele: o erro do
944
+ * `POST /identity/verify` é neutro e não devolve tentativas nem prazo. Por
945
+ * isso a UI relê a sessão depois de cada falha.
946
+ */
947
+ identity_attempts: {
948
+ remaining: number;
949
+ blocked_until: string | null;
950
+ };
715
951
  recording_status: RecordingStatus;
952
+ recording: IRoomRecordingStateDto;
953
+ /**
954
+ * feat-160 F16 — o que a AGENDA decidiu (`calendar.virtual_care` resolvido
955
+ * com os defaults). OPCIONAL: aditivo, SPA que não o conheça mantém o
956
+ * comportamento pré-F16.
957
+ */
958
+ policy?: IRoomSessionPolicyDto;
716
959
  transcription_status: TranscriptionStatus;
717
960
  /** Textos vigentes que ainda precisam de aceite antes do join. */
718
961
  required_consents: IRoomConsentRefDto[];
719
962
  accepted_consents: IRoomConsentRefDto[];
720
963
  /** Capabilities efetivas para esta sessão (entitlement AND rollout AND papel). */
721
964
  capabilities: Record<string, boolean>;
965
+ /** Presença do médico; `null` quando não há participante. Atalho de `participants`. */
966
+ doctor_presence: ParticipantState | null;
967
+ /** Presença do paciente. Atalho de `participants`. */
968
+ patient_presence: ParticipantState | null;
969
+ /** Os dois papéis, com `state`/`disconnected_at`/`reconnect_count`. */
970
+ participants: ITeleconsultationParticipantDto[];
971
+ /**
972
+ * Pacientes em `state === 'waiting'`, e a ponte OBRIGATÓRIA do `POST /admit`:
973
+ * o `participant_id` de domínio é o literal `'patient'`, enquanto o
974
+ * `custom_participant_id` devolvido no `POST /join` é hash opaco que nunca
975
+ * casaria com ele.
976
+ */
977
+ waiting_participants: ITeleconsultationParticipantDto[];
978
+ /**
979
+ * Máscara "Maria A. d. S." do titular do agendamento. SÓ na sessão do
980
+ * MÉDICO — o backend nunca a manda ao paciente (T01), e é por isso que é o
981
+ * único destes campos legitimamente opcional.
982
+ */
983
+ patient_display_masked?: string;
722
984
  professional_display_name?: string;
723
985
  clinic_display_name?: string;
724
986
  /** Expiração do access da sessão (15 min, rotativo via `/session/refresh`). */
@@ -760,11 +1022,93 @@ export interface ITeleconsultationArtifactDto {
760
1022
  error_code?: string;
761
1023
  created_at: string;
762
1024
  }
1025
+ /**
1026
+ * Modo da URL assinada de um artefato (feat-160 F21; D34).
1027
+ *
1028
+ * `attachment` é o default histórico (F8): o navegador BAIXA o arquivo.
1029
+ * `inline` existe para o `<video>` do painel fazer streaming por `Range` sem
1030
+ * baixar — e a única diferença técnica é NÃO emitir `Content-Disposition`.
1031
+ */
1032
+ export declare const ArtifactDispositionEnum: {
1033
+ readonly Inline: "inline";
1034
+ readonly Attachment: "attachment";
1035
+ };
1036
+ export type ArtifactDisposition = (typeof ArtifactDispositionEnum)[keyof typeof ArtifactDispositionEnum];
1037
+ /**
1038
+ * Teto de validade da URL `inline` (feat-160 F21): 15 min. Playback casa com a
1039
+ * duração de uma consulta; download curto casa com o clique. É TETO, não
1040
+ * default — o use case aplica, e o adapter recusa acima dele.
1041
+ */
1042
+ export declare const ARTIFACT_INLINE_SIGNED_URL_MAX_SECONDS = 900;
763
1043
  /** `POST /v1/teleconsultations/:id/artifacts/:artifactId/signed-url` — URL ≤ 5 min; evento `artifact.accessed`. */
764
1044
  export interface ISignedUrlResponseDto {
765
1045
  ok: true;
766
1046
  url: string;
767
1047
  expires_at: string;
1048
+ /** Modo efetivamente aplicado (`attachment` quando o comando omite). */
1049
+ disposition?: ArtifactDisposition;
1050
+ }
1051
+ export type TranscriptSpeakerRole = "doctor" | "patient" | "unknown";
1052
+ export interface ITranscriptSpeakerDto {
1053
+ /** `opaque_custom_participant_id` que amarra a fala ao papel. */
1054
+ key: string;
1055
+ display_name: string;
1056
+ role: TranscriptSpeakerRole;
1057
+ }
1058
+ export interface ITranscriptEntryDto {
1059
+ index: number;
1060
+ speaker_key: string;
1061
+ start_ms: number;
1062
+ end_ms: number;
1063
+ text: string;
1064
+ overlapping?: boolean;
1065
+ }
1066
+ /** Corpo da transcrição de UM artefato (`segment`). */
1067
+ export interface ITranscriptDto {
1068
+ artifact_id: string;
1069
+ segment: number;
1070
+ language?: string;
1071
+ generated_at?: string;
1072
+ speakers: ITranscriptSpeakerDto[];
1073
+ entries: ITranscriptEntryDto[];
1074
+ }
1075
+ /**
1076
+ * `GET /v1/teleconsultations/:id/artifacts/:artifactId/transcript` — envelope
1077
+ * da rota: `{ ok: true, ...ITranscriptDto }` (o DTO é espalhado, não aninhado).
1078
+ */
1079
+ export interface ITranscriptResponseDto extends ITranscriptDto {
1080
+ ok: true;
1081
+ }
1082
+ /**
1083
+ * Um agendamento que TEM teleconsulta, e o que ela produziu. Id ausente do mapa
1084
+ * = "nunca virou teleconsulta" — é essa diferença que impede a tela de
1085
+ * desenhar três ícones apagados em toda linha comum.
1086
+ */
1087
+ export interface ITeleconsultationBadgeDto {
1088
+ teleconsultation_id: string;
1089
+ status: TeleconsultationStatus;
1090
+ recording_audio: boolean;
1091
+ recording_video: boolean;
1092
+ transcript: boolean;
1093
+ }
1094
+ /** `GET /v1/appointments/teleconsultation-badges?ids=a,b,c` (máx. 50 ids). */
1095
+ export interface ITeleconsultationBadgesResponseDto {
1096
+ ok: true;
1097
+ /** Keyed por `appointment_id`. */
1098
+ items: Record<string, ITeleconsultationBadgeDto>;
1099
+ }
1100
+ /** Teto de ids por chamada; acima disso a rota responde 400. */
1101
+ export declare const TELECONSULTATION_BADGES_MAX_IDS = 50;
1102
+ /**
1103
+ * Corpo do `POST …/artifacts/:artifactId/signed-url` (feat-160 F21). O zod
1104
+ * espelho é `zArtifactSignedUrlCommandSchema`.
1105
+ */
1106
+ export interface IArtifactSignedUrlCommand {
1107
+ disposition?: ArtifactDisposition;
1108
+ /** 30..900; o teto REAL depende do modo e é aplicado pelo backend. */
1109
+ ttl_seconds?: number;
1110
+ /** Renova a URL de um artefato já acessado (evento `artifact.accessed`). */
1111
+ refresh?: boolean;
768
1112
  }
769
1113
  export interface ITeleconsultationEventDto {
770
1114
  id: string;
@@ -792,6 +1136,13 @@ export interface ITelemedicineLegalTextDto {
792
1136
  content_html: string;
793
1137
  content_hash: string;
794
1138
  effective_at?: string | null;
1139
+ /**
1140
+ * VALORES dos placeholders já resolvidos e filtrados pela allowlist do
1141
+ * próprio doc (`ITelemedicineLegalText.placeholders`, que guarda os NOMES
1142
+ * permitidos). ux-flows §3 exige "usada para {finalidade} e ficará
1143
+ * disponível por {prazo}", e D21 proíbe hardcode disso no bundle.
1144
+ */
1145
+ placeholders?: Record<string, string>;
795
1146
  }
796
1147
  /** `GET /api/room/v1/legal-texts`. */
797
1148
  export interface ILegalTextsResponseDto {
@@ -803,17 +1154,61 @@ export interface IIdentityVerifyResponseDto {
803
1154
  ok: true;
804
1155
  identity_level: IdentityLevel;
805
1156
  }
806
- /** `POST /v1/teleconsultations/:id/access/send`. */
1157
+ /**
1158
+ * `POST /api/room/v1/exchange` e `POST /api/room/v1/session/refresh`.
1159
+ *
1160
+ * O corpo NÃO repete o `sid` (está no cookie `__session`, `HttpOnly`,
1161
+ * `Path=/api`) nem o tenant; traz o papel, que é o que permite ao SPA escolher
1162
+ * a tela sem um `GET /session` extra.
1163
+ */
1164
+ export interface IExchangeResponseDto {
1165
+ ok: true;
1166
+ role: ParticipantRole;
1167
+ session_expires_at: string;
1168
+ }
1169
+ /** `POST /api/room/v1/participant-token/refresh` — token novo, MESMO participante lógico. */
1170
+ export interface IParticipantTokenRefreshDto {
1171
+ ok: true;
1172
+ provider_token: string;
1173
+ /** Nome do preset no provider (`hm_doctor`, `hm_patient_waiting`, ...). */
1174
+ preset: string;
1175
+ token_expires_at?: string;
1176
+ }
1177
+ /**
1178
+ * `POST /v1/teleconsultations/:id/access/send` (feat-160 F7).
1179
+ *
1180
+ * É RECIBO DE TASK, não confirmação de envio: a rota publica a mesma task fina
1181
+ * que a rotina publicaria (`telemedicine_join_reminder`) e responde antes de
1182
+ * existir grant — o executor é quem resolve template, canal e elegibilidade e
1183
+ * emite a capability, uma por perna do fan-out. Por isso NÃO há `grant_id` nem
1184
+ * `expires_at` aqui: forjá-los era mentir para a recepção sobre um acesso que
1185
+ * ainda não existia.
1186
+ */
807
1187
  export interface IAccessSendResponseDto {
808
1188
  ok: true;
809
- grant_id: string;
1189
+ task_id: string;
1190
+ /** `true` quando a chave de idempotência colapsou num envio já pedido. */
1191
+ reused: boolean;
810
1192
  channel_kind: AccessSendChannelKind;
1193
+ /** Eco do pedido: revogar a capability anterior antes de emitir a nova. */
1194
+ resend: boolean;
1195
+ /** Destinatário mascarado do canal pedido; ausente em `manual`. */
811
1196
  recipient_masked?: string;
1197
+ }
1198
+ /**
1199
+ * `POST /v1/teleconsultations/:id/access/link` (feat-160 F13; D31).
1200
+ *
1201
+ * **A `url` é CREDENCIAL** (capability de 128 bits do `/qr`), não um
1202
+ * identificador: não tem lugar em store, log, analytics nem storage do
1203
+ * navegador (T01/T04). Nasce nesta resposta, vai para a área de transferência e
1204
+ * morre com o diálogo. Cada revelação é uma chamada nova, de propósito — o que
1205
+ * fica registrado em `access.link_revealed` é o ato do usuário.
1206
+ */
1207
+ export interface IAccessLinkResultDto {
1208
+ ok: true;
1209
+ url: string;
1210
+ grant_id: string;
812
1211
  expires_at: string;
813
- /** Só para `channel_kind = manual` (smoke): URL mascarada, nunca a capability inteira. */
814
- url_masked?: string;
815
- /** Id da task `telemedicine_join.send` criada, quando houver canal. */
816
- task_id?: string;
817
1212
  }
818
1213
  export interface IWaitingPolicyCommand {
819
1214
  waiting_policy: WaitingPolicy;
@@ -853,6 +1248,26 @@ export interface IConsentCommand {
853
1248
  terms_version: string;
854
1249
  decision: Extract<ConsentDecision, "accepted" | "declined">;
855
1250
  }
1251
+ /**
1252
+ * `POST /api/room/v1/join` — intenção de mídia do preflight ("Entrar somente
1253
+ * com áudio"). Os dois campos são opcionais porque o backend só os REGISTRA
1254
+ * (escolha de preset e `audio_only_allowed`) e ignora o que não vier.
1255
+ */
1256
+ export interface IJoinCommand {
1257
+ audio?: boolean;
1258
+ video?: boolean;
1259
+ }
1260
+ /**
1261
+ * `POST /api/room/v1/leave` — saída TEMPORÁRIA (D10); nunca encerra a consulta.
1262
+ *
1263
+ * `reason` é string aberta e o backend só distingue UM valor: `'temporary'` é
1264
+ * saída explícita (`left`), qualquer outro é tratado como queda de rede
1265
+ * (`disconnected`). Ausente = `'temporary'`. Chega pelo `pagehide` com
1266
+ * `fetch(keepalive)`, então pode vir sem `Content-Type`.
1267
+ */
1268
+ export interface ILeaveCommand {
1269
+ reason?: string;
1270
+ }
856
1271
  /** `POST /api/room/v1/presence`. */
857
1272
  export interface IPresenceCommand {
858
1273
  state: PresenceState;
@@ -14,7 +14,7 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
14
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
15
  };
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
- exports.TelemedicineErrorCode = exports.EntitlementAuditActionEnum = exports.TranscriptionProviderEnum = exports.LegalTextStatusEnum = exports.WebhookEventStatusEnum = exports.TeleconsultationEventTypeEnum = exports.TeleconsultationEventSourceEnum = exports.TeleconsultationEventActorTypeEnum = exports.EndedByTypeEnum = exports.AccessSendChannelKindEnum = exports.AccessGrantStateEnum = exports.AccessGrantKindEnum = exports.ArtifactStatusEnum = exports.ArtifactTypeEnum = exports.ConsentActorTypeEnum = exports.ConsentDecisionEnum = exports.ConsentSubjectEnum = exports.TranscriptionStatusEnum = exports.RecordingStatusEnum = exports.IdentityLevelEnum = exports.PresenceStateEnum = exports.ParticipantStateEnum = exports.ParticipantRoleEnum = exports.TeleconsultationProviderEnum = exports.TeleconsultationModeEnum = exports.WaitingPolicyEnum = exports.TELECONSULTATION_TERMINAL_STATUSES = exports.TeleconsultationStatusEnum = exports.TELEMEDICINE_WINDOW_DEFAULTS = exports.TELEMEDICINE_JOIN_REMINDER_HANDLER = exports.TELEMEDICINE_JOIN_ACTION_TYPE = exports.EvoTelemedicinePermissions = void 0;
17
+ exports.TELECONSULTATION_BADGES_MAX_IDS = exports.ARTIFACT_INLINE_SIGNED_URL_MAX_SECONDS = exports.ArtifactDispositionEnum = exports.TelemedicineErrorCode = exports.EntitlementAuditActionEnum = exports.TELECONSULTATION_PROVIDER_ONLY_FIELDS = exports.TranscriptionProviderEnum = exports.LegalTextStatusEnum = exports.WebhookEventStatusEnum = exports.TeleconsultationEventTypeEnum = exports.TeleconsultationEventSourceEnum = exports.TeleconsultationEventActorTypeEnum = exports.EndedByTypeEnum = exports.AccessSendChannelKindEnum = exports.AccessGrantStateEnum = exports.AccessGrantKindEnum = exports.ArtifactStatusEnum = exports.ArtifactTypeEnum = exports.ConsentActorTypeEnum = exports.ConsentDecisionEnum = exports.ConsentSubjectEnum = exports.TranscriptionStatusEnum = exports.RecordingStatusEnum = exports.IdentityLevelEnum = exports.PresenceStateEnum = exports.ParticipantStateEnum = exports.ParticipantRoleEnum = exports.TeleconsultationProviderEnum = exports.TeleconsultationModeEnum = exports.WaitingPolicyEnum = exports.TELECONSULTATION_TERMINAL_STATUSES = exports.TeleconsultationStatusEnum = exports.TELEMEDICINE_WINDOW_DEFAULTS = exports.TELEMEDICINE_JOIN_REMINDER_HANDLER = exports.TELEMEDICINE_JOIN_ACTION_TYPE = exports.EvoTelemedicinePermissions = void 0;
18
18
  __exportStar(require("./fb_collections"), exports);
19
19
  // ======================================================
20
20
  // evo-telemedicine (feat-160 — Telemedicina integrada)
@@ -195,6 +195,18 @@ exports.AccessGrantKindEnum = {
195
195
  LaunchCode: "launch_code",
196
196
  /** Sessão do browser (cookie `__session`), 15 min, rotativa. */
197
197
  BrowserSession: "browser_session",
198
+ /**
199
+ * feat-160 F7 — `kind` de uma ENTRADA A MAIS no `grant-index`, apontando
200
+ * para o MESMO grant `qr_capability`, para o link do calendário (ICS)
201
+ * resolver o caminho da teleconsulta (T56/P1).
202
+ *
203
+ * ⚠️ NENHUM grant tem este kind: `ITeleconsultationAccessGrant.kind` nunca
204
+ * vale `ics_capability`. O poder de entrar continua amarrado ao
205
+ * `secret_hash` do grant, que é o HMAC do `cap` e não do `ics_cap`. Está no
206
+ * mesmo enum porque é o `kind` do índice e o índice é endereçado pelo mesmo
207
+ * espaço de nomes — não para virar um grant.
208
+ */
209
+ IcsCapability: "ics_capability",
198
210
  };
199
211
  exports.AccessGrantStateEnum = {
200
212
  Active: "active",
@@ -236,6 +248,12 @@ exports.TeleconsultationEventTypeEnum = {
236
248
  /** Alteração tardia na agenda com consulta já iniciada — tratamento operacional, não apaga o encontro. */
237
249
  TeleconsultationDiverged: "teleconsultation.diverged",
238
250
  AccessCreated: "access.created",
251
+ /**
252
+ * feat-160 F13/D31 — alguém REVELOU/copiou o link do paciente no painel. Um
253
+ * evento por revelação (é o ato do usuário que fica registrado, não a
254
+ * abertura da tela). Distinto de `access.created`, que é a emissão do grant.
255
+ */
256
+ AccessLinkRevealed: "access.link_revealed",
239
257
  AccessRevoked: "access.revoked",
240
258
  AccessExchanged: "access.exchanged",
241
259
  AccessVerificationFailed: "access.verification_failed",
@@ -259,8 +277,22 @@ exports.TeleconsultationEventTypeEnum = {
259
277
  RecordingConsentRequested: "recording.consent_requested",
260
278
  RecordingConsentAccepted: "recording.consent_accepted",
261
279
  RecordingConsentDeclined: "recording.consent_declined",
280
+ /**
281
+ * feat-160 F15 — o paciente RECUSOU a gravação automática ANTES de entrar.
282
+ * Não é `recording.consent_declined`: aquela é a recusa de uma solicitação
283
+ * feita em sala (a consulta segue sem gravar); esta IMPEDE a entrada, porque
284
+ * em `auto_*` o aceite é condição do join (D21).
285
+ */
286
+ RecordingConsentDeclinedPreJoin: "recording.consent_declined_pre_join",
262
287
  RecordingConsentWithdrawn: "recording.consent_withdrawn",
263
288
  RecordingStarted: "recording.started",
289
+ /**
290
+ * feat-160 F15 — gravação iniciada pela POLÍTICA da agenda (`auto_audio`/
291
+ * `auto_video`), não por comando do médico. Trilha própria porque
292
+ * `recording.started` sem um `recording.consent_requested` antes pareceria
293
+ * gravação sem solicitação na auditoria.
294
+ */
295
+ RecordingAutoStarted: "recording.auto_started",
264
296
  RecordingStopped: "recording.stopped",
265
297
  RecordingFailed: "recording.failed",
266
298
  TranscriptionQueued: "transcription.queued",
@@ -270,6 +302,15 @@ exports.TeleconsultationEventTypeEnum = {
270
302
  ConsultationStarted: "consultation.started",
271
303
  ConsultationReconnecting: "consultation.reconnecting",
272
304
  ConsultationEnded: "consultation.ended",
305
+ /**
306
+ * feat-160 F18 — consulta encerrada e MEDIDA como "não contada" (paciente
307
+ * não atendeu, sem gravação elegível, franquia). Existe porque
308
+ * `usage_metered_at` é carimbado nos DOIS casos: sem este evento a
309
+ * reconciliação "quantas `ended` carimbadas × quantas linhas no BigQuery"
310
+ * acusaria diferença em toda consulta não contada, indistinguível de evento
311
+ * perdido.
312
+ */
313
+ UsageSkipped: "teleconsultation.usage_skipped",
273
314
  ArtifactAccessed: "artifact.accessed",
274
315
  ArtifactDeleted: "artifact.deleted",
275
316
  EntitlementDenied: "entitlement.denied",
@@ -294,6 +335,14 @@ exports.TranscriptionProviderEnum = {
294
335
  None: "none",
295
336
  RealtimeKit: "realtimekit",
296
337
  };
338
+ /**
339
+ * Campos que o doc PRINCIPAL da teleconsulta jamais carrega — a asserção do
340
+ * `runTeleconsultationCommand` e do teste de sanidade itera esta lista.
341
+ */
342
+ exports.TELECONSULTATION_PROVIDER_ONLY_FIELDS = [
343
+ "provider_meeting_id",
344
+ "active_provider_session_id",
345
+ ];
297
346
  // ======================================================
298
347
  // Auditoria de entitlement (`.../entitlement-audit/{id}`, data-model §8)
299
348
  // ======================================================
@@ -359,3 +408,22 @@ exports.TelemedicineErrorCode = {
359
408
  /** 400 — body/params inválidos. */
360
409
  ValidationError: "VALIDATION_ERROR",
361
410
  };
411
+ /**
412
+ * Modo da URL assinada de um artefato (feat-160 F21; D34).
413
+ *
414
+ * `attachment` é o default histórico (F8): o navegador BAIXA o arquivo.
415
+ * `inline` existe para o `<video>` do painel fazer streaming por `Range` sem
416
+ * baixar — e a única diferença técnica é NÃO emitir `Content-Disposition`.
417
+ */
418
+ exports.ArtifactDispositionEnum = {
419
+ Inline: "inline",
420
+ Attachment: "attachment",
421
+ };
422
+ /**
423
+ * Teto de validade da URL `inline` (feat-160 F21): 15 min. Playback casa com a
424
+ * duração de uma consulta; download curto casa com o clique. É TETO, não
425
+ * default — o use case aplica, e o adapter recusa acima dele.
426
+ */
427
+ exports.ARTIFACT_INLINE_SIGNED_URL_MAX_SECONDS = 900;
428
+ /** Teto de ids por chamada; acima disso a rota responde 400. */
429
+ exports.TELECONSULTATION_BADGES_MAX_IDS = 50;