Patient Portal

Patient-facing dashboard for prescriptions, shipments, messaging, and telehealth.

Overview

The Patient Portal is an Express 5 BFF (Backend for Frontend) serving a React SPA at patient.hisera.com. It runs on ECS behind the ALB at priority 5 and provides patients with a self-service dashboard for managing their prescriptions, tracking shipments, messaging their care team, and scheduling telehealth appointments.

The BFF layer handles authentication, session management, and proxies requests to both Canvas FHIR and the Integration Service, ensuring patients only see their own data.

Architecture

┌──────────────────────────────────────────┐
│  patient.hisera.com (ECS via ALB)        │
│  Express 5 BFF + Vite React SPA          │
└───────────┬──────────────┬───────────────┘
            │              │
   Canvas FHIR API    Integration Service
   │                  │
   ├─ Patients        ├─ Shipments
   ├─ MedicationReq   ├─ Notifications
   ├─ Communications  ├─ FedEx Tracking
   └─ Appointments    └─ Scheduling

Infrastructure

ComponentValue
Host patient.hisera.com
ALB Priority 5 (highest priority rule)
Target Group hisera-tg-patient-portal
Runtime ECS Fargate

Authentication

The Patient Portal supports two authentication methods. Both result in a JWT session cookie with a 4-hour expiry.

Email OTP

Patients enter their email address and receive a verification code via SendGrid. The code is validated server-side and a JWT session cookie is set.

POST /api/patient/auth/send-code

Sends a verification code to the patient's email address via SendGrid.

POST /api/patient/auth/verify

Validates the verification code and sets a JWT session cookie (4h expiry).

Canvas OAuth SSO

Patients who access the portal from a Canvas magic link are authenticated via Canvas OAuth. The BFF exchanges the authorization code for a Canvas access token, looks up the patient, and issues a JWT session cookie.

Canvas Portal The Canvas patient portal at yourera.canvasmedical.com sends magic link emails via the SendInviteEffect plugin. The magic link redirects to the patient portal with an OAuth authorization code.

Dashboard

The dashboard is the patient's landing page after authentication. It displays a personalized greeting and a summary of their active treatment.

Dashboard Components

Prescriptions

The Prescriptions page displays the patient's medication history from Canvas FHIR MedicationRequest resources. Each prescription shows the medication name, dosage, prescriber, status, and date written.

GET /api/patient/prescriptions

Returns the authenticated patient's prescriptions from Canvas FHIR MedicationRequest.

Prescription Fields

FieldSourceDescription
medication MedicationRequest.medicationCodeableConcept Medication name and code
dosage MedicationRequest.dosageInstruction Dosage and frequency instructions
prescriber MedicationRequest.requester Prescribing practitioner name and NPI
status MedicationRequest.status active, completed, cancelled, stopped
dateWritten MedicationRequest.authoredOn Date the prescription was written

Shipments

The Shipments page shows all shipments for the patient, sourced from the Integration Service database. Each shipment includes real-time FedEx tracking data with a Leaflet map visualization.

Tracking Map

When a shipment has an active tracking number, the portal displays a Leaflet map (using CARTO Voyager tiles) with a pulsing location dot showing the package's last known location. The map is code-split into a ~47KB chunk and only loaded when needed.

GET /api/patient/shipments

Returns all shipments for the authenticated patient from the integration service database.

GET /api/patient/tracking/:trackingNumber

Proxies FedEx tracking data with ownership verification and geocoding. Results are cached for 30 minutes in the tracking_cache table.

Shipment Status Flow

label_created  packed  shipped  delivered
                                     
                                  voided
Ownership Check The /api/patient/tracking/:trackingNumber endpoint verifies that the tracking number belongs to the authenticated patient before returning data. This prevents patients from viewing other patients' shipment details.

Messages

The Messages page provides a secure messaging interface between the patient and their assigned care team. Messages are stored as Canvas FHIR Communication resources and auto-polled every 15 seconds for new messages.

Features

GET /api/patient/messages

Returns Canvas FHIR Communication resources for the authenticated patient.

POST /api/patient/messages

Sends a new message to the patient's assigned practitioner via Canvas FHIR Communication.

Scheduling

The Scheduling page allows patients to book, reschedule, and cancel telehealth appointments. The availability engine checks practitioner schedules and the Zoom integration creates meeting links automatically.

Booking Flow

  1. Patient selects a date from the availability calendar
  2. Available time slots are displayed based on practitioner schedules
  3. Patient selects a time slot and confirms the appointment
  4. A Zoom meeting is created automatically via the Zoom API
  5. Confirmation is sent to the patient via email and in-app notification
GET /api/patient/availability?date=2026-03-23

Returns available time slots for the given date from the availability engine.

POST /api/patient/appointments

Books a telehealth appointment. Creates a Zoom meeting and sends confirmation notifications.

GET /api/patient/appointments

Returns the patient's upcoming and past appointments with Zoom meeting links.

Notifications

The notification system provides persistent, database-backed notifications delivered via the Integration Service. Notifications are displayed as an in-app feed with an unread count badge on the dashboard.

Notification Types

GET /api/patient/notifications

Returns persistent notifications for the authenticated patient, ordered by creation date descending.

POST /api/patient/notifications/:id/read

Marks a notification as read.

API Endpoints

All /api/patient/* endpoints require a valid JWT session cookie. The BFF enforces patient-scoped access — patients can only view their own data.

Authentication

MethodEndpointDescription
POST /api/patient/auth/send-code Send verification code via SendGrid
POST /api/patient/auth/verify Verify code and set JWT session cookie
GET /api/patient/auth/canvas-callback Canvas OAuth callback handler
POST /api/patient/auth/logout Clear session cookie

Patient Data

MethodEndpointDescription
GET /api/patient/profile Patient profile from Canvas FHIR
GET /api/patient/prescriptions Prescription list from Canvas MedicationRequest
GET /api/patient/shipments Shipment history from integration DB
GET /api/patient/tracking/:trackingNumber FedEx tracking with ownership check
GET /api/patient/messages Messages from Canvas FHIR Communications
POST /api/patient/messages Send message to practitioner
GET /api/patient/notifications Notification feed
POST /api/patient/notifications/:id/read Mark notification as read
GET /api/patient/availability Available appointment time slots
POST /api/patient/appointments Book telehealth appointment
GET /api/patient/appointments Appointment list with Zoom links