Prescription
Global entity. Partition key: SourceOrganizationID. Trust Tier: T1 (PHI + controlled-substance data).
Schema
| Field | Type | Required | PK | FK | Notes |
| PrescriptionID | UUID | Yes | Yes | | Primary key |
| PatientID | UUID | Yes | | Patient | |
| PrescriberID | UUID | Yes | | Provider | |
| MedicationName | String(100) | Yes | | | Display name |
| MedicationCode | String(50) | Yes | | | RxNorm or NDC |
| Dose | String(50) | Yes | | | |
| SIG | Text | Yes | | | Directions for use |
| Quantity | Decimal | Yes | | | |
| QuantityUnit | String(50) | Yes | | | e.g. tablets, mL |
| Refills | Int | Yes | | | 0 = no refills |
| DaysSupply | Int | Yes | | | |
| PharmacyNcpdpId | String(50) | No | | | NCPDP pharmacy ID |
| PharmacyName | String(100) | No | | | |
| IsDispenseAsWritten | Bool | Yes | | | DAW flag |
| IsControlled | Bool | Yes | | | |
| Schedule | String(50) | No | | | II, III, IV, V, or null |
| RxMessageType | String(50) | Yes | | | NewRx / RxRenewal / RxChange / CancelRx / Compound |
| SurescriptsMessageId | String(50) | No | | | Surescripts tracking ID |
| Epaid | String(50) | No | | | Electronic prior-auth ID |
| Status | String(50) | Yes | | | Draft / Sent / Received / Completed / Cancelled / Error |
| SentDateTime | DateTime (UTC) | No | | | |
| CompletedDateTime | DateTime (UTC) | No | | | |
| SourceOrganizationID | UUID | Yes | | Organization | Global 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 prescriptions via portal |
| Front Desk (30) | T1 | Read prescription status |
| MA / RN (40) | T1 | Read + process non-controlled RxRenewal |
| Clinician (60) | T1 | Read / Write / Sign (EPCS requires DEA enrollment) |
| Practice Manager (70) | T1 | Read + override mandate |
| EditAMI (90) | T1 | Schema administration |
ControlledSubstanceAuth
Org-scoped. Trust Tier: T1 (identity proofing + DEA credentials).
Schema
| Field | Type | Required | PK | FK | Notes |
| ControlledSubstanceAuthID | UUID | Yes | Yes | | Primary key |
| ProviderID | UUID | Yes | | Provider | |
| DeaNumber | String(50) | Yes | | | DEA registration number |
| ScheduleAuthority | String(50) | Yes | | | Authorized schedules |
| IdentityProofingProvider | String(50) | Yes | | | e.g. ID.me |
| IdentityProofingStatus | String(50) | Yes | | | Pending / Verified / Expired / Revoked |
| IdentityProofingVerifiedDateTime | DateTime (UTC) | No | | | |
| TokenType | String(50) | Yes | | | HardToken / SoftToken |
| TokenSerialNumber | String(50) | Yes | | | |
| TokenActivationDateTime | DateTime (UTC) | Yes | | | |
| TokenExpirationDateTime | DateTime (UTC) | Yes | | | |
| SigningCertificateRef | String(200) | Yes | | | FIPS 140-2 HSM reference |
| DrummondCertified | Bool | Yes | | | Drummond Group certification |
| 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 |
| Clinician (60) | T1 | Read own auth record; initiate identity proofing |
| Practice Manager (70) | T1 | Read all; manage token lifecycle |
| EditAMI (90) | T1 | Schema administration |
PdmpQuery
Org-scoped. Trust Tier: T2 (controlled-substance check logs).
Schema
| Field | Type | Required | PK | FK | Notes |
| PdmpQueryID | UUID | Yes | Yes | | Primary key |
| PatientID | UUID | Yes | | Patient | |
| ProviderID | UUID | Yes | | Provider | |
| StateCode | String(50) | Yes | | | State PDMP queried |
| PdmpGateway | String(50) | Yes | | | BambooHealth / LogiCoy / DirectAPI |
| QuerySentDateTime | DateTime (UTC) | Yes | | | |
| ResponseReceivedDateTime | DateTime (UTC) | No | | | |
| IsMandated | Bool | Yes | | | State mandate requires check |
| MandateSatisfied | Bool | Yes | | | |
| ControlledSubstanceFillCount | Int | No | | | |
| NarxScore | Int | No | | | NarxCare risk score |
| AlertTriggered | Bool | Yes | | | |
| Summary | Text | No | | | Displayable summary |
| RawResponse | Text | No | | | Encrypted at rest |
| 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 |
| Clinician (60) | T2 | Read / Initiate PDMP query |
| Practice Manager (70) | T2 | Read all; override mandate flag |
| EditAMI (90) | T2 | Schema administration |
icApplication Overrides
How the four eRx & EPCS AMI schemas turn into a live application: module-specific stack additions, the Surescripts certification pipeline, override component bindings, EPCS hard/soft-token bindings, PDMP component integration, 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 eRx & EPCS-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 |
| eRx network | Surescripts (direct certification) | NCPDP SCRIPT 2017071: NewRx, RxRenewal, RxChange, CancelRx, MHX, RTPB, ePA. Per Integration Ecosystem decision (BUILD — direct cert, DrFirst as standby). |
| EPCS signing | FIPS 140-2 HSM + ID.me IAL2 | Hard token (SAV-Littleton, Episerver) or DEA-accepted soft token. Signing certificate managed in HSM. Drummond EPCS app certification required. |
| PDMP gateway | Bamboo Health PMP Gateway + LogiCoy (IL) | Covers >46 states via Bamboo; Illinois via LogiCoy. State-by-state API integration per mandate requirements. |
| DUR engine | Coding / CDS module | DDI, drug-allergy, drug-condition, dose-range checks invoked via CDS Hooks at prescribing time. |
| FHIR resource profiles | MedicationRequest, MedicationDispense, Task (ePA) | R4 baseline; USCDI v3 alignment for CY 2026; HTI-4 eRx criteria. |
Surescripts certification pipeline P0
Surescripts certification is a 9–12 month process from kickoff to production activation. It is a gating dependency for any eRx functionality. The pipeline runs in parallel with platform development:
flowchart LR
KICKOFF[Cert kickoff
+ NDA + fees]
TEST[Test environment
Surescripts sandbox]
CERT[Certification testing
Drummond + Surescripts]
PROD[Production activation
live trading partners]
KICKOFF --> TEST
TEST --> CERT
CERT --> PROD
| Stage | Duration | What happens | Environment |
| Cert kickoff | Month 0 | Sign NDA, pay fees, receive sandbox credentials, submit prescriber directory entries | n/a |
| Test environment | Months 1–6 | Build and validate SCRIPT 2017071 message construction; test NewRx, RxRenewal, RxChange, CancelRx, MHX, RTPB against Surescripts sandbox | Surescripts sandbox (cert-test.rev.health) |
| Certification testing | Months 6–10 | Drummond EPCS app certification; Surescripts interoperability test; EPCS two-factor signing verification; all SCRIPT transaction types validated | Surescripts staging + Drummond lab |
| Production activation | Months 10–12 | Go-live with live trading partners; prescriber directory published; production Surescripts routing enabled | Surescripts production |
Critical-path dependency. Surescripts certification takes 9–12 months from scratch. This must start in Month 1 of the project, not Month 12, or launch slips. DrFirst is maintained as a standby eRx provider in case Surescripts cert is delayed.
eRx-specific override bindings P0
These overrides are declared in rules/*.rules.json and replace the default for the matching field name pattern.
| Field | Default would render | Override component | Why |
Prescription.MedicationCodeString50 | plain text input | ic-ng21-erx-1-medication-search | RxNorm-aware medication search with auto-complete, NDC expansion, and SIG templates; prevents free-text drug entry. |
Prescription.PharmacyNcpdpIdString50 | plain text input | ic-ng21-erx-1-pharmacy-picker | NCPDP directory search; shows patient’s preferred pharmacy; validates NCPDP ID against Surescripts directory. |
Prescription.SIGText | plain textarea | ic-ng21-erx-1-prescription-writer | Structured SIG builder: verb + dose + route + frequency + duration + PRN reason; produces both human-readable and coded SIG. |
Prescription.StatusString50 | plain text display | ic-ng21-erx-1-rx-status-pill | Color-coded dark status pill (Draft / Sent / Received / Completed / Cancelled / Error). |
| (synthetic) EPCS signing gate | n/a | ic-ng21-erx-1-epcs-signer | Two-factor signing modal: biometric + token challenge + digital signature application. Only rendered for controlled Rx. |
| (synthetic) PDMP result panel | n/a | ic-ng21-erx-1-pdmp-query | Controlled-substance fill history display with NarxCare score, mandate badge, and prescriber acknowledgment gate. |
| (synthetic) RTPB cost panel | n/a | ic-ng21-erx-1-formulary-checker | Patient-specific cost + tier + PA flag + alternatives; rendered before Rx signing. |
| (synthetic) DUR alert panel | n/a | ic-ng21-erx-1-dur-alert-panel | DDI / allergy / condition / dose-range alerts with override + reason. Sourced from Coding / CDS. |
| (synthetic) RTPB cost display | n/a | ic-ng21-erx-1-rtpb-cost-display | Patient copay and total cost inline in the prescription writer; pulls from FormularyCheck. |
| (synthetic) RxRenewal inbasket | n/a | ic-ng21-erx-1-renewal-inbasket | Inbound RxRenewal/RxChange card with approve/deny/modify actions; routes through Task Management. |
| (synthetic) ePA form | n/a | ic-ng21-erx-1-epa-form | Pharmacy-benefit PA request form; submits via Surescripts ePA network. |
EPCS hard-token and soft-token bindings P0
Per DEA 21 CFR 1311, EPCS two-factor authentication requires an AAL2-compliant token. The system supports both hard tokens and soft tokens; the binding is per-org per-provider in ControlledSubstanceAuth.
| Token type | Binding | DEA compliance | When to use |
| Hard token (FIPS 140-2 Level 3) | Physical OTP token (e.g., SAV-Littleton, Episerver); serial number recorded in TokenSerialNumberString50 | Meets DEA hard-token requirement directly | P1; highest assurance; required for practices that prefer hardware tokens |
| Soft token (DEA-accepted authenticator app) | Mobile authenticator app (TOTP); enrollment tracked in TokenTypeString50 = "SoftToken" | DEA-accepted per 2015 interim final rule; requires Drummond-certified EPCS application | P2; reduces hardware overhead for small practices |
Both token types require IAL2 identity proofing (via ID.me) before enrollment. The ControlledSubstanceAuth row records which token type is active, when it was activated, and when it expires. The system blocks EPCS signing when the token is expired or revoked.
PDMP component — state-by-state API integration P0
PDMP queries are routed through two gateways based on state coverage:
| Gateway | States covered | Integration method | Component binding |
| Bamboo Health PMP Gateway | >46 states (all except IL and a few holdouts) | REST API via bamboo-pdmp.ts adapter; PMIX/NABP standard query format | ic-ng21-erx-1-pdmp-query |
| LogiCoy | Illinois only | REST API via logicoy-pdmp.ts adapter; IL-specific format | ic-ng21-erx-1-pdmp-query (same component; adapter routing is backend) |
The state mandate table is maintained in rules/pdmp-query.rules.json and encodes: (1) whether the state mandates a PDMP check before a controlled-substance Rx, (2) the mandate window (how recent the query must be to satisfy the mandate), and (3) the applicable schedule range. When the prescriber attempts a controlled-substance Rx, the mandate enforcer job checks this table and blocks the Rx if a mandated query has not been completed and acknowledged within the window.
Versioning — worked example P0
All eRx artifacts are versioned break.feature.bug.buildtimestamp per IC hard rule #9. The example below traces a feature bump on Prescription.
Prescription 1.0.0.20260301T120000Z — Initial schema. 20 business fields plus global audit columns. Component ic-ng21-erx-1-prescription-writer and ic-ng21-erx-1-epcs-signer bind to prescription@1.0.0.* via the DI manifest.
Prescription 1.1.0.20260515T093000Z — feature bump — Adds a single optional field, RxTransmissionIdString50, to capture the Surescripts transmission tracking ID separately from the message ID (for delivery-receipt correlation). Per the IC change matrix:
| Change | Version impact | Approval needed | Min permission |
Add optional field RxTransmissionIdString50 | feature bump (1.0.0 → 1.1.0) | No | Write (60) |
Because the change is backward-compatible, the component tag stays ic-ng21-erx-1-prescription-writer. Existing UI consumers continue to bind prescription@1.x.* and ignore the new field. New UI surfaces that need delivery-receipt correlation bind prescription@^1.1.0. No new database is required (IC rule #13 only applies to break bumps).
Prescription 2.0.0.20280101T120000Z — break bump (illustrative) — An illustrative future break bump: SIGText is split into separate coded fields (SIGVerbString50, SIGDoseString50, SIGRouteString50, SIGFrequencyString50, SIGDurationString50, SIGPRNReasonString50). Per the IC change matrix this is change field type + add required fields — 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-erx-2-prescription-writer; 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.
eRx & EPCS environment details
| Env | Surescripts | PDMP gateway | EPCS signing |
| Dev | Surescripts sandbox (test trading partners) | Bamboo Health sandbox | Soft-token only (Dev HSM) |
| QA | Surescripts sandbox (expanded test partner set) | Bamboo Health sandbox + LogiCoy sandbox | Soft-token only (QA HSM) |
| UAT | Surescripts staging (Drummond cert testing) | Bamboo Health staging (test patients) | Hard token (UAT HSM) |
| Prod | Surescripts production (live trading partners) | Bamboo Health prod + LogiCoy prod | Hard token + soft token (Prod HSM) |
eRx & EPCS RBAC notes
- EPCS signing gate. EPCS signing is gated at level ≥ 60 plus a valid
ControlledSubstanceAuth with IsActiveBool = true and schedule authority matching the Rx schedule.
- PDMP mandate enforcement. The
pdmp-mandate-enforcer.ts job blocks controlled-substance Rx creation when the state mandate is not satisfied. Override requires level ≥ 70 (practice manager) and creates an audit event.