Skip to content

Navigation: advocates, care plans, PIN/CHI/CCM time and a monthly superbill - #4

Merged
ralyodio merged 1 commit into
masterfrom
navigation-billing
Oct 6, 2026
Merged

ralyodio merged 1 commit into
masterfrom
navigation-billing

Conversation

@ralyodio

@ralyodio ralyodio commented Oct 6, 2026

Copy link
Copy Markdown
Contributor

Takes the core of Solace's model (patient advocates paid through Medicare's navigation codes) and makes it something every tleehealth practice can bill.

What it adds

  • Advocate role (navigator): a team member and a billed seat. They see the charts, run care plans and log time; they are not clinicians.
  • Care plans: one active plan per patient, with goals and tasks that have owners (team or patient) and due dates. Overdue tasks are flagged. Share puts the plan in the patient portal, without internal fields.
  • Programs: enroll a patient in PIN, PIN peer support, CHI or CCM with the condition, consent, initiating visit, billing practitioner and navigator. The initiating visit defaults to the last completed visit with the billing practitioner.
  • Time logging: minutes by activity (prior auth, referral, scheduling…) against one program, so no minute counts toward two codes.
  • Caseload (/app/caseload): each enrollment's minutes this month, a progress bar to the next unit, codes earned, open/overdue tasks, and what blocks billing. Advocates see their own patients by default.
  • Superbill (/app/superbill, owners/managers/providers): the month's codes per patient, marked ready / on hold (with the reason) / under threshold, with ready totals per code and a CSV download for a biller.
Program First unit Add-on
PIN G0023 at 60 min G0024 per 30 more
PIN peer support G0140 G0146
CHI G0019 G0022
CCM 99490 at 20 min 99439 per 20 more, max 2

Time rule: the default is full time per unit. rule=midpoint applies the CPT midpoint rule (G0023 at 31 min) for billers whose payers accept it; I could not confirm from CMS whether that applies to these codes, so it is opt-in. CCM always needs its full 20 minutes. No prices are shown, because they vary by locality.

Hold reasons: no consent, or consent over a year old (PIN/CHI renew yearly); no initiating visit, or one after the month; no billing practitioner, or no NPI; no condition; CCM without a care plan; enrolled after the month.

Every surface

API (documented in llms.txt), web app, portal, CLI (tleehealth caseload | superbill [--csv] [--rule midpoint] | log-time), MCP (get_caseload, get_superbill, log_navigation_time). CLI and MCP are bumped to 0.3.0. NPIs are editable on the Team page.

Migrations

  • 0004: alter type user_type add value 'advocate', in its own file because an enum value can't be used in the transaction that adds it.
  • 0005: rebuilds the generated billable column and the org_seats view so advocates count as seats; adds org_people.npi, care_plans, care_plan_items, care_programs and care_time. Prod runs Postgres 17.

Tests

  • test/navigation.test.js: 19 tests. Unit math for full/midpoint/CCM caps, blockers including yearly consent, CSV formula escaping; then the API end to end: advocate seat, NPI validation, care plan sharing to the portal, enrollment with the default initiating visit, time limits, caseload, superbill held → ready, CSV, author/admin-only delete, ended programs, audit log.
  • Full suite: 67 pass on a fresh Postgres 16.
  • In Chromium (puppeteer): seeded a practice, then the chart, caseload, log-time modal (submitted through the UI), superbill and portal render with no console errors.
  • CLI and MCP checked against a local server.

Note: test/calls.test.js failed 3 tests when the whole suite was rerun against the same database (they pass on a fresh one, which is what CI uses). I didn't check whether master does the same.

🤖 Generated with Claude Code

…erbill

Patient advocates (navigators) are a new team role and a billed seat. They keep a
care plan per patient (goals and tasks with owners and due dates, shared to the
portal on request), enroll patients in care-management programs and log their
minutes against them. The superbill turns a month's minutes into Medicare's
time-based codes: PIN G0023/G0024, PIN peer support G0140/G0146, CHI
G0019/G0022 and CCM 99490/99439 (capped at two).

- A row is ready only when the claim has what it needs: consent (renewed yearly
  for PIN and CHI), an initiating visit with the billing practitioner, the
  practitioner's NPI, the condition, and a care plan for CCM. Otherwise it is
  held with the reason.
- Units default to full time; ?rule=midpoint applies the CPT midpoint rule for
  billers whose payers accept it. CCM always needs its full 20 minutes.
- The initiating visit defaults to the last completed visit with the billing
  practitioner.
- CSV export with spreadsheet-formula escaping; every read and write is
  audit-logged.
- Surfaces: /app/caseload, /app/superbill, chart cards, portal, the API
  (llms.txt), CLI caseload/superbill/log-time and MCP get_caseload,
  get_superbill, log_navigation_time. CLI and MCP 0.3.0.

Migrations: 0004 adds the advocate user type on its own (an enum value cannot be
used in the transaction that adds it); 0005 rebuilds the billable column and
org_seats view to count advocates, adds org_people.npi, care_plans,
care_plan_items, care_programs and care_time.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@ralyodio ralyodio closed this Oct 6, 2026
@ralyodio ralyodio reopened this Oct 6, 2026
@ralyodio
ralyodio merged commit 9c67215 into master Oct 6, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant