Patient Portal App Backend Template
Deliver lab results, manage treatment plans, and enable secure doctor–patient messaging
A production-ready patient portal backend on Back4app with secure lab result delivery, treatment plan management, clinician messaging, appointment linking, and centralized audit logs. Includes ER diagram, data dictionary, JSON schema, API playground, and an AI Agent prompt for rapid bootstrap.
Key Takeaways
Ship a patient-facing backend with secure access controls, lab versioning, treatment plan histories, threaded messaging, and audit trails so your product team can focus on UX and compliance.
- Patient-first data model — Keep patient identity, lab results, treatments, and messages modeled separately but linked for clear provenance and authorization.
- Secure messaging — Threaded, attachment-friendly messages between patients and providers with clear read receipts and retention controls.
- Versioned lab results — Store lab results with provenance and version metadata so updated reports and addenda are tracked.
- Treatment plan lifecycle — Manage treatment plan drafts, approvals by providers, patient acknowledgement, and version history.
- Compliance-friendly logging — Centralized AuditLog class records sensitive events for review, monitoring, and compliance.
What Is the Patient Portal App Backend Template?
Back4app is a backend-as-a-service (BaaS) for rapid delivery. The Patient Portal App Backend Template is a pre-built schema for patient profiles, lab results, treatment plans, secure messaging, appointments, and audit logs. Connect your preferred frontend (React, Flutter, Next.js, and more) and ship faster.
Best for:
Overview
Patient portals require strong data boundaries, auditable changes, and reliable delivery of sensitive items like lab results and treatment plans.
This template defines PatientProfile, LabResult, TreatmentPlan, Message, ProviderProfile, Appointment, and AuditLog with ownership and role-based rules so teams can implement patient portals quickly and securely.
Core Patient Portal Features
Every technology card in this hub uses the same patient portal backend schema with PatientProfile, LabResult, TreatmentPlan, Message, ProviderProfile, Appointment, and AuditLog.
Patient profile & authentication
PatientProfile stores identity, contact details, and preferences with a pointer to the authenticated User.
Versioned lab results
LabResult stores test type, raw result payload, reportedAt, version, and provider provenance.
Treatment plan lifecycle
TreatmentPlan stores plan content, provider approver, status (draft, active, completed), and effective window.
Secure doctor–patient messaging
Message supports threads, attachments, sender/recipient pointers, and delivery/read status.
Appointment linking
Appointment links patient, provider, scheduled time, and status for visit context.
Centralized audit logs
AuditLog captures actor identity, action type, entity context, and payload metadata for compliance.
Why Build Your Patient Portal App Backend with Back4app?
Back4app handles the backend fundamentals—security, persistence, APIs, and realtime—so you can focus on patient experience, privacy workflows, and clinical integration.
- •Secure delivery of clinical data: Built-in auth and ACL/CLP patterns let you control exactly which users can see each lab result, treatment plan, or message.
- •Audit and provenance: AuditLog captures who viewed, published, or modified sensitive records so you can support compliance and debugging.
- •Messaging and notifications: Threaded messages, attachments, and optional live updates make clinician–patient conversations smooth and timely.
Deploy a secure patient portal backend quickly and iterate on clinical workflows instead of backend plumbing.
Core Benefits
A patient portal backend that emphasizes privacy, provenance, and rapid delivery.
Accelerated patient experiences
Ship lab result views, treatment plan delivery, and secure messaging faster by reusing a validated backend contract.
Strong data provenance
Version lab results and treatment plans so clinical changes are auditable and traceable.
Fine-grained permissions
Protect sensitive items with ACL/CLP and role checks so only permitted clinicians and patients can access them.
Integrated messaging
Threaded messages with attachments and optional real-time updates improve clinician–patient collaboration.
Compliance-ready logging
Centralized AuditLog supports reviews, incident investigation, and compliance reporting.
AI-assisted bootstrap
Jumpstart development with a curated AI Agent prompt that scaffolds schema, ACLs, and basic integration code.
Ready to build a secure patient portal?
Let the Back4app AI Agent scaffold your patient portal backend and generate patient profiles, lab results, treatment plans, messaging, and audit logs from one prompt.
Free to start — 50 AI Agent prompts/month, no credit card required
Technical Stack
Everything included in this Patient Portal backend template.
ER Diagram
Entity relationship model for the Patient Portal backend schema.
Schema covering patient profiles, providers, lab results, treatment plans, messaging, appointments, and audit logging.
View diagram source
erDiagram
PatientProfile ||--o{ LabResult : "has"
PatientProfile ||--o{ TreatmentPlan : "receives"
PatientProfile ||--o{ Message : "context for"
PatientProfile ||--o{ Appointment : "scheduled in"
_User ||--o{ Message : "sends/receives"
_User ||--o{ TreatmentPlan : "authors"
_User ||--o{ Appointment : "provides"
PatientProfile {
String objectId PK
Pointer user FK
String medicalRecordNumber
String displayName
Date dateOfBirth
String primaryClinic
Boolean isActive
Date createdAt
Date updatedAt
}
LabResult {
String objectId PK
Pointer patient FK
Pointer orderedBy FK
String testCode
String testName
String resultValue
String units
String referenceRange
String status
Date publishedAt
Array attachments
Date createdAt
Date updatedAt
}
TreatmentPlan {
String objectId PK
Pointer patient FK
Pointer createdBy FK
String summary
String details
String status
Date startDate
Date endDate
Date createdAt
Date updatedAt
}
Message {
String objectId PK
String conversationId
Pointer from FK
Pointer to FK
Pointer patient FK
String body
Array attachments
Boolean isRead
Date sentAt
Date createdAt
Date updatedAt
}
Appointment {
String objectId PK
Pointer patient FK
Pointer provider FK
Date startAt
Date endAt
String location
String status
String reason
Date createdAt
Date updatedAt
}
AuditLog {
String objectId PK
Pointer actor FK
String entityType
String entityId
String action
String summary
Object metadata
Date createdAt
Date updatedAt
}
Integration Flow
Typical runtime flow for authentication, lab result delivery, treatment plan updates, and messaging.
View diagram source
sequenceDiagram
participant Patient
participant App as Patient Portal App
participant Clinician
participant Back4app as Back4app Cloud
Patient->>App: Sign in with email or SSO
App->>Back4app: POST /login (credentials/SSO token)
Back4app-->>App: Return Session Token + Patient context
Patient->>App: Open Dashboard (profile & recent labs)
App->>Back4app: GET /classes/PatientProfile?where={"user":Pointer("_User", "u123")}
Back4app-->>App: PatientProfile object
App->>Back4app: GET /classes/LabResult?where={"patient":Pointer("PatientProfile","p123")}&order=-publishedAt
Back4app-->>App: List of LabResult (latest first)
Patient->>App: View active Treatment Plan
App->>Back4app: GET /classes/TreatmentPlan?where={"patient":Pointer("PatientProfile","p123"),"status":"active"}
Back4app-->>App: TreatmentPlan object
Patient->>App: Send secure message to clinician
App->>Back4app: POST /classes/Message (conversationId, body, to: Pointer(_User, clinicianId))
Back4app-->>App: Message objectId
Back4app-->>App: LiveQuery -> new Message or LabResult update
App-->>Patient: Real-time notification (new message / result available)
Clinician->>Back4app: Update LabResult (finalize)
Back4app-->>App: LiveQuery event -> App fetches updated LabResult
App-->>Patient: Alert: "New lab result available"Data Dictionary
Full field-level reference for every class in the Patient Portal schema.
| Field | Type | Description | Required |
|---|---|---|---|
| objectId | String | Auto-generated unique identifier | Auto |
| user | Pointer<_User> | Linked Back4app user account | |
| medicalRecordNumber | String | Unique MRN for the patient | |
| displayName | String | Patient full name shown in UI | |
| dateOfBirth | Date | Patient date of birth | — |
| primaryClinic | String | Primary clinic or provider group | — |
| isActive | Boolean | Active portal access flag | |
| createdAt | Date | Auto-generated creation timestamp | Auto |
| updatedAt | Date | Auto-generated last-update timestamp | Auto |
9 fields in PatientProfile
Security and Permissions
How ACL, CLP, and encryption strategies secure lab results, treatment plans, messages, and audit logs.
Role-based access and ownership
Apply ACLs so patients can see their own records and providers see assigned patient data; CLPs prevent unauthorized class operations.
Encrypted payloads and attachments
Store sensitive blobs (lab attachments, PDFs) behind signed URLs and use storage-level encryption for at-rest protection.
Append-only audit trails
Write AuditLog entries from server-side Cloud Code to ensure users cannot tamper with historical compliance records.
Schema (JSON)
Raw JSON schema definition ready to copy into Back4app or use as implementation reference.
{
"classes": [
{
"className": "PatientProfile",
"fields": {
"objectId": {
"type": "String",
"required": false
},
"user": {
"type": "Pointer",
"required": true,
"targetClass": "_User"
},
"medicalRecordNumber": {
"type": "String",
"required": true
},
"displayName": {
"type": "String",
"required": true
},
"dateOfBirth": {
"type": "Date",
"required": false
},
"primaryClinic": {
"type": "String",
"required": false
},
"isActive": {
"type": "Boolean",
"required": true
},
"createdAt": {
"type": "Date",
"required": false
},
"updatedAt": {
"type": "Date",
"required": false
}
}
},
{
"className": "LabResult",
"fields": {
"objectId": {
"type": "String",
"required": false
},
"patient": {
"type": "Pointer",
"required": true,
"targetClass": "PatientProfile"
},
"orderedBy": {
"type": "Pointer",
"required": false,
"targetClass": "_User"
},
"testCode": {
"type": "String",
"required": false
},
"testName": {
"type": "String",
"required": true
},
"resultValue": {
"type": "String",
"required": false
},
"units": {
"type": "String",
"required": false
},
"referenceRange": {
"type": "String",
"required": false
},
"status": {
"type": "String",
"required": true
},
"publishedAt": {
"type": "Date",
"required": false
},
"attachments": {
"type": "Array",
"required": false
},
"createdAt": {
"type": "Date",
"required": false
},
"updatedAt": {
"type": "Date",
"required": false
}
}
},
{
"className": "TreatmentPlan",
"fields": {
"objectId": {
"type": "String",
"required": false
},
"patient": {
"type": "Pointer",
"required": true,
"targetClass": "PatientProfile"
},
"createdBy": {
"type": "Pointer",
"required": true,
"targetClass": "_User"
},
"summary": {
"type": "String",
"required": true
},
"details": {
"type": "String",
"required": false
},
"status": {
"type": "String",
"required": true
},
"startDate": {
"type": "Date",
"required": false
},
"endDate": {
"type": "Date",
"required": false
},
"createdAt": {
"type": "Date",
"required": false
},
"updatedAt": {
"type": "Date",
"required": false
}
}
},
{
"className": "Message",
"fields": {
"objectId": {
"type": "String",
"required": false
},
"conversationId": {
"type": "String",
"required": true
},
"from": {
"type": "Pointer",
"required": true,
"targetClass": "_User"
},
"to": {
"type": "Pointer",
"required": true,
"targetClass": "_User"
},
"patient": {
"type": "Pointer",
"required": true,
"targetClass": "PatientProfile"
},
"body": {
"type": "String",
"required": true
},
"attachments": {
"type": "Array",
"required": false
},
"isRead": {
"type": "Boolean",
"required": true
},
"sentAt": {
"type": "Date",
"required": false
},
"createdAt": {
"type": "Date",
"required": false
},
"updatedAt": {
"type": "Date",
"required": false
}
}
},
{
"className": "Appointment",
"fields": {
"objectId": {
"type": "String",
"required": false
},
"patient": {
"type": "Pointer",
"required": true,
"targetClass": "PatientProfile"
},
"provider": {
"type": "Pointer",
"required": true,
"targetClass": "_User"
},
"startAt": {
"type": "Date",
"required": true
},
"endAt": {
"type": "Date",
"required": true
},
"location": {
"type": "String",
"required": false
},
"status": {
"type": "String",
"required": true
},
"reason": {
"type": "String",
"required": false
},
"createdAt": {
"type": "Date",
"required": false
},
"updatedAt": {
"type": "Date",
"required": false
}
}
},
{
"className": "AuditLog",
"fields": {
"objectId": {
"type": "String",
"required": false
},
"actor": {
"type": "Pointer",
"required": true,
"targetClass": "_User"
},
"entityType": {
"type": "String",
"required": true
},
"entityId": {
"type": "String",
"required": true
},
"action": {
"type": "String",
"required": true
},
"summary": {
"type": "String",
"required": true
},
"metadata": {
"type": "Object",
"required": false
},
"createdAt": {
"type": "Date",
"required": false
},
"updatedAt": {
"type": "Date",
"required": false
}
}
}
]
}Build with AI Agent
Use the Back4app AI Agent to generate a Patient Portal app from this template, including backend schema, ACLs, and starter frontend integration.
Create a Patient Portal backend on Back4app with this exact schema and behavior. Schema: 1. PatientProfile: user (Pointer to User, required), fullName (String, required), dob (Date, optional), contact (Object), medicalRecordNumber (String, required, unique); objectId, createdAt, updatedAt. 2. ProviderProfile: user (Pointer to User, required), specialty (String), clinic (String), contact (Object); objectId, createdAt, updatedAt. 3. LabResult: patient (Pointer to PatientProfile, required), provider (Pointer to ProviderProfile, required), reportType (String), resultData (Object), reportedAt (Date, required), version (Number, default 1), attachments (Array of File), visibility (String: patient-only, provider-only, shared); objectId, createdAt, updatedAt. 4. TreatmentPlan: patient (Pointer to PatientProfile, required), provider (Pointer to ProviderProfile, required), summary (String), details (Object), status (String: draft, active, completed), effectiveFrom (Date), effectiveTo (Date), version (Number); objectId, createdAt, updatedAt. 5. Message: sender (Pointer to User, required), recipient (Pointer to User, required), threadId (String, required), body (String), attachments (Array of File), status (String: sent, delivered, read), sentAt (Date); objectId, createdAt, updatedAt. 6. Appointment: patient (Pointer to PatientProfile, required), provider (Pointer to ProviderProfile, required), scheduledAt (Date, required), status (String: scheduled, canceled, completed), location (String); objectId, createdAt, updatedAt. 7. AuditLog: actor (Pointer to User, required), action (String, required), entityType (String, required), entityId (String, required), payload (Object, optional), createdAt (Date); objectId, createdAt, updatedAt. Security: - Enforce ACLs so patients only read their LabResult and TreatmentPlan records. Providers see assigned patients. Use Cloud Code for sensitive transitions and to write AuditLog entries server-side. Protect attachments with signed URLs and storage encryption. Auth: - Support sign-up for patients and providers; role assignment; secure login and session management. Behavior: - Patient logs in, fetches latest LabResult versions and TreatmentPlans, sends messages to provider threads, and receives notifications. Providers publish lab results and treatment plans; system writes AuditLog entries for publish actions. Deliver: - Back4app app with schema, CLPs, ACLs, Cloud Code hooks for publishing and audit logging, and starter frontend integration for patient and provider views.
Press the button below to open the Agent with this template prompt pre-filled.
This is the base prompt without a technology suffix. You can adapt the generated frontend stack afterward.
API Playground
Try REST and GraphQL endpoints against the Patient Portal schema. Responses use mock data and do not require a Back4app account.
Uses the same schema as this template.
Choose Your Technology
Expand each card for integration steps, state patterns, data model examples, and offline notes.
Flutter Patient Portal Backend
React Patient Portal Backend
React Native Patient Portal Backend
Next.js Patient Portal Backend
JavaScript Patient Portal Backend
Android Patient Portal Backend
iOS Patient Portal Backend
Vue Patient Portal Backend
Angular Patient Portal Backend
GraphQL Patient Portal Backend
REST API Patient Portal Backend
PHP Patient Portal Backend
.NET Patient Portal Backend
What You Get with Every Technology
Every stack uses the same Patient Portal backend schema and API contracts.
Unified patient data structure
Easily manage and access all patient information in one schema.
Secure messaging for patient portal
Facilitate safe communication between patients and healthcare providers.
Real-time appointment scheduling
Allow patients to book and manage appointments seamlessly.
Comprehensive lab results tracking
Enable patients to view and track their lab results securely.
Access control for sensitive data
Ensure that only authorized personnel can view patient records.
REST/GraphQL APIs for patient portal
Integrate easily with various frontends using flexible APIs.
Patient Portal Framework Comparison
Compare setup speed, SDK style, and AI support across all supported technologies.
| Framework | Setup Time | Patient Portal Benefit | SDK Type | AI Support |
|---|---|---|---|---|
| Rapid (5 min) setup | Single codebase for patient portal on mobile and web. | Typed SDK | Full | |
| ~5 min | Fast web dashboard for patient portal. | Typed SDK | Full | |
| About 5 min | Cross-platform mobile app for patient portal. | Typed SDK | Full | |
| Under 5 minutes | Server-rendered web app for patient portal. | Typed SDK | Full | |
| ~3 min | Lightweight web integration for patient portal. | Typed SDK | Full | |
| Rapid (5 min) setup | Native Android app for patient portal. | Typed SDK | Full | |
| ~5 min | Native iOS app for patient portal. | Typed SDK | Full | |
| About 5 min | Reactive web UI for patient portal. | Typed SDK | Full | |
| Under 5 minutes | Enterprise web app for patient portal. | Typed SDK | Full | |
| Quick (2 min) setup | Flexible GraphQL API for patient portal. | GraphQL API | Full | |
| ~2 min | REST API integration for patient portal. | REST API | Full | |
| Under 5 min | Server-side PHP backend for patient portal. | REST API | Full | |
| About 5 min | .NET backend for patient portal. | Typed SDK | Full |
Setup time reflects expected duration from project bootstrap to first patient login and lab result query using this template schema.
Frequently Asked Questions
Common questions about building a Patient Portal backend with this template.
Ready to Build Your Patient Portal App?
Start your patient portal project in minutes. No credit card required.