import type { Address, Location } from "fhir/r4"; import { writeThroughViewer } from "./writeThroughHold"; import { isSiteLocation } from "./roomLocation"; import type { SiteLocationDraft } from "./newSiteLocation"; // A receiving practice's first office: one resource at an id its practice alone names, so a lost answer, a reload or a // second tab can only ever find that same office. The server freezes what it was created for on the office itself; the // session copy below only saves retyping, and is never taken as proof of anything. export const FIRST_OFFICE_CLAIM_URL = "https://akashichealthrecords.com/fhir/StructureDefinition/first-office-claim"; /** The practice primary as it stood when the office was confirmed; making it primary is conditioned on exactly this. */ export type OfficeBasis = { orgVersionId: string; address0: Address | null }; export type FirstOfficeAnswer = | { state: "committed"; operationId: string; location: Location; primary: OfficeBasis | null } | { state: "mismatch"; location: Location } | { state: "unconfirmed" } | { state: "archived" } | { state: "held" } | { state: "none" }; /** What the server froze on a first office: its operation and the primary basis, or nothing when it carries no claim. */ export const officeClaimOf = (location: Location | undefined): { operationId: string; primary: OfficeBasis | null } | undefined => { const raw = location?.extension?.find((entry) => entry.url === FIRST_OFFICE_CLAIM_URL)?.valueString; if (!raw) return undefined; try { const claim = JSON.parse(raw) as { operationId?: unknown; primary?: OfficeBasis | null }; if (typeof claim.operationId !== "string") return undefined; const primary = claim.primary && typeof claim.primary.orgVersionId === "string" ? claim.primary : null; return { operationId: claim.operationId, primary }; } catch { return undefined; } }; /** Whether a Location can stand as the practice's office: its own, active (or unstated) and a site, never a room or the * virtual location. A claim on it does not make up for any of these. */ export const isEligibleOffice = (location: Location | undefined, practiceId: string | undefined): location is Location => Boolean(location && practiceId) && location!.managingOrganization?.reference === `Organization/${practiceId}` && (location!.status ?? "active") === "active" && isSiteLocation(location!); /** The office being created in this session: its operation, the frozen entries and whether it is to become primary. */ export type OfficeHold = { operationId: string; makePrimary: boolean; draft: SiteLocationDraft }; const STORAGE_KEY = "akashic.receivingOffice"; const keyOf = (practiceId: string) => practiceId + "|" + (writeThroughViewer() ?? "nobody"); const readAll = (): Record => { try { const parsed = JSON.parse(sessionStorage.getItem(STORAGE_KEY) ?? "{}"); return parsed && typeof parsed === "object" ? parsed : {}; } catch { return {}; } }; const writeAll = (holds: Record) => { try { sessionStorage.setItem(STORAGE_KEY, JSON.stringify(holds)); } catch { // Storage is a convenience: without it a reload re-reads the office from the server. } }; /** This practice and viewer's own office in progress, if this session holds one. */ export const readOfficeHold = (practiceId: string): OfficeHold | undefined => { const hold = readAll()[keyOf(practiceId)]; return hold && typeof hold.operationId === "string" && hold.draft ? hold : undefined; }; export const holdOffice = (practiceId: string, hold: OfficeHold): void => writeAll({ ...readAll(), [keyOf(practiceId)]: hold }); export const releaseOffice = (practiceId: string, operationId: string): void => { const holds = readAll(); if (holds[keyOf(practiceId)]?.operationId !== operationId) return; delete holds[keyOf(practiceId)]; writeAll(holds); };