Follow-ups in today's apps

Usama asked for doctor follow-ups in the apps people use today. Nabil built it all, but only for the new chat, which is off with no date to turn on. This page shows what to build in today's apps, how, and what you build.

Code read at 0e28d64745f (main, 10 Nov)Usama's handoff, 6 Nov, sections 2, 3 and 6

What Usama asked for

His Paper frames for today's apps. Tap one to see it large.

Doctor

Paper C-D4
C-D4

Chief Resident's plan gets a Follow-up group: a date chip and the reason under it.

Paper C-D5
C-D5

A new Follow-up tile in the Action Plan. Accept & Edit fills it.

Paper C-D6
C-D6

Required on a reply. Send stays off with "Add a follow-up first."

Paper C-D7
C-D7

An earlier date still ahead: "already requested", not required. Keeping it tells the patient "No change".

Paper C-D8
C-D8

The form: 1, 2, 4, 6, 8 weeks or 3 months, a date, "Why then, for Maya (required)", and a quiet "No follow-up needed".

Patient

Paper C-P1
C-P1

No more "Accept" or "I need to ask" choice. The check button closes the response.

Paper C-P2
C-P2

Follow-up is the last page: the date large, "In 4 weeks", "Why then", and the reminder line.

Paper C-P3
C-P3

Same date as before: "No change", same schedule.

Paper C-P4
C-P4

No follow-up needed: the letter's line, and "Write to Dr. Syed any time in this chat."

Paper C-P7
C-P7

On the morning of the day, a push and an email. Tapping opens the chat with that doctor.

How we build it

This is a proposal. Nabil confirms the server part before anyone starts.

One home for a follow-up

Nabil's table already holds a follow-up: a date with a reason, "not needed", or "kept the same". Today each row must hang off a new-chat card. We let it hang off a new-chat card or a visit reply from today's app. Then the reminder, "already requested" and the letter's sentence keep working, and nothing is thrown away when the new chat goes live.

card-records.ts:567 · shared/check-ins/

The doctor's draft

While the doctor writes the reply, the follow-up is one more field on the saved plan draft, beside diagnosis, prescriptions, labs, imaging, skincare and products.

/v1/encounters/{id}/plan-draft · plan-draft.schema.ts:370

The send rule lives on the server

The server refuses a reply with no follow-up unless an earlier date is still ahead. The app holds the button with "Add a follow-up first." using the same rule, so the two never disagree. Web and phone share that rule.

POST /v1/encounters/{id}/plan · send-control.ts · visitReplyNeedsCheckIn

One switch, off at first

Reuse the check-ins-enabled switch. Everything ships dark and turns on per doctor.

feature-flags.ts:2116 · check-in-switch.ts:21

Screens are code only

No new native parts, so phones get it as an over-the-air update. No store release.

Reuse, don't rewrite

Date maths, chip values and the letter line already exist from Nabil's work. The chips sit on the server today and move to a shared package. The patient page words there are a plain stand-in: Usama's words win.

checkInDueOn · CHECK_IN_CHIPS · check-in-sentence.ts · check-in-page-words.ts

Screen rules, in plain words

  • What the server sends stays in the app's data cache. No second copy.
  • The form is a small set of named states: empty, picking, filled, not needed.
  • Date and wording rules are plain functions in models/, and they get today's date passed in.
  • Calls to the server live in the module's api/ folder.
  • Web and phone share the rules in packages/encounter. Each app draws its own screens.

Server rules, in plain words

  • The database itself refuses a date with no reason.
  • Every read is limited to the doctor's own clinic.
  • A send that is retried can never make two follow-ups.
  • Old phone builds keep working when the new field appears. Only add, never change.

Who does what

Nabil, the server

  • The follow-up row for today's visit reply, and the send rule
  • "Already requested" and "No change"
  • Chief Resident suggests one in today's visits (Usama approves the prompt)
  • The letter's sentence
  • The reminder
  • What the patient apps read

You, the screens

  • Shared rules in packages/encounter
  • Doctor phone and web: tile, form, hold, Chief Resident group
  • Patient phone and web: the last page, without the accept/ask choice
  • Reminder tap opens the chat

Your PR list

The order

  1. Nabil lands the shared shapes and the switch. Small, first.
  2. You build the screens on mocks at the same time.
  3. Nabil's send rule and the reminder.
  4. Join up, check on the local stack, turn on for one doctor.

Worth knowing

The journey, after we build it

Rebuilt from today's code, with made-up people (Maya R., acne, tretinoin; Dr. Usama Syed). Parts that exist today are drawn as they are. New parts carry a New chip and use Usama's exact words.

New new partToday as it is nowRemoved taken outRows scroll sideways

Doctor

ehr-mobile

1

10:45
←
Maya R.
Texas · 29 · Acne flare along the jaw
Why they're here
Breakouts along the jaw for 3 months, worse before periods.
Medical Record
Photos and attachments
Chief Resident
Open the proposal
Action Plan
Your Response

Opens Maya's case and taps the Chief Resident.

Today Sketch: order from details/view.tsx

2

10:45
Chief Resident
Proposed plan for acne
What I think is going on
Hormonal-pattern acne along the jaw, flaring before periods.
What I think we should do
Start tretinoin slowly, every third night.
Diagnosis
Acne vulgaris
Prescription
Tretinoin 0.025% cream
New
Follow-up
In 4 weeks · Fri, Dec 4Check how her skin handles tretinoin before the refill
Accept & Edit
Write my own
Discuss with AI

Reads the suggestion, now with a follow-up, and taps Accept & Edit.

New group. Panel is today's (proposal-panel/component.tsx)

3

10:46
Action Plan
Ask a question
⌄DiagnosisEdit···
Acne vulgaris
L70.0
⌄PrescriptionsEdit···
Tretinoin 0.025% cream
45 g · pea-sized amount at night
›LabsAdd···
›ImagingAdd···
›SkincareAdd···
›ProductsAdd···
New
›Follow-up RequiredAdd···
No follow-up needed
Your Response
Hi Maya, this looks like hormonal acne. Start the tretinoin slowly.
Preview
NewAdd a follow-up first.

Sees the new Follow-up tile marked Required. Preview stays off.

New tile and hold. Tiles and Preview are today's (action-plan-tile.tsx, preview-provider-response.tsx)

4

10:46
New
Follow-up
When should Maya check in with you next?
In
1 week2 weeks4 weeks6 weeks8 weeks3 months
Date
Friday, December 4 ▦
Why then, for Maya (required)
To see how your skin is handling the tretinoin before your refill.
Maya reads this on the last page of your reply.
No follow-up needed
Cancel
Save

Taps Add, picks 4 weeks, writes why, taps Save.

New sheet. Words from Paper C-D8

5

10:47
Action Plan
Ask a question
›DiagnosisEdit···
›PrescriptionsEdit···
›LabsAdd···
›ImagingAdd···
›SkincareAdd···
›ProductsAdd···
New
⌄Follow-upEdit···
Fri, Dec 4 · in 4 weeks
To see how your skin is handling the tretinoin before your refill.
No follow-up needed
Your Response
...Start the tretinoin slowly, every third night. I'd like to hear from you on Friday, December 4, to see how your skin is handling the tretinoin before your refill.
Preview

The tile shows the date. Preview turns on.

New tile. The letter line is Nabil's (check-in-sentence.ts)

5b · a later visit

10:47
Action Plan
›DiagnosisEdit···
›PrescriptionsEdit···
New
⌄Follow-upEdit···
Fri, Dec 4 · already requested
Set in your last reply. Not required now: keep it or change it.
No follow-up needed
Preview

An earlier date is still ahead: not required.

New Paper C-D7

6

10:48
←
Maya R.
Texas · 29 · Acne flare along the jaw
Your Plan
Sent to the patient
⌄Diagnosis
Acne vulgaris
⌄Prescriptions
Tretinoin 0.025% cream
New
⌄Follow-up
Fri, Dec 4 · in 4 weeks
To see how your skin is handling the tretinoin before your refill.

Taps Preview, pages through, taps Send on the last page. The case shows what was sent.

Today "Your Plan / Sent to the patient" (send/copy.ts). New read-only tile

Patient

expo-patient

1

9:41
FutureClinic
Provider response
by Dr. Usama Syed
Overview
Hi Maya, thanks for the photos. This looks like hormonal-pattern acne. It is common, and it responds well to treatment. Here is the plan.
✓

Opens the doctor's response from the chat.

Today overview-page.tsx

2

9:41
✕
⚕PROVIDER RESPONSE
Acne vulgaris
Start the tretinoin slowly, every third night, then every other night once your skin settles.
Tretinoin 0.025% creamPea-sized amount at night
Removed
Please let me know how you'd like to proceed with this plan.
Accept doctor's recommendations
I need to ask follow-up questions
✓

Reads each part of the plan. The choice at the bottom goes.

Today page, choice removed (view.tsx:342, plans/copy.ts:33)

3

9:41
✕
▦PROVIDER RESPONSE
Follow-up
New
DEC
4
Dr. Syed wants to hear from you on
Friday, December 4
In 4 weeks
Why then
To see how your skin is handling the tretinoin before your refill.
🔔We'll send you a reminder on the day so you can check in.
✓
Last page · the check closes the response

The last page shows the date. The check button closes the response.

New page, words from Paper C-P2

3b · No change

9:41
▦PROVIDER RESPONSE
Follow-up
New
DEC
4
Your follow-up with Dr. Syed is still on
Friday, December 4
No change · in 2 weeks
Same schedule as before
Dr. Syed still wants you to follow up on the same schedule as before: to see how your skin is handling the tretinoin before your refill.

New Paper C-P3

3c · Not needed

9:41
▦PROVIDER RESPONSE
Follow-up
New
 
✓
Your follow-up
No set follow-up needed
From Dr. Syed
We don't need a strict follow-up for this. But I'm here any time you need me, in this same chat.
💬Write to Dr. Syed any time in this chat.

New Paper C-P4

4

Friday, December 4
9:00
New
F
Your follow-up with Dr. Syed is todaynow

How is your skin handling the tretinoin? Tap to check in before your refill.

On the morning of the day, a push and an email arrive.

New for today's app. Words from Paper C-P7; Nabil's server words differ, see Your input

5

9:00
Chat with Dr. Usama Syed
Earlier messages
Earlier messages
Message box

Taps it. The chat with Dr. Syed opens and she writes.

Today chat screen, sketch only. The tap target is new for today's chat (push-tap-actions.ts:213)

Web

ehr-web and the patient dashboard, the same steps in a line each

Doctor, ehr-web

1Chief Resident panel shows the Follow-up group.apps/ehr-web/src/modules/encounter/chief-resident/ui/proposal-panel.tsx · packages/api-schemas/src/chief-resident/display/proposal-panel.ts:94
2A Follow-up tile after Products, with Required and the quiet checkbox.apps/ehr-web/src/modules/encounter/action-plan/ui/provider-actions.tsx:114 · a new action-plan/follow-up/ folder
3The form opens in a dialog: chips, date, why then, not needed.new, in the same action-plan/follow-up/ folder
4Preview stays off with "Add a follow-up first." until filled.apps/ehr-web/src/modules/encounter/ui/detail/submit/index.tsx:105 (reads the shared send-control.ts)

Patient, patient-app-web dashboard

1Plan pages lose the accept/ask choice.apps/patient-app-web/src/modules/patient-dashboard/plan-review/ui/review/topic-step.tsx, choices-list.tsx · models/plan.ts:121
2A last Follow-up step in its three states.plan-review/ui/review/ (a new follow-up step beside topic-step.tsx)
3The reminder email's link opens the chat with the doctor.Nabil's email; not checked which route it opens

What you do

Six pull requests, in this order. Each one ships dark behind the switch.

Before you start

  • Nabil agrees the plan and takes the server side.
  • The shared shapes (the draft field and what the apps read) land first.

a. Shared follow-up rules

Mehr-mobile and ehr-webC-D6, C-D7, C-D8

The follow-up field on the draft, the "Add a follow-up first." hold, and the date and chip rules reused from Nabil's work.

packages/encounter/src/send/send-control.ts · packages/encounter/src/view-model/action-plan/tile-kinds.ts, copy.ts · a new packages/encounter/src/view-model/follow-up/ · packages/api-schemas/src/check-ins/check-ins.schemas.ts (checkInDueOn, visitReplyNeedsCheckIn)

b. Doctor phone: tile and form

Lehr-mobileC-D5 to C-D8

The Follow-up tile, the form sheet, "No follow-up needed" and "already requested".

apps/ehr-mobile/src/modules/encounter/ui/details/actions.tsx · details/action-plan/action-plan-tile.tsx · a new details/action-plan/follow-up-tile.tsx · a new route under app/(main)/encounter/[encounterId]/actions/

c. Doctor web: the same

Mehr-webC-D5 to C-D8

Tile, dialog and hold on the web case page.

apps/ehr-web/src/modules/encounter/action-plan/ui/provider-actions.tsx · a new action-plan/follow-up/

d. Chief Resident's Follow-up group

S to Mehr-mobile and ehr-webC-D4

The group in the plan card, on phone and web, once Nabil's proposal carries it.

packages/api-schemas/src/chief-resident/display/proposal-panel.ts · apps/ehr-mobile/src/modules/encounter/ui/chief-resident/proposal-panel/component.tsx · apps/ehr-web/src/modules/encounter/chief-resident/ui/proposal-panel.tsx

e. Patient: the last page, no accept/ask

Mexpo-patient and patient-app-webC-P1 to C-P4

The last page in its three states, and removing the accept/ask choice.

apps/expo-patient/src/modules/plan/modal/view.tsx · packages/patient/src/plans/copy.ts · apps/patient-app-web/src/modules/patient-dashboard/plan-review/ui/review/

f. Reminder tap opens the chat

Sexpo-patientC-P7

The phone already opens any chat by its id. If Nabil's reminder carries today's chat id, this may be a check, not a build.

apps/expo-patient/src/modules/push-notifications/push-tap-actions.ts

Proof

Each PR: screens checked on the local stack, with pictures and a short video.

Sources

Every path is at commit 0e28d64745f.

Where the code differs from the plan

  1. There is no "Send" on the case page. Both doctor apps show "Preview" there; Send is on the last preview page. The hold sits on Preview. (submit-encounter/preview-provider-response.tsx:58, response/preview/footer.tsx:83)
  2. The chip values live on the server only. CHECK_IN_CHIPS is in apps/api, so the apps can't import it. It moves to packages/api-schemas first. (check-in-decision.schema.ts:25)
  3. Nabil's patient words are not Usama's. check-in-page-words.ts says "Check in on Fri, Dec 4" and calls itself a stand-in "until Hassan's follow-up pages replace this plain one". Reuse its date maths, not its words.
  4. The reminder hides the doctor and the medicine on purpose. Today: "Your check-in is due" and "Your doctor asked to hear from you today. Tell them how it's going." Usama's C-P7 names Dr. Syed and tretinoin. Its tap carries the new chat's id. (patient-check-in-due-copy.ts:10, push-renderer.service.ts:1310)
  5. The doctor's "already requested" read is per new chat. GET /v1/chats/{chatId}/check-in. Today's visits need one per visit. (chats.routes.ts:347)
  6. Nabil's send check reads new-chat cards. sendGate in send-gate.ts works on new-chat cards; today's visits reuse the plainer visitReplyNeedsCheckIn and standingDateAhead. Also, the existing "held" kind in send-control.ts:34 means "draft still saving"; the follow-up hold fits better as a disabled Preview with a reason, like the draft hold.

Code

apps/api/src/db/models/replies/card-records.ts:567check_ins table. chat_card_id is required (line 574) and must point to a check_in card (lines 598, 626). Date needs a reason (line 639).
apps/api/src/shared/check-ins/Nabil's service, repository, reminder, sentence, page, switch
apps/api/src/shared/check-ins/check-in-switch.ts:21Reads check-ins-enabled per doctor, off by default
packages/api-schemas/src/posthog/feature-flags.ts:2116CHECK_INS_ENABLED, key check-ins-enabled, a release flag
apps/api/src/routes/encounters/encounters.routes.ts:196POST /v1/encounters/{id}/plan exists
apps/api/src/routes/encounters/encounters.routes.ts:413PATCH and GET /v1/encounters/{id}/plan-draft exist (also line 451)
packages/api-schemas/src/encounters/schemas/plan-draft.schema.ts:370The draft's shape, where a follow-up field would go
packages/api-schemas/src/check-ins/check-ins.schemas.ts:24Outcomes date, not_needed, unchanged; visitReplyNeedsCheckIn 147, standingDateAhead 157, checkInDueOn 170
packages/api-schemas/src/replies/send-gate.ts:85New-chat send check; visitReplyCheckIn at 183
packages/chat/src/replies/models/reply-words.ts:140"Add a follow-up first."
apps/api/src/shared/chief-resident/schemas/check-in-decision.schema.ts:25Chips 1, 2, 4, 6, 8 weeks and 3 months
apps/api/src/shared/check-ins/check-in-sentence.ts:15The letter's "not needed" line
packages/chat/src/core/models/check-in-page-words.ts:62Stand-in patient page words
apps/api/src/shared/product-notifications/patient-check-in-due-copy.ts:10Reminder title and body today
apps/api/src/shared/product-notifications/product-notification-push-renderer.service.ts:1310Reminder push, tap data reply_delivered with the chat id
apps/api/src/shared/check-ins/check-in-reminder.ts:61Reminder checks the follow-up still stands, 8am her time
apps/api/src/temporal/queues/encounter/workflows/clarification-request-v6.workflow.ts:78Notes "plan's pinned sequence"
packages/encounter/src/send/send-control.ts:34The shared Send control
packages/encounter/src/send/copy.ts:55"Your Plan", "Sent to the patient"
packages/encounter/src/view-model/action-plan/tile-kinds.ts:2The six tiles, in order
packages/encounter/src/view-model/action-plan/copy.ts:8Tile names
packages/encounter/src/view-model/diagnosis/constants.ts:11"No formal diagnosis required", the checkbox pattern
packages/encounter/src/chief-resident/proposal-cta.ts:9"Write my own", "Discuss with AI", "Accept & Edit" (16)
packages/api-schemas/src/chief-resident/display/proposal-panel.ts:94Chief Resident groups; no follow-up today
apps/ehr-mobile/src/modules/encounter/ui/details/view.tsx:729Case page order: Chief Resident, then Action Plan (736)
apps/ehr-mobile/src/modules/encounter/ui/details/actions.tsx:28Tiles in order
apps/ehr-mobile/src/modules/encounter/ui/details/action-plan/action-plan-tile.tsx:38Tile pattern
apps/ehr-mobile/src/modules/encounter/ui/details/submit-encounter/index.tsx:329Hold reason line under the button
apps/ehr-mobile/src/modules/encounter/ui/chief-resident/proposal-panel/component.tsx:272Plan card group row; headings 852, 906
apps/ehr-mobile/global.css:45Doctor app colours (brand 45, background 65)
apps/expo-patient/src/modules/plan/modal/view.tsx:342Accept/ask choice; "Submit decision" at 425
packages/patient/src/plans/copy.ts:33"Accept doctor's recommendations", "I need to ask follow-up questions"
apps/patient-app-web/src/modules/patient-dashboard/plan-review/models/plan.ts:121Patient web uses the same choice copy
apps/expo-patient/src/modules/plan/models/presentation.ts:44"PROVIDER RESPONSE" label
apps/expo-patient/src/modules/plan/components/overview-page/overview-page.tsx:79Overview page
apps/expo-patient/src/shared/modal/components/modal-page-header.tsx:22Page header and gradient
apps/expo-patient/src/shared/modal/components/bottom-bar.tsx:137Bottom bar
apps/expo-patient/global.css:355Patient app colours (ink-forest 355, brand-secondary 98)
apps/expo-patient/src/modules/push-notifications/push-tap-actions.ts:213Tap opens a chat by id, new or today's
apps/ehr-web/src/modules/encounter/action-plan/ui/provider-actions.tsx:114Web tiles
apps/ehr-web/src/modules/encounter/ui/detail/submit/index.tsx:105Web Send control

Handoff

Section 2Doctor-requested follow-up: the action, C-D4 to C-D8, reasoning, letter, reminder
Section 3Patient response, no accept/ask, the last page's three states
Section 6Who does what

Not checked

Your input

Your notes save in this browser. Copy them and paste them to me.

One home, or kept apart?

Today's visit follow-ups go in Nabil's table beside the new chat's. Fine, or do you want them fully separate?

Reminder words

Usama's frame names Dr. Syed and tretinoin on the lock screen. Nabil's server says "Your check-in is due", with no name or medicine, on purpose. Which do we ship?

Who does the reminder tap?

The phone may already open the right chat if the server sends today's chat id. Nabil checks it, or you take it?

One doctor first?

Turn it on for one doctor (you, or Usama) first, then everyone?

Accept/ask: remove now or behind the switch?

Take the choice out for every patient now, or only where the follow-up page is on?