From 1e1d093db65275af247763aa6026662b529ef782 Mon Sep 17 00:00:00 2001 From: classikdev Date: Fri, 16 Oct 2026 14:53:27 +0100 Subject: [PATCH 1/5] feat(patient): patient home as a care hub: what needs my attention now Ranks the dependents and health-profile data already available into Action needed / Coming up / Recent, fetches every source in parallel, and degrades one failing source to its own notice instead of blanking the hub. A source that cannot be queried yet (no care profile selected) reports unavailable rather than loading, so the screen no longer spins forever, and is never read as an empty profile. Sections for unbuilt features stay hidden; Coming up waits on #3. Closes #33 --- ARCHITECTURE_ESSENTIALS.md | 30 ++++ ROADMAP.md | 28 +++ .../components/CareCardList.module.css | 57 ++++++ .../care-hub/components/CareCardList.tsx | 25 +++ src/features/care-hub/hooks/useCareHub.ts | 118 +++++++++++++ src/features/care-hub/ranking.test.ts | 64 +++++++ src/features/care-hub/ranking.ts | 33 ++++ src/pages/PatientDashboardPage.module.css | 46 +++++ src/pages/PatientDashboardPage.test.tsx | 166 ++++++++++++++++++ src/pages/PatientDashboardPage.tsx | 58 +++++- 10 files changed, 620 insertions(+), 5 deletions(-) create mode 100644 src/features/care-hub/components/CareCardList.module.css create mode 100644 src/features/care-hub/components/CareCardList.tsx create mode 100644 src/features/care-hub/hooks/useCareHub.ts create mode 100644 src/features/care-hub/ranking.test.ts create mode 100644 src/features/care-hub/ranking.ts create mode 100644 src/pages/PatientDashboardPage.module.css create mode 100644 src/pages/PatientDashboardPage.test.tsx diff --git a/ARCHITECTURE_ESSENTIALS.md b/ARCHITECTURE_ESSENTIALS.md index 80f2be3..5965c1e 100644 --- a/ARCHITECTURE_ESSENTIALS.md +++ b/ARCHITECTURE_ESSENTIALS.md @@ -101,6 +101,36 @@ No new backend endpoint. The switcher is client-only UI state (Zustand store). Every patient API call and React Query key includes the selected `patientProfileId` so caches never mix profiles. +### Care hub — patient home (#33) +No new backend endpoint and no new assumed shape. The hub is a +client-side aggregation over the two contracts above — +`GET /patients/me/dependents` and `GET /patients/:profileId/health/:section` +— ranked into sections in `src/features/care-hub/ranking.ts`. The derived +`CareCard` is deliberately a presentation-only type (it exists in the +browser and is never sent to or received from `docforum-core`), so it does +not violate hard rule 2. + +Two things the issues ask for are not yet wired because their backend +contract does not exist here: +- **There is no way to learn the signed-in patient's own `patientProfileId`.** + `#20`'s profile store is populated only by tests — no response in this + repo carries an `ActingProfile`, and `User` has no profile id — so + `selectedProfileId` is `null` in a real session and every health-profile + query stays disabled. That is a `docforum-core` gap to file (hard rule 1), + not something to paper over by assuming `profileId === userId`. The care + hub reports such a source as `unavailable` rather than loading or failed, + so the screen renders the cards it *can* derive instead of spinning + forever, and never reads "we could not ask" as "you have nothing saved". + The health editor and dependents screens have the same dependency. +- **"Coming up"** (upcoming appointments) waits on the `GET /appointments/mine` + list from issue #3, which is not built in this repo yet. The section + renders nothing until a card source for it lands, rather than showing an + empty appointments-shaped shell. +- **Referrals awaiting acceptance, orders needing a facility, results + ready, waitlist offers, follow-ups** wait on `docforum-core`#5–#16 + (see issues #4 and #5 here). Each will contribute its own card source + when that lands. + ## Roadmap / status See `ROADMAP.md` in this repo, and Phase 7 in `docforum-core`'s `ROADMAP.md` for the original (pre-split) frontend phase this was carved diff --git a/ROADMAP.md b/ROADMAP.md index c40a727..13d00b5 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -43,6 +43,11 @@ real API" (no refresh-on-reload flow). - [x] Dependents management for guardians. Tracked as [issue #19](https://github.com/DocForum/docforum-web/issues/19) (High, 200 pts) — assumed contract against `docforum-core` issue #42. - [x] Acting-for profile switcher: book and view records on behalf of a dependent. Tracked as [issue #20](https://github.com/DocForum/docforum-web/issues/20) (High, 200 pts) — client-only UI state (Zustand), threads `patientProfileId` through API calls and query keys. - [x] Guardian consent and age-of-majority handover screens. Tracked as [issue #21](https://github.com/DocForum/docforum-web/issues/21) (High, 200 pts) — assumed contract against `docforum-core` issue #42. +- [x] Patient home as a care hub: action-first dashboard ranking what needs + attention now. Tracked as [issue #33](https://github.com/DocForum/docforum-web/issues/33) (High, 200 pts) — no new backend contract; aggregates the + dependents and health-profile endpoints above. Its "Coming up" section + stays hidden until [issue #3](https://github.com/DocForum/docforum-web/issues/3) (my appointments list) lands, which this issue lists as a + soft dependency. ## Phase W3 — Doctor core flow **Fully scoped into issues #6–#7.** @@ -316,3 +321,26 @@ real API" (no refresh-on-reload flow). (`/patient/dependents`, `/patient/health`, `/claim-account`). Profile switcher in header, acting-for banner on patient pages. Tests for every new component. +- 2026-10-16 — Rebuilt `PatientDashboardPage` from a placeholder into the + patient care hub ([issue #33](https://github.com/DocForum/docforum-web/issues/33)): `src/features/care-hub/` holds a pure + ranking module (`ranking.ts`) plus `useCareHub`, which fans out to the + existing dependents and health-profile queries in parallel and turns + their results into cards ranked `blocked now → needs you → good to know`, + with a 30-day "Recent" window. One failing source degrades its own + section instead of blanking the page, and a health section that *errored* + is never reported to the patient as an empty profile. Sections for + unbuilt features are hidden, not stubbed — "Coming up" appears only once + [#3](https://github.com/DocForum/docforum-web/issues/3) + supplies appointment cards. Adds `src/features/care-hub/ranking.test.ts` + and `src/pages/PatientDashboardPage.test.tsx`; 56 tests pass (was 44), + typecheck and build green. +- 2026-10-16 — Verified the three other assigned W2 issues against the + current code and backend: #32 (check-in + live queue position), #34 + ("who viewed my records" access log) and #37 (payment history and + receipts) each need a `docforum-core` endpoint that does not exist yet — + no check-in/queue route, no access-log route, and + `src/services/payments-service.ts` can create/read/fund a single + `PaymentIntent` by id but has no list-the-patient's-payments route. Per + hard rule 1 these are API gaps to file against `docforum-core`, not + shapes to invent here, so they stay unimplemented rather than built on a + fabricated contract. diff --git a/src/features/care-hub/components/CareCardList.module.css b/src/features/care-hub/components/CareCardList.module.css new file mode 100644 index 0000000..14f13a1 --- /dev/null +++ b/src/features/care-hub/components/CareCardList.module.css @@ -0,0 +1,57 @@ +.list { + display: flex; + flex-direction: column; + gap: var(--space-3); + list-style: none; + margin: 0; + padding: 0; +} + +.card { + display: flex; + flex-direction: column; + gap: var(--space-2); + padding: var(--space-4); + border-radius: var(--radius-md); + border: 1px solid var(--color-border); + background: var(--color-bg-raised); + color: inherit; + text-decoration: none; +} + +.card:hover { + background: var(--color-surface-hover); +} + +.card:focus-visible { + outline: 2px solid var(--color-focus-ring); + outline-offset: 2px; +} + +.head { + display: flex; + align-items: center; + gap: var(--space-3); + flex-wrap: wrap; +} + +.title { + font-family: var(--font-display); + font-size: var(--text-base); + color: var(--color-text); +} + +.badge { + font-size: var(--text-xs); + font-weight: 600; + padding: 2px var(--space-2); + border-radius: var(--radius-full); + background: var(--color-warning-surface); + color: var(--color-warning); +} + +.detail { + font-size: var(--text-sm); + color: var(--color-text-muted); + line-height: var(--leading-normal); +} diff --git a/src/features/care-hub/components/CareCardList.tsx b/src/features/care-hub/components/CareCardList.tsx new file mode 100644 index 0000000..b287367 --- /dev/null +++ b/src/features/care-hub/components/CareCardList.tsx @@ -0,0 +1,25 @@ +import { Link } from 'react-router-dom'; +import type { CareCard } from '../ranking'; +import styles from './CareCardList.module.css'; + +interface Props { + cards: CareCard[]; +} + +export function CareCardList({ cards }: Props) { + return ( + + ); +} diff --git a/src/features/care-hub/hooks/useCareHub.ts b/src/features/care-hub/hooks/useCareHub.ts new file mode 100644 index 0000000..0d62221 --- /dev/null +++ b/src/features/care-hub/hooks/useCareHub.ts @@ -0,0 +1,118 @@ +import { useDependents } from '../../dependents/hooks/useDependents'; +import { useHealthEntries } from '../../health-profile/hooks/useHealthEntries'; +import { useAuthStore } from '../../../store/auth-store'; +import { useProfileStore } from '../../../store/profile-store'; +import { PRIORITY, type CareCard } from '../ranking'; + +const RECENT_WINDOW_DAYS = 30; + +export interface SourceStatus { + isLoading: boolean; + failed: boolean; + /** The request cannot even be made yet (no session, no profile selected), + * which is not the same as loading and not the same as failed. */ + unavailable: boolean; +} + +export interface CareHub { + cards: CareCard[]; + sources: { dependents: SourceStatus; health: SourceStatus }; +} + +/** A handover invite with no expiry sent by the backend is not the same thing + * as an expired one, so absence must not read as "blocked". */ +function inviteExpired(expiresAt?: string): boolean { + return Boolean(expiresAt && new Date(expiresAt) < new Date()); +} + +export function useCareHub(now: Date = new Date()): CareHub { + const accessToken = useAuthStore((state) => state.accessToken); + const profileId = useProfileStore((state) => state.selectedProfileId); + const dependents = useDependents(); + const allergies = useHealthEntries('allergies'); + const conditions = useHealthEntries('conditions'); + const medications = useHealthEntries('medications'); + const healthQueries = [allergies, conditions, medications]; + + const dependentsUnavailable = !accessToken; + const healthUnavailable = !accessToken || !profileId; + + const healthEntries = healthQueries.flatMap((query) => query.data ?? []); + const healthSettled = healthQueries.every((query) => !query.isPending); + const healthFailed = healthQueries.some((query) => query.isError); + + const cards: CareCard[] = []; + + for (const dependent of dependents.data ?? []) { + if (dependent.handoverStatus === 'invited' && inviteExpired(dependent.claimInviteExpiresAt)) { + cards.push({ + id: `handover-expired-${dependent.id}`, + section: 'action', + priority: PRIORITY.blockedNow, + title: `Resend ${dependent.fullName}'s invite`, + detail: 'Their handover invite expired before they claimed it, so they still cannot manage their own record.', + to: '/patient/dependents', + badge: 'Invite expired', + }); + } else if (dependent.handoverStatus === 'eligible') { + cards.push({ + id: `handover-eligible-${dependent.id}`, + section: 'action', + priority: PRIORITY.needsYou, + title: `Start ${dependent.fullName}'s handover`, + detail: 'They are approaching the age where they can manage their own health record.', + to: '/patient/dependents', + }); + } + } + + // Only claim the profile is empty once every section answered successfully — + // a failed request would otherwise be reported to the patient as missing care + // data they may well have already entered. + if (dependents.isSuccess && healthSettled && !healthFailed && healthEntries.length === 0) { + cards.push({ + id: 'health-profile-empty', + section: 'action', + priority: PRIORITY.goodToKnow, + title: 'Add your allergies, conditions and medications', + detail: 'Doctors see these at every consult. Yours are all still empty.', + to: '/patient/health', + }); + } + + for (const entry of healthEntries) { + const updated = new Date(entry.updatedAt); + if (Number.isNaN(updated.getTime())) continue; + if (updated.getTime() > now.getTime() - RECENT_WINDOW_DAYS * 24 * 60 * 60 * 1000) { + cards.push({ + id: `health-updated-${entry.id}`, + section: 'recent', + priority: PRIORITY.recent, + title: `${entry.name} updated`, + detail: `Your ${entry.section} list changed on ${formatDate(entry.updatedAt)}.`, + to: '/patient/health', + }); + } + } + + return { + cards, + sources: { + dependents: { + isLoading: !dependentsUnavailable && dependents.isPending, + failed: !dependentsUnavailable && dependents.isError, + unavailable: dependentsUnavailable, + }, + health: { + isLoading: !healthUnavailable && healthQueries.some((query) => query.isPending), + failed: !healthUnavailable && healthFailed, + unavailable: healthUnavailable, + }, + }, + }; +} + +function formatDate(iso: string): string { + const date = new Date(iso); + return Number.isNaN(date.getTime()) ? iso : date.toLocaleDateString(); +} diff --git a/src/features/care-hub/ranking.test.ts b/src/features/care-hub/ranking.test.ts new file mode 100644 index 0000000..b8037c0 --- /dev/null +++ b/src/features/care-hub/ranking.test.ts @@ -0,0 +1,64 @@ +import { describe, expect, it } from 'vitest'; +import { groupBySection, PRIORITY, rankCards, type CareCard } from './ranking'; + +function card(overrides: Partial): CareCard { + return { + id: overrides.id ?? 'card', + section: overrides.section ?? 'action', + priority: overrides.priority ?? PRIORITY.needsYou, + title: overrides.title ?? 'Card', + detail: 'detail', + to: '/patient', + ...overrides, + }; +} + +describe('rankCards', () => { + it('sorts by ascending priority so the most urgent action is first', () => { + const ranked = rankCards([ + card({ id: 'later', priority: PRIORITY.goodToKnow, title: 'Add allergies' }), + card({ id: 'urgent', priority: PRIORITY.blockedNow, title: 'Resend invite' }), + card({ id: 'middle', priority: PRIORITY.needsYou, title: 'Start handover' }), + ]); + + expect(ranked.map((c) => c.id)).toEqual(['urgent', 'middle', 'later']); + }); + + it('breaks priority ties alphabetically for a stable order', () => { + const ranked = rankCards([ + card({ id: 'zoe', title: 'Zoe', priority: PRIORITY.needsYou }), + card({ id: 'amy', title: 'Amy', priority: PRIORITY.needsYou }), + ]); + + expect(ranked.map((c) => c.title)).toEqual(['Amy', 'Zoe']); + }); + + it('does not mutate the input', () => { + const input = [card({ id: 'b', priority: 2 }), card({ id: 'a', priority: 1 })]; + + rankCards(input); + + expect(input.map((c) => c.id)).toEqual(['b', 'a']); + }); +}); + +describe('groupBySection', () => { + it('splits cards into the three hub sections, each ranked', () => { + const grouped = groupBySection([ + card({ id: 'r2', section: 'recent', priority: PRIORITY.recent, title: 'B' }), + card({ id: 'a1', section: 'action', priority: PRIORITY.needsYou, title: 'A' }), + card({ id: 'r1', section: 'recent', priority: PRIORITY.recent, title: 'A' }), + card({ id: 'u1', section: 'upcoming', priority: PRIORITY.needsYou, title: 'U' }), + ]); + + expect(grouped.action.map((c) => c.id)).toEqual(['a1']); + expect(grouped.upcoming.map((c) => c.id)).toEqual(['u1']); + expect(grouped.recent.map((c) => c.id)).toEqual(['r1', 'r2']); + }); + + it('returns empty arrays rather than omitting sections with no cards', () => { + const grouped = groupBySection([]); + + expect(grouped).toEqual({ action: [], upcoming: [], recent: [] }); + }); +}); diff --git a/src/features/care-hub/ranking.ts b/src/features/care-hub/ranking.ts new file mode 100644 index 0000000..aec350e --- /dev/null +++ b/src/features/care-hub/ranking.ts @@ -0,0 +1,33 @@ +export type CareSection = 'action' | 'upcoming' | 'recent'; + +export interface CareCard { + id: string; + section: CareSection; + /** Lower sorts first: the hub answers "what do I do next", so the most + * time-critical thing the patient can still act on ranks highest. */ + priority: number; + title: string; + detail: string; + to: string; + badge?: string; +} + +export const PRIORITY = { + blockedNow: 10, + needsYou: 20, + goodToKnow: 30, + recent: 40, +} as const; + +export function rankCards(cards: CareCard[]): CareCard[] { + return [...cards].sort((a, b) => (a.priority - b.priority) || a.title.localeCompare(b.title)); +} + +export function groupBySection(cards: CareCard[]): Record { + const ranked = rankCards(cards); + return { + action: ranked.filter((card) => card.section === 'action'), + upcoming: ranked.filter((card) => card.section === 'upcoming'), + recent: ranked.filter((card) => card.section === 'recent'), + }; +} diff --git a/src/pages/PatientDashboardPage.module.css b/src/pages/PatientDashboardPage.module.css new file mode 100644 index 0000000..289bb38 --- /dev/null +++ b/src/pages/PatientDashboardPage.module.css @@ -0,0 +1,46 @@ +.title { + text-wrap: balance; +} + +.heading { + font-family: var(--font-display); + font-size: var(--text-lg); + color: var(--color-text); + margin: var(--space-6) 0 var(--space-3); +} + +.loading { + font-size: var(--text-sm); + color: var(--color-text-faint); + margin: var(--space-3) 0 0; +} + +.sourceError { + font-size: var(--text-sm); + color: var(--color-text-muted); + background: var(--color-warning-surface); + border-radius: var(--radius-sm); + padding: var(--space-3); + margin: var(--space-3) 0; +} + +.empty { + font-size: var(--text-sm); + color: var(--color-text-muted); + margin: 0; +} + +.links { + display: flex; + gap: var(--space-4); + margin-top: var(--space-6); +} + +/* Same breakpoint HomePage uses — at phone width the two links each wrapped + onto two lines side by side, which reads as a broken row. */ +@media (max-width: 760px) { + .links { + flex-direction: column; + gap: var(--space-3); + } +} diff --git a/src/pages/PatientDashboardPage.test.tsx b/src/pages/PatientDashboardPage.test.tsx new file mode 100644 index 0000000..4619672 --- /dev/null +++ b/src/pages/PatientDashboardPage.test.tsx @@ -0,0 +1,166 @@ +import { beforeEach, describe, expect, it, vi } from 'vitest'; +import { render, screen, within } from '../test/render'; +import { PatientDashboardPage } from './PatientDashboardPage'; +import { useAuthStore } from '../store/auth-store'; +import { useProfileStore } from '../store/profile-store'; +import type { Dependent, HealthEntry, HealthSectionKey } from '../types/models'; +import * as dependentsService from '../services/dependents-service'; +import * as healthService from '../services/health-profile-service'; + +vi.mock('../services/dependents-service'); +vi.mock('../services/health-profile-service'); + +const DAY_MS = 24 * 60 * 60 * 1000; + +function dependent(overrides: Partial): Dependent { + return { + id: 'dep-1', + guardianProfileId: 'gp-1', + fullName: 'Child One', + dateOfBirth: '2012-05-15', + relationship: 'parent', + handoverStatus: 'not_eligible', + createdAt: '2026-01-01T00:00:00Z', + updatedAt: '2026-01-01T00:00:00Z', + ...overrides, + }; +} + +function entry(overrides: Partial): HealthEntry { + return { + id: 'he-1', + patientProfileId: 'pp-1', + section: 'allergies', + name: 'Penicillin', + version: 1, + updatedAt: new Date(Date.now() - 2 * DAY_MS).toISOString(), + createdAt: '2026-01-01T00:00:00Z', + ...overrides, + }; +} + +/** Every section resolves to the same list unless a section map is given, so + * tests describe only the data they care about. */ +function mockHealth(bySection: Partial> = {}) { + vi.mocked(healthService.listHealthEntries).mockImplementation((_profileId, section) => { + const value = bySection[section] ?? []; + return value instanceof Error ? Promise.reject(value) : Promise.resolve(value); + }); +} + +describe('PatientDashboardPage care hub', () => { + beforeEach(() => { + useAuthStore.setState({ accessToken: 'test-token', user: null }); + useProfileStore.setState({ profiles: [{ id: 'pp-1', fullName: 'Self', isSelf: true }], selectedProfileId: 'pp-1' }); + vi.mocked(dependentsService.listDependents).mockReset(); + vi.mocked(healthService.listHealthEntries).mockReset(); + }); + + it('ranks an expired handover invite above a not-yet-blocked one', async () => { + vi.mocked(dependentsService.listDependents).mockResolvedValue([ + dependent({ id: 'dep-2', fullName: 'Child Two', handoverStatus: 'eligible' }), + dependent({ + id: 'dep-1', + fullName: 'Amara', + handoverStatus: 'invited', + claimEmail: 'amara@example.test', + claimInviteExpiresAt: new Date(Date.now() - DAY_MS).toISOString(), + }), + ]); + mockHealth({ allergies: [entry({})] }); + + render(); + + const actionHeading = await screen.findByRole('heading', { name: 'Action needed' }); + const actionSection = actionHeading.parentElement as HTMLElement; + await within(actionSection).findByText(/Resend Amara's invite/i); + const cards = within(actionSection).getAllByRole('link'); + expect(cards[0]).toHaveTextContent(/Resend Amara's invite/i); + expect(cards[1]).toHaveTextContent(/Start Child Two's handover/i); + expect(within(actionSection).getByText('Invite expired')).toBeInTheDocument(); + }); + + it('prompts for a health profile that is genuinely empty', async () => { + vi.mocked(dependentsService.listDependents).mockResolvedValue([]); + mockHealth(); + + render(); + + expect(await screen.findByText(/Add your allergies, conditions and medications/i)).toBeInTheDocument(); + }); + + it('does not call a profile empty when a health section failed to load', async () => { + vi.mocked(dependentsService.listDependents).mockResolvedValue([]); + mockHealth({ conditions: new Error('offline') }); + + render(); + + await screen.findByText(/could not be loaded/i); + expect(screen.queryByText(/Add your allergies, conditions and medications/i)).not.toBeInTheDocument(); + }); + + it('keeps rendering the rest of the hub when one source fails', async () => { + vi.mocked(dependentsService.listDependents).mockResolvedValue([ + dependent({ handoverStatus: 'eligible' }), + ]); + mockHealth({ medications: new Error('offline') }); + + render(); + + expect(await screen.findByText(/Start Child One's handover/i)).toBeInTheDocument(); + expect(screen.getByText(/could not be loaded/i)).toBeInTheDocument(); + }); + + it('renders the dependent cards instead of an endless spinner while no care profile is selected', async () => { + useProfileStore.setState({ profiles: [], selectedProfileId: null }); + vi.mocked(dependentsService.listDependents).mockResolvedValue([ + dependent({ handoverStatus: 'eligible' }), + ]); + mockHealth(); + + render(); + + expect(await screen.findByText(/Start Child One's handover/i)).toBeInTheDocument(); + expect(screen.queryByText(/Loading your care summary/i)).not.toBeInTheDocument(); + // Nothing was fetched, so nothing was fetched-and-found-empty either: the + // hub must not read a profile with no health data as an empty one. + expect(healthService.listHealthEntries).not.toHaveBeenCalled(); + expect(screen.queryByText(/Add your allergies, conditions and medications/i)).not.toBeInTheDocument(); + }); + + it('lists a recently updated entry under Recent', async () => { + vi.mocked(dependentsService.listDependents).mockResolvedValue([]); + mockHealth({ allergies: [entry({ id: 'he-9', name: 'Latex' })] }); + + render(); + + expect(await screen.findByText('Latex updated')).toBeInTheDocument(); + expect(screen.getByRole('heading', { name: 'Recent' })).toBeInTheDocument(); + }); + + it('hides the Recent section when nothing changed recently', async () => { + vi.mocked(dependentsService.listDependents).mockResolvedValue([]); + mockHealth({ + conditions: [entry({ id: 'he-old', name: 'Asthma', updatedAt: new Date(Date.now() - 90 * DAY_MS).toISOString() })], + }); + + render(); + + await screen.findByText(/Nothing needs your attention right now/i); + expect(screen.queryByRole('heading', { name: 'Recent' })).not.toBeInTheDocument(); + expect(screen.queryByText('Asthma updated')).not.toBeInTheDocument(); + }); + + it('keeps the detail links reachable from the hub', async () => { + vi.mocked(dependentsService.listDependents).mockResolvedValue([]); + mockHealth({ + conditions: [entry({ id: 'he-settled', name: 'Asthma', updatedAt: new Date(Date.now() - 90 * DAY_MS).toISOString() })], + }); + + render(); + + await screen.findByText(/Nothing needs your attention right now/i); + expect(screen.getByRole('link', { name: /manage dependents/i })).toBeInTheDocument(); + expect(screen.getByRole('link', { name: /health profile/i })).toBeInTheDocument(); + }); +}); diff --git a/src/pages/PatientDashboardPage.tsx b/src/pages/PatientDashboardPage.tsx index 5a623c3..a9c0520 100644 --- a/src/pages/PatientDashboardPage.tsx +++ b/src/pages/PatientDashboardPage.tsx @@ -1,20 +1,68 @@ import { Link, Route, Routes } from 'react-router-dom'; -import { useAuthStore } from '../store/auth-store'; import { ActingForBanner } from '../features/dependents/components/ActingForBanner'; +import { CareCardList } from '../features/care-hub/components/CareCardList'; +import { useCareHub } from '../features/care-hub/hooks/useCareHub'; +import { groupBySection } from '../features/care-hub/ranking'; import { DependentsPage } from './DependentsPage'; import { HealthProfilePage } from './HealthProfilePage'; +import styles from './PatientDashboardPage.module.css'; function PatientHome() { - const user = useAuthStore((state) => state.user); + const { cards, sources } = useCareHub(); + const sections = groupBySection(cards); + + // A source that failed must not blank the hub: its section says so, the + // others still render from the data that did arrive. + const anyLoading = sources.dependents.isLoading || sources.health.isLoading; return (
+
Phase W2 · in progress -

Welcome{user ? `, ${user.email}` : ''}

-

Doctor search, booking, and your appointments will live here — see ROADMAP.md Phase W2.

-
@@ -77,6 +78,7 @@ export function PatientDashboardPage() { } /> } /> } /> + } /> ); } diff --git a/src/pages/PaymentDetailPage.module.css b/src/pages/PaymentDetailPage.module.css new file mode 100644 index 0000000..64535f0 --- /dev/null +++ b/src/pages/PaymentDetailPage.module.css @@ -0,0 +1,27 @@ +.title { + text-wrap: balance; +} + +.loading { + font-size: var(--text-sm); + color: var(--color-text-faint); + margin: var(--space-3) 0 0; +} + +.actions { + display: flex; + flex-wrap: wrap; + align-items: center; + gap: var(--space-4); +} + +.back { + margin: var(--space-6) 0 0; + font-size: var(--text-sm); +} + +@media print { + .noPrint { + display: none; + } +} diff --git a/src/pages/PaymentDetailPage.test.tsx b/src/pages/PaymentDetailPage.test.tsx new file mode 100644 index 0000000..4cbd8f2 --- /dev/null +++ b/src/pages/PaymentDetailPage.test.tsx @@ -0,0 +1,183 @@ +import { beforeEach, describe, expect, it, vi } from 'vitest'; +import userEvent from '@testing-library/user-event'; +import { render as rtlRender, screen, within } from '@testing-library/react'; +import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; +import { MemoryRouter, Route, Routes } from 'react-router-dom'; +import { PaymentDetailPage } from './PaymentDetailPage'; +import * as paymentHistoryService from '../services/payment-history-service'; +import { ApiError } from '../services/api-client'; +import { useAuthStore } from '../store/auth-store'; +import type { PaymentHistoryEntry } from '../types/models'; + +vi.mock('../services/payment-history-service'); + +const TX = 'a'.repeat(64); +const CONTRACT = 'CA'.padEnd(56, 'B'); + +function entry(overrides: Partial = {}): PaymentHistoryEntry { + return { + id: 'pi-1', + orderType: 'prescription', + orderId: 'ord-1', + status: 'escrowed', + patientProfileId: 'pp-1', + facilityId: 'fac-1', + amountStroops: '25000000', + escrowId: '77', + stellarTxHash: TX, + sorobanContractId: CONTRACT, + createdAt: '2026-10-01T10:00:00Z', + updatedAt: '2026-10-01T10:00:00Z', + ...overrides, + }; +} + +function renderAt(path: string) { + const queryClient = new QueryClient({ + defaultOptions: { queries: { retry: false }, mutations: { retry: false } }, + }); + return rtlRender( + + + + } /> + + + , + ); +} + +describe('PaymentDetailPage', () => { + beforeEach(() => { + useAuthStore.setState({ accessToken: 'test-token', user: null }); + vi.mocked(paymentHistoryService.getPaymentHistoryEntry).mockReset(); + window.print = vi.fn(); + }); + + it('prints a receipt that is still verifiable on paper', async () => { + vi.mocked(paymentHistoryService.getPaymentHistoryEntry).mockResolvedValue(entry()); + + const { container } = renderAt('/payments/pi-1'); + + const receipt = await screen.findByTestId('payment-receipt'); + // The status word appears twice on this page (the pill above the receipt + // and the line inside it), so the receipt itself is the scope here. + expect(within(receipt).getByText('2.5 XLM')).toBeInTheDocument(); + expect(within(receipt).getByText('Held in escrow')).toBeInTheDocument(); + // The hashes have to be readable text, not only hrefs, or a printed + // receipt proves nothing to whoever receives it. + expect(within(receipt).getByText(TX)).toBeInTheDocument(); + expect(within(receipt).getByText(CONTRACT)).toBeInTheDocument(); + // …and the internal pointers a patient cannot act on stay off it. + expect(container.textContent).not.toMatch(/fac-1|ord-1|pp-1/); + }); + + it('links the explorer from the page chrome, never the printed copy', async () => { + vi.mocked(paymentHistoryService.getPaymentHistoryEntry).mockResolvedValue(entry()); + + renderAt('/payments/pi-1'); + + const txLink = await screen.findByRole('link', { name: 'transaction' }); + expect(txLink).toHaveAttribute('href', `https://testnet.stellar.expert/explorer/public/transaction/${TX}`); + expect(txLink).toHaveAttribute('target', '_blank'); + expect(txLink).toHaveAttribute('rel', 'noopener noreferrer'); + + const contractLink = screen.getByRole('link', { name: 'escrow contract' }); + expect(contractLink).toHaveAttribute('href', `https://testnet.stellar.expert/explorer/public/contract/${CONTRACT}`); + expect(contractLink).toHaveAttribute('rel', 'noopener noreferrer'); + }); + + it('does not offer to print a receipt that was never fetched', async () => { + vi.mocked(paymentHistoryService.getPaymentHistoryEntry).mockResolvedValue(entry()); + + renderAt('/payments/pi-1'); + + await screen.findByTestId('payment-receipt'); + await userEvent.click(screen.getByRole('button', { name: /print receipt/i })); + expect(window.print).toHaveBeenCalledTimes(1); + }); + + it('says there is nothing to verify before the payment is on-chain', async () => { + vi.mocked(paymentHistoryService.getPaymentHistoryEntry).mockResolvedValue( + entry({ stellarTxHash: null, sorobanContractId: null }), + ); + + renderAt('/payments/pi-1'); + + expect(await screen.findByText(/no on-chain transaction yet/i)).toBeInTheDocument(); + expect(screen.queryByRole('link', { name: 'transaction' })).not.toBeInTheDocument(); + }); + + it('explains what each status means for the money', async () => { + vi.mocked(paymentHistoryService.getPaymentHistoryEntry).mockResolvedValue( + entry({ status: 'released' }), + ); + + renderAt('/payments/pi-1'); + + expect(await screen.findByText(/the money was released to the facility/i)).toBeInTheDocument(); + }); + + it('shows a refund window that is still open', async () => { + vi.mocked(paymentHistoryService.getPaymentHistoryEntry).mockResolvedValue( + entry({ + status: 'released', + refundDeadlineAt: new Date(Date.now() + 5 * 24 * 60 * 60 * 1000).toISOString(), + }), + ); + + renderAt('/payments/pi-1'); + + expect(await screen.findByText(/can still be refunded until/i)).toBeInTheDocument(); + }); + + it('shows a refund window that has already closed', async () => { + vi.mocked(paymentHistoryService.getPaymentHistoryEntry).mockResolvedValue( + entry({ + refundDeadlineAt: new Date(Date.now() - 24 * 60 * 60 * 1000).toISOString(), + }), + ); + + renderAt('/payments/pi-1'); + + expect(await screen.findByText(/the refund window closed on/i)).toBeInTheDocument(); + }); + + it('omits the refund window entirely when the response has none', async () => { + vi.mocked(paymentHistoryService.getPaymentHistoryEntry).mockResolvedValue(entry()); + + renderAt('/payments/pi-1'); + + await screen.findByTestId('payment-receipt'); + expect(screen.queryByText(/refund window/i)).not.toBeInTheDocument(); + }); + + it('labels a lab order as a lab order', async () => { + vi.mocked(paymentHistoryService.getPaymentHistoryEntry).mockResolvedValue( + entry({ orderType: 'lab_order' }), + ); + + renderAt('/payments/pi-1'); + + expect(await screen.findByText('Lab order')).toBeInTheDocument(); + }); + + it('says the receipt is unavailable rather than showing an empty one', async () => { + vi.mocked(paymentHistoryService.getPaymentHistoryEntry).mockRejectedValue(new ApiError('Not Found', 404)); + + renderAt('/payments/pi-1'); + + expect(await screen.findByText(/not available for this deployment yet/i)).toBeInTheDocument(); + expect(screen.queryByTestId('payment-receipt')).not.toBeInTheDocument(); + expect(screen.getByRole('link', { name: /back to your payments/i })).toHaveAttribute('href', '/payments'); + }); + + it('asks the visitor to sign in instead of guessing', async () => { + useAuthStore.setState({ accessToken: null }); + + renderAt('/payments/pi-1'); + + expect(await screen.findByText(/sign in to see this payment/i)).toBeInTheDocument(); + expect(paymentHistoryService.getPaymentHistoryEntry).not.toHaveBeenCalled(); + }); +}); diff --git a/src/pages/PaymentDetailPage.tsx b/src/pages/PaymentDetailPage.tsx new file mode 100644 index 0000000..0c1b02a --- /dev/null +++ b/src/pages/PaymentDetailPage.tsx @@ -0,0 +1,78 @@ +import { Link, useParams } from 'react-router-dom'; +import { Button } from '../components/Button'; +import { FormError } from '../components/FormError'; +import { PaymentReceipt } from '../features/payments/components/PaymentReceipt'; +import { contractUrl, transactionUrl } from '../features/payments/explorer'; +import { usePaymentHistoryEntry } from '../features/payments/hooks/usePaymentHistory'; +import { historyErrorCopy, statusLabel } from '../features/payments/status'; +import styles from './PaymentDetailPage.module.css'; + +export function PaymentDetailPage() { + const { intentId } = useParams(); + const entryQuery = usePaymentHistoryEntry(intentId); + const now = new Date(); + + if (entryQuery.isError) { + return ( +
+
+

Payment

+ +

+ Back to your payments +

+
+
+ ); + } + + const entry = entryQuery.data; + if (!entry) { + return ( +
+
+

Payment

+

+ {entryQuery.isFetching ? 'Loading this payment…' : 'Sign in to see this payment.'} +

+
+
+ ); + } + + const txLink = transactionUrl(entry.stellarTxHash); + const contractLink = contractUrl(entry.sorobanContractId); + + return ( +
+
+ {statusLabel(entry.status)} +

Payment

+ + {/* The print button is the only action here: a receipt has to be + produceable without a developer knowing which element to hide. */} +
+ + {txLink ? ( + + View transaction on the explorer + + ) : null} + {contractLink ? ( + + View escrow contract + + ) : null} +
+ + + +

+ Back to your payments +

+
+
+ ); +} diff --git a/src/pages/PaymentHistoryPage.module.css b/src/pages/PaymentHistoryPage.module.css new file mode 100644 index 0000000..ee94a0c --- /dev/null +++ b/src/pages/PaymentHistoryPage.module.css @@ -0,0 +1,17 @@ +.title { + text-wrap: balance; +} + +.intro { + margin-top: 0; +} + +.loading { + font-size: var(--text-sm); + color: var(--color-text-faint); + margin: var(--space-3) 0; +} + +.older { + margin-top: var(--space-4); +} diff --git a/src/pages/PaymentHistoryPage.test.tsx b/src/pages/PaymentHistoryPage.test.tsx new file mode 100644 index 0000000..4a215a9 --- /dev/null +++ b/src/pages/PaymentHistoryPage.test.tsx @@ -0,0 +1,140 @@ +import { beforeEach, describe, expect, it, vi } from 'vitest'; +import userEvent from '@testing-library/user-event'; +import { render, screen, waitFor } from '../test/render'; +import { PaymentHistoryPage } from './PaymentHistoryPage'; +import * as paymentHistoryService from '../services/payment-history-service'; +import { ApiError } from '../services/api-client'; +import { useAuthStore } from '../store/auth-store'; +import type { PaymentHistoryEntry, PaymentHistoryPage as Page } from '../types/models'; + +vi.mock('../services/payment-history-service'); + +function entry(overrides: Partial = {}): PaymentHistoryEntry { + return { + id: 'pi-1', + orderType: 'prescription', + orderId: 'ord-1', + status: 'escrowed', + patientProfileId: 'pp-1', + facilityId: 'fac-1', + amountStroops: '25000000', + escrowId: '77', + stellarTxHash: null, + sorobanContractId: null, + createdAt: '2026-10-01T10:00:00Z', + updatedAt: '2026-10-01T10:00:00Z', + ...overrides, + }; +} + +function page(intents: PaymentHistoryEntry[], nextCursor: string | null): Page { + return { intents, nextCursor }; +} + +describe('PaymentHistoryPage', () => { + beforeEach(() => { + useAuthStore.setState({ accessToken: 'test-token', user: null }); + vi.mocked(paymentHistoryService.listPaymentHistory).mockReset(); + }); + + it('shows the amount with its unit and the status in plain words', async () => { + vi.mocked(paymentHistoryService.listPaymentHistory).mockResolvedValue(page([entry()], null)); + + const { container } = render(); + + expect(await screen.findByText('2.5 XLM')).toBeInTheDocument(); + expect(screen.getByText('Held in escrow')).toBeInTheDocument(); + expect(screen.getByText('Prescription')).toBeInTheDocument(); + + // facilityId/orderId are pointers the patient cannot act on, and the + // facility name is only an assumed extra — never fall back to the id. + expect(container.textContent).not.toMatch(/fac-1|ord-1|pp-1/); + expect(screen.getByText('Prescription')).toBeInTheDocument(); + }); + + it('names the facility when the response carries it', async () => { + vi.mocked(paymentHistoryService.listPaymentHistory).mockResolvedValue( + page([entry({ facilityName: 'Bello Lab' })], null), + ); + + render(); + + expect(await screen.findByText(/Bello Lab/)).toBeInTheDocument(); + }); + + // The review criterion for #37: above 2^53 a JS number would round the + // patient's own payment. + it('prints an amount larger than 2^53 stroops exactly', async () => { + vi.mocked(paymentHistoryService.listPaymentHistory).mockResolvedValue( + page([entry({ amountStroops: '9007199254740993' })], null), + ); + + render(); + + expect(await screen.findByText('900,719,925.4740993 XLM')).toBeInTheDocument(); + }); + + it('links each payment to its own page', async () => { + vi.mocked(paymentHistoryService.listPaymentHistory).mockResolvedValue(page([entry()], null)); + + render(); + + expect(await screen.findByRole('link', { name: /2\.5 XLM/i })).toHaveAttribute('href', '/payments/pi-1'); + }); + + it('asks for the next cursor only when the patient asks for older payments', async () => { + vi.mocked(paymentHistoryService.listPaymentHistory) + .mockResolvedValueOnce(page([entry()], 'cursor-2')) + .mockResolvedValueOnce(page([entry({ id: 'pi-0', amountStroops: '10000000' })], null)); + + render(); + + await screen.findByText('2.5 XLM'); + expect(screen.queryByText('1 XLM')).not.toBeInTheDocument(); + + await userEvent.click(screen.getByRole('button', { name: /show older payments/i })); + + await waitFor(() => expect(screen.getByText('1 XLM')).toBeInTheDocument()); + expect(paymentHistoryService.listPaymentHistory).toHaveBeenLastCalledWith('cursor-2', 'test-token'); + }); + + it('says history is unavailable rather than empty when the endpoint is missing', async () => { + vi.mocked(paymentHistoryService.listPaymentHistory).mockRejectedValue(new ApiError('Not Found', 404)); + + render(); + + expect(await screen.findByText(/not available for this deployment yet/i)).toBeInTheDocument(); + expect(screen.queryByText(/have not paid for anything/i)).not.toBeInTheDocument(); + }); + + it('describes an account that genuinely has no payments', async () => { + vi.mocked(paymentHistoryService.listPaymentHistory).mockResolvedValue(page([], null)); + + render(); + + expect(await screen.findByText(/have not paid for anything/i)).toBeInTheDocument(); + }); + + it('explains every status the contract has, without printing the token', async () => { + vi.mocked(paymentHistoryService.listPaymentHistory).mockResolvedValue( + page( + [ + entry({ id: 'a', status: 'created' }), + entry({ id: 'b', status: 'escrowed' }), + entry({ id: 'c', status: 'released' }), + entry({ id: 'd', status: 'refunded' }), + entry({ id: 'e', status: 'failed' }), + ], + null, + ), + ); + + render(); + + await screen.findByText(/not funded/i); + for (const label of ['Not funded', 'Held in escrow', 'Released', 'Refunded', 'Failed']) { + expect(screen.getByText(label)).toBeInTheDocument(); + } + expect(document.body.textContent).not.toMatch(/\bescrowed\b/); + }); +}); diff --git a/src/pages/PaymentHistoryPage.tsx b/src/pages/PaymentHistoryPage.tsx new file mode 100644 index 0000000..b14e7db --- /dev/null +++ b/src/pages/PaymentHistoryPage.tsx @@ -0,0 +1,51 @@ +import type { ReactNode } from 'react'; +import { Button } from '../components/Button'; +import { FormError } from '../components/FormError'; +import { PaymentHistoryList } from '../features/payments/components/PaymentHistoryList'; +import { usePaymentHistory } from '../features/payments/hooks/usePaymentHistory'; +import { historyErrorCopy } from '../features/payments/status'; +import styles from './PaymentHistoryPage.module.css'; + +export function PaymentHistoryPage() { + const historyQuery = usePaymentHistory(); + const entries = historyQuery.data?.pages.flatMap((page) => page.intents) ?? []; + + // "You have paid for nothing" is a statement about the patient's money, so + // it is only rendered from a response that arrived. A failed request says + // what failed instead — and a later page failing still shows what loaded. + let body: ReactNode; + if (entries.length > 0) body = ; + else if (historyQuery.isError) body = null; + else if (historyQuery.isFetching) body =

Loading your payments…

; + else body = ; + + return ( +
+
+ Payments +

Your payments

+

+ Every payment you have made through DocForum, with where the money is now: still yours, held in escrow, + released to the facility, or returned to you. +

+ + {historyQuery.isError ? ( + 0 ? 'Older payments could not be loaded.' : historyErrorCopy(historyQuery.error)} /> + ) : null} + + {body} + + {historyQuery.hasNextPage ? ( + + ) : null} +
+
+ ); +} diff --git a/src/services/access-log-service.ts b/src/services/access-log-service.ts new file mode 100644 index 0000000..3865cec --- /dev/null +++ b/src/services/access-log-service.ts @@ -0,0 +1,27 @@ +// 'Who viewed my records' access log. Assumed contract against +// docforum-core#45 (PHI read-access logging), which has not landed — see +// ARCHITECTURE_ESSENTIALS.md "Known assumptions". This repo never reads a +// log from anywhere else (hard rule 1). +import { apiFetch } from './api-client'; +import type { AccessLogPage, AccessRecordType } from '../types/models'; + +export interface AccessLogFilters { + from?: string; + to?: string; + recordType?: AccessRecordType; + cursor?: string; +} + +function toQuery(filters: AccessLogFilters): string { + const params = new URLSearchParams(); + for (const value of ['from', 'to', 'recordType', 'cursor'] as const) { + const param = filters[value]; + if (param) params.set(value, param); + } + const query = params.toString(); + return query ? `?${query}` : ''; +} + +export function listAccessLog(filters: AccessLogFilters, accessToken: string): Promise { + return apiFetch(`/patients/me/access-log${toQuery(filters)}`, { accessToken }); +} diff --git a/src/services/appointments-service.ts b/src/services/appointments-service.ts new file mode 100644 index 0000000..9e92f3c --- /dev/null +++ b/src/services/appointments-service.ts @@ -0,0 +1,27 @@ +// Appointments calls to docforum-core. +// +// `GET /appointments/mine` is REAL (its appointments/routes + +// appointments/repositories, which include the availability slot). The two +// check-in/queue calls are an assumed contract against docforum-core#129, +// which has not landed — see ARCHITECTURE_ESSENTIALS.md "Known assumptions". +// +// Nothing here needs the patient's own `patientProfileId`: core scopes +// `/appointments/mine` from the session, which is why the patient-facing +// endpoints in #32/#34/#37 are all built as `me`-scoped calls (the frontend +// has no way to learn that id — documented gap). +import { apiFetch } from './api-client'; +import type { Appointment, AppointmentQueue } from '../types/models'; + +export function listMyAppointments(accessToken: string): Promise { + return apiFetch('/appointments/mine', { accessToken }); +} + +/** assumed (core#129) */ +export function getAppointmentQueue(appointmentId: string, accessToken: string): Promise { + return apiFetch(`/appointments/${appointmentId}/queue`, { accessToken }); +} + +/** assumed (core#129) */ +export function checkIn(appointmentId: string, accessToken: string): Promise { + return apiFetch(`/appointments/${appointmentId}/check-in`, { method: 'POST', accessToken }); +} diff --git a/src/services/payment-history-service.ts b/src/services/payment-history-service.ts new file mode 100644 index 0000000..c1ed3af --- /dev/null +++ b/src/services/payment-history-service.ts @@ -0,0 +1,17 @@ +// Patient-facing payment history. The PaymentIntent shape these return is +// real (docforum-core Phase 5.5, its docs/adr/0004-custodial-payments-v1.md); +// the `mine` list/detail endpoints themselves are assumed against +// docforum-core#90, which has not landed — today core only exposes +// admin-only `/payments/intents...` routes. See ARCHITECTURE_ESSENTIALS.md +// "Known assumptions". No Stellar call happens here (hard rule 1). +import { apiFetch } from './api-client'; +import type { PaymentHistoryEntry, PaymentHistoryPage } from '../types/models'; + +export function listPaymentHistory(cursor: string | undefined, accessToken: string): Promise { + const query = cursor ? `?cursor=${encodeURIComponent(cursor)}` : ''; + return apiFetch(`/payments/mine${query}`, { accessToken }); +} + +export function getPaymentHistoryEntry(id: string, accessToken: string): Promise { + return apiFetch(`/payments/mine/${encodeURIComponent(id)}`, { accessToken }); +} diff --git a/src/styles/global.css b/src/styles/global.css index 4aacd22..de30db1 100644 --- a/src/styles/global.css +++ b/src/styles/global.css @@ -255,3 +255,13 @@ code, color: var(--color-accent-2); margin-bottom: var(--space-4); } + +/* Printing should hand over the document, not the app around it. The patient + receipt (#37) is the first thing here worth printing. */ +@media print { + header, + nav, + footer { + display: none; + } +} diff --git a/src/types/models.ts b/src/types/models.ts index 9a5d080..64c266a 100644 --- a/src/types/models.ts +++ b/src/types/models.ts @@ -139,3 +139,96 @@ export interface PaymentIntent { createdAt: string; updatedAt: string; } + +// --- Appointments (docforum-core Phase 1 — real) ------------------------- +// Mirrors `prisma.appointment.findMany({ include: { availabilitySlot: true } })` +// in docforum-core's appointments/repositories, which is exactly what its +// real `GET /appointments/mine` returns (a bare array, newest first). +// Dates are ISO strings here because that is what JSON carries. + +export type SlotStatus = 'open' | 'held' | 'booked'; +export type AppointmentStatus = 'scheduled' | 'completed' | 'cancelled' | 'no_show'; +export type AppointmentOrigin = 'direct_booking' | 'referral'; + +export interface AvailabilitySlot { + id: string; + doctorProfileId: string; + status: SlotStatus; + startTime: string; + endTime: string; + createdAt: string; + updatedAt: string; +} + +export interface Appointment { + id: string; + patientProfileId: string; + doctorProfileId: string; + availabilitySlotId: string; + status: AppointmentStatus; + origin: AppointmentOrigin; + availabilitySlot: AvailabilitySlot; + createdAt: string; + updatedAt: string; +} + +// --- Check-in + live queue position (assumed, docforum-core#129) --------- +// `AppointmentStatus` has no checked-in or being-seen value, so the visit's +// phase cannot come from the appointment row. It comes from this assumed +// queue projection instead. Reconcile when core#129 lands. + +export type QueuePhase = 'not_open' | 'waiting' | 'being_seen' | 'completed'; + +export interface AppointmentQueue { + appointmentId: string; + phase: QueuePhase; + /** Patients still ahead. null means no queue is published yet — which is + * not the same as being first. */ + peopleAhead: number | null; + /** Minutes. Always rendered as an estimate. */ + estimatedWaitMinutes: number | null; + /** null = this backend has no check-in window, so the UI says "check in on + * the day" instead of inventing an opening time. */ + checkInOpensAt: string | null; + checkedInAt: string | null; +} + +// --- 'Who viewed my records' access log (assumed, docforum-core#45) ------ + +export type AccessActorRole = 'doctor' | 'facility' | 'patient' | 'admin'; +export type AccessRecordType = 'health_profile' | 'appointment' | 'referral' | 'order' | 'dependent'; +export type AccessReason = 'consultation' | 'order_fulfillment' | 'result_delivery' | 'handover_claim' | 'support'; + +export interface AccessLogEvent { + id: string; + occurredAt: string; + actorRole: AccessActorRole; + actorName: string; + recordType: AccessRecordType; + reason: AccessReason; +} + +export interface AccessLogPage { + events: AccessLogEvent[]; + nextCursor: string | null; +} + +// --- Payment history for patients (assumed, docforum-core#90) ------------ +// `PaymentIntent` above is the real, mirrored shape and stays untouched; the +// patient-facing list is assumed to return it plus two display fields. +// Neither #34's nor #37's list exists in docforum-core yet, and it has no +// pagination helper to mirror, so both assume the same smallest envelope: +// send `?cursor=`, read `nextCursor` (null once exhausted). + +export interface PaymentHistoryEntry extends PaymentIntent { + /** assumed — the real row has no refund deadline column. */ + refundDeadlineAt?: string | null; + /** assumed — the real response carries only `facilityId`, an internal id + * the patient-facing UI must not render. */ + facilityName?: string; +} + +export interface PaymentHistoryPage { + intents: PaymentHistoryEntry[]; + nextCursor: string | null; +} From 6e69b34d0d5c1c12313073e807342f599829cc59 Mon Sep 17 00:00:00 2001 From: classikdev Date: Fri, 16 Oct 2026 19:06:40 +0100 Subject: [PATCH 4/5] docs(patient): #32, #34 and #37 screens at desktop and mobile widths Captured at 1440 and 390 CSS px against a local stub of docforum-core seeded with fixture appointments, queue positions, access-log entries and payment intents, so the states behind core#129, core#45 and core#90 are reviewable before those backends land. The receipt shot is the reason the receipt's two-column grid collapses below 760px: at 390px the value column was starved and the transaction hash was unreadable. --- .../access-log-desktop.png | Bin 0 -> 38674 bytes .../access-log-mobile.png | Bin 0 -> 32017 bytes .../appointment-queue-desktop.png | Bin 0 -> 18028 bytes .../appointment-queue-mobile.png | Bin 0 -> 15246 bytes .../care-hub-desktop.png | Bin 0 -> 30298 bytes .../care-hub-mobile.png | Bin 0 -> 25251 bytes .../payment-receipt-desktop.png | Bin 0 -> 29976 bytes .../payment-receipt-mobile.png | Bin 0 -> 24785 bytes .../payments-history-desktop.png | Bin 0 -> 26483 bytes .../payments-history-mobile.png | Bin 0 -> 22391 bytes 10 files changed, 0 insertions(+), 0 deletions(-) create mode 100755 docs/screenshots/2026-10-16-patient-checkin-access-log-payments/access-log-desktop.png create mode 100755 docs/screenshots/2026-10-16-patient-checkin-access-log-payments/access-log-mobile.png create mode 100755 docs/screenshots/2026-10-16-patient-checkin-access-log-payments/appointment-queue-desktop.png create mode 100755 docs/screenshots/2026-10-16-patient-checkin-access-log-payments/appointment-queue-mobile.png create mode 100755 docs/screenshots/2026-10-16-patient-checkin-access-log-payments/care-hub-desktop.png create mode 100755 docs/screenshots/2026-10-16-patient-checkin-access-log-payments/care-hub-mobile.png create mode 100755 docs/screenshots/2026-10-16-patient-checkin-access-log-payments/payment-receipt-desktop.png create mode 100755 docs/screenshots/2026-10-16-patient-checkin-access-log-payments/payment-receipt-mobile.png create mode 100755 docs/screenshots/2026-10-16-patient-checkin-access-log-payments/payments-history-desktop.png create mode 100755 docs/screenshots/2026-10-16-patient-checkin-access-log-payments/payments-history-mobile.png diff --git a/docs/screenshots/2026-10-16-patient-checkin-access-log-payments/access-log-desktop.png b/docs/screenshots/2026-10-16-patient-checkin-access-log-payments/access-log-desktop.png new file mode 100755 index 0000000000000000000000000000000000000000..a0f8a1946ab76067dd8d9850c9334cf066141693 GIT binary patch literal 38674 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 literal 0 HcmV?d00001 diff --git a/docs/screenshots/2026-10-16-patient-checkin-access-log-payments/access-log-mobile.png b/docs/screenshots/2026-10-16-patient-checkin-access-log-payments/access-log-mobile.png new file mode 100755 index 0000000000000000000000000000000000000000..bd545a3915ce4cf8e02e24b94f6d87cec26472f9 GIT binary patch literal 32017 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 literal 0 HcmV?d00001 diff --git a/docs/screenshots/2026-10-16-patient-checkin-access-log-payments/appointment-queue-desktop.png b/docs/screenshots/2026-10-16-patient-checkin-access-log-payments/appointment-queue-desktop.png new file mode 100755 index 0000000000000000000000000000000000000000..54e3c240cecc3aef6e4afd90366d4d3acdc5f806 GIT binary patch literal 18028 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 VU!G{-zsQj3Y8z;kUH{|B{{mljLID5( literal 0 HcmV?d00001 diff --git a/docs/screenshots/2026-10-16-patient-checkin-access-log-payments/appointment-queue-mobile.png b/docs/screenshots/2026-10-16-patient-checkin-access-log-payments/appointment-queue-mobile.png new file mode 100755 index 0000000000000000000000000000000000000000..5dced2c88d09b0dc5ad90e82f28065afa07c5c11 GIT binary patch literal 15246 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 literal 0 HcmV?d00001 diff --git a/docs/screenshots/2026-10-16-patient-checkin-access-log-payments/care-hub-desktop.png b/docs/screenshots/2026-10-16-patient-checkin-access-log-payments/care-hub-desktop.png new file mode 100755 index 0000000000000000000000000000000000000000..29e1412736e88f584637bc1c8f767fc94e4e826c GIT binary patch literal 30298 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 D*atDA literal 0 HcmV?d00001 diff --git a/docs/screenshots/2026-10-16-patient-checkin-access-log-payments/care-hub-mobile.png b/docs/screenshots/2026-10-16-patient-checkin-access-log-payments/care-hub-mobile.png new file mode 100755 index 0000000000000000000000000000000000000000..0c1e2bf6c464f1357eefe6b684ec27398fafbcfe GIT binary patch literal 25251 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 literal 0 HcmV?d00001 diff --git a/docs/screenshots/2026-10-16-patient-checkin-access-log-payments/payment-receipt-desktop.png b/docs/screenshots/2026-10-16-patient-checkin-access-log-payments/payment-receipt-desktop.png new file mode 100755 index 0000000000000000000000000000000000000000..b6b4b8e9b7b5bd4e55c9067e1e7a7c6f275615af GIT binary patch literal 29976 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%0DNQ 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 literal 0 HcmV?d00001 diff --git a/docs/screenshots/2026-10-16-patient-checkin-access-log-payments/payment-receipt-mobile.png b/docs/screenshots/2026-10-16-patient-checkin-access-log-payments/payment-receipt-mobile.png new file mode 100755 index 0000000000000000000000000000000000000000..6fe44ada0f0dcf430a5430259c2d375f4fb5aa6d GIT binary patch literal 24785 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 X`Hh^p&-hmrTvLCftz4yO^WxtC1M4a9 literal 0 HcmV?d00001 diff --git a/docs/screenshots/2026-10-16-patient-checkin-access-log-payments/payments-history-desktop.png b/docs/screenshots/2026-10-16-patient-checkin-access-log-payments/payments-history-desktop.png new file mode 100755 index 0000000000000000000000000000000000000000..a36eb056940fb86b540db01337a7b480ab0bbbe5 GIT binary patch literal 26483 zcmeFZc|26_|38cgNs&~thawVXAM2o^vXzj%1tV*WCBqm>NJVAKGK^&3!q~S;_HAU# zGGv`GV>d&V;Xb3!`}29<-_PgsyTAY3_h0wp95ZLG?Of+|U9ao)d_Aw%@zTgZ=hzXR zBXo3h$8P9ey+cRGh^C_hwH^imDQ8&nH|gl;gN*dyomz8mVP!Ph<>%uuZ#9QhEcVY+`z!;iT9n7I6xZ_}fnrzO}GG*`YgEQ-0`@K&`lL@vi)CL>h$Z4A;c z_Px`a=xC(rQzSIQQ?kVUOpN_`1k4O>uN`N}9dYA~pW*piN&YvJ9-F@mR!e*)AMU3Q z54i~sv2cf8_IWPr%ulm!`*%#ips(JV6$Rh5gt#MoZ=N&p>)k7UAIgfS}w{Rj5&T>{{FL`QVq*C%=`O08Tlp`JL1m^e|+EBQV|q> z82$3#k1jDh9Qga|C+++HoD}%}&ZyyXs+nPhF`fQZa)Ekks3XUUA-x<&Z$()h^|=B& z_UhHFO}SXL33_D+CkMiE6WPB(|K}ETJb&6hj7DC-3JPk>MTLjAW1>_nq4SF^C5PY$ zCr?i&l!m>qM1y*&KD4hJ?+M!88k@mUC^gZro~?AzkDk10?g(qajw6J-E}q2VU8Akt zr%p0)Q-(?5Ql&jFUPzgs1r7CwB}eaaa>U+9t*Ec>nPtG}skf+d^7cHE8D8a=emL!r zynjDD`x8P+j@>!}vfRnPeoz0}awV6B+;6W_WtUzWr_}aA&3cemuHOB|$@fAGe3OGf zX`7biNfk7NcXfx?$q#p7Pub2cXQ}R>By4A+7i_X~=fd~x!UH3IsBzA{df{xiKvK00 zyp{I#)fos^;>-no^rct63lon7aTifvJ>G1WI#NuMWt39}Akfmf*yZ2LaRfXA92U@2 z-yN{!li9e;P8O@@B@FB}GWaGc_0hpy*S?w^O}2W+t>mN8cp$z@pcOql3CP+PR$e9u}6BmwR;Xo@E&r98_pg zgOHq;+scMMZg+6+6RcbpbrpD>8>HB6NUMSbmEA&t5#LV=gO%Tr^H=Rz$hs98m&;SF z>pb4#7B&>y-A7IVCtS>Xdp-#lDn8W-@$vXiu*!Ew(Yij}W{Kx7eszv0p3$ts6f90io4mPN0 z|Ls>$rZu5$h|1;*UW#g{;;PKJ z+Z__RN7>l;zyvQw+RGB$*`n;0-`JTUxko1m0w>gQP zH56mSWmDkWQNVy1yZA1_O-4%^!>4Ta)9{__lg(c$ir|dUuIQ4>uKJ@95 z@uK?r8e2Zg#mLhY`GN(p^rSFhbgjTn%^gRE+IwvZTtz=+M&^SZ&A<0Le>v3#h~GH*<@plE zpuI!btMN>P1yVwi>+>zhe*KWFBTj{LEh@X^=#q*E;Tyzuz0=PLjk?%roP315(7)cL zB7heBDf^>|!9u^^wEw&GQAciY%aNiw6?JB7>QZD4!5~v=tc``0(23w)R0+{2zM#

DqA|7e};|P?Cm0?lOBU>$qeM8NdZ}8Nh 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 literal 0 HcmV?d00001 diff --git a/docs/screenshots/2026-10-16-patient-checkin-access-log-payments/payments-history-mobile.png b/docs/screenshots/2026-10-16-patient-checkin-access-log-payments/payments-history-mobile.png new file mode 100755 index 0000000000000000000000000000000000000000..8375cb4b819460c89621b5d830ad5eb23c18b5d0 GIT binary patch literal 22391 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 Date: Tue, 20 Oct 2026 05:40:42 +0100 Subject: [PATCH 5/5] fix(patient): restore the branch content the web conflict editor dropped Both "Merge branch 'main'" commits on this branch (5705ef6, d97c8e8, b5ba38d) resolved every conflicted file by taking main's side. That removed work this PR exists to add: src/types/models.ts lost 12 declarations, App.tsx lost the #34/#37 routes, PatientDashboardPage.tsx lost the #33 care hub (its 52-line result referenced an undefined `user` and did not compile), global.css lost the #37 print block and both docs lost their changelog entries. 45 typecheck errors and 19 failing tests were waiting under that. Re-landed as a real three-way merge (main's def988c merged into the branch's 6e69b34, identical content to that resolution, kept here as a forward commit so nothing already reviewed is rewritten): - models.ts: main's `Appointment`/`AppointmentStatus` stay authoritative. The patient-side `GET /appointments/mine` row is now `PatientAppointment`, because it carries `availabilitySlot`, `origin` and timestamps main's shape does not, and two interfaces cannot share one name. QueuePhase, AppointmentQueue, the AccessLog* and PaymentHistory* shapes come back after main's file, still marked assumed. - AppointmentDetailPage: `checked_in` and `in_progress` are new in main's AppointmentStatus. A patient already in the queue gets the live panel, so CLOSED_COPY now covers only completed/cancelled/no_show, plus tests for both. - PatientDashboardPage keeps the care hub and gains main's facilities, settings and care/* routes; App.tsx keeps both sides' routes; global.css keeps main's theming and the print block; the two docs are the union of both changelogs. - AppointmentDetailPage.test.tsx: the page reads the wall clock for "is this visit today" while the fixture froze 2026-10-16, so two tests failed on every day after it, including on CI. The clock is now frozen to the fixture. --- ARCHITECTURE_ESSENTIALS.md | 128 ++++++++++++++++++ ROADMAP.md | 83 +++++++++++- src/App.tsx | 31 +++++ .../components/QueuePanel.test.tsx | 4 +- .../appointments/components/QueuePanel.tsx | 4 +- src/features/appointments/slot.test.ts | 6 +- src/features/appointments/slot.ts | 10 +- src/pages/AppointmentDetailPage.test.tsx | 28 +++- src/pages/AppointmentDetailPage.tsx | 27 ++-- src/pages/PatientDashboardPage.test.tsx | 4 +- src/pages/PatientDashboardPage.tsx | 47 ++++++- src/services/appointments-service.ts | 6 +- src/styles/global.css | 10 ++ src/types/models.ts | 90 ++++++++++++ 14 files changed, 444 insertions(+), 34 deletions(-) diff --git a/ARCHITECTURE_ESSENTIALS.md b/ARCHITECTURE_ESSENTIALS.md index d4be416..cde87c3 100644 --- a/ARCHITECTURE_ESSENTIALS.md +++ b/ARCHITECTURE_ESSENTIALS.md @@ -264,6 +264,134 @@ assumed and mirrored in `models.ts` under "Phase W6 — Feature flags console". - Approaching deadline warnings: prominent alerts when held escrow refund deadline is < 48 hours away and order is unfulfilled (Threat Model T8 compliance). - Direct explorer links to Stellar testnet transactions (`https://stellar.expert/explorer/testnet/tx/...`). +### Care hub — patient home (#33) +No new backend endpoint and no new assumed shape. The hub is a +client-side aggregation over the two contracts above — +`GET /patients/me/dependents` and `GET /patients/:profileId/health/:section` +— ranked into sections in `src/features/care-hub/ranking.ts`. The derived +`CareCard` is deliberately a presentation-only type (it exists in the +browser and is never sent to or received from `docforum-core`), so it does +not violate hard rule 2. + +Two things the issues ask for are not yet wired because their backend +contract does not exist here: +- **There is no way to learn the signed-in patient's own `patientProfileId`.** + `#20`'s profile store is populated only by tests — no response in this + repo carries an `ActingProfile`, and `User` has no profile id — so + `selectedProfileId` is `null` in a real session and every health-profile + query stays disabled. That is a `docforum-core` gap to file (hard rule 1), + not something to paper over by assuming `profileId === userId`. The care + hub reports such a source as `unavailable` rather than loading or failed, + so the screen renders the cards it *can* derive instead of spinning + forever, and never reads "we could not ask" as "you have nothing saved". + The health editor and dependents screens have the same dependency. +- **Referrals awaiting acceptance, orders needing a facility, results + ready, waitlist offers, follow-ups** wait on `docforum-core`#5–#16 + (see issues #4 and #5 here). Each will contribute its own card source + when that lands. + +"Coming up" is no longer one of those: since #32 it is fed by +`useMyAppointments()`, which reads `docforum-core`'s **real** +`GET /appointments/mine` (see below), so a visit happening today ranks under +"Action needed" and a later one under "Coming up" in a real session — the +appointments source needs only the access token, not a `patientProfileId`. + +## Known assumptions — Phase W2 patient follow-ons (#32, #34, #37) + +Everything under "assumed" below is a shape this repo *wrote down*, not one +`docforum-core` serves yet; each screen treats a 404 as "not available for +this deployment yet", never as "you have nothing". Reconcile against the real +contract when the backend issues land. + +### Appointments — the real part (`docforum-core` Phase 1) +- `GET /appointments/mine` (Bearer access token) → a **bare array**, not an + envelope, newest-first, each item with `availabilitySlot` included + (`{id, doctorProfileId, status, startTime, endTime, createdAt, updatedAt}`). +- `AppointmentStatus` is `scheduled | completed | cancelled | no_show` — + there is **no** `checked_in`/`being_seen` in the real enum, which is why + queue state lives in its own shape below rather than in `status`. +- `AppointmentOrigin` is `direct_booking | referral`; `SlotStatus` is + `open | held | booked`. +- **Still-missing from this real endpoint: no clinician name and no facility + name.** It returns `doctorProfileId` only, so every visit card and the + appointment detail page describe the *time*, never "Dr —". Putting a name + there needs a `docforum-core` change (include the doctor profile, or a + patient-facing summary route); this repo will not resolve a name by + guessing from an id. + +### Check-in and live queue (#32, assumed — `docforum-core` #129) +- `GET /appointments/:appointmentId/queue` → `AppointmentQueue` +- `POST /appointments/:appointmentId/check-in` → `AppointmentQueue` +- Both are keyed by an appointment id the patient already owns: + `AppointmentDetailPage` only asks for a queue after matching that id + against the real `GET /appointments/mine` list, so an unfamiliar id reads + "we cannot find that appointment on your account" and never reaches the + queue route at all. Authorising the id itself is still `docforum-core`'s + job. +- `AppointmentQueue` shape: `{appointmentId, phase: 'not_open'|'waiting'|'being_seen'|'completed', peopleAhead: number|null, estimatedWaitMinutes: number|null, checkInOpensAt: string|null, checkedInAt: string|null}` +- `null` in `peopleAhead`/`estimatedWaitMinutes` means "not published", and + is rendered as such — `0` would be a claim about the waiting room. +- Polling, not SSE: `refetchInterval` 15s while the panel is on screen, and + `gcTime: 0` so unmounting the page stops the requests. `docforum-core` has + no SSE endpoint to hook to yet. + +### 'Who viewed my records' access log (#34, assumed — `docforum-core` #45) +- `GET /patients/me/access-log?from&to&recordType&cursor` → `AccessLogPage` +- `AccessLogPage` shape: `{events: AccessLogEvent[], nextCursor: string|null}` +- `AccessLogEvent` shape: `{id, occurredAt, actorRole: 'doctor'|'facility'|'patient'|'admin', actorName, recordType: 'health_profile'|'appointment'|'referral'|'order'|'dependent', reason: 'consultation'|'order_fulfillment'|'result_delivery'|'handover_claim'|'support'}` +- The `me` scope is used because, again, the frontend cannot learn its own + `patientProfileId` (the gap above) — an id in the path would have to be + guessed. +- The "report a concern" link is gated on `VITE_SUPPORT_EMAIL` — no address + configured means no link, not a `mailto:` to an invented one. + +### Payment history and receipts (#37, partly real) +- **Real today:** the `PaymentIntent` row itself — `{id, orderType, orderId, + status, patientProfileId, facilityId, amountStroops, escrowId, + stellarTxHash, sorobanContractId, createdAt, updatedAt}` — with the BigInt + columns (`amountStroops`, `escrowId`) serialized to **strings**. Those + strings are kept as strings in `models.ts` and converted with `BigInt` + only (`src/features/payments/stroops.ts`); `Number` would round a payment + above 2^53 stroops. +- **Real today, admin-only:** `POST /payments/intents*` and + `GET /payments/intents/:id` require the `admin` role, which is why the + patient screens below are separate. +- Assumed (`docforum-core` #90 has not landed): + - `GET /payments/mine?cursor` → `PaymentHistoryPage` + - `GET /payments/mine/:intentId` → `PaymentHistoryEntry` + - `PaymentHistoryEntry extends PaymentIntent` with optional + `facilityName?: string` and `refundDeadlineAt?: string` — presentation + extras layered *on top of* the mirrored row, not a parallel shape (hard + rule 2). Both are omitted from the UI when absent. + - `patients` routes in `docforum-core` are still a placeholder module, so + every `me`-scoped patient endpoint above is a request, not a report. +- `src/features/payments/explorer.ts` builds testnet explorer links from + `VITE_STELLAR_EXPLORER_BASE_URL` (default + `https://testnet.stellar.expert/explorer/public`). This is display-only: + nothing here queries Stellar (hard rule 1) — it turns a hash + `docforum-core` already returned into a URL. + +### Cursor pagination (assumed across #34 and #37) +`docforum-core` has **no** cursor-pagination helper in `main` — the one +patient list that does exist, `GET /appointments/mine`, returns a bare +array. The `{ : [], nextCursor: string|null }` envelope used by +the access log and payment history is therefore an assumption, and the +frontend treats `nextCursor: null` as "nothing older". If the backend lands +offset pagination instead, only the two services and their +`getNextPageParam` need to change. + +### New routes from these three issues +- `/patient/appointments/:appointmentId` — nested under the patient + dashboard, because it is a detail screen of the hub. +- `/account/access-log`, `/payments`, `/payments/:intentId` — **not** nested + under `/patient`. `#34` names `/account/access-log` in the issue body and + payments are not patient-profile-scoped UI (a doctor or facility arriving + at `/payments` later would not belong under `/patient`), so these sit at + the literal paths the issues ask for, gated on the `patient` role in + `src/App.tsx` until a role actually needs them. +- All three lists are `useInfiniteQuery`-based; the patient asks for older + entries, the page never fetches ahead on its own. + ## Roadmap / status See `ROADMAP.md` in this repo, and Phase 7 in `docforum-core`'s `ROADMAP.md` for the original (pre-split) frontend phase this was carved diff --git a/ROADMAP.md b/ROADMAP.md index c874dd8..2d65ca3 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -33,7 +33,7 @@ real API" (no refresh-on-reload flow). this repo's static frontend only. ## Phase W2 — Patient core flow -**Fully scoped into issues #1–#5, #18–#21, #26–#29.** +**Fully scoped into issues #1–#5, #18–#21, #26–#29, plus the follow-on patient issues #32–#34 and #37.** - [ ] Doctor search (specialty + availability filter). Tracked as [issue #1](https://github.com/DocForum/docforum-web/issues/1) (Medium, 150 pts) — built against a documented assumed API shape, since `docforum-core` has no doctor-list endpoint yet. - [ ] Booking + intake form. Tracked as [issue #2](https://github.com/DocForum/docforum-web/issues/2) (High, 200 pts) — must handle the `409` slot-taken response from `docforum-core`'s real booking-concurrency guarantee explicitly, not as a generic error. - [ ] My appointments list. Tracked as [issue #3](https://github.com/DocForum/docforum-web/issues/3) (Trivial, 100 pts) — calls `docforum-core`'s real, already-implemented `GET /appointments/mine`, no assumption involved. @@ -49,6 +49,15 @@ real API" (no refresh-on-reload flow). - [x] Facility finder with a map and distance-sorted results. Tracked as [issue #29](https://github.com/DocForum/docforum-web/issues/29) (High, 200 pts) — assumed contract against `docforum-core` issue #74. +- [x] Patient home as a care hub: action-first dashboard ranking what needs + attention now. Tracked as [issue #33](https://github.com/DocForum/docforum-web/issues/33) (High, 200 pts) — no new backend contract; aggregates the + dependents and health-profile endpoints above. Its "Coming up" section is fed + by the appointment cards below, which read `docforum-core`'s real + `GET /appointments/mine`; a dedicated appointments list screen + ([issue #3](https://github.com/DocForum/docforum-web/issues/3)) is still open. +- [x] Check-in and live queue position on appointment day. Tracked as [issue #32](https://github.com/DocForum/docforum-web/issues/32) (High, 200 pts) — the visit itself comes from `docforum-core`'s real `GET /appointments/mine`; the queue, check-in and its window are an assumed contract against `docforum-core` issue #129, which has not landed. +- [x] 'Who viewed my records' access log. Tracked as [issue #34](https://github.com/DocForum/docforum-web/issues/34) (High, 200 pts) — assumed contract against `docforum-core` issue #45 (PHI read-access log), which has not landed. +- [x] Payment history and receipts for patients. Tracked as [issue #37](https://github.com/DocForum/docforum-web/issues/37) (High, 200 pts) — `PaymentIntent` mirrors `docforum-core`'s real Phase 5.5 shape (`amountStroops`/`escrowId` arrive as strings and are formatted with BigInt, never through `Number`); the patient list/detail routes and the `refundDeadlineAt`/`facilityName` display fields are an assumed contract against `docforum-core` issue #90, which has not landed. ## Phase W3 — Doctor core flow **Fully scoped into issues #6–#7, with #45–#49 added as doctor core-flow features.** - [x] Today's appointments / intake view. Tracked as [issue #6](https://github.com/DocForum/docforum-web/issues/6) (Medium, 150 pts) — foundation laid via the doctor dashboard's live queue (`src/features/queue/`). @@ -355,6 +364,78 @@ Admin-only screens beyond payments. Everything goes through `docforum-core`'s ad `/patient/facilities`). Strict privacy enforcement: transient in-memory location only (never persisted to storage or URLs). 15 test files and 62/62 tests passing. +- 2026-10-16 — Rebuilt `PatientDashboardPage` from a placeholder into the + patient care hub ([issue #33](https://github.com/DocForum/docforum-web/issues/33)): `src/features/care-hub/` holds a pure + ranking module (`ranking.ts`) plus `useCareHub`, which fans out to the + existing dependents and health-profile queries in parallel and turns + their results into cards ranked `blocked now → needs you → good to know`, + with a 30-day "Recent" window. One failing source degrades its own + section instead of blanking the page, and a health section that *errored* + is never reported to the patient as an empty profile. Sections for + unbuilt features are hidden, not stubbed — "Coming up" only appears once + a card source for it lands, which [issue #32](https://github.com/DocForum/docforum-web/issues/32) + supplies from `docforum-core`'s real `GET /appointments/mine`. Adds + `src/features/care-hub/ranking.test.ts` and + `src/pages/PatientDashboardPage.test.tsx`; 57 tests pass (was 44 on + `main`), typecheck and build green. +- 2026-10-16 — Checked the three other assigned W2 issues against the + current code and backend: #32 (check-in + live queue position), #34 + ("who viewed my records" access log) and #37 (payment history and + receipts) each need a `docforum-core` endpoint that does not exist yet — + no check-in/queue route, no access-log route, and + `src/services/payments-service.ts` can create/read/fund a single + `PaymentIntent` by id but has no list-the-patient's-payments route. + Concluded they "stay unimplemented rather than built on a fabricated + contract", which was the wrong call and is corrected by the entries + below: hard rule 1 forbids calling Stellar/escrow directly, not building + a patient screen against a *documented* assumed shape — and #18, #19 and + #21 all did exactly that, recorded in "Known assumptions". What the check + did establish and what still gates these screens is the missing backend + work (`docforum-core` #129, #45 and #90). +- 2026-10-16 — Built #32: check-in and live queue position on appointment + day. `src/services/appointments-service.ts` calls `docforum-core`'s real + `GET /appointments/mine` (a bare array, newest-first, `availabilitySlot` + included) and the assumed queue/check-in routes. `src/features/appointments/` + holds the pure parts (`slot.ts` — local-calendar-day maths, so "today" + means the patient's day not UTC's; `queue.ts` — notification threshold and + a signature so a patient is told about a *change*, not every poll), the + `useAppointmentQueue` hook (polls only while the visit is on screen and + `status === 'scheduled'`, `gcTime: 0` so leaving the page stops the + requests) and `QueuePanel`. `AppointmentDetailPage` at + `/patient/appointments/:appointmentId` is reachable from the care hub's + "Coming up"/"Action needed" cards; check-in UI only appears on the day of + the visit. Estimates are always labelled as estimates, `peopleAhead: null` + renders as "not published" rather than "zero people ahead", and a 404 from + the unlanded queue route reads "check-in is not available for this visit + yet" instead of an empty queue. `src/hooks/useBrowserNotification.ts` asks + for permission only on a click and never re-asks after a refusal. +- 2026-10-16 — Built #34: 'who viewed my records' access log at + `/account/access-log`. `src/services/access-log-service.ts` reads the + assumed `GET /patients/me/access-log` (cursor-paginated, `from`/`to`/ + `recordType` filters) through `useInfiniteQuery`, so "show older entries" + asks for the next cursor only when the patient asks for it. + `src/features/account/` renders who (name + role), what and why, and + never an internal id; the "why" copy explains the treating-clinician and + fulfilling-facility cases rather than dumping a reason code. The + report-a-concern link is only rendered when `VITE_SUPPORT_EMAIL` is set — + an invented mailto would send a patient's privacy complaint nowhere. +- 2026-10-16 — Built #37: payment history and printable receipts at + `/payments` and `/payments/:intentId`. `src/features/payments/stroops.ts` + converts `amountStroops` with BigInt only, so an amount above 2^53 prints + exactly (`900,719,925.4740993 XLM`) instead of silently rounding the + patient's own money; `explorer.ts` is the single source of testnet + explorer links (all calls still go through `docforum-core` — hard rule 1 + — this only turns a hash core already returned into a URL); `status.ts` + labels and explains every `PaymentIntentStatus` in the patient's terms. + `PaymentReceipt` keeps the transaction hash and escrow contract id as + readable text so a printed copy is still verifiable, hides the page + chrome at print time, and omits `orderId`, which a patient cannot act on. + The assumed `refundDeadlineAt` renders nothing when absent rather than a + guessed window. +- 2026-10-16 — #32/#34/#37 together: 156 tests pass across 25 files (57 on + this branch before, 44 on `main`), `npm run typecheck` clean, `npm run + build` clean. Types for every assumed shape are annotated as assumed in + `src/types/models.ts` and recorded in `ARCHITECTURE_ESSENTIALS.md`. - 2026-10-17 — Built Phase W3 doctor core flow (#45–#49): live queue with start/complete visits, running delay + manual override and 4s undo window (#49); doctor messages inbox with unread badge, truncated PHI previews, diff --git a/src/App.tsx b/src/App.tsx index 6f63b37..a0158f1 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -9,6 +9,9 @@ import { DoctorDashboardPage } from './pages/DoctorDashboardPage'; import { FacilityDashboardPage } from './pages/FacilityDashboardPage'; import { AdminDashboardPage } from './pages/AdminDashboardPage'; import { ClaimAccountPage } from './pages/ClaimAccountPage'; +import { AccessLogPage } from './pages/AccessLogPage'; +import { PaymentDetailPage } from './pages/PaymentDetailPage'; +import { PaymentHistoryPage } from './pages/PaymentHistoryPage'; import { CareThreadPage } from './pages/CareThreadPage'; import { AccountDeletedPage } from './pages/AccountDeletedPage'; import { NotFoundPage } from './pages/NotFoundPage'; @@ -32,6 +35,34 @@ export default function App() { } /> } /> } /> + {/* Issue-path routes (#34 `/account/access-log`, #37 `/payments`) stay + at the literal path the issues name, guarded to patients, rather + than being folded under /patient where the hub's nested routes + live. #32's detail page has no path of its own, so it nests. */} + + + + } + /> + + + + } + /> + + + + } + /> } /> = {}): AppointmentQueue { }; } -const APPOINTMENT: Appointment = { +const APPOINTMENT: PatientAppointment = { id: 'apt-1', patientProfileId: 'pp-1', doctorProfileId: 'dp-1', diff --git a/src/features/appointments/components/QueuePanel.tsx b/src/features/appointments/components/QueuePanel.tsx index e77fb2d..d9f000b 100644 --- a/src/features/appointments/components/QueuePanel.tsx +++ b/src/features/appointments/components/QueuePanel.tsx @@ -6,11 +6,11 @@ import { ApiError } from '../../../services/api-client'; import { useAppointmentQueue, useCheckIn, useQueueNotification } from '../hooks/useAppointmentQueue'; import { canCheckIn } from '../queue'; import { formatSlotTime, shouldPollQueue } from '../slot'; -import type { Appointment, AppointmentQueue } from '../../../types/models'; +import type { PatientAppointment, AppointmentQueue } from '../../../types/models'; import styles from './QueuePanel.module.css'; interface Props { - appointment: Appointment; + appointment: PatientAppointment; now: Date; } diff --git a/src/features/appointments/slot.test.ts b/src/features/appointments/slot.test.ts index 9bc43bd..b671977 100644 --- a/src/features/appointments/slot.test.ts +++ b/src/features/appointments/slot.test.ts @@ -1,6 +1,6 @@ import { describe, expect, it } from 'vitest'; import { formatSlotDate, formatSlotTime, isOnSlotDay, isUpcoming, shouldPollQueue } from './slot'; -import type { Appointment } from '../../types/models'; +import type { PatientAppointment } from '../../types/models'; /** Local-time builders, so nothing in these assertions depends on the TZ the * suite happens to run in. */ @@ -13,7 +13,7 @@ function local(dayOffset: number, hour: number, minute = 0): string { const TODAY = new Date(2026, 9, 16, 12, 0, 0); -function appointment(overrides: Partial = {}): Appointment { +function appointment(overrides: Partial = {}): PatientAppointment { return { id: 'apt-1', patientProfileId: 'pp-1', @@ -36,7 +36,7 @@ function appointment(overrides: Partial = {}): Appointment { }; } -function withSlot(overrides: Partial): Appointment { +function withSlot(overrides: Partial): PatientAppointment { const base = appointment(); return { ...base, availabilitySlot: { ...base.availabilitySlot, ...overrides } }; } diff --git a/src/features/appointments/slot.ts b/src/features/appointments/slot.ts index 83624c4..c039f44 100644 --- a/src/features/appointments/slot.ts +++ b/src/features/appointments/slot.ts @@ -1,8 +1,8 @@ -import type { Appointment } from '../../types/models'; +import type { PatientAppointment } from '../../types/models'; const DAY_MS = 24 * 60 * 60 * 1000; -function slotStart(appointment: Appointment): number { +function slotStart(appointment: PatientAppointment): number { return new Date(appointment.availabilitySlot.startTime).getTime(); } @@ -18,7 +18,7 @@ function isSameLocalDay(a: number, b: number): boolean { ); } -export function isOnSlotDay(appointment: Appointment, now: Date): boolean { +export function isOnSlotDay(appointment: PatientAppointment, now: Date): boolean { const start = slotStart(appointment); return !Number.isNaN(start) && isSameLocalDay(start, now.getTime()); } @@ -26,13 +26,13 @@ export function isOnSlotDay(appointment: Appointment, now: Date): boolean { /** Live updates only make sense for a visit that is happening today and has * not already been settled — a past or cancelled appointment must not keep * a poll running. */ -export function shouldPollQueue(appointment: Appointment, now: Date): boolean { +export function shouldPollQueue(appointment: PatientAppointment, now: Date): boolean { return appointment.status === 'scheduled' && isOnSlotDay(appointment, now); } /** The hub shows a visit while it is still ahead of you (or happening today); * anything older drops out on its own without a server-side filter. */ -export function isUpcoming(appointment: Appointment, now: Date): boolean { +export function isUpcoming(appointment: PatientAppointment, now: Date): boolean { const start = slotStart(appointment); if (Number.isNaN(start)) return false; return appointment.status === 'scheduled' && (start >= now.getTime() || isSameLocalDay(start, now.getTime())); diff --git a/src/pages/AppointmentDetailPage.test.tsx b/src/pages/AppointmentDetailPage.test.tsx index f3c4eac..01a711c 100644 --- a/src/pages/AppointmentDetailPage.test.tsx +++ b/src/pages/AppointmentDetailPage.test.tsx @@ -6,7 +6,7 @@ import { AppointmentDetailPage } from './AppointmentDetailPage'; import * as appointmentsService from '../services/appointments-service'; import { ApiError } from '../services/api-client'; import { useAuthStore } from '../store/auth-store'; -import type { Appointment, AppointmentQueue } from '../types/models'; +import type { PatientAppointment, AppointmentQueue } from '../types/models'; vi.mock('../services/appointments-service'); @@ -28,7 +28,7 @@ vi.mock('../features/appointments/hooks/useAppointmentQueue', () => ({ const NOW = new Date('2026-10-16T12:00:00Z'); -function appointment(overrides: Partial = {}): Appointment { +function appointment(overrides: Partial = {}): PatientAppointment { const slotStart = new Date(NOW.getTime() + 2 * 60 * 60 * 1000); const slotEnd = new Date(slotStart.getTime() + 30 * 60 * 1000); return { @@ -79,6 +79,9 @@ describe('AppointmentDetailPage', () => { beforeEach(() => { useAuthStore.setState({ accessToken: 'test-token', user: null }); vi.mocked(appointmentsService.listMyAppointments).mockReset(); + // The page reads the wall clock for "is this visit today", so the clock is + // frozen to NOW. Only Date is faked — waitFor still runs on real timers. + vi.useFakeTimers({ now: NOW.getTime(), toFake: ['Date'] }); queueHook.mockReset(); queueHook.mockReturnValue({ data: QUEUE, @@ -89,6 +92,10 @@ describe('AppointmentDetailPage', () => { } as never); }); + afterEach(() => { + vi.useRealTimers(); + }); + it('names the day and the time of the visit', async () => { vi.mocked(appointmentsService.listMyAppointments).mockResolvedValue([appointment()]); @@ -107,6 +114,21 @@ describe('AppointmentDetailPage', () => { expect(screen.getByText(/about 9 min \(estimate\)/i)).toBeInTheDocument(); }); + it.each(['checked_in', 'in_progress'] as const)( + 'keeps the live queue visible for a visit that is %s', + async (status) => { + // The doctor-side flow added these two statuses to AppointmentStatus. A + // patient already in the queue must not be told there is "nothing to + // check in to". + vi.mocked(appointmentsService.listMyAppointments).mockResolvedValue([appointment({ status })]); + + renderAt('/patient/appointments/apt-1'); + + expect(await screen.findByText(/2 people ahead of you/i)).toBeInTheDocument(); + expect(screen.queryByText(/nothing to check in to/i)).not.toBeInTheDocument(); + }, + ); + it('does not start reading the queue before the day of the visit', async () => { const later = appointment(); later.availabilitySlot.startTime = new Date(NOW.getTime() + 26 * 60 * 60 * 1000).toISOString(); @@ -140,7 +162,7 @@ describe('AppointmentDetailPage', () => { }); it('surfaces a failed appointments request', async () => { - vi.mocked(appointmentsService.listMyAppointments).mockRejectedValue(new ApiError('Appointment service is down.', 503)); + vi.mocked(appointmentsService.listMyAppointments).mockRejectedValue(new ApiError('PatientAppointment service is down.', 503)); renderAt('/patient/appointments/apt-1'); diff --git a/src/pages/AppointmentDetailPage.tsx b/src/pages/AppointmentDetailPage.tsx index e1138e5..d3f54d9 100644 --- a/src/pages/AppointmentDetailPage.tsx +++ b/src/pages/AppointmentDetailPage.tsx @@ -9,6 +9,8 @@ import styles from './AppointmentDetailPage.module.css'; const STATUS_COPY: Record = { scheduled: 'Booked', + checked_in: 'Checked in', + in_progress: 'Being seen', completed: 'Completed', cancelled: 'Cancelled', no_show: 'Marked as a no-show', @@ -16,12 +18,19 @@ const STATUS_COPY: Record = { /** Settled visits have no queue to join, and saying why is kinder than * silently omitting the panel. */ -const CLOSED_COPY: Record, string> = { +const CLOSED_COPY: Record<'completed' | 'cancelled' | 'no_show', string> = { completed: 'This visit is already closed, so there is nothing to check in to.', cancelled: 'This appointment was cancelled, so there is nothing to check in to.', no_show: 'This appointment was recorded as a no-show, so there is nothing to check in to.', }; +/** `checked_in` and `in_progress` came from the doctor-side statuses the W3 + * flow added: a patient already in the queue must still see the live panel, + * not a "nothing to check in to" message. */ +function isClosedVisit(status: AppointmentStatus): status is 'completed' | 'cancelled' | 'no_show' { + return status === 'completed' || status === 'cancelled' || status === 'no_show'; +} + export function AppointmentDetailPage() { const { appointmentId } = useParams(); const appointmentsQuery = useMyAppointments(); @@ -94,16 +103,14 @@ export function AppointmentDetailPage() { : 'You booked this visit yourself.'}

- {appointment.status === 'scheduled' ? ( - isOnSlotDay(appointment, now) ? ( - - ) : ( -

- Check-in opens on the day of your visit ({formatSlotDate(slot.startTime, now)}). -

- ) - ) : ( + {isClosedVisit(appointment.status) ? (

{CLOSED_COPY[appointment.status]}

+ ) : appointment.status === 'scheduled' && !isOnSlotDay(appointment, now) ? ( +

+ Check-in opens on the day of your visit ({formatSlotDate(slot.startTime, now)}). +

+ ) : ( + )}

diff --git a/src/pages/PatientDashboardPage.test.tsx b/src/pages/PatientDashboardPage.test.tsx index ec9b1eb..a26d2df 100644 --- a/src/pages/PatientDashboardPage.test.tsx +++ b/src/pages/PatientDashboardPage.test.tsx @@ -3,7 +3,7 @@ import { render, screen, within } from '../test/render'; import { PatientDashboardPage } from './PatientDashboardPage'; import { useAuthStore } from '../store/auth-store'; import { useProfileStore } from '../store/profile-store'; -import type { Appointment, Dependent, HealthEntry, HealthSectionKey } from '../types/models'; +import type { PatientAppointment, Dependent, HealthEntry, HealthSectionKey } from '../types/models'; import * as dependentsService from '../services/dependents-service'; import * as healthService from '../services/health-profile-service'; import * as appointmentsService from '../services/appointments-service'; @@ -58,7 +58,7 @@ function laterToday(): Date { return new Date(now.getFullYear(), now.getMonth(), now.getDate(), 23, 50, 0); } -function appointment(start: Date, status: Appointment['status'] = 'scheduled'): Appointment { +function appointment(start: Date, status: PatientAppointment['status'] = 'scheduled'): PatientAppointment { return { id: 'apt-1', patientProfileId: 'pp-1', diff --git a/src/pages/PatientDashboardPage.tsx b/src/pages/PatientDashboardPage.tsx index 801bdf6..6675f3b 100644 --- a/src/pages/PatientDashboardPage.tsx +++ b/src/pages/PatientDashboardPage.tsx @@ -9,6 +9,7 @@ import { HealthProfilePage } from './HealthProfilePage'; import { AccountSettingsPage } from './AccountSettingsPage'; import { FacilityFinderPage } from './FacilityFinderPage'; import { CareThreadPage } from './CareThreadPage'; +import styles from './PatientDashboardPage.module.css'; function PatientHome() { const { cards, sources } = useCareHub(); @@ -24,14 +25,53 @@ function PatientHome() {

Phase W2 · in progress -

Welcome{user ? `, ${user.email}` : ''}

-

Doctor search, booking, and your appointments will live here — see ROADMAP.md Phase W2.

-
@@ -47,6 +87,7 @@ export function PatientDashboardPage() { } /> } /> } /> + } /> ); } diff --git a/src/services/appointments-service.ts b/src/services/appointments-service.ts index 9e92f3c..d4c5cd8 100644 --- a/src/services/appointments-service.ts +++ b/src/services/appointments-service.ts @@ -10,10 +10,10 @@ // endpoints in #32/#34/#37 are all built as `me`-scoped calls (the frontend // has no way to learn that id — documented gap). import { apiFetch } from './api-client'; -import type { Appointment, AppointmentQueue } from '../types/models'; +import type { PatientAppointment, AppointmentQueue } from '../types/models'; -export function listMyAppointments(accessToken: string): Promise { - return apiFetch('/appointments/mine', { accessToken }); +export function listMyAppointments(accessToken: string): Promise { + return apiFetch('/appointments/mine', { accessToken }); } /** assumed (core#129) */ diff --git a/src/styles/global.css b/src/styles/global.css index d8b10bb..8ed8091 100644 --- a/src/styles/global.css +++ b/src/styles/global.css @@ -117,3 +117,13 @@ --color-danger-surface: #2e1c15; --color-focus-ring: #4a + +/* Printing should hand over the document, not the app around it. The patient + receipt (#37) is the first thing here worth printing. */ +@media print { + header, + nav, + footer { + display: none; + } +} diff --git a/src/types/models.ts b/src/types/models.ts index b9f6135..0481520 100644 --- a/src/types/models.ts +++ b/src/types/models.ts @@ -777,3 +777,93 @@ export interface LabResult { isCritical: boolean; issuedAt: string; } + +// --- Patient-side appointment view (issues #32/#33/#34/#37) ------------------ +// `Appointment` above is the doctor-facing row the W3 queue screens use. The +// patient screens in this feature set read docforum-core's real +// `GET /appointments/mine`, which `include`s the availability slot and returns +// the origin and audit timestamps, so it is a different shape and gets its own +// name rather than a second declaration of `Appointment`. Dates are ISO strings +// because that is what JSON carries. + +export type SlotStatus = 'open' | 'held' | 'booked'; +export type AppointmentOrigin = 'direct_booking' | 'referral'; + +export interface AvailabilitySlot { + id: string; + doctorProfileId: string; + status: SlotStatus; + startTime: string; + endTime: string; + createdAt: string; + updatedAt: string; +} + +export interface PatientAppointment { + id: string; + patientProfileId: string; + doctorProfileId: string; + availabilitySlotId: string; + status: AppointmentStatus; + origin: AppointmentOrigin; + availabilitySlot: AvailabilitySlot; + createdAt: string; + updatedAt: string; +} + +// --- Live visit queue (#32) -------------------------------------------------- +// assumed — docforum-core has no queue endpoint yet; the shape is the smallest +// one that can distinguish "no queue published" from "you are first". + +export type QueuePhase = 'not_open' | 'waiting' | 'being_seen' | 'completed'; + +export interface AppointmentQueue { + appointmentId: string; + phase: QueuePhase; + /** Patients still ahead. null means no queue is published yet — which is + * not the same as being first. */ + peopleAhead: number | null; + /** Minutes. Always rendered as an estimate. */ + estimatedWaitMinutes: number | null; + /** null = this backend has no check-in window, so the UI says "check in on + * the day" instead of inventing an opening time. */ + checkInOpensAt: string | null; + checkedInAt: string | null; +} + +// --- PHI access log (#34) ---------------------------------------------------- +// assumed — docforum-core#40 (audit log read API) is not landed; these mirror +// the event its write-side middleware already records. + +export type AccessActorRole = 'doctor' | 'facility' | 'patient' | 'admin'; +export type AccessRecordType = 'health_profile' | 'appointment' | 'referral' | 'order' | 'dependent'; +export type AccessReason = 'consultation' | 'order_fulfillment' | 'result_delivery' | 'handover_claim' | 'support'; + +export interface AccessLogEvent { + id: string; + occurredAt: string; + actorRole: AccessActorRole; + actorName: string; + recordType: AccessRecordType; + reason: AccessReason; +} + +export interface AccessLogPage { + events: AccessLogEvent[]; + nextCursor: string | null; +} + +// --- Payment history and receipts (#37) -------------------------------------- + +export interface PaymentHistoryEntry extends PaymentIntent { + /** assumed — the real row has no refund deadline column. */ + refundDeadlineAt?: string | null; + /** assumed — the real response carries only `facilityId`, an internal id + * the patient-facing UI must not render. */ + facilityName?: string; +} + +export interface PaymentHistoryPage { + intents: PaymentHistoryEntry[]; + nextCursor: string | null; +}