import { STAFF_WORKSPACES } from './staffRoleCatalog.ts'; import { PLATFORM_MANAGER_LANDING } from './platformManagerWorkspace.ts'; import { workspaceWorksTheBench, workspaceWorksTheDiagnosticQueue } from './diagnosticOrderQueue.ts'; /** * WHERE A WORKSPACE LANDS, ANSWERED IN ONE PLACE. * * There were two of these and they had drifted. `DashboardPage` held the one the workspace switcher * and the single-workspace sign-in landing use; `HomePageRedirect` in `App.tsx` held a second copy, * reached by anybody who asks for `/dashboard` - which is what the dashboard's own index route does, * so it is the ordinary path rather than an exotic one. * * WHAT THE SECOND COPY WAS MISSING, measured 2026-09-08 by signing in as the imaging technician: * * Referrals no branch * LabTech no branch * ImagingTech no branch * * All three fell through to its `Navigate to="/dashboard/profile"` tail, so the person whose whole job * is the imaging worklist arrived at a form for editing their own name. Nothing was unreachable and no * guard refused anything - one of two answers to one question simply had three fewer answers. * * AND THE TWO DISAGREED ABOUT A FOURTH. The Platform Manager's landing moved from the questionnaire * library to Portal pages in the copy that was maintained; the other copy still said `questionnaires`. * * MARKETING HAD NO BRANCH IN EITHER COPY until the marketing navigation deck decided it: "Campaigns * first", every board opening on Dashboard > Campaigns. * * PURE, AND KEYED ON THE WORKSPACE STRING, so both callers reach it without either importing the * other's context. `STAFF_WORKSPACES` and `USER_ROLES` carry identical literals for every workspace, * and this reads the one that is a plain constant rather than a value handed out by a service. */ /** * `undefined` when this build has no landing for that workspace, which is a DIFFERENT answer from * Profile even though Profile is what most callers do with it. * * The two callers part company exactly there. The dashboard sends an unknown workspace to Profile; * `HomePageRedirect` sends a staff-mounted Practitioner to Profile and everybody else to the patient * home. Collapsing that into a single Profile tail while unifying these lists would have quietly * moved somebody with a stale stored workspace off the patient home, which is nobody's card. */ export const defaultDashboardPathFor = (workspace: string | undefined): string | undefined => { if (workspace === STAFF_WORKSPACES.ADMIN) return '/dashboard/organization'; if (workspace === STAFF_WORKSPACES.RECEPTIONIST) return '/dashboard/receptionist'; if (workspace === STAFF_WORKSPACES.PRACTITIONER) return '/dashboard/overview'; // This workspace has NO DASHBOARD by design (it is set-up-then-forget: an agency configures a // practice once and returns occasionally to change one thing, so a landing page summarising state // would be read once and then be wrong for a year), so the landing IS its most-used destination. // That is Portal pages: the one REQUIRED onboarding task this hat can complete, and a practice // whose portal pages are unmapped can never finish setup. if (workspace === STAFF_WORKSPACES.PLATFORM_MANAGER) return PLATFORM_MANAGER_LANDING; if (workspace === STAFF_WORKSPACES.GENERIC) return '/dashboard/profile'; if (workspace === STAFF_WORKSPACES.BILLING) return '/dashboard/billing'; if (workspace === STAFF_WORKSPACES.HR) return '/dashboard/staff'; if (workspace === STAFF_WORKSPACES.REFERRALS) return '/dashboard/referrals'; if (workspace === STAFF_WORKSPACES.RECORDS) return '/dashboard/records'; if (workspace === STAFF_WORKSPACES.MARKETING) return '/dashboard/campaigns'; // THE BENCH IS THE JOB FOR THE LABORATORY HAT, so it is where that hat lands. It is checked // first because it is the narrower of the two: a lab technologist works by specimen, and the // order queue is the practice-wide question they look at second. if (workspaceWorksTheBench(workspace)) { return '/dashboard/bench'; } // The queue IS the job for the imaging hat, which has no specimens and therefore no bench until // its own department is built. A workspace with no branch here lands on Profile, which for these // hats is a page they never want. // // THE SAME EXPRESSIONS THE RAIL READS, not a second list saying the same thing. Landing somebody // on a screen their rail does not offer, or offering a row the landing never reaches, is one // fact written twice - which this pair has already done once. if (workspaceWorksTheDiagnosticQueue(workspace)) { return '/dashboard/diagnostic-orders'; } return undefined; }; /** The same answer with the dashboard's own tail applied: an unknown workspace lands on Profile. */ export const getDefaultDashboardPath = (workspace: string | undefined): string => defaultDashboardPathFor(workspace) ?? '/dashboard/profile';