RTM Billing System¶
Overview¶
The RTM (Remote Therapeutic Monitoring) billing system tracks patient engagement and therapist management time, generating CPT billing codes for reimbursement. The system consists of two complementary billing tracks:
| Track | Codes | Based On | Cycle |
|---|---|---|---|
| Workout-based | 98975, 98985, 98977 | Patient workout completion | 30-day rolling windows |
| Time-based | 98979, 98980, 98981 | Therapist management time | Calendar month |
Both tracks share the same tenant feature flag, Zustand store (rtmBilling.ts), and dashboard UI (RtmBillingTabs).
CPT Codes Quick Reference¶
Workout-Based Codes (Patient Activity)¶
| Code | Trigger | Description |
|---|---|---|
| 98975 | Patient invited to system | Initial setup code |
| 98985 | 2-15 distinct workout days in 30-day window | Low-tier engagement |
| 98977 | 16+ distinct workout days in 30-day window | High-tier engagement |
Time-Based Codes (Therapist Activity)¶
| Code | Trigger | Description |
|---|---|---|
| 98979 | 10-19 minutes of management time in a calendar month | First threshold |
| 98980 | 20+ minutes of management time in a calendar month | Base 20+ code |
| 98981 | Each additional 20-minute increment beyond 20 min | Stacking add-on |
Dashboard Structure¶
RTM Billing Tab
├── Billable Codes
│ └── Table of billing records (workout + time codes) with status management
├── In Progress
│ ├── [Sub-tab] Workout Progress — Kanban board
│ │ ├── Never Logged In
│ │ ├── Needs Engagement
│ │ └── On Track
│ └── [Sub-tab] Time Tracking — Table view
│ └── All patients with current month's accumulated time + progress bars
└── Insights
└── Analytics: trends, code distribution, counts
Key UI Patterns¶
- "My Patients" / "All Patients" toggle — Available across all tabs, filters by therapist connection
- 5-minute client-side cache — All data endpoints use the same caching pattern in the Zustand store
- Independent data fetching — Each view (kanban, time table, billable codes, insights) fetches from its own endpoint; switching tabs doesn't block on unrelated data
- Optimistic updates — Settings changes update the UI immediately before server confirmation
Architecture¶
Backend¶
All API endpoints live under /v2/rtm-billing and require authentication.
| Endpoint | Purpose | Docs |
|---|---|---|
GET /feature-access |
Check tenant feature flag | Workout docs |
GET / |
Workout billing records | Workout docs |
PATCH /:id/status |
Update workout billing status | Workout docs |
POST /recalculate |
Recalculate workout billing | Workout docs |
GET /in-progress |
Kanban data (workout progress) | Workout docs |
GET /time-progress |
Time tracking progress table | Time docs |
POST /time-sessions |
Record time sessions | Time docs |
POST /time-sessions/beacon |
Record time (beacon) | Time docs |
GET /time-billing |
Time billing records | Time docs |
PATCH /time-billing/:id/status |
Update time billing status | Time docs |
POST /time-billing/recalculate |
Recalculate time aggregates | Time docs |
GET /time-entries/:patientId/:calendarMonth |
Audit entries | Time docs |
GET /settings |
Therapist reimbursement rates | Workout docs |
PATCH /settings |
Update reimbursement rates | Workout docs |
POST /nudge |
Send nudge email | Workout docs |
GET /insights |
Analytics/trends | Workout docs |
Frontend Store¶
The main Zustand store (lib/stores/rtmBilling.ts) manages state for the entire RTM billing dashboard. A separate store (lib/stores/rtmTimeTracking.ts) manages the pending entry queue for the time tracking hook.
Database Models¶
| Model | Purpose | Docs |
|---|---|---|
RtmBillingRecord |
Workout-based billing records | Workout docs |
RtmBillingRecordEvent |
Audit log for workout status changes | Workout docs |
RtmTimeEntry |
Granular time tracking audit log | Time docs |
RtmTimeBillingRecord |
Monthly time aggregates | Time docs |
TherapistSettings |
Per-code reimbursement rates | Workout docs |
Enabling the Feature¶
-- Enable RTM billing (all features) for a tenant:
UPDATE "TenantSettings"
SET features = jsonb_set(COALESCE(features, '{}'::jsonb), '{rtmBillingDashboard}', 'true')
WHERE "tenantId" = <TENANT_ID>;
A single feature flag controls the entire RTM billing system (both workout-based and time-based).
Detailed Documentation¶
- RTM CPT Billing Dashboard — Workout-based billing (98975, 98985, 98977): billing records, kanban board, insights, nudge emails, projected codes calculator
- RTM Time-Based Billing — Time tracking system (98979, 98980, 98981): time tracking hook, heartbeat model, multi-tab coordination, beacon delivery, time progress table