Refactor Sequence
The ordered build order for rolling out the Canvas-first architecture. Foundational services first, then services that depend on them.
Philosophy
Every refactor step follows the same pattern:
- Red-line the domain spec (lives in Architecture or its subpages).
- Plan the migration — what moves where, what's deleted, what's dual-written during cut-over.
- Implement in the new service.
- Cut over with event subscribers + feature flag if needed.
- E2E tests verify no regressions.
- Update docs to match what was actually built.
Steps run in dependency order below. Phases 1–2 are foundational; nothing else can land until they do. Phase 14 (retire canvas-pioneer-integration-service) can only happen once every responsibility it owns has been redistributed.
17-Step Refactor Plan
organizations rows with Canvas Organization mirrors.canvas-pioneer-integration-service into a reusable npm package. Typed resource wrappers, retries, pagination. Every downstream service depends on this library.patient_directory (MRN ↔ canvas_patient_id ↔ stripe_customer_id ↔ clerk_id ↔ organization_id) + INSERT-only intake_snapshots. Migrate existing patient records. Drop clinical columns. Add POST /patients/email-lookup for intake duplicate detection.intake_sessions for resume + lead capture. Emit contact.captured, intake.progressed, intake.abandoned, intake.disqualified, intake.completed.prescription_queue, portal_invite, and other SDK plugins to respect managingOrganization for routing and branding. Use CPA (Canvas Plugin Assistant) — Canvas's own Claude Code plugin for development. See Canvas Plugins.refill.upcoming, refill.due, refill.overdue. Writes zero Canvas resources.pharmacy_routes with GMP's state-license matrix. Live routing re-evaluation per saga (ops updates routes as GMP adds licenses; refills automatically migrate).pending_payment per commerce integration.contacts, campaigns, campaign_enrollments, messaging_preferences. Per-org verified senders (SES + Twilio). HIPAA-aware category model (transactional / clinical / marketing). Event-triggered drips + scheduled campaigns + one-off blasts. HubSpot retires.organization_branding. Clerk auth with org-scoped sessions. Live canvas-client reads for clinical data. Patient-initiated cancel (cancel_at_period_end), pause, payment method update.guide-glp standalone service + DB. Migrate each GuideGLP client's patients into the shared Canvas instance as Patient.managingOrganization = {their_canvas_org_id}. Their orders and subscriptions now flow through the unified orchestrator + core services. Their branded portal is served from the shared patient-portal via custom domain.Verification after each phase
- All existing tests still pass (no regressions).
- New service passes independently.
- End-to-end pipeline works against a test Canvas instance.
- Tenant scoping verified: cross-org queries return empty for non-superadmin callers.
- Docs updated on this site; phase marked complete.
- Health check returns 200 on the new ALB path.
Historical: Bask → Canvas cutover (completed 2026-03-05)
Before the Canvas-first redesign, YourEra migrated from Bask EMR to Canvas Medical. That migration is done. Key markers for historical context:
intake.yourera.comis BASK (never deploy to it);intake.hisera.comis Canvas.- Ghost sub-domains (
portal.yourera.com,admin.yourera.com) were moved to BASK as part of the cutover. admin.hisera.combecame the Canvas-side admin portal.- Canvas plugin
prescription_queuev1.3.4 deployed withadmin.hisera.comURLs.
The full Bask migration runbook is preserved in the repo at yourera_to_hisera/MIGRATION-RUNBOOK.md. If you need to understand historical domain ownership or DNS state, consult that file. It is not part of the live Canvas-first architecture.