Skip to content

RestartiX -- Implementation Plan

Master plan organised in two phases: Foundation (everything required for the three audiences — superadmin, clinic staff, patient — to log in and run their own house, without any medical data) and Features (clinical and operational behaviour built on top). A separate production launch readiness gate sits between F-tier feature completion and real-clinic go-live.

The active plan is Platform Completion (2026-08-02 →). No target date; the ~20k legacy migration is the LAST step, not a driver. Scope: F1 Specialists, the F2.1 offerings stand-in, F3 Forms, F4 Scheduling, F5 Appointments, F6 Documents, F11 hardening. F1–F6 are ports from the live restartix-leo-* + restartix-intakes systems, not greenfield builds — the UI and business rules come across, the leo database explicitly does not. The survey behind that plan is leo-port-map.md.

Detailed checklists live in:

  • Platform Completionthe active plan. Phase 0 audit → Phase 1 feature build → Phase 2 harden → Phase 3 migration
  • Leo Port Map — the survey of the four live leo/intakes repos that the active plan rests on: per-feature port plans, foundation conflicts, anti-pattern guardrails, open decisions
  • Foundation — the five sub-phases (1A–1E); authoritative for checkbox-level foundation status
  • Features — F-tier specs, in dependency order (stale in places; reconciled during the active plan's Phase 0)
  • Production Launch Readiness — operational gate (Sentry / Bunny / first-clinic onboarding / on-call / Romanian compliance sign-off) that flips the switch on real clinics at scale
  • June 10 Demo — Single-Session Stress Testhistorical. Shipped 2026-06-10; stress-tested the session player + Bunny streaming on the now-live production substrate. Legacy (Strapi) → platforma.restartix.ro → auto Clerk account → one-click consent → play one curated session → stats.
  • June / September launch planhistorical. Framed the work around a launch date and treated the ~20k migration as near-term. Superseded 2026-08-02 by Platform Completion.

Three distinct gates, in order: Foundation 1E.3 (substrate validated — passed 2026-05-15) → F-tier features (built on the substrate; this is where the work is today) → Production Launch Readiness (operational checklist for real clinics at scale, and what the legacy migration waits behind). Don't conflate them — features needed "for launch" usually means production launch, which is F11+ scope, not 1E.3.

Cross-cutting taxonomy is canonical per the glossary. When this doc, the codebase, or other docs disagree with the glossary, the glossary wins.

Architecture is authoritative for design:

If a feature spec disagrees with the architecture docs, the architecture docs win.


Foundation principle

Foundation is the actor-identity stack across all three audiences plus the org-admin surface. It is paid for once, before any feature lands. Every feature rides on top.

What's in the foundation, by sub-phase:

1A — Cross-Cutting Runtime: audit logging, encryption, soft-delete, PII redaction, error envelope, API contract conventions, file storage, internal event bus, i18n, activity tracking, reserved columns, rate limiting + SOUP, column-level data classification, RLS test harness, notifications & email transport (1A.18).

1B — Identity & Tenancy: principals + humans + agents + service_accounts; organisations, memberships, RBAC, RLS; org settings/billing/entitlements; tiers/subscriptions/overrides; patient tiers + middleware (Permission / TierEntitlement / OrgEntitlement / Limit); patient_profiles + patients + patient_subscriptions + portal onboarding; consents ledger (platform-scope + org-scope, append-on-grant); privacy notice templates (platform-versioned, clinic-filled); break-glass access (platform staff → cross-tenant patient data, per-org, audited, always-on clinic notification); patient impersonation (clinic staff → one of their patients, per-org, audited, patient access-history view); member invite flow; locations & multi-site.

1C — Capabilities, Integrations & Metering (new): internal capability framework, Curated Providers (Cat A) + provider-resolution table (dedicated-tier readiness), internal events registry (Cat E), Outbound Webhook Subscriptions (Cat C) with Day-1 Make.com consumer, Connected Accounts (Cat B) table + framework (OAuth deferred to first OAuth consumer), Inbound Webhook Framework (Cat D), Metering & Quotas (cost-runaway guard at the capability seam — non-optional before AI ships), AI Capability Hooks (model registry, provenance, per-call cost capture), entitlements rename (features / plan_features / organization_capabilitiesentitlements family, resolves the architectural-vs-billing vocabulary collision per the glossary).

1D — Admin Surfaces: Console (orgs, tiers/overrides, entitlement flags, privacy-notice templates, break-glass elevation, consent purpose catalog viewer); Clinic admin (org settings, billing, members, roles, custom domains, privacy notice editor, patient tiers, per-patient consents view, break-glass session banner, integrations marketplace, audit log); Patient self-service (sign-up consent block, profile, subscription, consent trail, my-clinics, data export, account deletion request); cross-org account surface (account.restartix.pro); shared UI primitives.

1E — Foundation Gate: setup-a-clinic acceptance test (re-run against staging), AWS staging deployment (KMS, S3, RDS, ALB, custom-domain DNS, two-pool RLS, Clerk in production mode, SES production identity + suppression list).

What's not in the foundation:

  • Specialist profiles (specialty, signature, scheduling timezone)
  • Service catalog
  • Forms infrastructure (custom fields, form templates, form instances) — and the form-driven Tier B medical consents that ride on top of it (telemedicine, video recording, biometric capture, treatment-specific)
  • Scheduling, appointments, documents
  • Treatment plans, exercises, telerehab
  • Automations, webhooks, segments
  • Telemetry pipeline (Layer 2 feature; PG aggregates + S3 replay blobs, no separate compliance DB or ClickHouse — see decisions.md → Why telemetry is PG + S3, not ClickHouse)

Foundation ships the consent ledger and platform/org-scope SaaS-style consents; medical-grade form-driven consents extend the same ledger from F3.5.

Acceptance: a superadmin can create and manage orgs from Console; a clinic admin can manage their org's settings, billing, members, roles, domains, tiers, privacy notice, and audit log from Clinic; a patient can sign up, onboard, view and edit their profile, view their subscription, manage their consent toggles, and request a data export from Portal. All three flows end-to-end on AWS staging with real Clerk, real KMS, real S3.

Hard rules (foundation guardrails)

  • Clinic is data controller; platform is processor. Patient health data is the clinic's responsibility. The platform processes on the clinic's documented instructions (DPA). Substantive design in decisions.md → Why clinic is controller, platform is processor.
  • Cross-tenant features operate on anonymised data only. Any feature that needs identifiable cross-tenant data must go through the break-glass pattern (per-org scope, time-bound, justified, always-on clinic notification) or surface as an explicit ADR-worthy request to break the rule. Joint controllership (GDPR Art. 26) is the failure mode this rule prevents.
  • DSAR routing flows through the clinic, never the platform. The platform auto-responds + offers portal self-service ("your clinics" list); the clinic processes the actual request as controller. Genuinely orphaned requests (ex-patient, no active account) are break-glass-gated.

Naming Convention

Consistent terminology used throughout this document, codebase, and all internal communication.

Brand layer

TermMeaning
RestartiXThe company and brand. Never refers to a specific app or service.
(clinic's brand)What patients see in white-labeled deployments (universal — available on both shared and dedicated tenancy modes).

Product layer (internal docs & communication)

TermMeaningExample
PlatformThe entire system (backend + frontends + infra)"The platform supports multi-tenancy"
Clinic AppThe staff-facing frontend application"The clinic app shows specialist calendars"
Patient PortalThe patient-facing frontend application"The patient portal handles consent forms"
ConsoleThe superadmin platform management application"The console lets platform operators onboard new clinics"

Technical layer (code, repos, architecture)

TermMeaningLocation
APIThe main Go backend servicecmd/api/
Telemetry APIThe patient-engagement + pose-ingest Go service (F10)services/telemetry/cmd/
ClinicStaff frontend appapps/clinic/
PortalPatient frontend appapps/portal/
ConsoleSuperadmin frontend appapps/console/
UIShared component librarypackages/ui/

Usage rules

  • "RestartiX" = brand/company only
  • "Platform" = the whole product
  • "API" = the main backend (not "the API")
  • "Clinic app" / "Patient portal" / "Console" = the three frontends
  • In code: api, telemetry-api, clinic, portal, console, ui

Current initiative — platform completion

No target date. The migration is last. There is nowhere to migrate the ~20k legacy patients into until the platform can actually run a clinic, so the order is: build every remaining feature properly → harden → then plan the migration against a complete, real target schema. Full premise, phases, and locked decisions: platform-completion.md.

Scope (locked 2026-08-02). In: F1 Specialists & Specialties, the F2.1 offerings stand-in (catalog identity + offering_specialists + offering_forms — no pricing, no plans, no products, no purchase path), F3 Forms & Consents, F4 Scheduling, F5 Appointments, F6 Documents, F11 compliance hardening, plus the 1D admin surface each feature needs. Out of scope, deliberately: F7 automations, F8 segments, F12 billing engine (clinics invoice by hand), the F10 pose ingest pipeline (client-side skeleton preview only — no MDR / IEC-62304 scope), F13 dedicated tenancy.

Build order is not negotiable: F1 → F2.1 → F3 → F4 → F5 → F6. F3 precedes F4 because calendars reference form_templates; F5 depends on F1 + F4; F6 depends on F3 + F5.

F1–F6 are ports. A working implementation of all six runs in production today across restartix-leo-dashboard (staff UI), restartix-leo-platform (patient app), restartix-leo-api (Strapi) and restartix-intakes (the booking service, holding the 976-line availability engine, the double-booking exclusion constraint, and the hold protocol). What is carried: UI, UX, and above all the business rules — status lifecycles, transition guards, validation, and the edge cases learned from running a real clinic. What is not carried: the leo database — its schema, framework-generated naming and tenancy model are incompatible with the foundation. See leo-port-map.md.

Demo shipped 2026-06-10 (historical). The June-10 single-session demo is a completed milestone: a logged-in legacy (Strapi) patient was auto-provisioned a Clerk account, accepted a one-click consent, and played one curated session in the real Portal player, with adherence + media-QoS telemetry captured at production quality. It proved the substrate holds. Production has stayed live serving real patients since 2026-06-05. Full plan + checkboxes: june-demo.md.

Status

PhaseSub-phaseNameStatus
0Boot (scaffolding, DB foundation, three apps with auth, multi-tenancy, RBAC, RLS, custom domains)Done
11ACross-Cutting Runtime — audit, encryption, soft-delete, PII redaction, error envelope, API contract, file storage, event bus, i18n, activity tracking, reserved columns, rate limiting + SOUP, data classification, audit log partitioning, postgres extensions, notifications + email transportShipped (staging-bound items — KMS, S3 bucket, audit-roll cron, RDS parameter group, SES production identity + suppression list — close in 1E)
11BIdentity & Tenancy — principal model, org settings/billing/entitlements, tiers/subscriptions/overrides, patient tiers, tier-entitlement / org-entitlement / limit middleware, patient identity, patient subscriptions, portal onboarding, consents ledger, privacy notice templates, break-glass access, member invite, patient impersonation, locations & multi-site1B.1–1B.14 backend shipped; UI consumers deferred to unified UI pass; original 1B.15 retired into 1C
11CCapabilities, Integrations & Metering — capability framework, Curated Providers (Cat A) + provider resolution, internal events registry, Outbound Webhook Subscriptions (Cat C — Day-1 Make.com), Connected Accounts (Cat B) table + framework, Inbound Webhook Framework (Cat D), Metering & Quotas, AI Capability Hooks, entitlements renameShipped end-to-end 2026-05-06/07 (1C.1–1C.9): capability framework, Cat A providers + resolver, events registry, Outbound Webhooks (Cat C), Connected Accounts (Cat B), Inbound Webhook Framework (Cat D), Metering & Quotas (1C.7), AI Capability Hooks (1C.8), entitlements rename (1C.9). Cat B/D are framework-only — first F-tier consumer ships the first catalog row
11DAdmin Surfaces — Console UI (orgs/users/tiers/break-glass/templates), Clinic admin UI (settings/billing/members/roles/privacy notice/consents/integrations), Patient self-service (profile/subscription/consents/clinics/data export), cross-org account surface, shared UI primitivesPartially shipped during the F-tier wave; remainder in flight (see 1d-ui-inventory.md + foundation.md)
11EFoundation Gate — setup-a-clinic acceptance test, foundation gate documentation, AWS staging deploymentClosed 2026-05-15. 1E.3 staging stack live (full chain: Cloudflare → ALB → ECS → pgbouncer → Aurora); 1E.2 closed by scope reduction (substrate validation covered by other means + post-deploy smoke test).
2F1Specialists & SpecialtiesIn scope. Not started — no specialists / specialties tables, no domain, no routes, no seeded permissions. First feature after Phase 0. specialties are per-org (settled 2026-08-02)
2F2Service CatalogF2.1 stand-in in scopeofferings + offering_specialists + offering_forms, named offerings from day one, catalog identity only (no pricing / plans / products / purchase path). F2.2 service plans + F2.3 products stay deferred. Blocks F3/F4/F5/F6 — three in-scope features need the FK target
2F3Forms & ConsentsBUILT, repo-only (000042000044). Precedes F4 (calendars reference form_templates). CNP is encrypted BYTEA on patient_profiles + a blind index for search, never in a generic value column and never in forms.values; patient-entered only, staff read it through a permissioned, audited reveal endpoint. No per-template opt-in — the field's presence is the declaration
2F4SchedulingIn scope. Not started — no calendars, no specialist_weekly_hours. Blocked on F2.1 + F3. Availability engine + hold protocol + overlap exclusion constraint port from restartix-intakes
2F5AppointmentsIn scope. Not started — the appointments table does not exist. Every reference to it in migrations is a forward-looking comment; docs claiming its substrate "already landed" are wrong. Blocked on F1 + F4
2F6DocumentsIn scope. Not started — no pdf_templates, no documents. Blocked on F3 + F5
2F7Automations & WebhooksOut of scope (locked 2026-08-02)
2F8SegmentsOut of scope (locked 2026-08-02) — belongs to a later patient-data-segmentation feature
2F9TelerehabPatient slice shipped and live (programs → sessions → protocols → session_runs, portal player, catalog, enrollment, instruments, stats). Editor UIs + specialist prescribing need F1, F3, F5
2F10Telemetry ServiceMedia/engagement half shipped (separate Go service, video/session events ingest, aggregation). Pose ingest is out of scope — client-side pose preview only, no MDR / IEC-62304 scope; pose tables already partitioned, migrate empty. Locked design: PG aggregates + S3 replay blobs, no ClickHouse — see /architecture/decisions#why-telemetry-is-pg--s3-not-clickhouse
2F11Compliance Hardening + Production DeployIn scope (Phase 2). Operational hardening pass; not the billing engine. Shipped: F11.4 production AWS, F11.1 basic DSAR + erasure stub, F11.2 prod KMS rotation, F11.0.5 Romanian counsel. Open: DSAR/erasure end-to-end, retention automation, F11.0 IEC 62304 prep, F11.3 deep security
2F12Billing & Invoicing (platform → clinic) — subscription state machine, invoice generation from usage_summaries + AI cost line items, dunning, refunds, billing UI. Default impls: Stripe (international); FGO + e-Factura (Romania). Foundation declares the payment.Provider + invoicing.Provider capability interfaces (1C.1); F12 ships the engine + impls.Interface-skeleton-only; out of scope (locked 2026-08-02) — clinics invoice by hand until it ships. Only the auto-renew/invoicing engine is deferred; the shipped paid-self-enroll + expiry sweep stay
2F14Commerce & Access OffersShipped — access grants from shop orders + marketing campaigns, refund → revoke (migrations 000035000038)
Post-launchF13Tenant Isolation Mode (Dedicated Tier) — premium clinic-tier deployment mode with per-tenant identity namespace (Clerk org). Foundation pre-work shipped: organizations.tenancy_mode, organizations.activated_at + draft index, humans.provider_org_id + composite UNIQUE. Runtime build (Clerk org provisioner, re-introduced finalize endpoint, own-S3 / own-CMK entitlement addons, Terraform module) deferred until first paying dedicated-mode contract closes. Renamed from F12 → F13 when F12 Billing was added.Out of scope (locked 2026-08-02). Trigger: first paying dedicated-mode contract
FutureMarketplace Mediation (patient → clinic via platform; Stripe Connect or equivalent; KYB/KYC onboarding; payout management; fee model). Foundation accommodates via the four billing capability skeletons; engine is a strategic future feature.Strategic decision; trigger TBD

Open decisions (foundation)

DecisionWhereWhen to resolve
Manual entitlement lock — organization_entitlements.manually_locked_* so superadmin disables aren't overwritten by tier-engine projection?1BBefore tier-engine projection ships its first regulated entitlement
Tier-version migration policy — when Pro v3 → v4 publishes, force-upgrade at renewal, one-click prompt, or hold v3 indefinitely?1BBefore first tier version bump in production
Trial mechanics — trialing status per-subscription, per-org-lifetime, or per-tier-code?1BBefore self-service signup ships
Default-tier auto-assignment vs explicit pick at portal sign-up1BBefore portal self-service signup goes public
Subscription engine — own implementation vs use payment provider's native engine (Stripe Subscriptions / Chargebee / euplatesc.ro recurring etc.). Decides whether the platform owns renewal scheduling, dunning, customer-portal UX, and proration logic, or delegates them to the provider and only mirrors subscription state. Direct consequence: whether tiers stays as a single conflated catalog row or splits into tiers (feature bundle) + plans (billing variant) layers. See features/platform/tenant-isolation.md → Open questions and the tier-model commit b805726 for the deferral rationale.F12 (or earlier, when payment provider integration scope opens)Before the first paid subscription is processed against the provider

Resolved this cycle:

  • IaC tool — Terraform, with state in S3 and native conditional-write locking (use_lockfile = true). Rejected Pulumi (smaller community, fewer training-data-derived examples) and AWS CDK (single-cloud lock-in at the abstraction layer, slower CloudFormation backend). See decisions.md → Why Terraform for infrastructure as code and iac-layout.md for the module structure.
  • AWS infrastructure stack — full topology settled: ECS Fargate everywhere, RDS Multi-AZ prod / Aurora Serverless v2 staging, Cloudflare for SaaS for custom domains, eu-central-1, Terraform IaC, GitHub Actions OIDC + manual approval gate for prod. See aws-infrastructure.md for the full picture, decisions.md for the five new ADRs (ECS Fargate over App Runner, Aurora Serverless v2 staging-only, Cloudflare for SaaS, Terraform, telemetry PG+S3).
  • Consent surface split — single consents ledger spanning platform-scope + org-scope, with legal_basis discriminator. Tier B (form-driven) layers on top in F3.5. See decisions.md → Why clinic is controller, platform is processor.
  • Privacy notice ownership — platform provides versioned templates; clinic fills placeholders + selects toggleable sections; clinic publishes the assembled notice as their org_privacy_notice version. See foundation.md → 1B.10 Privacy Notice Templates.
  • Cross-tenant patient access in Console — break-glass pattern, per-org scope, always-on clinic notification. Primitive shipped (schema + middleware + endpoints + audit attribution + notification fan-out). Console route gating + Clinic admin banner light up as 1C.1 / 1C.2 surfaces ship. See foundation.md → 1B.11 Platform Break-Glass Access.
  • Break-glass platform-permission model — pure Go (PlatformPerm* constants + role → perms map in internal/core/principal/platform_permissions.go), not data-driven. support_engineer platform role added with PatientList + PatientDetail + AuditFull scopes; CrossOrgLookup + Manage stay superadmin-only.
  • Email transport for break-glass clinic notifications — via 1A.18 (notify.Send(notify.To(admin), CategoryBreakGlassOpened, data, IdempotencyKey(<session>:<admin>))). Per-admin idempotency keys dedup retries at the notification layer.
  • DSAR routing — patient → clinic, not patient → platform. Platform auto-responds and offers self-service routing.
  • Member invite flow — both patterns ship (1B.12). Personal invites via auth-provider abstraction (auth.InvitationProvider, Clerk today) for staff + named patients; multi-use code-anchored share-links (patient-only) for QR posters / intake desks. See foundation.md → 1B.12 Personal Invitations + Patient Share-Links.
  • Locations status lifecycle (1B.14) — closed is terminal (one-way transition; new row to re-open), inactive is reversible (renovation / lease / seasonal); closed_at auto-stamped at clock_timestamp() on transition into closed; CHECK pins the consistency. Slug is mutable (unlike organizations.slug which lives in DNS); country is free TEXT (no ISO 3166-1 enforcement at this layer); DELETE exposed but PATCH ... {status:"closed"} is the canonical retire flow. See foundation.md → 1B.14 Locations & Multi-Site Support.

Feature-level open decisions live in the features doc.


How this plan differs from the previous version

The previous plan organised work as twelve sequential layers (0–12). It scrambled identity work between Layer 1 and Layer 2 — patient_profiles, patients, patient_subscriptions, and portal onboarding all read as foundation work but lived under "Layer 2 People" alongside specialist profiles, which are clearly a feature. The current rewrite draws the line cleanly: identity (any audience) is foundation; everything clinical is a feature. Layer numbering inside the foundation is five sub-phases (1A–1E); medical features start at F1.

The 2026-05-06 renumber moved foundation work into 1A–1E sub-phases — old Layer 1.X numbers do not map one-to-one to new slot numbers (1.17 was AWS staging deployment; the new 1A.17 is Frontend Performance Foundation). References to old Layer 1.X numbering across code + docs have been updated to the new slots; if you find a stale one, it's a bug, please fix it.

The shipped sections that previously ran 50–80 lines each are collapsed to a one-line status + cross-link to the architecture doc that owns the design. The "why" stays in decisions.md; this plan is now a checklist + status, not a history book.

Pivot history (historical note). The active initiative moved three times, and the sequence is worth keeping legible because stale docs still carry each framing: (1) the original June 10 full-beta plan (june-launch.md) narrowed on 2026-06-03 to a single-session demo (june-demo.md); (2) that demo shipped 2026-06-10 to a production substrate that is now live and serving real patients, and on 2026-06-19 the initiative was recast as a September 2026 full launch — real clinics + the ~20k legacy migration, planned backwards from a date; (3) on 2026-08-02 the launch-date framing was retired. Planning backwards from a date produced pressure to cut scope, which the Foundation Discipline rules exist to prevent — and the migration has nowhere to land until the platform can run a clinic. The order is now build → harden → migrate, with no date. june-launch.md and june-demo.md are historical records; platform-completion.md is the active plan.