OHMOHM Studio

Onboarding a non-clinical user

End-to-end flow for getting a medical coder or billing staff member onto the Tools Portal — from DNS through their first AI extraction.

View as Markdown

Four roles, four steps. Same backend, same login, same Organization scoping as the doctor app.

DevOps — one-time infra

# 1a — pull the latest code with codes-tool + apps/tools
git pull origin main

# 1b — apply schema additions to your DB (additive, zero-downtime)
cd apps/api && pnpm db:push

# 1c — build + start the new container
cd ../..
docker compose build tools
docker compose up -d tools

# 1d — local smoke
curl -I http://localhost:8085/healthz   # → 200

For production:

  • Add tools.ohm.doctor A/CNAME → same target as studio.ohm.doctor.
  • Caddy auto-issues the Let's Encrypt cert (the new block is already in Caddyfile).
  • curl -I https://tools.ohm.doctor → 200 from the SPA shell.

Platform Admin — enable the feature for an org

There's no UI for the paywall layer yet — it's one SQL statement:

UPDATE organizations
SET features = features || '{"codes": true}'::jsonb
WHERE slug = 'kauvery';

Until this is set, no user in that org can use the Codes Tool even if their per-user flag is on. This is the layer that maps to billing / sales entitlement.

Org Admin — invite the coder

  1. Open https://admin.ohm.doctorInvitations+ Invite doctor button.
  2. Email = priya@kauvery.com, name = Priya Menon.
  3. Role dropdown → pick Other (tools.ohm.doctor).
  4. Enabled tools card appears → tick Codes Tool.
  5. (Optional) Auto-approve + set password if you want them in immediately.
  6. Send invite.

Mistake the role or features? On the same page, find the row → click the pencil icon to edit a still-pending invitation. No need to revoke and resend.

Coder — accept and use

  1. Priya clicks the email link → lands on app.ohm.doctor/accept-invite.
  2. Sets her password.
  3. The page detects roles === ["OTHER"] and redirects her to https://tools.ohm.doctor/login automatically.
  4. She signs in with the password she just set.
  5. Sidebar shows AI Code Assistant (because codes is enabled). Other tools are hidden.
  6. She pastes a discharge summary → clicks Extract codes → sees ranked ICD-10/SNOMED/LOINC suggestions with rationale.

Day 2 — change which tools a user has

  1. Admin console → Doctors (lists all users including OTHER — the table now shows a Role column).
  2. Her row shows role badge OTHER + her current feature chips.
  3. menu → Manage tools → tick / un-tick → Save.
  4. Effect is immediate on her next page load. JWT strategy reads enabledFeatures fresh from DB every request — no logout needed.

Sanity checks after onboarding

# As Priya (OTHER user with `codes` enabled)
curl -H "Authorization: Bearer $PRIYA_JWT" \
     "https://api.ohm.doctor/api/codes/icd10/search?q=fever"
# → 200 with results

# PHI access blocked
curl -H "Authorization: Bearer $PRIYA_JWT" https://api.ohm.doctor/api/patients
# → 403 (OtherRoleGuard)
curl -H "Authorization: Bearer $PRIYA_JWT" https://api.ohm.doctor/api/visit-notes
# → 403 (ClinicalStaff guard)

# Doctor flow unchanged
curl -H "Authorization: Bearer $DOCTOR_JWT" https://api.ohm.doctor/api/patients
# → 200

Edge cases

ScenarioOutcome
Admin invites OTHER with no features tickedCoder lands at tools.ohm.doctor and sees "No tools enabled. Ask your admin to enable a tool."
Org's features.codes is falseCoder gets 403 Feature "codes" is not enabled for this organization on any /api/codes/* action. Solution: SQL update in Step 2.
Admin unchecks codes for an active coderCoder's sidebar hides the tool on next page reload. Backend rejects immediately (DB-fresh feature read).
OTHER user navigates to app.ohm.doctor/loginLogin redirect detects role and bounces them to tools.ohm.doctor/login.
Doctor wants to use the Codes Tool tooThey can navigate to tools.ohm.doctor directly. Their DOCTOR role is in the codes-tool allowlist. Auto-redirect only fires for sole-OTHER users.