Secure messaging, document management, online payments, and sensitive-class consent gating for patient-facing portal features.
Data Classification: Mixed scoping. PortalMessage and Payment are org-scoped (partitioned by OrganizationID). PatientDocument and SensitiveClassGating are global (no OrganizationID) — these are exceptions to IC rule #11 because documents and consent travel with the patient across organizations. See Data Model for ownership rules.
PortalMessage
Org-scoped. Trust Tier: T1 (PHI in message body).
Schema
Field
Type
Required
PK
FK
Notes
PortalMessageID
UUID
Yes
Yes
Primary key
PatientID
UUID
Yes
Patient
SenderUserID
UUID
Yes
User
RecipientUserID
UUID
Yes
User
AttachedDocumentID
UUID
No
PatientDocument
ThreadID
UUID
Yes
Groups messages in a thread
Subject
String(100)
Yes
Body
Text
Yes
Category
String(50)
Yes
e.g. Clinical, Billing, Administrative
Priority
String(50)
Yes
Normal / Urgent
IsReadByRecipient
Bool
Yes
ReadDateTime
DateTime (UTC)
No
IsPatientInitiated
Bool
Yes
ResponseSLAHours
Int
No
SLA deadline in hours
IsActive
Bool
Yes
OrganizationID
UUID
Yes
Organization
Tenant partition key
CreatedByUserID
UUID
Yes
User
Audit
CreatedDateTime
DateTime (UTC)
Yes
Audit
UpdatedByUserID
UUID
Yes
User
Audit
UpdatedDateTime
DateTime (UTC)
Yes
Audit
RBAC
Role
Tier
Permissions
Patient (10)
T1
Read own messages; send new messages
Family Proxy (10*)
T1
Consent-gated access to patient messages
Front Desk (30)
T1
Read / respond to administrative messages
MA / RN (40)
T1
Read messages; attach to encounter
Clinician (60)
T1
Read / respond to clinical messages; sign documents
Manager (70)
T1
Read all; manage SLA configuration
EditAMI (90)
T1
Schema administration
PatientDocument
Global entity (no OrganizationID) — exception to IC rule #11. Documents travel with the patient. Trust Tier: T1 (PHI content).
Schema
Field
Type
Required
PK
FK
Notes
PatientDocumentID
UUID
Yes
Yes
Primary key
PatientID
UUID
Yes
Patient
EncounterID
UUID
No
Encounter
SourceOrganizationID
UUID
Yes
Organization
Originating org (not partition key)
DocumentType
String(50)
Yes
e.g. Lab Result, Consent, Insurance Card
FileName
String(100)
Yes
MimeType
String(50)
Yes
application/pdf, image/jpeg, etc.
FileSizeBytes
Int
Yes
StorageUrl
String
Yes
Blob storage URL (SAS-token gated)
Description
String(200)
No
IsSensitive
Bool
Yes
Triggers consent gating
SensitiveClass
String(50)
No
e.g. BehavioralHealth, SubstanceUse, HIV
IsActive
Bool
Yes
CreatedByUserID
UUID
Yes
User
Audit
CreatedDateTime
DateTime (UTC)
Yes
Audit
UpdatedByUserID
UUID
Yes
User
Audit
UpdatedDateTime
DateTime (UTC)
Yes
Audit
RBAC
Role
Tier
Permissions
Patient (10)
T1
Read own documents; upload documents
Family Proxy (10*)
T1
Consent-gated read access
Front Desk (30)
T1
Read non-sensitive; upload insurance/admin docs
MA / RN (40)
T1
Read; attach to encounter
Clinician (60)
T1
Read all; sign clinical documents
Manager (70)
T1
Read all; manage document types
EditAMI (90)
T1
Schema administration
Payment
Org-scoped. Trust Tier: T2 (financial data, no clinical PHI).
Schema
Field
Type
Required
PK
FK
Notes
PaymentID
UUID
Yes
Yes
Primary key
PatientID
UUID
Yes
Patient
EncounterID
UUID
No
Encounter
StatementID
UUID
No
PatientStatement
PaymentPlanID
UUID
No
Optional payment plan reference
PaymentAmount
Money
Yes
PaymentCurrencyCode
String(3)
Yes
ISO 4217
PaymentMethod
String(50)
Yes
CreditCard / DebitCard / ACH / Cash / Check
PaymentProcessorRef
String(100)
No
Stripe/processor transaction ID
PaymentDateTime
DateTime (UTC)
Yes
Category
String(50)
Yes
Copay / Coinsurance / Deductible / Balance
IsPortalInitiated
Bool
Yes
Status
String(50)
Yes
Pending / Completed / Failed / Refunded / Voided
IsActive
Bool
Yes
OrganizationID
UUID
Yes
Organization
Tenant partition key
CreatedByUserID
UUID
Yes
User
Audit
CreatedDateTime
DateTime (UTC)
Yes
Audit
UpdatedByUserID
UUID
Yes
User
Audit
UpdatedDateTime
DateTime (UTC)
Yes
Audit
RBAC
Role
Tier
Permissions
Patient (10)
T2
Read own payments; initiate portal payments
Front Desk (30)
T2
Read; create copay payments
MA / RN (40)
T2
Read
Biller (51)
T2
Create / adjust payments
Clinician (60)
T2
Read
Manager (70)
T2
Read all; void / refund
EditAMI (90)
T2
Schema administration
SensitiveClassGating
Global entity (no OrganizationID) — exception to IC rule #11. Consent decisions travel with the patient. Trust Tier: T1 (consent metadata for sensitive categories).
Schema
Field
Type
Required
PK
FK
Notes
SensitiveClassGatingID
UUID
Yes
Yes
Primary key
PatientID
UUID
Yes
Patient
SensitiveClass
String(50)
Yes
BehavioralHealth / SubstanceUse / HIV / ReproductiveHealth
IsConsented
Bool
Yes
ConsentedDateTime
DateTime (UTC)
No
ConsentRevokedDateTime
DateTime (UTC)
No
ProxyAccessAllowed
Bool
Yes
Family proxy can view this class
SharingWithOtherOrgsAllowed
Bool
Yes
Cross-org sharing permission
GatingPromptText
Text
No
Displayed to user before access
IsActive
Bool
Yes
CreatedByUserID
UUID
Yes
User
Audit
CreatedDateTime
DateTime (UTC)
Yes
Audit
UpdatedByUserID
UUID
Yes
User
Audit
UpdatedDateTime
DateTime (UTC)
Yes
Audit
RBAC
Role
Tier
Permissions
Patient (10)
T1
Read own consent records; update consent decisions
Family Proxy (10*)
T1
Read if ProxyAccessAllowed = true
Clinician (60)
T1
Read consent status (not modify)
Manager (70)
T1
Read all consent records
EditAMI (90)
T1
Schema administration
Trust tier roll-up
Entity
Tier
Source of truth
PortalMessage
1 — Internal canonical
Authored by a verified user within the system (patient or practice staff)
PatientDocument
1 — Internal canonical
Uploaded by an authenticated user; content trust depends on source (patient-attested vs. practice-scanned)
Payment
1 — Internal canonical
Created from payment processor webhook (confirmed) or manual entry (pending confirmation)
SensitiveClassGating
1 — Internal canonical
Set by the patient or authorized proxy; consent actions are audited
RBAC matrix (IC 0–100 scale)
Role
Level
PortalMessage
PatientDocument
Payment
SensitiveClassGating
Patient (self)
10
Read own; write own
Read own; upload own
Read own
Read own; update own consent
Family / Proxy
10*
Read dependant’s; write on behalf
Read dependant’s (consent-gated)
Read dependant’s
Read dependant’s; update with consent chain
Front desk (Jordan)
30
Read / respond in own org
Read (own org context)
Create copay payments
Read gating state
MA / RN (Tasha)
40
Read / respond clinical
Read; attach to encounter
Read
Read gating state
Biller (Priya)
51
Read billing-category
Read billing-related
Create / adjust / reconcile
Read gating state
Clinician (Dr. M / Maria)
60
Read / respond clinical
Read all; sign off on uploaded docs
Read
Read; recommend consent change
Practice manager (Sam)
70
Read all in org; manage SLA
Read all
Void / refund
Read; override proxy disputes
EditAMI
90
Required for any AMI schema break (per IC hard rule #5)
* Proxy level is context-dependent: the base level is 10, but proxy access is further gated by the SensitiveClassGating consent flags and the authorization-chain trace. A proxy without consent for a sensitive class cannot view data in that class even at level 10.
stateDiagram-v2
[*] --> Draft
Draft --> Sent : Patient or staff sends
Sent --> Read : Recipient opens
Read --> Replied : Recipient responds
Replied --> Read : Original sender reads reply
Read --> Closed : Manager closes thread
Replied --> Closed : Manager closes thread
Sent --> Escalated : SLA breached
Escalated --> Read : Recipient opens after escalation
Functional Requirements
P0 The system SHALL allow patients to send secure messages to their care team and receive threaded responses.
P0 The system SHALL enforce sensitive-class consent gating: documents marked IsSensitive=true are hidden from any user/proxy until the matching SensitiveClassGating record shows IsConsented=true.
P0 The system SHALL allow patients to grant or revoke consent per sensitive class (BehavioralHealth, SubstanceUse, HIV, ReproductiveHealth) at any time.
P0 The system SHALL process online payments (credit/debit/ACH) via the patient portal with PCI-DSS compliant tokenization (no card numbers stored).
P0 The system SHALL support family/proxy access gated by per-class ProxyAccessAllowed flag on SensitiveClassGating.
P1 The system SHALL track message SLA (ResponseSLAHours) and trigger escalation workflows when deadlines are breached.
P1 The system SHALL allow patients to upload documents (insurance cards, forms, images) with file-type validation and virus scanning.
P1 The system SHALL display patient statements and support partial payments and payment plans.
P1 The system SHALL allow staff to attach portal messages to an encounter record.
P1 The system SHALL support message categorization (Clinical, Billing, Administrative) for routing.
P1 The system SHALL allow billers to create and adjust payment records for copays and balances.
P1 The system SHALL allow managers to void or refund payments with audit trail.
P2 The system SHALL support cross-org document sharing when SharingWithOtherOrgsAllowed=true on the relevant SensitiveClassGating record.
P2 The system SHALL support payment receipt generation and email delivery.
P2 The system SHALL provide read-receipt tracking for portal messages.
P2 The system SHALL allow patients to download their complete document history as a ZIP export.
Non-Functional Requirements
Availability: Patient portal 99.9% uptime; maintenance windows outside 6AM-10PM patient-local-time.
Latency: Message send/receive round-trip under 2 seconds (95th percentile).
Security: All documents encrypted at rest (AES-256); SAS-token gated blob access with 15-minute expiry.
PCI-DSS: Payment processing uses tokenized card references only; no PAN stored in application database.
File Upload: Maximum 25 MB per file; allowed MIME types: PDF, JPEG, PNG, TIFF, HEIC; virus scan before storage.
Consent Audit: Every consent change (grant/revoke) logged with actor, timestamp, IP; immutable audit trail.
SLA Monitoring: Escalation engine checks unread messages every 5 minutes; alert to manager when ResponseSLAHours exceeded.
icApplication Overrides
How the four Patient Portal AMI schemas turn into a live application: module-specific stack additions, override component bindings, a versioning worked example, environment cascade, and RBAC enforcement.
Shared generation map. The IC platform code-gen flow, default bindings, environment cascade, RBAC model, and CLI commands are identical across all modules. See the IC Reference for the canonical shared reference. This section covers only Patient Portal-specific content.
Technology stack P0
The shared platform stack (Cosmos DB, Redis, IC-generated API, Angular 21, SQS+SNS, OpenTelemetry, etc.) is documented in the IC Reference. Module-specific additions:
Layer
Technology
Notes
Document storage
S3 + KMS
Encrypted at rest with KMS-managed keys; pre-signed URLs for download. Per BUILD decision in PRD §4.6.
FHIR Patient Access API
FHIR R4 + HTI-1 USCDI v3
Mandatory per HTI-1 §170.315(e)(1). Supports VDT, SMART on FHIR app launch.
SMART on FHIR
OAuth 2.0 + OpenID Connect
Third-party app launch with granular scopes. Backend-services SMART for server-to-server.
Messaging / notifications
Twilio (BAA), AWS SES, SendGrid
BUY primitives per PRD §4.6. TCPA opt-in/out management built on Twilio.
Custom consent-gating widget: class name, consent toggle, proxy-access toggle, prompt text, with audit logging.
(synthetic) AVS viewer
n/a
ic-ng21-portal-1-avs-viewer
Custom: encounter-derived AVS with plain-language toggle, translation selector, and education-content links.
(synthetic) VDT actions
n/a
ic-ng21-portal-1-vdt-actions
Custom: View / Download (CCDA + FHIR Bundle) / Transmit (SMART on FHIR launch) with audit logging.
(synthetic) Slot picker
n/a
ic-ng21-portal-1-slot-picker
Custom: provider + visit-type filter, eligibility status badge, booking confirmation with cost estimate.
Versioning — worked example P0
All Patient Portal artifacts are versioned break.feature.bug.buildtimestamp per IC hard rule #9. The example below traces a feature bump on SensitiveClassGating.
SensitiveClassGating 1.0.0.20260515T100000Z — Initial schema. Seven business fields plus three global audit columns (no OrganizationID — deliberate exception). Five sensitive classes: MentalHealth, SUD, HIV, Genetic, Reproductive. Component ic-ng21-portal-1-sensitive-class-gate binds to sensitiveclassgating@1.0.0.* via the DI manifest.
SensitiveClassGating 1.1.0.20260801T120000Z — feature bump — Adds a single optional field, AutoReConsentIntervalDaysInt, to support periodic re-consent prompts (e.g., ask the patient to re-confirm consent every 365 days for SUD data per 42 CFR Part 2 best practice). Per the IC change matrix:
Change
Version impact
Approval needed
Min permission
Add optional field AutoReConsentIntervalDaysInt
feature bump (1.0.0 → 1.1.0)
No
Write (51)
Because the change is backward-compatible, the component tag stays ic-ng21-portal-1-sensitive-class-gate. Existing UI consumers continue to bind sensitiveclassgating@1.x.* and ignore the new field. New UI surfaces that need the re-consent feature bind sensitiveclassgating@^1.1.0. No new database is required (IC rule #13 only applies to break bumps).
SensitiveClassGating 2.0.0.20280101T120000Z — break bump (illustrative) — An illustrative future break bump: SensitiveClassString50 is changed from a free-form String to a strongly-typed Enum with a fixed value set enforced at the DB layer. Per the IC change matrix this is change field type — break bump, EditAMI (90) approval, and per IC rule #13 a new database is provisioned with ETL from the old one. The component tag becomes ic-ng21-portal-2-sensitive-class-gate; consumers must re-bind. The old database stays live for the configured grace period (default 90 days) for rollback.
Illustrative. The 2.0.0 example is illustrative of the change matrix and IC rule #13; it is not a committed roadmap item.
Patient Portal environment details
Env
Payment processor
FHIR Patient Access API
Dev
Processor sandbox
Local FHIR server (test data)
QA
Processor sandbox
HL7 reference server + test patients
UAT
Processor UAT
Live FHIR endpoints (test patients)
Prod
Processor production
Live FHIR endpoints (real patients)
Patient Portal RBAC notes
Patient access. Self-only: the authenticated UserID must match the PatientID in the query. Proxy access is validated through the consent-chain service.
Sensitive-class gating. Before returning clinical fact data, the API checks SensitiveClassGating for the patient and suppresses categories where IsConsentedBool = false.
Proxy authorization. Proxy access is validated through the consent-chain service. The proxy’s relationship to the patient, the scope of authorization (full vs. category-limited), and any state minor-consent rules are checked before granting read access.
VDT compliance. View and Download actions are always available to the authenticated patient (Cures Act information-blocking rule). Transmit actions require the patient to authorize the third-party app through SMART on FHIR consent. Sensitive-class gating is a permitted privacy exception under the information-blocking rule, not a block.
Cross-Module Dependencies
Scheduling — provides available slots for self-scheduling; receives appointment-confirmed events from the portal.
Eligibility — provides coverage status and cost estimates at self-scheduling; portal surfaces patient-facing cost information.
Clinical Documentation — provides encounter notes for AVS generation; clinical facts (allergies, medications, conditions, labs) are global data surfaced via VDT; patient intake flows feed into the clinical intake workflow.
RCM — provides outstanding statements and balance information for bill-pay; Payment rows reconcile back to RCM.
Task Management — receives inbound patient messages as task queue items; SLA tracking on message response times.
eRx / EPCS — medication list surfaced in portal; prescription renewal requests routed through messaging.
Data Model — sensitive-class gating and read-access audit trail enforce the data ownership contract on every patient data view.
Terms of Service & Care — consent-chain tracking, proxy authorization, and VDT compliance follow the platform’s authorization model.
Cross-Module Links
eRx & EPCS — patients view prescription status and formulary results