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.

Detailed checklists live in:

  • Foundation — the five sub-phases (1A–1E) that close before staging ships
  • Features — what builds on top of the foundation, in dependency order
  • Production Launch Readiness — operational gate (Sentry / Bunny / first-clinic onboarding / on-call / Romanian compliance sign-off) that flips the switch on real patients

Three distinct gates, in order: Foundation 1E.3 (staging works, no real patients) → F-tier features (F1–F12 built on substrate) → Production Launch Readiness (operational checklist for first paying clinic). 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
Core 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
  • "Core API" = the main backend (not "the API")
  • "Clinic app" / "Patient portal" / "Console" = the three frontends
  • In code: core-api, telemetry-api, clinic, portal, console, ui

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 rename1C.9 (rename) + 1C.1 (capability framework) + 1C.2 (Cat A providers) + 1C.3 (events registry) + 1C.4 (Outbound Webhooks Cat C) + 1C.5 (Connected Accounts Cat B) + 1C.6 (Inbound Webhook Framework Cat D, framework-only) shipped; 1C.7 / 1C.8 design-locked, implementation queued
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 primitivesDataTable + audit log shipped; rest open
11EFoundation Gate — setup-a-clinic acceptance test, foundation gate documentation, AWS staging deploymentSetup-clinic test green locally; staging deployment pending
2F1Specialists & SpecialtiesBlocked on 1E
2F2Service CatalogBlocked on F1
2F3Forms & ConsentsBlocked on F1
2F4SchedulingBlocked on F2, F3
2F5AppointmentsBlocked on F4
2F6DocumentsBlocked on F5
2F7Automations & WebhooksBlocked on F5
2F8SegmentsBlocked on F5
2F9TelerehabBlocked on F3, F5
2F10Telemetry ServiceParallel-eligible with F1–F9; held until 1E closes per Layer Discipline. Locked design: PG aggregates + S3 replay blobs, no ClickHouse — see /architecture/decisions#why-telemetry-is-pg--s3-not-clickhouse
2F11Compliance Hardening + Production DeployOperational hardening pass; not the billing engine
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.Blocked on F11
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.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.