💬 Discussion no comments on technical yet comments don't trigger digest emails (mentions do)
Mention: @email@domain for a person,
@role:designer for everyone with that role,
or @all for everyone watching this module.
Markdown supported in the body.
No comments on the technical spec yet. Be the first.
Care Plan Subscriptions – Technical Specification
1. Module Purpose & Scope (Authoritative)
Care Plan Subscriptions is Primoro's in-house membership and capitation engine, enabling practices to run fully branded dental care plans with automated billing, entitlements, recalls, and governance — without reliance on third-party providers. The module delivers predictable recurring revenue via subscription billing, improves patient retention through prepaid preventive care, and replaces third-party scheme commissions with practice-owned plans. It enforces fair, auditable entitlement usage across the patient journey.
It governs:
- End-to-end lifecycle of practice-branded care plan tiers, from configuration through renewal or cancellation
- Direct Debit billing via GoCardless, including payment failure handling and suspension logic
- Entitlement creation, tracking, enforcement, and audit — including waiting-period and booking-window rules
- Recall interval locking for plan members, in coordination with Appointment Manager and Recall & Reconnect
- Signed contract storage (via Document Hub) and full audit trail of all member and plan events
It explicitly does not:
- Own generic payment-plan or instalment tooling (not in scope for any current module)
- Resurface or resell third-party membership schemes such as Denplan
- Own the surfacing of payment exceptions or staff tasks generated by failed payments — that responsibility belongs to Integrated Payments
- Own recall interval storage or recall notifications — the Practice Management System (PMS) is the sole source of truth for recall data
- Own points accrual or reward balance mutation — that responsibility belongs to Rewards Manager
- Own loyalty profile enrichment or churn scoring — that responsibility belongs to Loyalty Insights
- Own form-based patient intake or advisory capture — Digital Forms Workflow owns the intake surface; Care Plan Subscriptions is the authoritative source of plan truth that Digital Forms reads from
- Own hygiene product subscriptions or their associated recurring billing — Hygiene Subscriptions owns that domain
2. Ownership & Responsibilities
2.1 Care Plan Subscriptions IS Responsible For
- Defining, versioning, and governing care plan tiers, pricing, entitlements, and eligibility rules
- Processing and recording all Direct Debit billing events via GoCardless, including proration
- Enforcing entitlement availability (including waiting-period and contribution-threshold rules) and exposing status signals to consuming modules
- Locking recall intervals for plan members and exposing the
cadence_lockedsignal to Recall & Reconnect - Emitting plan-lifecycle events to Recall & Reconnect, Rewards Manager, and Loyalty Insights per the defined outbound contracts
- Emitting subscription billing, payment failure, and mandate cancellation signals to Financial Insights for aggregation into financial dashboards
- Storing immutable signed contracts and plan-version history in coordination with Document Hub
- Providing staff dashboards for member status, renewals, failed payments, and entitlement usage
- Audit-logging all state transitions, entitlement decisions, payment events, staff overrides, and outbound events
2.2 Care Plan Subscriptions IS NOT Responsible For
- Surfacing payment exceptions or creating staff follow-up tasks for failed payments — Integrated Payments owns exception surfacing and task creation via Communication Hub
- Storing or modifying recall intervals in the PMS — the PMS remains sole authority for recall data
- Awarding or mutating reward point balances — Rewards Manager owns all accrual logic
- Enriching patient loyalty profiles or computing churn scores — Loyalty Insights owns this
- Sending patient communications directly — Communication Hub owns all outbound messaging
- Task assignment and completion tracking — Communication Hub owns task creation; Task Manager owns task lifecycle
- Direct patient enrolment via forms — Digital Forms Workflow is advisory and data-capture only; Care Plan Subscriptions is the enrolment authority
- Managing hygiene product subscriptions or their billing — Hygiene Subscriptions owns that domain; patient record updates issued by this module MUST be scoped to care plan membership fields only, and MUST NOT overwrite subscription status fields owned by Hygiene Subscriptions
2.3 Boundary with Hygiene Subscriptions
Both Care Plan Subscriptions and Hygiene Subscriptions manage patient subscriptions with recurring Direct Debit billing via GoCardless. The boundary is defined as follows:
- Care Plan Subscriptions owns care plan memberships, plan entitlements, recall interval locking, and all associated billing and lifecycle events for care plans.
- Hygiene Subscriptions owns hygiene product subscriptions, their recurring billing, and the
subscription_statusandsubscription_labelfields on the patient's Primoro record as they pertain to hygiene plans.
To prevent patient record collisions:
- Each module MUST update only the patient record fields within its own domain.
- Payment failure escalation to Integrated Payments is performed independently by each module; neither module MUST duplicate the other's escalation events.
- If a patient holds both a care plan membership and a hygiene subscription simultaneously, the two sets of billing events are treated as independent and MUST NOT interfere with each other's suspension or reinstatement logic.
3. Core Objects (Normative)
3.1 CarePlan (Canonical Artefact)
A CarePlan is a governed digital artefact representing a versioned, practice-branded subscription plan template defining tier, pricing, entitlements, eligibility, and billing rules.
Minimum required fields:
plan_id(UUID PRIMARY KEY)practice_id(FK — owning practice)plan_nametier(e.g. Basic / Standard / Premium / Family)billing_cadence(monthly | annual)price_per_periodplan_statusversion(integer; incremented on any rule change)created_by(user/role)created_ataudit_trail(immutable)
3.2 CarePlanMembership (Canonical Artefact)
A CarePlanMembership is a governed digital artefact representing a single patient's enrolment in a specific CarePlan version, including contract acceptance, billing mandate, and term dates.
Minimum required fields:
membership_id(UUID PRIMARY KEY)plan_id(FK → CarePlan)patient_id(FK — Primoro patient identifier)membership_statusplan_start_dateplan_end_datemandate_id(GoCardless Direct Debit mandate reference)signed_contract_doc_id(FK → Document Hub)created_by(user/role)created_ataudit_trail(immutable)
3.3 Entitlement (Canonical Artefact)
An Entitlement is a governed digital artefact representing one discrete included service allocation within a plan year for a member.
Minimum required fields:
entitlement_id(UUID PRIMARY KEY)membership_id(FK → CarePlanMembership)entitlement_type(e.g.examination|hygiene|emergency)included_visits_per_year(integer)visits_used(integer)visits_remaining(integer)entitlement_statusnext_entitlement_due_date(ISO 8601)unlock_date(ISO 8601; populated when waiting period applies)payments_required(integer; remaining qualifying payments needed)reason_codeaudit_trail(immutable)
3.4 CarePlanMembership State Machine (Authoritative)
States:
pending_enrolment— mandate and terms not yet completedactive— fully enrolled, payments currentsuspended— payment failure; benefits temporarily withheldpending_renewal— current term expiring; auto-renewal queuedcancelled— plan terminated (mid-term by staff override, or at term end)lapsed— renewal not completed; plan expired without active cancellation
Rules:
- State transitions are auditable and timestamped.
- A membership MUST NOT return to
activefromsuspendedwithout a confirmed successful payment event from GoCardless. - A membership MUST NOT be cancelled mid-term except by an authorised staff override; the override MUST be audit-logged with actor and justification.
lapsedis a terminal state; re-enrolment requires a new CarePlanMembership record.- All transitions MUST propagate updated status to consuming modules (Recall & Reconnect, Rewards Manager, Loyalty Insights) via the defined outbound contracts.
3.5 Entitlement Status Values (Authoritative)
- Available — entitlement exists and the waiting-period/contribution threshold has been met; appointment MAY be marked £0
- Not Yet Available — entitlement exists but waiting-period or minimum contribution threshold has not been met
- Exhausted — entitlement fully used within the current plan year
- Missed — booking window has passed; entitlement is forfeited
3.6 Loyalty Insights Signal Schema & Availability Contract
The following normative section supplements §10.6 by specifying update frequency and null-state behaviour for the signals exposed to Loyalty Insights.
Update frequency:
- Plan longevity signals (
plan_start_date,continuous_membership_months,current_term_start_date,plan_tier_history) MUST be updated on every membership state transition and on every successful billing-period payment confirmation. - Cancellation-risk signals (
cancellation_requested,cancellation_effective_date,payment_failure_count_rolling_90d,suspension_active) MUST be updated in real time on the triggering event (cancellation notice, payment failure, suspension transition). - Renewal signals (
renewal_status,next_renewal_date) MUST be updated whenever membership status transitions to or frompending_renewal,lapsed, orcancelled.
Null-state handling:
- When Care Plan Subscriptions is disabled at practice level, all signals MUST return a null payload with a
module_disabledindicator; Loyalty Insights MUST NOT treat a null payload as a data error. - When a patient has no active or historical care plan membership,
continuous_membership_monthsMUST be returned as0; list fields such asplan_tier_historyMUST be returned as an empty ordered list. - Signal availability is unidirectional: Care Plan Subscriptions MUST NOT receive mutated or scored data back from Loyalty Insights.
Changes to this signal schema require a versioned update coordinated with Loyalty Insights (see §10.6).
4. Plan Configuration & Governance
4.1 Plan Tier Configuration (Authoritative)
Practices MAY create multiple care plan tiers (e.g. Basic / Standard / Premium / Family).
Each plan MUST define:
- Plan name and branding
- Billing cadence (monthly or annual)
- Price per billing period
- Included services per plan year (e.g. examinations, hygiene visits, emergency consultations), expressed as non-monetary entitlements
- Optional benefits (e.g. treatment discounts, emergency allowances)
- Eligibility rules
- Entitlement timing rules and booking windows
- Waiting-period and minimum-contribution rules (see §4.2)
Rules:
- Unused entitlements DO NOT roll over between plan years.
- Unused entitlements DO NOT convert to monetary credit.
- Plan changes apply only at renewal for existing members, with advance notice.
- Historical plan versions MUST be immutable once members have enrolled against them.
4.2 Waiting-Period & Contribution Rules (Authoritative)
Care Plan Subscriptions MUST support waiting-period and minimum-contribution rules to ensure fairness and financial sustainability of prepaid benefits.
The module MUST:
- Allow practices to define a waiting period (expressed as number of successful subscription payments or time elapsed) before specific entitlements become available
- Mark entitlements as
Not Yet Availableand surfaceunlock_dateandpayments_requiredwhen thresholds are not yet met - Expose waiting-period status consistently in Appointment Manager booking context, the patient mobile app, and staff dashboards
- Emit entitlement-status transition events to Recall & Reconnect when an entitlement moves from
Not Yet AvailabletoAvailable, so that Recall & Reconnect can re-evaluate recall eligibility for the affected patient (see §4.4)
The module MUST NOT:
- Apply rule changes mid-contract; waiting-period and contribution rules are version-locked at enrolment and apply only at renewal
Common configuration patterns include: first hygiene visit unlocked after N monthly payments; higher-value entitlements unlocked later in the plan year.
4.3 Practice-Level Entitlement Model Controls (Authoritative)
Practices MUST be able to define practice-level rules governing entitlement models.
Controls MUST allow practices to:
- Force pooled entitlements for specific plan types
- Force per-member entitlements for specific plan types
- Restrict switching between entitlement models
Rules:
- Entitlement model rules apply at plan creation.
- Rules MUST be visible to administrators.
- Overrides MUST be logged and permission-gated.
4.4 Entitlement-Availability Event Contract with Recall & Reconnect (Authoritative)
Care Plan Subscriptions MUST emit a structured entitlement-availability event to Recall & Reconnect whenever an entitlement transitions between availability states. Recall & Reconnect is required to consume this event and re-evaluate recall eligibility accordingly.
Event type: entitlement_status_changed
Event payload:
| Field | Description |
|---|---|
event_type |
entitlement_status_changed |
patient_id |
Primoro patient identifier |
membership_id |
FK → CarePlanMembership |
entitlement_type |
examination | hygiene | emergency |
previous_status |
Prior entitlement status value |
new_status |
Updated entitlement status value |
unlock_date |
ISO 8601; populated when new_status is not_yet_available; null otherwise |
payments_required |
Integer; remaining qualifying payments needed; null when not applicable |
reason_code |
waiting_period_payments | waiting_period_time | contribution_threshold | null |
effective_at |
ISO 8601 timestamp of the status transition |
Timing:
- The event MUST be emitted synchronously with the entitlement status transition; no deferred or batched emission is permitted.
- Recall & Reconnect MUST NOT override or adjust recall intervals for patients where
cadence_lockedistrue, regardless of the entitlement-availability event received. - All emitted events MUST be audit-logged, including suppressed events with reason codes.
4.5 Contract Term & Renewal
Plans operate on a 12-month minimum term, renewing automatically thereafter.
Cancellation:
- Not permitted mid-term except by exceptional staff override (audit-logged)
- Requires notice period (practice-defined)
Plan changes (pricing or benefits) apply at renewal only; existing members MUST receive advance notice per §11.2.
5. Eligibility & Enrolment (Governed)
5.1 Clinical Eligibility
Patients MUST meet clinician-defined eligibility rules before enrolment.
Default (configurable) rule: patient must have completed a qualifying exam and hygiene visit within the last 30 days.
Enrolment MUST be blocked if eligibility is not met.
5.2 Enrolment Channels
Patients MAY enrol via:
- Primoro Patient Mobile App (primary channel)
- Secure web portal
- Staff-assisted enrolment (in-practice)
Enrolment MUST include:
- Plan selection
- Direct Debit mandate setup via GoCardless
- Acceptance and e-signature of plan Terms & Conditions
Signed contracts MUST be stored in Document Hub and must be accessible to both patient and staff.
6. Billing & Payments (Authoritative)
6.1 Direct Debit Billing
All care plans MUST be billed via GoCardless Direct Debit.
Rules:
- Card payments are not permitted for subscriptions.
- Billing dates and proration rules are practice-configurable.
- All payments MUST be logged per member and per plan period.
6.2 Failed Payments & Suspension Rules
If a Direct Debit payment fails:
- The payment is marked
Failed. - Member benefits MAY be temporarily suspended; membership status transitions to
suspended. - An automated patient notification is triggered via Communication Hub.
- Retries follow GoCardless rules.
The module MUST emit the payment failure event — including relevant membership context — to Integrated Payments. Integrated Payments is then responsible for:
- Surfacing the exception in its exceptions view
- Creating the staff follow-up task in Communication Hub
Task creation MUST NOT be duplicated by Care Plan Subscriptions; Integrated Payments owns that step. No silent failures are permitted.
Fulfilment gating on Integrated Payments payment status:
Integrated Payments surfaces subscription payment status — including Failed — across the unified payment layer. Care Plan Subscriptions MUST gate fulfilment (i.e. entitlement availability) based on the confirmed payment status as reported by Integrated Payments, not solely on the raw GoCardless webhook. Specifically:
- When Integrated Payments reports a subscription payment as
Failed, Care Plan Subscriptions MUST transition the affected membership tosuspendedand withhold entitlement access. - When Integrated Payments confirms a successful collection or recovery, Care Plan Subscriptions MAY reinstate
activestatus, subject to the confirmation rules in §3.4. - Care Plan Subscriptions MUST NOT reinstate benefits on the basis of a GoCardless retry event alone if Integrated Payments has not yet confirmed the payment as collected.
Refund and PMS writeback coordination:
Where Integrated Payments initiates a refund against a care plan payment (e.g. following a dispute or billing error), Care Plan Subscriptions MUST be notified via the inbound event from Integrated Payments and MUST evaluate whether a membership state transition is required. Refund events MUST carry mandatory reason codes (as defined by Integrated Payments) so that the correct suspension or cancellation logic can be applied. Refund-triggered state transitions MUST be audit-logged with the Integrated Payments refund reference.
6.3 Financial Reconciliation
Finance Module MUST:
- Log recurring subscription income
- Record GoCardless fees
- Support export/sync to accounting systems (e.g. Xero)
Care Plan Subscriptions MUST sync membership status, tier, entitlement usage, and recall intervals to the PMS.
6.4 Financial Insights Signal Emission (Authoritative)
Care Plan Subscriptions MUST emit subscription lifecycle signals to Financial Insights so that subscription revenue can be accurately represented in Financial Insights dashboards and Insight Cards.
Signals MUST be emitted for the following event types:
| Signal type | Trigger | Key fields |
|---|---|---|
subscription_payment_collected |
Successful GoCardless collection confirmed | patient_id, membership_id, plan_id, amount, billing_period_start, billing_period_end, collected_at |
subscription_payment_failed |
GoCardless payment failure event received | patient_id, membership_id, plan_id, amount, failed_at, retry_count, reason_code |
subscription_payment_retry_outcome |
GoCardless retry succeeds or exhausts retries | patient_id, membership_id, plan_id, amount, outcome (recovered | exhausted), outcome_at |
subscription_mandate_cancelled |
Direct Debit mandate cancelled (member cancellation or lapse) | patient_id, membership_id, plan_id, mandate_id, cancelled_at, reason |
Rules:
- All signals MUST be emitted asynchronously via event (see §13.2).
- Signals MUST NOT be emitted in batch; each event MUST be emitted at the point the triggering condition is confirmed.
- All emitted signals MUST be audit-logged by Care Plan Subscriptions.
- Financial Insights is a consumer only; no data MUST flow back to Care Plan Subscriptions from Financial Insights.
- Changes to signal schema require a versioned update coordinated with Financial Insights.
7. AI Boundaries (Non-Negotiable)
AI MAY:
- Surface prompts suggesting plan enrolment or upgrade to staff for human review
- Explain care plan options to patients or staff in plain language
- Summarise entitlement usage and member activity for human review
AI MAY NOT:
- Auto-enrol patients in any plan
- Auto-apply plan changes, cancellations, or overrides
- Bypass entitlement enforcement, waiting-period rules, or audit logging
- Make billing commitments on behalf of the practice
- Replace required clinical or administrative judgement on plan suitability
8. Audit & Compliance
The system MUST log:
- All CarePlanMembership state transitions, with actor and timestamp
- All enrolment events, including channel and eligibility check outcome
- All payment events (collected, failed, retried, recovered) with GoCardless reference
- All entitlement usage decisions, including status at time of booking and the reason code applied
- All waiting-period enforcement decisions (including
Not Yet Availabledeterminations) - All staff overrides (mid-term cancellations, entitlement model changes, recall interval exceptions), with actor and justification
- All contract versions accepted by patients, with e-signature timestamp
- All outbound events emitted to Recall & Reconnect, Rewards Manager, Loyalty Insights, and Financial Insights — including suppressed events with reason codes
- All AI suggestions surfaced, and whether they were accepted or rejected by humans
- All Digital Forms captures referencing a plan member (advisory; read from this module's state)
- All refund events received from Integrated Payments, including refund reference and resulting membership state transition
Audit logs MUST be immutable and exportable for inspection.
All handling MUST comply with:
- UK Direct Debit Scheme rules
- GDPR and data minimisation principles
9. Access Control
Access roles below are drawn from patterns stated in the original; specific role names must be confirmed against Access Manager's role registry.
| Action | Role(s) |
|---|---|
| Create / configure plan tiers | Practice Administrator |
| Enrol patient in plan | Receptionist, Care Plan Coordinator, Practice Administrator |
| View member status and entitlements | Receptionist, Clinician, Care Plan Coordinator, Practice Administrator |
| Apply staff override (mid-term cancellation, entitlement model change) | Practice Administrator (permission-gated; audit-logged) |
| View audit log | Practice Administrator |
| Export audit log | Practice Administrator |
MFA requirements for sensitive operations — such as mid-term cancellation overrides or plan version publishing — must be confirmed against Access Manager's MFA policy before build.
10. Entitlements, Usage & Recall Alignment
10.1 Entitlement Enforcement
Each included service is represented as a non-transferable entitlement tied to a plan year. Entitlements are enforced at the point of booking via Appointment Manager (see §10.3).
Examples:
- 2 examinations per year
- 2 hygienist visits per year
- 1 emergency consultation per year
10.2 Booking Window & Recall Logic
Entitlements MUST be linked to recall logic.
Default booking window: appointment may be booked ±1 month around the due date.
Rules:
- Booking outside the window invalidates entitlement coverage.
- Missed booking results in the entitlement being marked
Missedand forfeited.
Recall reminders are delivered app-first, with fallbacks via Communication Hub.
10.3 Appointment Manager Integration (Authoritative)
Appointment Manager MUST:
- Recognise plan membership
- Validate entitlement availability at booking, consuming the status payload from Care Plan Subscriptions
- Mark covered services as £0 on invoices
Care Plan Subscriptions MUST expose the following entitlement status payload to Appointment Manager for each entitlement at the point of diary booking:
| Field | Description |
|---|---|
entitlement_id |
Unique identifier |
status |
available | not_yet_available | exhausted | missed |
unlock_date |
ISO 8601; populated when status is not_yet_available |
payments_required |
Integer; remaining qualifying payments needed (where applicable) |
reason_code |
waiting_period_payments | waiting_period_time | contribution_threshold |
When status is not_yet_available, Appointment Manager MUST:
- Present the patient and/or staff with a plain-language explanation of why the entitlement is unavailable and the earliest date it will unlock
- Default the appointment to chargeable (standard fee applies) or offer deferral, per the rules defined in §4.2
- NOT block the slot from being booked entirely; diary access remains, but entitlement coverage is withheld
All enforcement decisions based on this payload MUST be audit-logged.
Entitlement query API — real-time validation contract:
Appointment Manager queries entitlement status via a synchronous API call at each booking attempt. The contract MUST satisfy the following requirements:
- The API endpoint MUST accept
patient_idandappointment_type(mapped toentitlement_type) as minimum query parameters. - The response MUST include the full entitlement status payload defined above for every entitlement relevant to the requested appointment type.
- The API MUST return a response within the latency threshold defined in §19 (target ≤300ms p95).
- Where a patient holds no active care plan membership, the API MUST return a structured null response indicating
no_active_plan; Appointment Manager MUST NOT treat this as an error. - Where the patient's plan status is
suspended, the API MUST return all entitlements with statusnot_yet_availableandreason_codeset toplan_suspended. - The API contract MUST be versioned; changes to field names or response semantics require a documented version increment and coordinated release with Appointment Manager.
- Appointment Manager validates active plan membership, waiting-period thresholds, minimum-contribution thresholds, and remaining entitlement balance exclusively via this API; Care Plan Subscriptions is the sole authority for all these determinations.
10.4 Recall & Reconnect Integration Contract (Authoritative)
Recall & Reconnect consumes visit cadence, included-visit entitlement status, and plan status directly from Care Plan Subscriptions. Care Plan Subscriptions is the authoritative supplier of these data for all patients on an active plan.
Plan status fields (per patient/member):
| Field | Description |
|---|---|
plan_id |
Unique identifier of the active plan |
plan_name |
Plan name |
tier |
Plan tier |
plan_status |
active | suspended | cancelled | pending_renewal |
plan_start_date |
ISO 8601 |
plan_end_date |
ISO 8601 (current term) |
Visit cadence fields:
| Field | Description |
|---|---|
recall_interval_months |
Recall interval mandated by the active plan (integer) |
cadence_locked |
Boolean; true = interval is plan-governed and MUST NOT be overridden by Recall & Reconnect |
Entitlement status fields (per entitlement type, per member):
| Field | Description |
|---|---|
entitlement_type |
examination | hygiene | emergency |
included_visits_per_year |
Integer |
visits_used |
Integer |
visits_remaining |
Integer |
next_entitlement_due_date |
ISO 8601 |
entitlement_status |
available | not_yet_available | exhausted | missed |
Rules:
- Recall & Reconnect MUST NOT override or adjust recall intervals for patients where
cadence_lockedistrue. - Where
entitlement_statusisexhaustedormissed, Recall & Reconnect MAY surface informational prompts but MUST NOT represent the visit as plan-covered. - Recall & Reconnect MUST consume
entitlement_status_changedevents (see §4.4) and re-evaluate recall eligibility when an entitlement transitions fromnot_yet_availabletoavailable. - Recall & Reconnect MUST respect waiting-period and minimum-contribution rules as supplied by this module; it MUST NOT independently compute or override these thresholds.
- This contract MUST be versioned; changes to field names or semantics require a documented version increment and coordinated release with Recall & Reconnect.
10.5 Rewards Manager Integration — Participation Event Contract (Authoritative)
Care Plan Subscriptions MUST emit a defined participation event to Rewards Manager when a patient constitutes an active, qualifying plan participant, enabling points accrual for active plan membership as governed by Rewards Manager.
Qualifying participation conditions — event MUST be emitted when ALL of the following are true:
- The patient has an active Care Plan subscription (
plan_status: active) - The most recent Direct Debit payment has been collected successfully (no outstanding failed payments)
- The plan is within its current contracted term (not cancelled, not suspended)
Event payload:
| Field | Description |
|---|---|
event_type |
care_plan_participation_active |
patient_id |
Primoro patient identifier |
plan_id |
Unique identifier of the active plan |
plan_tier |
Plan tier name (e.g. Basic / Standard / Premium) |
participation_date |
ISO 8601 date of the qualifying payment or status confirmation |
subscription_months_active |
Integer; cumulative months of uninterrupted active participation |
Timing:
- The event MUST be emitted once per billing period upon successful payment confirmation from GoCardless.
- It MUST NOT be emitted for suspended, cancelled, or failed-payment states.
- If a suspension is subsequently resolved (payment recovered), the event MAY be re-emitted for the recovered period, subject to Rewards Manager deduplication rules.
Rules:
- Care Plan Subscriptions MUST NOT mutate reward balances directly; all points accrual logic is owned by Rewards Manager.
- The event payload is read-only from Care Plan Subscriptions' perspective.
- All emitted events MUST be audit-logged, including suppressed events with reason codes.
10.6 Loyalty Insights Integration — Plan-Lifecycle Signal Exposure (Authoritative)
When Loyalty Insights is enabled, Care Plan Subscriptions MUST expose plan-lifecycle signals so that Loyalty Insights can enrich patient loyalty profiles with plan longevity and cancellation-risk data. The detailed signal schema, update frequency, and null-state handling are specified in §3.6.
Plan longevity signals:
| Field | Description |
|---|---|
plan_start_date |
Date the patient first enrolled in any Care Plan |
continuous_membership_months |
Integer; total uninterrupted months of active plan membership |
current_term_start_date |
Start of the current contracted term |
plan_tier_history |
Ordered list of plan tiers held, with effective dates |
Cancellation-risk signals:
| Field | Description |
|---|---|
cancellation_requested |
Boolean; true if cancellation notice submitted but plan not yet expired |
cancellation_effective_date |
ISO 8601; populated when cancellation_requested is true |
payment_failure_count_rolling_90d |
Integer; failed Direct Debit payments in rolling 90-day window |
suspension_active |
Boolean; whether plan is currently suspended due to payment failure |
Renewal signals:
| Field | Description |
|---|---|
renewal_status |
auto_renewing | pending_patient_action | opted_out | lapsed |
next_renewal_date |
ISO 8601 |
Rules:
- Loyalty Insights MUST treat Care Plan Subscriptions as the authoritative source for all plan-status and longevity data.
- Care Plan Subscriptions MUST NOT receive mutated or scored data back from Loyalty Insights; the data flow is unidirectional.
- Changes to the signal schema require a versioned update coordinated with Loyalty Insights.
11. Delivery Surfaces & Access (Authoritative)
11.1 Web Portal (Staff)
Staff dashboards MUST surface:
- Active members
- Upcoming renewals
- Failed payments and suspension status
- Unused or missed entitlements
- Care Plan Outcomes (from Digital Forms captures — see §12.4)
11.2 Tablet App / Appointment Workflow
When Care Plan Subscriptions is enabled, the appointment workflow (including F&A App or equivalent clinician workflows) MUST include a Care Plan Advisory step for qualifying appointments (e.g. New Patient Exam, Exam, Scale & Polish).
Rules:
- The Care Plan Advisory step MUST appear before any recall interval setting step.
- If the patient is not on a Care Plan: the clinician MUST be prompted to discuss and recommend an appropriate plan; the workflow MUST capture: whether discussed (Yes/No), recommended plan (if any), and patient interest or decision (Interested / Declined / Deferred).
- If the patient IS on a Care Plan: the recall interval screen MUST be locked to the interval defined by the active plan; the clinician MUST NOT be able to change the recall interval within the appointment workflow.
- Any recommendation to change recall frequency is advisory only; recommendations MUST be recorded but MUST NOT alter live recall data.
- Ad-hoc appointments outside recall (e.g. additional hygiene visits) MUST remain payable separately and MUST NOT modify recall interval or entitlements.
11.3 Patient Mobile App
The Patient Mobile App MUST provide:
- Care Plan status and tier summary
- Real-time entitlement balances in plain language
- Family Entitlements View (see §11.4)
- Waiting-period status and unlock dates where applicable
- Upcoming Changes Banners when future plan changes are scheduled (see §11.5)
- Proration explanations in plain English where applicable (see §11.6)
- Enrolment flow (primary channel)
- Recall reminders linked to entitlement due dates
11.4 Family Entitlements View (Authoritative)
The Patient Mobile App and Web Portal MUST provide a clear, real-time Family Entitlements View.
The view MUST:
- Display all family members under the plan
- Show the active entitlement model (Pooled or Per-Member)
- Surface entitlement balances in plain language
For pooled entitlements: show total shared allowance, usage by member (where applicable), and remaining balance.
For per-member entitlements: show individual allowances per member, and used vs remaining entitlements.
The Family Entitlements View MUST be accessible from the main care plan summary screen and from appointment booking flows (contextually).
11.5 Upcoming Changes Banners & Notices (Authoritative)
The system MUST surface Upcoming Changes Banners across the patient experience when future changes are scheduled.
Banners MUST appear on: care plan dashboards, during appointment booking, and within renewal journeys.
Each banner MUST clearly state: what is changing (price, entitlements, member age band), when it will happen (effective date), and whether action is required or the change will apply automatically.
Where staff approval is required, the banner MUST state that the change is pending review.
11.6 Proration Explanations (Patient-Facing)
Where proration applies, the system MUST explain changes in plain English.
Proration explanations MUST: state why the adjustment is happening; explain how pricing or entitlements are being adjusted; and confirm whether changes apply now or at renewal.
Explanations MUST appear in-app alongside the change notification, in renewal summaries, and within plan documentation where relevant.
11.7 Engagement Signals
The following engagement signals are drawn from dashboard and integration requirements stated throughout the original; precise metric names and export format should be confirmed during build.
Staff visibility signals MUST include: failed payment counts, suspension counts, upcoming renewal counts, unused/missed entitlement counts, and care plan outcomes from Digital Forms captures.
Optional integration with Campaign Manager enables marketing campaigns targeting eligible patients.
12. Digital Forms Workflow Integration (Authoritative)
12.1 Conditional Enablement via Admin Settings
Care Plan Subscriptions MUST integrate with Digital Forms Workflow when that module is enabled.
Rules:
- Integration MUST be configurable at practice level via Admin Control Plane.
- A dedicated setting MUST allow administrators to: enable or disable Care Plan logic within digital forms; and select which form types and appointment contexts trigger Care Plan interactions.
- If Care Plan Subscriptions is disabled: no Care Plan-related fields, prompts, or logic MUST appear in digital forms.
12.2 Digital Forms Behaviour (When Enabled)
When enabled, Digital Forms MUST:
- Surface Care Plan awareness contextually, including: patient Care Plan status (on / not on plan); current plan name and tier (if enrolled)
- Allow structured capture of: practitioner Care Plan recommendation; whether the plan was discussed; patient interest or decision
Forms MUST NOT:
- Directly enrol patients into plans
- Modify live plan rules, pricing, or recall intervals
All form interactions are advisory and data-capture only. Digital Forms MUST NOT be the source of truth for Care Plan enrolment or recall rules.
12.3 Workflow Triggers, Messaging & Outcome Tracking (Authoritative)
Captured Care Plan data from Digital Forms MUST trigger Primoro-native follow-up actions.
When a patient shows interest in a Care Plan, is recommended a plan by a practitioner, or makes a decision (accept/decline/defer), the platform MUST create:
- Communication Hub threads/messages to the patient (mobile-app first)
- Tasks assigned to the appropriate team (reception/care plan team) with due dates
- Care Plan Follow-Up Status updates for tracking outcomes
Patient follow-up MUST be mobile-app first; if not enrolled at the appointment, Primoro MUST send reminders in the patient mobile app to complete sign-up. Fallback channels (email/SMS) MAY be used via Communication Hub configuration.
Rules:
- Workflows MUST reuse approved message templates
- Workflows MUST respect suppression rules (e.g. do not chase if already enrolled)
- All actions, messages, and outcomes MUST be audit-logged
Follow-up behaviour captured during the appointment workflow MUST align with Digital Forms integration rules and the Care Plan Outcomes Dashboard.
If a patient expresses interest but does not enrol during the appointment:
- Primoro MUST trigger mobile-app follow-up reminders
- Follow-ups MUST be suppressed automatically once enrolment is completed
12.4 Care Plan Outcomes Dashboard (Authoritative)
When Digital Forms capture Care Plan interest or decisions, the system MUST provide a status dashboard for staff to track outcomes.
The dashboard MUST:
- List patients captured from appointments with Care Plan outcomes (interested / declined / enrolled / follow-up pending)
- Show whether the patient enrolled during the appointment or later
- Show current follow-up state and next action owner
- Surface overdue follow-ups and failed contact attempts
The dashboard MUST integrate with: task assignment and completion; Communication Hub message history; and Care Plan enrolment status (this module as source of truth).
12.5 Governance & Data Integrity
- Digital Forms MUST NOT be the source of truth for Care Plan enrolment or recall rules.
- All Care Plan contracts, pricing, renewals, and entitlement logic remain owned by Care Plan Subscriptions.
- All captured form data MUST be timestamped and reference appointment, practitioner, and patient identifiers.
- All captured data MUST be available for reporting, audit, and KPI analysis.
13. Integration Contracts
13.1 Inbound (this module consumes from)
| From module | What | Contract |
|---|---|---|
| GoCardless | Payment collection confirmations, failure events, retry outcomes | Webhook (async) |
| Appointment Manager | Booking events triggering entitlement validation requests | Sync API call |
| Digital Forms Workflow | Advisory capture: plan discussions, patient decisions | Event (async) |
| Integrated Payments | Payment status confirmations, refund events with reason codes | Event (async) |
| PMS (e.g. Dentally) | Patient record, recall baseline | Sync |
13.2 Outbound (this module emits to)
| To module | What | Contract |
|---|---|---|
| Integrated Payments | Payment failure event with membership context | Event (async) |
| Communication Hub | Notification triggers (payment failure, renewal, recall reminder) | Event (async) |
| Appointment Manager | Entitlement status payload per booking | Sync API response |
| Recall & Reconnect | Plan status, cadence, and entitlement status contract (§10.4); entitlement-availability events (§4.4) | Sync / query + Event (async) |
| Rewards Manager | care_plan_participation_active event (§10.5) |
Event (async) |
| Loyalty Insights | Plan longevity, cancellation-risk, renewal signals (§10.6, §3.6) | Sync / query |
| Document Hub | Signed contracts for storage | Sync |
| Finance Module | Subscription income, GoCardless fees | Event / sync |
| Financial Insights | Subscription payment collected/failed/retry-outcome/mandate-cancelled signals (§6.4) | Event (async) |
| Campaign Manager | Eligible patient signals for marketing (optional) | Event (async) |
13.3 PMS Boundary
The PMS (e.g. Dentally) remains the sole source of truth for recall intervals and recall notifications.
Care Plan Subscriptions MUST sync membership status, tier, entitlement usage, and recall intervals to the PMS.
Appointment workflows MUST NOT write back changes to recall data for patients on an active Care Plan. The workflow MUST prevent accidental or indirect recall changes caused by form completion or screen navigation.
14. Analytics, KPIs & Reporting (Authoritative)
14.1 Family Plan Performance Metrics
The system MUST provide analytics measuring family plan profitability versus utilisation.
Metrics MUST include:
- Total subscription revenue per family plan
- Entitlement utilisation rate
- Average cost of fulfilment per family
- Profitability by plan type and entitlement model
Dashboards SHOULD allow filtering by: pooled vs per-member entitlements; family size; age band distribution; renewal outcomes.
15. Integration Summary
- GoCardless — inbound Direct Debit billing and payment event webhooks
- Appointment Manager — sync entitlement status validation at booking via versioned query API (§10.3); recall interval locking
- Integrated Payments — outbound payment failure events; inbound payment status confirmations and refund events; Integrated Payments owns exception surfacing and staff task creation
- Communication Hub — outbound notification triggers; owns all patient-facing messaging and task creation
- Recall & Reconnect — outbound plan status, cadence lock, and entitlement status contract; outbound
entitlement_status_changedevents (§4.4) - Rewards Manager — outbound
care_plan_participation_activeparticipation events (§10.5) - Loyalty Insights — outbound plan longevity, cancellation-risk, and renewal signals (§10.6, §3.6)
- Document Hub — signed contract storage
- Finance Module — subscription income and GoCardless fee logging
- Financial Insights — outbound subscription billing, failure, retry, and mandate cancellation signals (§6.4)
- Digital Forms Workflow — inbound advisory capture; Care Plan Subscriptions is the authority Digital Forms reads from
- Campaign Manager — optional outbound eligible-patient signals for marketing
- Access Manager — RBAC for all read/write/approve/override operations
- Audit & Compliance — immutable event log for all state transitions and data events
- PMS (e.g. Dentally) — authoritative source of recall intervals; sync target for membership status
- Hygiene Subscriptions — adjacent module; patient record updates are domain-scoped to prevent field collisions (§2.3)
16. Explicit Non-Goals
- Care Plan Subscriptions is not a generic payment-plan or instalment tool; a future instalment module would own that concern.
- Care Plan Subscriptions does not resurface or resell third-party membership schemes (e.g. Denplan).
- Care Plan Subscriptions does not own discount-only features unconnected to prepaid entitlements.
- Care Plan Subscriptions does not own hygiene product subscriptions; that domain belongs to Hygiene Subscriptions.
17. Versioning & Governance
Module ownership role should be confirmed against the Primoro product ownership registry before this spec is promoted from draft.
This specification is owned by: (module owner role — to be confirmed)
Changes to this spec require:
- Review by the Post-MVP module owner
- Impact analysis across all declared related modules (see /propose), specifically Appointment Manager, Recall & Reconnect, Rewards Manager, Loyalty Insights, Integrated Payments, Financial Insights, and Digital Forms Workflow, which have versioned integration contracts
- Version bump (patch / minor / major) per the versioning policy
- Coordinated release where schema or contract changes affect consuming modules
18. Build Contract (Engineering & QA)
18.1 Canonical Data Model
(Full schema to be specified during engineering design; fields defined in §3 are normative minimums.)
care_plans (
plan_id UUID PRIMARY KEY,
practice_id UUID NOT NULL,
plan_name TEXT NOT NULL,
tier TEXT NOT NULL,
billing_cadence TEXT NOT NULL, -- 'monthly' | 'annual'
price_per_period NUMERIC NOT NULL,
plan_status TEXT NOT NULL,
version INTEGER NOT NULL DEFAULT 1,
created_by UUID NOT NULL,
created_at TIMESTAMPTZ NOT NULL,
audit_trail JSONB NOT NULL
)
care_plan_memberships (
membership_id UUID PRIMARY KEY,
plan_id UUID NOT NULL REFERENCES care_plans(plan_id),
patient_id UUID NOT NULL,
membership_status TEXT NOT NULL,
plan_start_date DATE NOT NULL,
plan_end_date DATE NOT NULL,
mandate_id TEXT NOT NULL,
signed_contract_doc_id UUID NOT NULL,
created_by UUID NOT NULL,
created_at TIMESTAMPTZ NOT NULL,
audit_trail JSONB NOT NULL
)
entitlements (
entitlement_id UUID PRIMARY KEY,
membership_id UUID NOT NULL REFERENCES care_plan_memberships(membership_id),
entitlement_type TEXT NOT NULL,
included_visits_per_year INTEGER NOT NULL,
visits_used INTEGER NOT NULL DEFAULT 0,
visits_remaining INTEGER NOT NULL,
entitlement_status TEXT NOT NULL,
next_entitlement_due_date DATE,
unlock_date DATE,
payments_required INTEGER,
reason_code TEXT,
audit_trail JSONB NOT NULL
)
18.2 Core Behaviour Rules
- A patient MUST NOT be enrolled unless all eligibility rules defined on the plan are satisfied at enrolment time.
- A CarePlanMembership MUST NOT reach
activestatus until a GoCardless mandate is confirmed and Terms & Conditions are e-signed. - Entitlement status MUST be recalculated and the updated payload MUST be available to Appointment Manager in real time at each booking attempt.
- When entitlement status is
not_yet_available, Appointment Manager MUST receiveunlock_dateandpayments_requiredin the status payload. - Recall intervals for plan members MUST be locked; the appointment workflow MUST prevent write-back to PMS recall data for active plan members.
- A payment failure event MUST be emitted to Integrated Payments within one retry cycle; no silent failures are permitted.
- The
care_plan_participation_activeevent MUST be emitted to Rewards Manager once per billing period on successful payment confirmation; it MUST NOT be emitted in suspended, cancelled, or failed-payment states. - Unused entitlements MUST NOT roll over between plan years and MUST NOT convert to monetary credit.
- Plan rule changes (pricing, entitlements, waiting periods) MUST NOT apply mid-contract; they apply at renewal only.
- Mid-term cancellations MUST be permission-gated and MUST generate an immutable audit record including actor ID and justification.
- All outbound integration events MUST be audit-logged, including suppressed events with reason codes.
- Signed contracts MUST be stored in Document Hub and MUST remain accessible to both patient and staff for the life of the membership.
- Digital Forms captures MUST trigger follow-up actions (Communication Hub message and task) and MUST be suppressed once enrolment is completed.
- Staff tasks for failed payments MUST be created by Integrated Payments, not duplicated by Care Plan Subscriptions.
- Entitlement fulfilment MUST be gated on payment status as confirmed by Integrated Payments; GoCardless retry events alone MUST NOT reinstate entitlement access without Integrated Payments confirmation.
- An
entitlement_status_changedevent MUST be emitted to Recall & Reconnect on every entitlement status transition; no batched or deferred emission is permitted. - Financial Insights subscription lifecycle signals (§6.4) MUST be emitted per-event at point of trigger; batched emission is not permitted.
- Patient record updates MUST be scoped to care plan membership fields only and MUST NOT overwrite fields owned by Hygiene Subscriptions.
18.3 Configuration Surfaces
- Admin Control Plane (practice-level): Plan tier creation and versioning; billing cadence and proration rules; eligibility rule definition; waiting-period and contribution thresholds; entitlement model controls (pooled vs per-member); Digital Forms Workflow integration toggle; campaign integration toggle; message template selection
- Access Manager (per-user): Role-based permissions for plan management, enrolment, and override actions
- Per-plan overrides (this module): Entitlement model, booking window, and waiting-period rules — version-locked at enrolment
18.4 Filtering & Views
Staff dashboards MUST support filtering by:
- Membership status (active / suspended / pending renewal / cancelled / lapsed)
- Plan tier
- Payment status (current / failed / recovering)
- Renewal date range
- Entitlement utilisation (used / unused / missed)
- Care Plan Outcomes status (interested / declined / enrolled / follow-up pending)
Saved view functionality (user-defined filter sets) should be confirmed as in or out of scope for the initial build before engineering begins.
18.5 Module Extension Map
The following extension points are anticipated without breaking this contract:
- Additional entitlement types (beyond examination / hygiene / emergency) via plan configuration, without schema changes
- Additional participation event types to Rewards Manager, gated by the existing event contract versioning mechanism
- Additional plan-lifecycle signals to Loyalty Insights, via a versioned schema increment
- Additional subscription lifecycle signal types to Financial Insights, via a versioned schema increment
- Multi-currency or multi-jurisdiction billing rules, if GoCardless configuration supports them
18.6 Acceptance Criteria
The build of Care Plan Subscriptions is complete when:
- [ ] All canonical objects (CarePlan, CarePlanMembership, Entitlement) can be created, read, and updated through the API
- [ ] State machine transitions enforce all rules in §3.4 and §3.5
- [ ] All integrations in §13 are wired and verified by integration tests
- [ ] Entitlement status payload is returned in real time to Appointment Manager with all required fields; versioned API contract is enforced
- [ ] Entitlement query API returns structured null response for patients with no active plan; plan-suspended state returns
not_yet_availablefor all entitlements - [ ] Recall interval locking prevents write-back to PMS for active plan members
- [ ] Payment failure events are emitted to Integrated Payments; no staff tasks are created by this module directly
- [ ] Fulfilment gating on Integrated Payments payment status is enforced; GoCardless retry alone does not reinstate benefits
- [ ] Refund events from Integrated Payments trigger correct membership state transitions and are audit-logged with refund reference
- [ ]
care_plan_participation_activeevents are emitted to Rewards Manager per billing cycle on successful payment; negative tests confirm suppression on failure/suspension - [ ]
entitlement_status_changedevents are emitted to Recall & Reconnect on every status transition; timing and payload tests pass - [ ] Financial Insights subscription lifecycle signals are emitted per-event for all four signal types (§6.4); payload and timing tests pass
- [ ] Loyalty Insights and Recall & Reconnect integration contracts are queryable with versioned schemas; null-state handling returns expected responses when module is disabled or patient has no plan
- [ ] Patient record updates are scoped to care plan fields; no collision with Hygiene Subscriptions fields (negative tests pass)
- [ ] Digital Forms integration conditional logic enforces enable/disable per Admin Control Plane setting
- [ ] Care Plan Outcomes Dashboard reflects real-time enrolment and follow-up state
- [ ] Follow-up suppression triggers automatically on enrolment completion
- [ ] AI boundaries in §7 are enforced (negative tests pass — AI cannot auto-enrol or auto-apply overrides)
- [ ] Audit log captures every event category in §8; logs are immutable and exportable
- [ ] Access control is enforced per §9; permission-gated overrides require elevated role
- [ ] All non-functional requirements in §19 are met
19. Non-Functional Requirements
- Performance: Entitlement status payload MUST be returned to Appointment Manager with sufficient latency to not degrade the booking flow. Target latency threshold to be defined during engineering design; a value of ≤300ms p95 is a common benchmark for sync booking validation calls and should be validated against actual GoCardless and PMS round-trip characteristics.
- Reliability: The module should target high availability consistent with Primoro's platform SLA; graceful degradation behaviour on GoCardless webhook delay must be defined — specifically, whether entitlement validation fails open or closed when the billing status is transiently unavailable.
- Scalability: The module MUST support multi-site, multi-tenant operation; plan configurations and memberships MUST be fully isolated per practice.
- Security: All patient and payment data MUST be encrypted at rest and in transit. GoCardless mandate references MUST be stored and handled per GoCardless security requirements. Signed contract storage in Document Hub MUST be access-controlled per membership.
- Privacy: The module MUST honour GDPR rights including the right to access and the right to erasure, subject to legal retention obligations for financial and contract records. Data minimisation principles apply to all fields collected at enrolment. Specific retention periods for membership records, payment logs, and signed contracts must be confirmed with the Data Protection Officer before build.
- Observability: The module MUST export metrics for: active membership count by status; payment success/failure rates per billing cycle; entitlement utilisation rates; outbound event emission counts and failure rates (including Financial Insights and Recall & Reconnect event channels). Structured logs MUST be emitted for all state transitions and integration events. Distributed tracing MUST cover the entitlement validation path from Appointment Manager request to response.
- Accessibility: All patient-facing surfaces (mobile app enrolment, Family Entitlements View, Upcoming Changes Banners, proration explanations) MUST meet WCAG 2.1 AA. Staff dashboard accessibility requirements should be confirmed against Primoro's internal accessibility standard.
20. Open Questions
- Fail-open vs fail-closed on GoCardless delay (§6.1, §19): When the GoCardless webhook is transiently delayed, should entitlement validation in Appointment Manager fail open (assume active) or fail closed (treat as suspended)? This is a product decision with financial and patient-experience implications.
- MFA for sensitive overrides (§9): Which specific operations (e.g. mid-term cancellation, plan version publish, entitlement model change) require MFA? Must be confirmed against Access Manager's MFA policy.
- Latency SLA for entitlement status payload (§10.3, §19): What is the maximum acceptable p95 latency for the entitlement status response to Appointment Manager? The original is silent on a target; this must be defined before QA acceptance criteria can be written.
- Data retention periods for financial and contract records (§8, §19): What are the specific retention periods for membership records, payment logs, and signed contracts? Must be confirmed with the Data Protection Officer given GDPR and UK Direct Debit Scheme obligations.
- Campaign Manager integration scope (§11.7, §13.2): The original lists Campaign Manager as an optional integration but does not define the event contract. What signals does Care Plan Subscriptions emit to Campaign Manager, and what is the trigger logic?
- Saved views in staff dashboards (§18.4): Is user-defined saved-view functionality in scope for the initial build, or deferred?
- Module ownership role (§17): Which product role owns this module's spec governance? Must be confirmed against the Primoro product ownership registry before the spec can be promoted from draft to published.
- Lapsed re-enrolment flow (§3.4): The state machine specifies that
lapsedis terminal and re-enrolment requires a new CarePlanMembership. Is there a defined re-enrolment UX flow, and does it require a fresh eligibility check? - Mandate cancellation event ownership (§6.4): When a Direct Debit mandate is cancelled, does Care Plan Subscriptions emit the
subscription_mandate_cancelledsignal to Financial Insights directly, or does Integrated Payments own that emission following its own webhook from GoCardless? The handoff point must be agreed between module owners before build to prevent duplicate signals.