@everfur/sdk 0.5.1 → 0.5.3

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 (130) hide show
  1. package/CHANGELOG.md +351 -0
  2. package/dist/BookedScreen-BJPbXLCG.d.ts +54 -0
  3. package/dist/BookedScreen-Cnld-jB_.d.cts +54 -0
  4. package/dist/{Chat-Rzplrf5M.d.ts → Chat-CNRZEu92.d.ts} +3 -3
  5. package/dist/{Chat-ypo6miKm.d.cts → Chat-a6If51cF.d.cts} +3 -3
  6. package/dist/{DepthViews-CeTfPUBX.d.ts → DepthViews-Bfv2DTUl.d.ts} +1 -1
  7. package/dist/{DepthViews-Cui3oonj.d.cts → DepthViews-Cl4AoL3X.d.cts} +1 -1
  8. package/dist/{DepthViews-ClykXOJj.d.cts → DepthViews-kURiusNd.d.cts} +1 -1
  9. package/dist/{DepthViews-baYLMNQ-.d.ts → DepthViews-zhn3Rk5Z.d.ts} +1 -1
  10. package/dist/animations/index.d.cts +3 -3
  11. package/dist/animations/index.d.ts +3 -3
  12. package/dist/{attachments-D3HCBmOE.d.ts → attachments-5_p7kE38.d.ts} +2 -2
  13. package/dist/{attachments-CwsR-bPN.d.cts → attachments-CHgc11hT.d.cts} +5 -5
  14. package/dist/{attachments-CzZ7in24.d.ts → attachments-TXOhN36S.d.ts} +5 -5
  15. package/dist/{attachments-Nk73Lll8.d.cts → attachments-affGN_Uv.d.cts} +2 -2
  16. package/dist/{bookingCopy-SDkXaxDf.d.ts → bookingCopy-BQ7Pg7qg.d.ts} +38 -200
  17. package/dist/{bookingCopy-Dv8rKqyV.d.cts → bookingCopy-BpZvZO1S.d.cts} +38 -200
  18. package/dist/bookingTypes-DCs8mmBb.d.cts +188 -0
  19. package/dist/bookingTypes-DCs8mmBb.d.ts +188 -0
  20. package/dist/{callCopy-rDH9JTFo.d.cts → callCopy-CPe9mbwG.d.cts} +7 -2
  21. package/dist/{callCopy-rDH9JTFo.d.ts → callCopy-CPe9mbwG.d.ts} +7 -2
  22. package/dist/{casesRepository-BTAecTnF.d.ts → casesRepository-YCI0OVwl.d.ts} +1 -1
  23. package/dist/{casesRepository-aryld7fJ.d.cts → casesRepository-z2JAFlKA.d.cts} +1 -1
  24. package/dist/chat/index.cjs +1 -1
  25. package/dist/chat/index.d.cts +14 -10
  26. package/dist/chat/index.d.ts +14 -10
  27. package/dist/chat/index.js +1 -1
  28. package/dist/client/index.cjs +1 -1
  29. package/dist/client/index.d.cts +6 -6
  30. package/dist/client/index.d.ts +6 -6
  31. package/dist/client/index.js +1 -1
  32. package/dist/{config-X6BtwDwQ.d.ts → config-BXVgTLCh.d.ts} +1 -1
  33. package/dist/{config-6qS7Sohy.d.cts → config-Bkbqkjb0.d.cts} +1 -1
  34. package/dist/consent/index.d.cts +5 -5
  35. package/dist/consent/index.d.ts +5 -5
  36. package/dist/{context-7f3Nb_xE.d.ts → context-BVpOBDMe.d.ts} +5 -5
  37. package/dist/{context-CkqPM4Ml.d.cts → context-ChPrlKhy.d.cts} +5 -5
  38. package/dist/{copy-Bd__Pw5s.d.cts → copy-Be2H2i-D.d.cts} +2 -2
  39. package/dist/{copy-NgKgOOET.d.ts → copy-SxmZ-Eps.d.ts} +2 -2
  40. package/dist/core/index.cjs +5 -5
  41. package/dist/core/index.d.cts +12 -12
  42. package/dist/core/index.d.ts +12 -12
  43. package/dist/core/index.js +5 -5
  44. package/dist/{depth-CYPH92jE.d.ts → depth-By8dFpLA.d.ts} +2 -2
  45. package/dist/{depth-CyjaJJ6V.d.cts → depth-Dne8Qoss.d.cts} +2 -2
  46. package/dist/{entitlementRepository-DdeFuEKp.d.ts → entitlementRepository-Big-K_In.d.ts} +2 -2
  47. package/dist/{entitlementRepository-Dl1qRLcJ.d.cts → entitlementRepository-BmghvtGT.d.cts} +2 -2
  48. package/dist/{identity-Dy_L7Yq4.d.ts → identity-AuoeDRTh.d.ts} +1 -1
  49. package/dist/{identity-DjqhDm5Z.d.cts → identity-Z0yj-fC_.d.cts} +1 -1
  50. package/dist/index.cjs +6 -6
  51. package/dist/index.d.cts +13 -13
  52. package/dist/index.d.ts +13 -13
  53. package/dist/index.js +6 -6
  54. package/dist/notifications/index.d.cts +2 -2
  55. package/dist/notifications/index.d.ts +2 -2
  56. package/dist/{pets-BSG2qbr_.d.cts → pets-DfXGYmMk.d.cts} +1 -1
  57. package/dist/{pets-D7cZutrX.d.ts → pets-FD-5nMXr.d.ts} +1 -1
  58. package/dist/{petsRepository-DhsX3GLw.d.ts → petsRepository-BaTOwJ5L.d.ts} +1 -1
  59. package/dist/{petsRepository-D1bnxDZg.d.cts → petsRepository-CsvreWlY.d.cts} +1 -1
  60. package/dist/{ports-C0m1G1fS.d.ts → ports-DNIvfzBP.d.ts} +16 -5
  61. package/dist/{ports-DNXyyzZF.d.cts → ports-Dof7AQjk.d.cts} +16 -5
  62. package/dist/records/depth/index.d.cts +7 -7
  63. package/dist/records/depth/index.d.ts +7 -7
  64. package/dist/records/index.cjs +3 -3
  65. package/dist/records/index.d.cts +10 -10
  66. package/dist/records/index.d.ts +10 -10
  67. package/dist/records/index.js +3 -3
  68. package/dist/{requestFunnel-FvE5yLDD.d.ts → requestFunnel-CJC_q4BZ.d.ts} +2 -2
  69. package/dist/{requestFunnel-Bqc1inM9.d.cts → requestFunnel-DrigK6q_.d.cts} +2 -2
  70. package/dist/{runtimeTypes-C0yPBz89.d.ts → runtimeTypes-BiqMY6pC.d.ts} +4 -4
  71. package/dist/{runtimeTypes-RN-VXTFV.d.cts → runtimeTypes-Doj95Gll.d.cts} +4 -4
  72. package/dist/server/events/index.cjs +1 -1
  73. package/dist/server/events/index.d.cts +2 -2
  74. package/dist/server/events/index.d.ts +2 -2
  75. package/dist/server/events/index.js +1 -1
  76. package/dist/server/index.cjs +2 -2
  77. package/dist/server/index.d.cts +3 -3
  78. package/dist/server/index.d.ts +3 -3
  79. package/dist/server/index.js +2 -2
  80. package/dist/televet/booking/index.cjs +1 -1
  81. package/dist/televet/booking/index.d.cts +17 -9
  82. package/dist/televet/booking/index.d.ts +17 -9
  83. package/dist/televet/booking/index.js +1 -1
  84. package/dist/televet/call/index.cjs +1 -1
  85. package/dist/televet/call/index.d.cts +13 -1
  86. package/dist/televet/call/index.d.ts +13 -1
  87. package/dist/televet/call/index.js +1 -1
  88. package/dist/televet/index.cjs +1 -1
  89. package/dist/televet/index.js +1 -1
  90. package/dist/testing/index.d.cts +1 -1
  91. package/dist/testing/index.d.ts +1 -1
  92. package/dist/testing/rn/index.d.cts +7 -7
  93. package/dist/testing/rn/index.d.ts +7 -7
  94. package/dist/testing/web/index.d.cts +7 -7
  95. package/dist/testing/web/index.d.ts +7 -7
  96. package/dist/{timelineRows-D4U6A8zE.d.ts → timelineRows-BHA0gIKH.d.ts} +1 -1
  97. package/dist/{timelineRows-DAB5dpjF.d.cts → timelineRows-CHeqZRpM.d.cts} +1 -1
  98. package/dist/{uploadTransport-DKJHs3Yj.d.cts → uploadTransport-C1p8FuG8.d.cts} +5 -1
  99. package/dist/{uploadTransport-D0M0T4hN.d.ts → uploadTransport-bZIKBTyK.d.ts} +5 -1
  100. package/dist/{useRecordsDepth--ObtMyjH.d.ts → useRecordsDepth-CG63cXFZ.d.ts} +1 -1
  101. package/dist/{useRecordsDepth-B35y8bV-.d.cts → useRecordsDepth-ChhS4c6r.d.cts} +1 -1
  102. package/dist/{view-B-Toym_j.d.cts → view-2pXv8ex7.d.cts} +7 -4
  103. package/dist/{view-D9JqNQai.d.ts → view-BKy44Q-3.d.ts} +7 -4
  104. package/dist/web/consent/index.d.cts +5 -5
  105. package/dist/web/consent/index.d.ts +5 -5
  106. package/dist/web/index.cjs +10 -10
  107. package/dist/web/index.d.cts +14 -14
  108. package/dist/web/index.d.ts +14 -14
  109. package/dist/web/index.js +10 -10
  110. package/dist/web/notifications/index.d.cts +3 -3
  111. package/dist/web/notifications/index.d.ts +3 -3
  112. package/dist/web/records/depth/index.d.cts +7 -7
  113. package/dist/web/records/depth/index.d.ts +7 -7
  114. package/dist/web/records/index.cjs +3 -3
  115. package/dist/web/records/index.d.cts +9 -9
  116. package/dist/web/records/index.d.ts +9 -9
  117. package/dist/web/records/index.js +3 -3
  118. package/dist/web/televet/booking/index.cjs +2 -2
  119. package/dist/web/televet/booking/index.d.cts +35 -50
  120. package/dist/web/televet/booking/index.d.ts +35 -50
  121. package/dist/web/televet/booking/index.js +2 -2
  122. package/dist/web/televet/call/index.cjs +1 -1
  123. package/dist/web/televet/call/index.d.cts +12 -5
  124. package/dist/web/televet/call/index.d.ts +12 -5
  125. package/dist/web/televet/call/index.js +1 -1
  126. package/dist/web/televet/index.cjs +4 -1
  127. package/dist/web/televet/index.d.cts +31 -2
  128. package/dist/web/televet/index.d.ts +31 -2
  129. package/dist/web/televet/index.js +4 -1
  130. package/package.json +4 -3
@@ -1,12 +1,12 @@
1
1
  import { E as EverfurError } from './EverfurError-DmELDpXp.js';
2
2
  import { E as EverfurResult } from './EverfurResult-SGvHKsCB.js';
3
3
  import { C as ConversationId, P as PetRef, b as ResponseId } from './ids-B2GAAifq.js';
4
- import { f as ChatFeedbackType, j as ChatStatus, i as ChatMessage, c as ChatConversationListOptions, d as ChatConversationPage, g as ChatHistoryOptions, h as ChatMessagePage, a as ChatCheckinTarget, e as ChatFeedbackReceipt } from './ports-C0m1G1fS.js';
5
- import { C as CheckinAnswer, a as CheckinOutcome } from './casesRepository-BTAecTnF.js';
6
- import { i as UrgencyLevel } from './config-X6BtwDwQ.js';
7
- import { W as WidgetPet } from './petsRepository-DhsX3GLw.js';
4
+ import { f as ChatFeedbackType, j as ChatStatus, i as ChatMessage, c as ChatConversationListOptions, d as ChatConversationPage, g as ChatHistoryOptions, h as ChatMessagePage, a as ChatCheckinTarget, e as ChatFeedbackReceipt } from './ports-DNIvfzBP.js';
5
+ import { C as CheckinAnswer, a as CheckinOutcome } from './casesRepository-YCI0OVwl.js';
6
+ import { i as UrgencyLevel } from './config-BXVgTLCh.js';
7
+ import { W as WidgetPet } from './petsRepository-BaTOwJ5L.js';
8
8
  import { U as UploadTransport, F as FileHandle } from './ports-BN6RHF9W.js';
9
- import { c as AttachmentQueue, d as AttachmentState, A as AttachmentError, b as AttachmentOutcome } from './attachments-D3HCBmOE.js';
9
+ import { c as AttachmentQueue, d as AttachmentState, A as AttachmentError, b as AttachmentOutcome } from './attachments-5_p7kE38.js';
10
10
 
11
11
  /** The three thumbs. `'neutral'` is the app's rotated thumbs-down glyph. */
12
12
  type ChatSentiment = 'up' | 'neutral' | 'down';
@@ -1,7 +1,7 @@
1
1
  import { E as EverfurError } from './EverfurError-DmELDpXp.cjs';
2
- import { R as RequestFunnel } from './requestFunnel-Bqc1inM9.cjs';
2
+ import { R as RequestFunnel } from './requestFunnel-DrigK6q_.cjs';
3
3
  import { F as FileHandle, U as UploadTransport, a as UploadPolicyWire } from './ports-BN6RHF9W.cjs';
4
- import { R as ReadableStore, T as Timers } from './ports-DNXyyzZF.cjs';
4
+ import { R as ReadableStore, T as Timers } from './ports-Dof7AQjk.cjs';
5
5
 
6
6
  /** The image MIME types the chat accepts (the server's `CHAT_ATTACHMENT` rule, plus the `image/jpg` alias). */
7
7
  declare const ATTACHMENT_MIME_TYPES: readonly string[];
@@ -1,197 +1,12 @@
1
+ import { a as TelevetStatePolicy, b as TelevetBookingEntitlement, c as TelevetCancellationPolicy, d as TelevetClinician, e as TelevetSlot, f as TelevetSlotHold, g as TelevetBookingBody, T as TelevetConsult, h as TelevetCancelReceipt, C as ConsultStatus } from './bookingTypes-DCs8mmBb.js';
1
2
  import { E as EverfurError } from './EverfurError-DmELDpXp.js';
2
3
  import { E as EverfurResult } from './EverfurResult-SGvHKsCB.js';
3
- import { R as RequestFunnel } from './requestFunnel-FvE5yLDD.js';
4
- import { A as AuthContext } from './identity-Dy_L7Yq4.js';
4
+ import { R as RequestFunnel } from './requestFunnel-CJC_q4BZ.js';
5
+ import { A as AuthContext } from './identity-AuoeDRTh.js';
5
6
  import { E as ErrorPolicyPort } from './ErrorPolicyPort-D22LUVrK.js';
6
7
  import { T as TelemetryPort } from './TelemetryPort-BDNr00hu.js';
7
8
  import { b as VetCallCredential, c as VetCallJoinRefusal } from './callRoom-7wrE3RP2.js';
8
9
 
9
- /** The consult lifecycle, as the platform names it. `unknown` for a status this SDK build has not heard of. */
10
- declare const CONSULT_STATUSES: readonly ["scheduled", "in_progress", "awaiting_summary", "completed", "cancelled_owner", "cancelled_ops", "no_show_owner", "no_show_vet"];
11
- type ConsultStatus = (typeof CONSULT_STATUSES)[number] | 'unknown';
12
- /**
13
- * Statuses after which a consult can never change again.
14
- *
15
- * `awaiting_summary` is deliberately NOT terminal: the call is over but the write-up has not landed, and that
16
- * is precisely the window a summary surface polls through.
17
- */
18
- declare const TERMINAL_CONSULT_STATUSES: ReadonlySet<ConsultStatus>;
19
- declare const CONSULT_KINDS: readonly ["wellness", "prescription"];
20
- type ConsultKind = (typeof CONSULT_KINDS)[number] | 'unknown';
21
- /**
22
- * What a US state permits. TWO INDEPENDENT SERVER FACTS, not one.
23
- *
24
- * `wellnessAvailable` and `prescriptionsAvailable` are separate because "we cannot prescribe here but a
25
- * wellness visit is available" is a real state the booking flow reads, not a copy decision.
26
- */
27
- interface TelevetStatePolicy {
28
- readonly state: string;
29
- readonly wellnessAvailable: boolean;
30
- readonly prescriptionsAvailable: boolean;
31
- /**
32
- * ALWAYS NULL against a real server, and kept only so a host that reads it still compiles.
33
- *
34
- * `StateCapabilitiesResponse` has no `cancellation_policy_text` and never did: it is the jurisdiction
35
- * matrix, and its own docstring refuses to carry a booking acknowledgement. The terms live on
36
- * `GET /cancellation-policy` with the version token that makes them reportable, which is what
37
- * `TelevetCancellationPolicy` and `TelevetBookingController.cancellationPolicy` read. Prefer that; this
38
- * field is a wire that was never connected, left in place rather than removed because dropping a public
39
- * field is a release decision, and documented rather than quietly parsed so the next surface does not
40
- * build a tick on it.
41
- */
42
- readonly cancellationPolicyText: string | null;
43
- }
44
- /**
45
- * A clinician card. BIOS ONLY AT LAUNCH, per the platform's own docstring: `photoRef` is an image REF and not a
46
- * URL, so a surface that has no presign path renders initials rather than a broken image.
47
- */
48
- interface TelevetClinician {
49
- readonly clinicianId: string;
50
- readonly displayName: string;
51
- readonly credentials: string | null;
52
- /** Null below the platform's publication threshold. NEVER coerce to 0: no stars is not zero stars. */
53
- readonly rating: number | null;
54
- readonly ratingCount: number | null;
55
- /** The clinician's own words, or null until they write one. Rendered verbatim, never summarised. */
56
- readonly bio: string | null;
57
- /** An image ref, not a URL. Null for a clinician without a photo. */
58
- readonly photoRef: string | null;
59
- /** Where they may practise and what they may do there. Empty until served. */
60
- readonly licensedStates: readonly {
61
- readonly state: string;
62
- readonly canPrescribe: boolean;
63
- }[];
64
- }
65
- /** One bookable opening. */
66
- interface TelevetSlot {
67
- readonly slotId: string;
68
- readonly startsAt: string;
69
- readonly endsAt: string;
70
- }
71
- /**
72
- * An awarded hold. NO HOLD ID: the hold is identified by the slot it sits on plus an expiry, which is why the
73
- * booking's idempotency key is derived from the SLOT and not from a hold reference that does not exist.
74
- */
75
- interface TelevetSlotHold {
76
- readonly slotId: string;
77
- readonly expiresAt: string;
78
- }
79
- /** A booked consult, as the server created it. What we asked for is the draft; this is what we got. */
80
- interface TelevetConsult {
81
- readonly consultId: string;
82
- readonly petId: string;
83
- readonly clinicianId: string;
84
- /** The clinician's name, or null when the server has none. Never invented. */
85
- readonly clinicianName: string | null;
86
- /** What the owner wrote at booking, echoed back. */
87
- readonly reasonText: string | null;
88
- /** Attachment refs as stored against the consult. */
89
- readonly mediaRefs: readonly string[];
90
- readonly status: ConsultStatus;
91
- readonly kind: ConsultKind;
92
- readonly scheduledAt: string;
93
- readonly emergencyFlagged: boolean;
94
- /**
95
- * Has the visit's video room been created? Read from the presence of `meeting_url`, which is the same
96
- * signal the backend's `assert_joinable` checks; the URL itself is NOT kept, because the room credential
97
- * is minted by the join and a list read is the last place to hold a link to a recorded clinical room.
98
- * False moments after booking, while the provisioning outbox drains.
99
- */
100
- readonly hasRoom: boolean;
101
- }
102
- /** The televet entitlement verdict. True only for a live PAID subscription; promo and trial are not enough. */
103
- interface TelevetBookingEntitlement {
104
- readonly active: boolean;
105
- }
106
- /**
107
- * The cancellation terms, and the token that says WHICH terms they are.
108
- *
109
- * WHY THIS IS ITS OWN READ. `TelevetStatePolicy.cancellationPolicyText` was parsed off the state-policy
110
- * response, and no such field exists on it: `StateCapabilitiesResponse` carries the jurisdiction matrix and
111
- * says so in its own docstring, and its `policy_version` is the state matrix's effective date, not the
112
- * cancellation terms. So the terms tick could never render and there was no version to report, which is why
113
- * the booking body omitted the attestation pair entirely. The server has always served this on its own route
114
- * (`GET /cancellation-policy`, CancellationPolicyResponse), unfenced by entitlement precisely so someone
115
- * deciding whether to book can read what cancelling costs.
116
- *
117
- * NEITHER FIELD IS EVER LOCAL. `summary` is the sentence the server derives from the numbers it enforces (the
118
- * consumer app shipped a placeholder and a wrong hardcoded fee before this route existed), and `version` is
119
- * evidence of what was on screen: a client-authored token would make the audit row a fiction, and a stale one
120
- * is refused with a typed 409 rather than recorded as agreement to terms nobody saw.
121
- */
122
- interface TelevetCancellationPolicy {
123
- /** The served sentence, rendered verbatim. Never composed, templated or abbreviated by a client. */
124
- readonly summary: string;
125
- /** The server's own version token, reported back in `cancellation_policy_version`. */
126
- readonly version: string;
127
- }
128
- /**
129
- * The booking request body, in the platform's own field names. Built by `buildBookingBody`, never by hand.
130
- *
131
- * THE ATTESTATION PAIR IS BOUND, and the binding is the server's, not a house convention. `BookConsultRequest`
132
- * declares `state_attested` and `cancellation_policy_version` individually optional and then refuses a request
133
- * carrying exactly one (`_attestation_evidence_is_whole`, a 422). The compatibility case the pair is optional
134
- * FOR is a client that predates the review screen and sends neither; a client that renders the tick and the
135
- * terms and reports half of what the owner did writes an audit row nobody can read. So the SDK models both
136
- * fields as jointly present or jointly absent and `validateBookingBody` refuses the half pair locally, before
137
- * it can become a 422 the owner reads as "booking failed".
138
- */
139
- interface TelevetBookingBody {
140
- readonly pet_id: string;
141
- readonly clinician_id: string;
142
- readonly slot_id: string;
143
- readonly state: string;
144
- readonly reason_text: string;
145
- readonly species: string | null;
146
- readonly media_refs: readonly string[];
147
- readonly emergency_acknowledged: boolean;
148
- readonly share_health_records: boolean;
149
- /**
150
- * The review screen's jurisdiction tick, as evidence.
151
- *
152
- * `true` ONLY, never `false`: the server's field is `Literal[True] | None` because persisting an explicit
153
- * `false` is evidence of nothing and accepting it would let a client "attest false". An owner who has not
154
- * ticked sends the pair absent, not a `false` half of it.
155
- */
156
- readonly state_attested?: true;
157
- /**
158
- * Which cancellation terms the owner was SHOWN: the served version token, never a client-authored value.
159
- *
160
- * Paired with `state_attested` above. A stale token is refused with a typed 409 rather than recorded as if
161
- * the owner had read the current terms, which is why it is the SERVER's token and why there is no local
162
- * default: a build with no version to report sends the pair absent and the audit row says so honestly.
163
- */
164
- readonly cancellation_policy_version?: string;
165
- }
166
- /** The server's own ceiling on `cancellation_policy_version` (`Field(max_length=64)`). */
167
- declare const CANCELLATION_POLICY_VERSION_MAX = 64;
168
- /** The server's own bound on `reason_text`. Enforced locally so an over-long description fails on the screen. */
169
- declare const REASON_TEXT_MAX = 2000;
170
- /** The server's own ceiling on `media_refs`. */
171
- declare const MEDIA_REFS_MAX = 10;
172
- /** A two-letter US state code, the only shape the booking wire accepts for `state`. */
173
- declare function isWellFormedStateCode(state: string | null | undefined): boolean;
174
- /**
175
- * What cancelling cost, as the server recorded it (`CancelConsultResponse`).
176
- *
177
- * `summary` IS THE SERVER'S SENTENCE, rendered verbatim: it is derived from the amount the cancel transaction
178
- * itself computed, and the backend states the one rule it keeps (a recorded fee is worded as recorded and
179
- * payable, never as "you will not be charged"). A client-side sentence built from `feeCents` would be a
180
- * second author for a commercial statement.
181
- */
182
- interface TelevetCancelReceipt {
183
- /** What was recorded against this cancellation, in cents. Zero inside the free window. */
184
- readonly feeCents: number;
185
- /** ISO-4217, lowercase. */
186
- readonly currency: string;
187
- /** The flag to branch on, rather than comparing `feeCents` to zero or parsing `summary`. */
188
- readonly feeRecorded: boolean;
189
- /** The served sentence for the confirmation. Null when the server sent none; never composed here. */
190
- readonly summary: string | null;
191
- }
192
- /** The server's own bound on a cancellation reason (`PartnerCancelRequest.reason`, 1..240). */
193
- declare const CANCEL_REASON_MAX = 240;
194
-
195
10
  /** The partner booking surface, relative to the API base. One prefix, so a dark tenant is dark for all of it. */
196
11
  declare const TELEVET_BOOKING_BASE = "/widget/v1/televet";
197
12
  /**
@@ -249,9 +64,14 @@ interface TelevetBookingController {
249
64
  /**
250
65
  * Create the consult.
251
66
  *
252
- * `idempotencyKey` is the IDENTITY of this booking, derived once from the held slot when the draft is
253
- * composed. It seeds the header the funnel writes, so a resubmit after a timeout is the same booking and
254
- * cannot create a second consult. It is not itself the header: see `book` in the factory below.
67
+ * `idempotencyKey` is the IDENTITY of ONE booking attempt, minted when a hold is awarded
68
+ * (`televetBookingKey`) and kept for as long as that hold is the one being booked. It seeds the header the
69
+ * funnel writes, so a resubmit after a timeout is the same attempt and cannot create a second consult, while
70
+ * a new hold, even on the same slot, is a new attempt with a new key. It is not itself the header: see
71
+ * `book` in the factory below.
72
+ *
73
+ * A 2xx carrying a consult that is not live settles as an error (`televetBookingNotLiveError`), never as a
74
+ * booking: see `LIVE_CONSULT_STATUSES`.
255
75
  */
256
76
  book(body: TelevetBookingBody, idempotencyKey: string): Promise<EverfurResult<TelevetConsult>>;
257
77
  /** Move an existing consult to an already-held slot. One server operation, not a book-then-cancel. */
@@ -500,10 +320,10 @@ interface TelevetBookingDraft {
500
320
  /** The consent tick that mints a records grant in the booking transaction. */
501
321
  readonly shareHealthRecords: boolean;
502
322
  /**
503
- * Minted ONCE per composed booking and reused across retries.
323
+ * Minted ONCE per awarded hold (`televetBookingKey`) and reused across retries of that booking.
504
324
  *
505
- * Derived from the SLOT rather than a hold id, which this wire does not have. A timeout followed by a retry
506
- * must not create a second consult.
325
+ * One attempt, not one slot: a timeout followed by a retry must not create a second consult, and a new hold
326
+ * on the same slot (after a cancel, say) must not be answered with the old consult.
507
327
  */
508
328
  readonly idempotencyKey: string | null;
509
329
  }
@@ -583,7 +403,21 @@ declare function canConfirm(draft: TelevetBookingDraft, reasonText: string): boo
583
403
  */
584
404
  declare function isHoldExpired(draft: TelevetBookingDraft, nowMs: number): boolean;
585
405
  /**
586
- * The idempotency key for a composed booking, derived from the SLOT.
406
+ * The idempotency key for ONE booking attempt: minted when a hold is awarded, and a NEW key on every call.
407
+ *
408
+ * CALL IT ONCE PER AWARDED HOLD and keep the result in the draft (`idempotencyKey`). Every submit of that draft
409
+ * then reuses it, so a Confirm pressed again after a timeout is the same booking and the server answers with the
410
+ * consult it recorded rather than creating a second one. That is what the key is for.
411
+ *
412
+ * IT USED TO BE DERIVED FROM THE SLOT ALONE (`televet.book.<slotId>`), and that made two DIFFERENT bookings of
413
+ * one slot the same booking to the server. On staging, 2026-09-23: a member booked a slot, cancelled the visit,
414
+ * and booked the same slot again; the server treated the second booking as a replay of the first and answered
415
+ * 201 with the first consult, cancelled, and the flow said "You're booked". No visit existed. A slot can be
416
+ * booked, released and booked again; a hold cannot, so the key belongs to the hold.
417
+ *
418
+ * THE ATTEMPT COMES FIRST and the slot after it, because the funnel caps a seeded key at 128 characters (the
419
+ * route's own bound) by cutting the tail: a long slot id may lose its end, the part that tells two attempts
420
+ * apart never does. The slot stays in the key so a server log still says which slot an attempt was for.
587
421
  *
588
422
  * One definition, because the reducer clears it and the flow mints it: two spellings would let a retry after a
589
423
  * cleared draft create a second consult.
@@ -625,7 +459,11 @@ declare function attestation(stateAttested: boolean, termsAttested: boolean, pol
625
459
  type TelevetBookingFailure = 'taken' | 'expired' | 'failed' | 'not_entitled'
626
460
  /** The remedy is a DIFFERENT VET, not a different time: re-picking a slot with the same clinician refuses again. */
627
461
  | 'clinician_unavailable'
628
- /** Per-owner caps. The remedy is WAITING, so this must never render as an invitation to press again. */
462
+ /**
463
+ * Per-owner caps. Kept apart from `failed` so a host can tell them apart, and both steps render the same
464
+ * generic line for it, "That did not book. Try again.", never the server's own sentence: the owner's
465
+ * decision of 2026-09-24, matching consumer web, which shows its generic booking failure for a 429.
466
+ */
629
467
  | 'rate_limited'
630
468
  /** The partner booking surface is dark here. No retry can fix it, so the flow says so and offers its exit. */
631
469
  | 'unavailable' | null;
@@ -817,9 +655,9 @@ type TelevetBookingRefusal =
817
655
  /**
818
656
  * The SERVER'S OWN wording, when it sends any.
819
657
  *
820
- * Carried rather than replaced with a string written here: a wait message is the server's to phrase, it
821
- * can change without an app release, and this SDK does not author user-facing copy. Null renders no line
822
- * at all rather than a placeholder.
658
+ * Carried for a host that reads it, and rendered by no SDK screen: since the owner's decision of
659
+ * 2026-09-24 the booking steps and the visits list show their existing generic line for a 429, as
660
+ * consumer web does. The SDK writes no rate-limit sentence of its own.
823
661
  */
824
662
  readonly message: string | null;
825
663
  }
@@ -1132,4 +970,4 @@ type TelevetBookingCopy = typeof TELEVET_BOOKING_COPY;
1132
970
  */
1133
971
  declare function isTelevetBookingCopyReady(): boolean;
1134
972
 
1135
- export { createTelevetBookingController as $, type TelevetBookingCopy as A, type TelevetBookingDraft as B, CANCELLATION_POLICY_VERSION_MAX as C, type TelevetBookingEntitlement as D, type TelevetBookingFailure as E, type TelevetBookingRefusal as F, type TelevetBookingState as G, type TelevetCancellationPolicy as H, type TelevetClinician as I, type TelevetEarlyTriage as J, type TelevetEmptyRosterView as K, type TelevetJoinReadiness as L, MEDIA_REFS_MAX as M, NO_MEDIA_SHORTFALL as N, type TelevetJoinState as O, type TelevetMediaRefusal as P, type TelevetRead as Q, REASON_TEXT_MAX as R, type TelevetSlotHold as S, type TelevetEmptyRosterCause as T, type TelevetStateInterestReason as U, type TelevetStatePolicy as V, type TelevetTriageVerdict as W, type TelevetWrite as X, attestation as Y, canConfirm as Z, canManageTelevetVisit as _, type TelevetStateInterestAction as a, currentStep as a0, emptyTelevetDraft as a1, formatVisitRange as a2, formatWhen as a3, formatWhenWithDay as a4, hasPreviousStep as a5, initialTelevetBookingState as a6, isHoldExpired as a7, isMediaShortfallEmpty as a8, isSkipped as a9, useTelevetJoin as aA, useTelevetNextSlot as aB, useTelevetRescheduleConsult as aC, useTelevetSlots as aD, useTelevetStatePolicy as aE, validateBookingBody as aF, withUnsentPicks as aG, type TelevetJoinBlock as aH, type TelevetJoinDecision as aI, televetJoinDecision as aJ, isTelevetBookingCopyReady as aa, isWellFormedStateCode as ab, mediaShortfallFromUnsentPicks as ac, splitTelevetVisits as ad, televetBookingKey as ae, televetBookingReducer as af, televetBookingRefusal as ag, televetCancelCall as ah, televetConsultCall as ai, televetEmptyRosterCause as aj, televetEmptyRosterView as ak, televetHoldCall as al, televetJoinCall as am, televetJoinOpensAtMs as an, televetJoinReadiness as ao, televetMediaShortfallLines as ap, televetRescheduleCall as aq, useEarlyTriage as ar, useStateInterest as as, useTelevetBookConsult as at, useTelevetBookingAvailable as au, useTelevetBookingController as av, useTelevetBookingEntitlement as aw, useTelevetCancellationPolicy as ax, useTelevetClinicians as ay, useTelevetHoldSlot as az, type TelevetMediaShortfall as b, type TelevetConsult as c, type TelevetBookingStep as d, type TelevetBookingController as e, type TelevetTriageRead as f, type TelevetStateInterestWrite as g, type TelevetCancelReceipt as h, type TelevetSlot as i, CANCEL_REASON_MAX as j, CONSULT_KINDS as k, CONSULT_MINUTES as l, CONSULT_STATUSES as m, type ConsultKind as n, type ConsultStatus as o, TELEVET_BOOKING_BASE as p, TELEVET_BOOKING_COPY as q, TELEVET_BOOKING_STEPS as r, TELEVET_CONSULT_PAGE_LIMIT as s, TELEVET_JOIN_CLOSES_MINUTES_AFTER as t, TELEVET_JOIN_OPENS_MINUTES_BEFORE as u, TERMINAL_CONSULT_STATUSES as v, type TelevetBookingAction as w, type TelevetBookingBody as x, type TelevetBookingContext as y, type TelevetBookingControllerDeps as z };
973
+ export { televetConsultCall as $, type TelevetStateInterestReason as A, type TelevetTriageVerdict as B, CONSULT_MINUTES as C, type TelevetWrite as D, attestation as E, canConfirm as F, canManageTelevetVisit as G, createTelevetBookingController as H, currentStep as I, emptyTelevetDraft as J, formatVisitRange as K, formatWhen as L, formatWhenWithDay as M, NO_MEDIA_SHORTFALL as N, hasPreviousStep as O, initialTelevetBookingState as P, isHoldExpired as Q, isMediaShortfallEmpty as R, isSkipped as S, type TelevetEmptyRosterCause as T, isTelevetBookingCopyReady as U, mediaShortfallFromUnsentPicks as V, splitTelevetVisits as W, televetBookingKey as X, televetBookingReducer as Y, televetBookingRefusal as Z, televetCancelCall as _, type TelevetStateInterestAction as a, televetEmptyRosterCause as a0, televetEmptyRosterView as a1, televetHoldCall as a2, televetJoinCall as a3, televetJoinOpensAtMs as a4, televetJoinReadiness as a5, televetMediaShortfallLines as a6, televetRescheduleCall as a7, useEarlyTriage as a8, useStateInterest as a9, useTelevetBookConsult as aa, useTelevetBookingAvailable as ab, useTelevetBookingController as ac, useTelevetBookingEntitlement as ad, useTelevetCancellationPolicy as ae, useTelevetClinicians as af, useTelevetHoldSlot as ag, useTelevetJoin as ah, useTelevetNextSlot as ai, useTelevetRescheduleConsult as aj, useTelevetSlots as ak, useTelevetStatePolicy as al, validateBookingBody as am, withUnsentPicks as an, type TelevetJoinBlock as ao, type TelevetJoinDecision as ap, televetJoinDecision as aq, type TelevetMediaShortfall as b, type TelevetBookingStep as c, type TelevetBookingController as d, type TelevetTriageRead as e, type TelevetStateInterestWrite as f, TELEVET_BOOKING_BASE as g, TELEVET_BOOKING_COPY as h, TELEVET_BOOKING_STEPS as i, TELEVET_CONSULT_PAGE_LIMIT as j, TELEVET_JOIN_CLOSES_MINUTES_AFTER as k, TELEVET_JOIN_OPENS_MINUTES_BEFORE as l, type TelevetBookingAction as m, type TelevetBookingContext as n, type TelevetBookingControllerDeps as o, type TelevetBookingCopy as p, type TelevetBookingDraft as q, type TelevetBookingFailure as r, type TelevetBookingRefusal as s, type TelevetBookingState as t, type TelevetEarlyTriage as u, type TelevetEmptyRosterView as v, type TelevetJoinReadiness as w, type TelevetJoinState as x, type TelevetMediaRefusal as y, type TelevetRead as z };
@@ -1,197 +1,12 @@
1
+ import { a as TelevetStatePolicy, b as TelevetBookingEntitlement, c as TelevetCancellationPolicy, d as TelevetClinician, e as TelevetSlot, f as TelevetSlotHold, g as TelevetBookingBody, T as TelevetConsult, h as TelevetCancelReceipt, C as ConsultStatus } from './bookingTypes-DCs8mmBb.cjs';
1
2
  import { E as EverfurError } from './EverfurError-DmELDpXp.cjs';
2
3
  import { E as EverfurResult } from './EverfurResult-ZtH-YV1h.cjs';
3
- import { R as RequestFunnel } from './requestFunnel-Bqc1inM9.cjs';
4
- import { A as AuthContext } from './identity-DjqhDm5Z.cjs';
4
+ import { R as RequestFunnel } from './requestFunnel-DrigK6q_.cjs';
5
+ import { A as AuthContext } from './identity-Z0yj-fC_.cjs';
5
6
  import { E as ErrorPolicyPort } from './ErrorPolicyPort-D6CybiqJ.cjs';
6
7
  import { T as TelemetryPort } from './TelemetryPort-BDNr00hu.cjs';
7
8
  import { b as VetCallCredential, c as VetCallJoinRefusal } from './callRoom-B_EqaUzx.cjs';
8
9
 
9
- /** The consult lifecycle, as the platform names it. `unknown` for a status this SDK build has not heard of. */
10
- declare const CONSULT_STATUSES: readonly ["scheduled", "in_progress", "awaiting_summary", "completed", "cancelled_owner", "cancelled_ops", "no_show_owner", "no_show_vet"];
11
- type ConsultStatus = (typeof CONSULT_STATUSES)[number] | 'unknown';
12
- /**
13
- * Statuses after which a consult can never change again.
14
- *
15
- * `awaiting_summary` is deliberately NOT terminal: the call is over but the write-up has not landed, and that
16
- * is precisely the window a summary surface polls through.
17
- */
18
- declare const TERMINAL_CONSULT_STATUSES: ReadonlySet<ConsultStatus>;
19
- declare const CONSULT_KINDS: readonly ["wellness", "prescription"];
20
- type ConsultKind = (typeof CONSULT_KINDS)[number] | 'unknown';
21
- /**
22
- * What a US state permits. TWO INDEPENDENT SERVER FACTS, not one.
23
- *
24
- * `wellnessAvailable` and `prescriptionsAvailable` are separate because "we cannot prescribe here but a
25
- * wellness visit is available" is a real state the booking flow reads, not a copy decision.
26
- */
27
- interface TelevetStatePolicy {
28
- readonly state: string;
29
- readonly wellnessAvailable: boolean;
30
- readonly prescriptionsAvailable: boolean;
31
- /**
32
- * ALWAYS NULL against a real server, and kept only so a host that reads it still compiles.
33
- *
34
- * `StateCapabilitiesResponse` has no `cancellation_policy_text` and never did: it is the jurisdiction
35
- * matrix, and its own docstring refuses to carry a booking acknowledgement. The terms live on
36
- * `GET /cancellation-policy` with the version token that makes them reportable, which is what
37
- * `TelevetCancellationPolicy` and `TelevetBookingController.cancellationPolicy` read. Prefer that; this
38
- * field is a wire that was never connected, left in place rather than removed because dropping a public
39
- * field is a release decision, and documented rather than quietly parsed so the next surface does not
40
- * build a tick on it.
41
- */
42
- readonly cancellationPolicyText: string | null;
43
- }
44
- /**
45
- * A clinician card. BIOS ONLY AT LAUNCH, per the platform's own docstring: `photoRef` is an image REF and not a
46
- * URL, so a surface that has no presign path renders initials rather than a broken image.
47
- */
48
- interface TelevetClinician {
49
- readonly clinicianId: string;
50
- readonly displayName: string;
51
- readonly credentials: string | null;
52
- /** Null below the platform's publication threshold. NEVER coerce to 0: no stars is not zero stars. */
53
- readonly rating: number | null;
54
- readonly ratingCount: number | null;
55
- /** The clinician's own words, or null until they write one. Rendered verbatim, never summarised. */
56
- readonly bio: string | null;
57
- /** An image ref, not a URL. Null for a clinician without a photo. */
58
- readonly photoRef: string | null;
59
- /** Where they may practise and what they may do there. Empty until served. */
60
- readonly licensedStates: readonly {
61
- readonly state: string;
62
- readonly canPrescribe: boolean;
63
- }[];
64
- }
65
- /** One bookable opening. */
66
- interface TelevetSlot {
67
- readonly slotId: string;
68
- readonly startsAt: string;
69
- readonly endsAt: string;
70
- }
71
- /**
72
- * An awarded hold. NO HOLD ID: the hold is identified by the slot it sits on plus an expiry, which is why the
73
- * booking's idempotency key is derived from the SLOT and not from a hold reference that does not exist.
74
- */
75
- interface TelevetSlotHold {
76
- readonly slotId: string;
77
- readonly expiresAt: string;
78
- }
79
- /** A booked consult, as the server created it. What we asked for is the draft; this is what we got. */
80
- interface TelevetConsult {
81
- readonly consultId: string;
82
- readonly petId: string;
83
- readonly clinicianId: string;
84
- /** The clinician's name, or null when the server has none. Never invented. */
85
- readonly clinicianName: string | null;
86
- /** What the owner wrote at booking, echoed back. */
87
- readonly reasonText: string | null;
88
- /** Attachment refs as stored against the consult. */
89
- readonly mediaRefs: readonly string[];
90
- readonly status: ConsultStatus;
91
- readonly kind: ConsultKind;
92
- readonly scheduledAt: string;
93
- readonly emergencyFlagged: boolean;
94
- /**
95
- * Has the visit's video room been created? Read from the presence of `meeting_url`, which is the same
96
- * signal the backend's `assert_joinable` checks; the URL itself is NOT kept, because the room credential
97
- * is minted by the join and a list read is the last place to hold a link to a recorded clinical room.
98
- * False moments after booking, while the provisioning outbox drains.
99
- */
100
- readonly hasRoom: boolean;
101
- }
102
- /** The televet entitlement verdict. True only for a live PAID subscription; promo and trial are not enough. */
103
- interface TelevetBookingEntitlement {
104
- readonly active: boolean;
105
- }
106
- /**
107
- * The cancellation terms, and the token that says WHICH terms they are.
108
- *
109
- * WHY THIS IS ITS OWN READ. `TelevetStatePolicy.cancellationPolicyText` was parsed off the state-policy
110
- * response, and no such field exists on it: `StateCapabilitiesResponse` carries the jurisdiction matrix and
111
- * says so in its own docstring, and its `policy_version` is the state matrix's effective date, not the
112
- * cancellation terms. So the terms tick could never render and there was no version to report, which is why
113
- * the booking body omitted the attestation pair entirely. The server has always served this on its own route
114
- * (`GET /cancellation-policy`, CancellationPolicyResponse), unfenced by entitlement precisely so someone
115
- * deciding whether to book can read what cancelling costs.
116
- *
117
- * NEITHER FIELD IS EVER LOCAL. `summary` is the sentence the server derives from the numbers it enforces (the
118
- * consumer app shipped a placeholder and a wrong hardcoded fee before this route existed), and `version` is
119
- * evidence of what was on screen: a client-authored token would make the audit row a fiction, and a stale one
120
- * is refused with a typed 409 rather than recorded as agreement to terms nobody saw.
121
- */
122
- interface TelevetCancellationPolicy {
123
- /** The served sentence, rendered verbatim. Never composed, templated or abbreviated by a client. */
124
- readonly summary: string;
125
- /** The server's own version token, reported back in `cancellation_policy_version`. */
126
- readonly version: string;
127
- }
128
- /**
129
- * The booking request body, in the platform's own field names. Built by `buildBookingBody`, never by hand.
130
- *
131
- * THE ATTESTATION PAIR IS BOUND, and the binding is the server's, not a house convention. `BookConsultRequest`
132
- * declares `state_attested` and `cancellation_policy_version` individually optional and then refuses a request
133
- * carrying exactly one (`_attestation_evidence_is_whole`, a 422). The compatibility case the pair is optional
134
- * FOR is a client that predates the review screen and sends neither; a client that renders the tick and the
135
- * terms and reports half of what the owner did writes an audit row nobody can read. So the SDK models both
136
- * fields as jointly present or jointly absent and `validateBookingBody` refuses the half pair locally, before
137
- * it can become a 422 the owner reads as "booking failed".
138
- */
139
- interface TelevetBookingBody {
140
- readonly pet_id: string;
141
- readonly clinician_id: string;
142
- readonly slot_id: string;
143
- readonly state: string;
144
- readonly reason_text: string;
145
- readonly species: string | null;
146
- readonly media_refs: readonly string[];
147
- readonly emergency_acknowledged: boolean;
148
- readonly share_health_records: boolean;
149
- /**
150
- * The review screen's jurisdiction tick, as evidence.
151
- *
152
- * `true` ONLY, never `false`: the server's field is `Literal[True] | None` because persisting an explicit
153
- * `false` is evidence of nothing and accepting it would let a client "attest false". An owner who has not
154
- * ticked sends the pair absent, not a `false` half of it.
155
- */
156
- readonly state_attested?: true;
157
- /**
158
- * Which cancellation terms the owner was SHOWN: the served version token, never a client-authored value.
159
- *
160
- * Paired with `state_attested` above. A stale token is refused with a typed 409 rather than recorded as if
161
- * the owner had read the current terms, which is why it is the SERVER's token and why there is no local
162
- * default: a build with no version to report sends the pair absent and the audit row says so honestly.
163
- */
164
- readonly cancellation_policy_version?: string;
165
- }
166
- /** The server's own ceiling on `cancellation_policy_version` (`Field(max_length=64)`). */
167
- declare const CANCELLATION_POLICY_VERSION_MAX = 64;
168
- /** The server's own bound on `reason_text`. Enforced locally so an over-long description fails on the screen. */
169
- declare const REASON_TEXT_MAX = 2000;
170
- /** The server's own ceiling on `media_refs`. */
171
- declare const MEDIA_REFS_MAX = 10;
172
- /** A two-letter US state code, the only shape the booking wire accepts for `state`. */
173
- declare function isWellFormedStateCode(state: string | null | undefined): boolean;
174
- /**
175
- * What cancelling cost, as the server recorded it (`CancelConsultResponse`).
176
- *
177
- * `summary` IS THE SERVER'S SENTENCE, rendered verbatim: it is derived from the amount the cancel transaction
178
- * itself computed, and the backend states the one rule it keeps (a recorded fee is worded as recorded and
179
- * payable, never as "you will not be charged"). A client-side sentence built from `feeCents` would be a
180
- * second author for a commercial statement.
181
- */
182
- interface TelevetCancelReceipt {
183
- /** What was recorded against this cancellation, in cents. Zero inside the free window. */
184
- readonly feeCents: number;
185
- /** ISO-4217, lowercase. */
186
- readonly currency: string;
187
- /** The flag to branch on, rather than comparing `feeCents` to zero or parsing `summary`. */
188
- readonly feeRecorded: boolean;
189
- /** The served sentence for the confirmation. Null when the server sent none; never composed here. */
190
- readonly summary: string | null;
191
- }
192
- /** The server's own bound on a cancellation reason (`PartnerCancelRequest.reason`, 1..240). */
193
- declare const CANCEL_REASON_MAX = 240;
194
-
195
10
  /** The partner booking surface, relative to the API base. One prefix, so a dark tenant is dark for all of it. */
196
11
  declare const TELEVET_BOOKING_BASE = "/widget/v1/televet";
197
12
  /**
@@ -249,9 +64,14 @@ interface TelevetBookingController {
249
64
  /**
250
65
  * Create the consult.
251
66
  *
252
- * `idempotencyKey` is the IDENTITY of this booking, derived once from the held slot when the draft is
253
- * composed. It seeds the header the funnel writes, so a resubmit after a timeout is the same booking and
254
- * cannot create a second consult. It is not itself the header: see `book` in the factory below.
67
+ * `idempotencyKey` is the IDENTITY of ONE booking attempt, minted when a hold is awarded
68
+ * (`televetBookingKey`) and kept for as long as that hold is the one being booked. It seeds the header the
69
+ * funnel writes, so a resubmit after a timeout is the same attempt and cannot create a second consult, while
70
+ * a new hold, even on the same slot, is a new attempt with a new key. It is not itself the header: see
71
+ * `book` in the factory below.
72
+ *
73
+ * A 2xx carrying a consult that is not live settles as an error (`televetBookingNotLiveError`), never as a
74
+ * booking: see `LIVE_CONSULT_STATUSES`.
255
75
  */
256
76
  book(body: TelevetBookingBody, idempotencyKey: string): Promise<EverfurResult<TelevetConsult>>;
257
77
  /** Move an existing consult to an already-held slot. One server operation, not a book-then-cancel. */
@@ -500,10 +320,10 @@ interface TelevetBookingDraft {
500
320
  /** The consent tick that mints a records grant in the booking transaction. */
501
321
  readonly shareHealthRecords: boolean;
502
322
  /**
503
- * Minted ONCE per composed booking and reused across retries.
323
+ * Minted ONCE per awarded hold (`televetBookingKey`) and reused across retries of that booking.
504
324
  *
505
- * Derived from the SLOT rather than a hold id, which this wire does not have. A timeout followed by a retry
506
- * must not create a second consult.
325
+ * One attempt, not one slot: a timeout followed by a retry must not create a second consult, and a new hold
326
+ * on the same slot (after a cancel, say) must not be answered with the old consult.
507
327
  */
508
328
  readonly idempotencyKey: string | null;
509
329
  }
@@ -583,7 +403,21 @@ declare function canConfirm(draft: TelevetBookingDraft, reasonText: string): boo
583
403
  */
584
404
  declare function isHoldExpired(draft: TelevetBookingDraft, nowMs: number): boolean;
585
405
  /**
586
- * The idempotency key for a composed booking, derived from the SLOT.
406
+ * The idempotency key for ONE booking attempt: minted when a hold is awarded, and a NEW key on every call.
407
+ *
408
+ * CALL IT ONCE PER AWARDED HOLD and keep the result in the draft (`idempotencyKey`). Every submit of that draft
409
+ * then reuses it, so a Confirm pressed again after a timeout is the same booking and the server answers with the
410
+ * consult it recorded rather than creating a second one. That is what the key is for.
411
+ *
412
+ * IT USED TO BE DERIVED FROM THE SLOT ALONE (`televet.book.<slotId>`), and that made two DIFFERENT bookings of
413
+ * one slot the same booking to the server. On staging, 2026-09-23: a member booked a slot, cancelled the visit,
414
+ * and booked the same slot again; the server treated the second booking as a replay of the first and answered
415
+ * 201 with the first consult, cancelled, and the flow said "You're booked". No visit existed. A slot can be
416
+ * booked, released and booked again; a hold cannot, so the key belongs to the hold.
417
+ *
418
+ * THE ATTEMPT COMES FIRST and the slot after it, because the funnel caps a seeded key at 128 characters (the
419
+ * route's own bound) by cutting the tail: a long slot id may lose its end, the part that tells two attempts
420
+ * apart never does. The slot stays in the key so a server log still says which slot an attempt was for.
587
421
  *
588
422
  * One definition, because the reducer clears it and the flow mints it: two spellings would let a retry after a
589
423
  * cleared draft create a second consult.
@@ -625,7 +459,11 @@ declare function attestation(stateAttested: boolean, termsAttested: boolean, pol
625
459
  type TelevetBookingFailure = 'taken' | 'expired' | 'failed' | 'not_entitled'
626
460
  /** The remedy is a DIFFERENT VET, not a different time: re-picking a slot with the same clinician refuses again. */
627
461
  | 'clinician_unavailable'
628
- /** Per-owner caps. The remedy is WAITING, so this must never render as an invitation to press again. */
462
+ /**
463
+ * Per-owner caps. Kept apart from `failed` so a host can tell them apart, and both steps render the same
464
+ * generic line for it, "That did not book. Try again.", never the server's own sentence: the owner's
465
+ * decision of 2026-09-24, matching consumer web, which shows its generic booking failure for a 429.
466
+ */
629
467
  | 'rate_limited'
630
468
  /** The partner booking surface is dark here. No retry can fix it, so the flow says so and offers its exit. */
631
469
  | 'unavailable' | null;
@@ -817,9 +655,9 @@ type TelevetBookingRefusal =
817
655
  /**
818
656
  * The SERVER'S OWN wording, when it sends any.
819
657
  *
820
- * Carried rather than replaced with a string written here: a wait message is the server's to phrase, it
821
- * can change without an app release, and this SDK does not author user-facing copy. Null renders no line
822
- * at all rather than a placeholder.
658
+ * Carried for a host that reads it, and rendered by no SDK screen: since the owner's decision of
659
+ * 2026-09-24 the booking steps and the visits list show their existing generic line for a 429, as
660
+ * consumer web does. The SDK writes no rate-limit sentence of its own.
823
661
  */
824
662
  readonly message: string | null;
825
663
  }
@@ -1132,4 +970,4 @@ type TelevetBookingCopy = typeof TELEVET_BOOKING_COPY;
1132
970
  */
1133
971
  declare function isTelevetBookingCopyReady(): boolean;
1134
972
 
1135
- export { createTelevetBookingController as $, type TelevetBookingCopy as A, type TelevetBookingDraft as B, CANCELLATION_POLICY_VERSION_MAX as C, type TelevetBookingEntitlement as D, type TelevetBookingFailure as E, type TelevetBookingRefusal as F, type TelevetBookingState as G, type TelevetCancellationPolicy as H, type TelevetClinician as I, type TelevetEarlyTriage as J, type TelevetEmptyRosterView as K, type TelevetJoinReadiness as L, MEDIA_REFS_MAX as M, NO_MEDIA_SHORTFALL as N, type TelevetJoinState as O, type TelevetMediaRefusal as P, type TelevetRead as Q, REASON_TEXT_MAX as R, type TelevetSlotHold as S, type TelevetEmptyRosterCause as T, type TelevetStateInterestReason as U, type TelevetStatePolicy as V, type TelevetTriageVerdict as W, type TelevetWrite as X, attestation as Y, canConfirm as Z, canManageTelevetVisit as _, type TelevetStateInterestAction as a, currentStep as a0, emptyTelevetDraft as a1, formatVisitRange as a2, formatWhen as a3, formatWhenWithDay as a4, hasPreviousStep as a5, initialTelevetBookingState as a6, isHoldExpired as a7, isMediaShortfallEmpty as a8, isSkipped as a9, useTelevetJoin as aA, useTelevetNextSlot as aB, useTelevetRescheduleConsult as aC, useTelevetSlots as aD, useTelevetStatePolicy as aE, validateBookingBody as aF, withUnsentPicks as aG, type TelevetJoinBlock as aH, type TelevetJoinDecision as aI, televetJoinDecision as aJ, isTelevetBookingCopyReady as aa, isWellFormedStateCode as ab, mediaShortfallFromUnsentPicks as ac, splitTelevetVisits as ad, televetBookingKey as ae, televetBookingReducer as af, televetBookingRefusal as ag, televetCancelCall as ah, televetConsultCall as ai, televetEmptyRosterCause as aj, televetEmptyRosterView as ak, televetHoldCall as al, televetJoinCall as am, televetJoinOpensAtMs as an, televetJoinReadiness as ao, televetMediaShortfallLines as ap, televetRescheduleCall as aq, useEarlyTriage as ar, useStateInterest as as, useTelevetBookConsult as at, useTelevetBookingAvailable as au, useTelevetBookingController as av, useTelevetBookingEntitlement as aw, useTelevetCancellationPolicy as ax, useTelevetClinicians as ay, useTelevetHoldSlot as az, type TelevetMediaShortfall as b, type TelevetConsult as c, type TelevetBookingStep as d, type TelevetBookingController as e, type TelevetTriageRead as f, type TelevetStateInterestWrite as g, type TelevetCancelReceipt as h, type TelevetSlot as i, CANCEL_REASON_MAX as j, CONSULT_KINDS as k, CONSULT_MINUTES as l, CONSULT_STATUSES as m, type ConsultKind as n, type ConsultStatus as o, TELEVET_BOOKING_BASE as p, TELEVET_BOOKING_COPY as q, TELEVET_BOOKING_STEPS as r, TELEVET_CONSULT_PAGE_LIMIT as s, TELEVET_JOIN_CLOSES_MINUTES_AFTER as t, TELEVET_JOIN_OPENS_MINUTES_BEFORE as u, TERMINAL_CONSULT_STATUSES as v, type TelevetBookingAction as w, type TelevetBookingBody as x, type TelevetBookingContext as y, type TelevetBookingControllerDeps as z };
973
+ export { televetConsultCall as $, type TelevetStateInterestReason as A, type TelevetTriageVerdict as B, CONSULT_MINUTES as C, type TelevetWrite as D, attestation as E, canConfirm as F, canManageTelevetVisit as G, createTelevetBookingController as H, currentStep as I, emptyTelevetDraft as J, formatVisitRange as K, formatWhen as L, formatWhenWithDay as M, NO_MEDIA_SHORTFALL as N, hasPreviousStep as O, initialTelevetBookingState as P, isHoldExpired as Q, isMediaShortfallEmpty as R, isSkipped as S, type TelevetEmptyRosterCause as T, isTelevetBookingCopyReady as U, mediaShortfallFromUnsentPicks as V, splitTelevetVisits as W, televetBookingKey as X, televetBookingReducer as Y, televetBookingRefusal as Z, televetCancelCall as _, type TelevetStateInterestAction as a, televetEmptyRosterCause as a0, televetEmptyRosterView as a1, televetHoldCall as a2, televetJoinCall as a3, televetJoinOpensAtMs as a4, televetJoinReadiness as a5, televetMediaShortfallLines as a6, televetRescheduleCall as a7, useEarlyTriage as a8, useStateInterest as a9, useTelevetBookConsult as aa, useTelevetBookingAvailable as ab, useTelevetBookingController as ac, useTelevetBookingEntitlement as ad, useTelevetCancellationPolicy as ae, useTelevetClinicians as af, useTelevetHoldSlot as ag, useTelevetJoin as ah, useTelevetNextSlot as ai, useTelevetRescheduleConsult as aj, useTelevetSlots as ak, useTelevetStatePolicy as al, validateBookingBody as am, withUnsentPicks as an, type TelevetJoinBlock as ao, type TelevetJoinDecision as ap, televetJoinDecision as aq, type TelevetMediaShortfall as b, type TelevetBookingStep as c, type TelevetBookingController as d, type TelevetTriageRead as e, type TelevetStateInterestWrite as f, TELEVET_BOOKING_BASE as g, TELEVET_BOOKING_COPY as h, TELEVET_BOOKING_STEPS as i, TELEVET_CONSULT_PAGE_LIMIT as j, TELEVET_JOIN_CLOSES_MINUTES_AFTER as k, TELEVET_JOIN_OPENS_MINUTES_BEFORE as l, type TelevetBookingAction as m, type TelevetBookingContext as n, type TelevetBookingControllerDeps as o, type TelevetBookingCopy as p, type TelevetBookingDraft as q, type TelevetBookingFailure as r, type TelevetBookingRefusal as s, type TelevetBookingState as t, type TelevetEarlyTriage as u, type TelevetEmptyRosterView as v, type TelevetJoinReadiness as w, type TelevetJoinState as x, type TelevetMediaRefusal as y, type TelevetRead as z };