// Build-time gates for the telehealth video feature. Deliberately its OWN module, not a constant in // `videoContract.ts`: the contract file is the frozen wire shape transcribed from the server design, // and a local ship switch has no business living in it. EVERY entry point imports from here, so the // feature is turned on in exactly one place instead of several that can disagree - as of Task 13 that // is: `EncounterVideoPane` (start a visit), `StartCaseConferenceButton` (start a conference), // `AvailableMeetingBanner` (JOIN one - the patient's only way in) and the late-joiner // `listAvailable()` lookup in `VideoService`. // // THE LOOKUP IS GATED TOO, and it is the one that is easy to miss: it is not an affordance, it is // an authenticated `GET /R4/video-session` that fires on EVERY app mount for EVERY signed-in user. // Ungated it would put a request for an unshipped feature on the critical path of every session, // against a route that exists only on staging. /** * **ON since 2026-08-02**, flipped deliberately after the first real two-party browser call against * deployed staging. Everything below is the history of why it was closed and what it cost to open - * keep it, because the reasons are the argument for the next flag someone is tempted to skip. * * **What that call actually verified, in a browser:** two-way audio (the silent-call defect is closed), * a rendering self-view, camera-off NOT reading as "waiting", the surface handover on navigation, and * leave/rejoin. It also found FIVE defects a green unit suite could not have caught - which is the * whole case for having made the flag conditional on a browser rather than on the tests. * * **TWO CONDITIONS REMAIN UNSEEN, recorded on as untested rather than passed:** * 1. **TRUE two-way video** - the test machine has ONE webcam, so two browsers could never both hold * it and one side always had `cameraAvailable: false`. Needs a second camera on live staging. * 2. **The DOCKED encounter pane** - the primary clinical surface - has still never run in a browser. * It mounts only inside the encounter workspace, reached from the clinician queue. * **CORRECTION 2026-08-02:** this used to say the queue was "blocked by new Appointments not * reaching the HealthLake search index". That was wrong, and it was a bug in my test fixture * rather than in the product - there is no indexing problem. The org appointment search scopes on * `actor=PractitionerRole/`, and the fixture omitted the PractitionerRole participant, so it * was never *matchable* rather than merely not-yet-indexed. A fixture that includes the role is * reachable immediately. Left in place because a wrong diagnosis quoted in a comment outlives the * conversation that produced it. * * **This is not a release.** The only accounts are Spencer, Toncy and Ed, and video must be finished * before anything ships - which is why ON is safe now and would not have been on a live product. * * **Still asserted, in the other direction.** `EncounterVideoPane.gate.test.tsx` pins this as `true` * via `importActual`; both `.gate` test files now MOCK the flag closed so "a closed gate really closes * the entry point" stays covered whatever this ships as. Changing it in either direction is deliberate. * * history * OFF because THE BROKER DOES NOT EXIST YET. * * (Lane A) owns `POST/GET /R4/video-session*`, and as of 2026-08-01 `aws lambda * list-functions` returns **zero** video functions on HIS-Dev - the handlers are its T6 and are not * deployed. Meanwhile this client is fully wired: Task 9 mounted a real "Start video" button in the * encounter workspace and Task 11 pointed the app at the LIVE transport. So without this flag a * plugin build ships a practitioner a button that 404s, and the previous state (the in-memory stub) * was worse - it fed FABRICATED `Meeting`/`Attendee` objects straight into the real Chime SDK. * * The control stays VISIBLE and disabled with honest copy rather than hidden. Spencer's product call * on: a visible "coming soon" beats a feature that silently isn't there, because a missing * button reads as "this product has no telehealth" while a disabled one reads as "not yet". * * **THE BROKER HALF OF THIS CONDITION IS NOW MET** - Task 12's integration checkpoint ran green * against deployed staging on 2026-08-01: all seven routes answered, a real Chime meeting was minted * and torn down, and every response was a **superset** of what this client expects (zero shape * incompatibilities). So the transport is no longer the thing holding the flag closed. * * **BOTH TASK 9 REVIEW DEFECTS ARE NOW FIXED** (2026-08-01), so neither is holding this closed any * longer: * 1. ~~"Waiting for the patient to join..." is WRONG whenever the patient has no video.~~ It is now * derived from zero remote **ATTENDEES** (`realtimeSubscribeToAttendeeIdPresence`, tracked in * `ChimeCallSession`), not zero remote tiles - so an audio-only patient, and one who turns their * camera off mid-visit, both read as PRESENT. `remoteTiles` remains, for layout only. * 2. ~~A docked call has NO surface once the practitioner navigates off its encounter.~~ * `EncounterVideoPane` now registers itself as the docked surface while it is showing the call, * and `CallOverlay` renders the FULL floating surface when a live call has no such surface * mounted. The one-grid rule is unchanged: while the pane is up, the overlay is silent. * Task 13 replaced the minimal Leave-only affordance this used to describe, because the same * branch turned out to serve a PATIENT in an `encounter#` visit - who has no encounter workspace * at all, so a Leave-only stub was their entire view of the visit. * * **STILL DO NOT FLIP - the browser call is still owed.** Nothing in the video client has run in a * **browser** yet: no real camera, no real microphone, no real two-party call. Everything below the * transport is mock-verified, which is precisely how the silent-call defect survived a clean review * once already - and the presence fix above is mock-verified in exactly the same way. * * FLIP TO `true` WHEN: one real two-party call has been observed on a deployed build - hear the * other person, see your own tile, watch the camera light go out on Leave, and (the two fixes above) * confirm an audio-only participant does NOT read as "waiting" and that leaving the encounter mid-call * still leaves a way out. * * ** IS DONE - the prerequisite that used to sit here is CLEARED** (Spencer picked option (a) * on 2026-08-02: the client names a `teamId`). `findTeamForPatient` and its tiebreaker-free GSI query * are gone from the invite path; the practitioner picks which of the patient's teams to pull in, and the * server pins the named team to the encounter's subject before notifying anybody - refusing "not this * patient's team" byte-identically to "no such team" so the caller-supplied id is not an existence * oracle. The server half is COMMITTED, NOT DEPLOYED: `git push origin dev` is what deploys it, so * confirm the invite route is live before relying on this in a smoke. * * **THAT TWO-PARTY CALL IS NOW ACTUALLY REACHABLE.** Until Task 13 nothing called `joinAvailable()`, * so there was no way for a second person to get INTO a meeting from the UI - the condition on this * flag could not have been met even in principle. The banner is what closes that. * * ## HOW TO ACTUALLY RUN THAT CALL - this flag is a SHIP gate, not a TEST gate * * Read on its own, the condition above looks circular: the observation needs a call, and the flag * shuts every door a call could come through (claude-4 read it exactly that way on 2026-08-02, and the * omission was mine). It is not circular - the wording just never said how, so it says it now. * * **The smoke runs on a TEMPORARY, UNCOMMITTED flip.** Set this to `true`, have Spencer run the * human-gated build + `deploy:local`, run the call, then decide: * - it works commit the flip **together with** the two gate tests below, and put the browser * evidence in the commit message. That is the whole point of the gate tests: the flip cannot be * quiet. * - it does not restore the one file (from a COPY - never `git checkout --` in this repo, * ) and nothing was ever claimed. * A plugin build compiles source and runs no tests, so a red suite never blocks the build - but it * WILL red, deliberately: `EncounterVideoPane.gate.test.tsx` asserts the OFF default and * `AvailableMeetingBanner.gate.test.tsx` does the same for the JOIN half (3 tests total). That is the * tripwire working, not a break. * **Say so on the session board before flipping.** An uncommitted flag flip is invisible to every * other session, and this board has been bitten by state that lived in exactly one working tree. * * This is already the codebase's idiom, not a new workflow: `EncounterVideoPane.test.tsx` and * `AvailableMeetingBanner.test.tsx` mock this module ON to describe the behaviour, while their `.gate` * counterparts render against the real OFF value. Exercise on, ship off. */ export const TELEHEALTH_VIDEO_ENABLED = true;