Skip to content

Work first visit: slim sign-in line, Finish setting up row, one empty-state line, no duplicate My Day tiles - #3495

Merged
gitar-bot[bot] merged 10 commits into
mainfrom
claude/site-work-firstrun-xk2j9i
Oct 12, 2026
Merged

gitar-bot[bot] merged 10 commits into
mainfrom
claude/site-work-firstrun-xk2j9i

Conversation

@BigSimmo

@BigSimmo BigSimmo commented Oct 12, 2026 •

Copy link
Copy Markdown
Owner

User description

Requested by Josh · project thread

Summary

Site recommendations 12 Oct 2026, items 2 and 7.

Before: signed out, On Call Now opened with a large "Hospital numbers are for signed-in members" card that pushed the shift half a screen down; nothing pointed a new doctor to Work setup outside My Day; some empty On Call rows said "Not set up for this hospital" with nothing to tap; while on call, My Day showed Log a call and Handover in the hero and again in the tiles straight below.

After: one slim line "Sign in to see your hospital's numbers" with a Sign in button; a one-line "Finish setting up" row (with a cross to hide it on this device, with Undo) on the first page of On Call, Teaching and CPD while setup is incomplete; empty rows use one shared line, a sentence plus at most one real link (Service handbook); while on call the My Day tiles are Playbook, Contacts, Who's on and Remind me (unchanged off call).

How: new shared WorkEmptyLine (mode-kit) and WorkSetupRow (work-setup, same device-only progress as My Day's Set up Work card); handbook-state big card replaced by the slim notice; My Day on-call tile list swapped.

Areas touched: Personal practice, App experience, Design system (plus 1 file not yet placed in any area)

Safety: no crisis line, phone number, escalation step or their wording changed or moved; crisis lines still sit directly under the sign-in line.

Screenshots (before and after, 390 light and dark, 1440, 320): /mnt/project-files/site-recommendations-2026-10-12/built/work-firstrun/ in the project files.

Verification

  • eslint on changed files: clean
  • npm run test:focused: "Test Files 85 passed (85), Tests 1168 passed"
  • typecheck passed; prettier written
  • Browser: planner says full UI level; full suite to run on this draft before it goes ready

Risk and rollout

  • Risk: low; UI only, example and signed-out states. Admin and Roster skipped (owned by other open PRs).
  • Rollback: revert this PR.
  • Provider or production effects: None

Notes

  • Signed out, On Call shows the sign-in line and the Finish setting up row stacked (setup works signed out). My Day's card hides when signed out; matching that needs a non-throwing auth hook, left as is.
  • my-day-today-cards.tsx is also edited by draft Design: 12 px text floor, mono figures, status shapes, paler fades, Bright light #3489; this PR only swaps the on-call tile list.
  • On a computer the existing first-visit "AI Search, NEW" tip now sits over the slim line's Sign in button until Got it is tapped (search chrome, not changed here).

🤖 Generated with Claude Code

https://claude.ai/code/session_01Mws6schjKQbpCQqQzPMKSL

Generated by Claude Code

Summary by cubic

Trims the first-visit experience across On Call, Teaching, CPD, and My Day: the signed-out "Hospital numbers are for signed-in members" card becomes a slim "Sign in to see your hospital's numbers" line, incomplete Work setup shows a dismissible "Finish setting up" row on each area's first page, and empty On Call rows now offer one real action (Service handbook) instead of dead-ending at "Not set up for this hospital". While on call, My Day swaps its Log a call and Handover tiles for Playbook and Contacts, since the hero already offers those.

Crisis lines, phone numbers, escalation steps, and their wording are untouched; crisis lines stay above the setup row. The empty shift-lists sheet explains itself instead of showing a blank: while the handbook is still loading, signed out, or unavailable it says shift lists are not available right now; once it has loaded it says the service has added no lists, and a reader with no service at all sees the "Not set up" line with the handbook action rather than an outage message.

Written for commit 01f278e. Summary will update on new commits.

View guided diff Turn on auto-fix


CodeAnt-AI Description

Add setup prompts and simplify On Call guidance

What Changed

  • On Call pages replace the large signed-out notice with a compact sign-in line, keeping crisis contacts below it.
  • On Call, Teaching, and CPD show a “Finish setting up” row while setup is incomplete. It resumes where setup was left off and can be hidden on this device.
  • Missing On Call information now uses a clear empty-state message and links to the Service handbook where relevant. Shift lists show as unavailable until the handbook is ready, rather than implying none are set up.
  • While on call, My Day tiles show Playbook and Contacts instead of repeating Log a call and Handover from the hero.

Impact

✅ Less screen space used by the signed-out prompt
✅ Resume or hide setup from On Call, Teaching, and CPD
✅ No repeated call or handover tiles while on call

💡 Usage Guide

Checking Your Pull Request

Every time you make a pull request, our system automatically looks through it. We check for security issues, mistakes in how you're setting up your infrastructure, and common code problems. We do this to make sure your changes are solid and won't cause any trouble later.

Talking to CodeAnt AI

Got a question or need a hand with something in your pull request? You can easily get in touch with CodeAnt AI right here. Just type the following in a comment on your pull request, and replace "Your question here" with whatever you want to ask:

@codeant-ai ask: Your question here

This lets you have a chat with CodeAnt AI about your pull request, making it easier to understand and improve your code.

Example

@codeant-ai ask: Can you suggest a safer alternative to storing this secret?

Preserve Org Learnings with CodeAnt

You can record team preferences so CodeAnt AI applies them in future reviews. Reply directly to the specific CodeAnt AI suggestion (in the same thread) and replace "Your feedback here" with your input:

@codeant-ai: Your feedback here

This helps CodeAnt AI learn and adapt to your team's coding style and standards.

Example

@codeant-ai: Do not flag unused imports.

Retrigger review

Ask CodeAnt AI to review the PR again, by typing:

@codeant-ai: review

Check Your Repository Health

To analyze the health of your code repository, visit our dashboard at https://app.codeant.ai. This tool helps you identify potential issues and areas for improvement in your codebase, ensuring your repository maintains high standards of code health.

…tate line, no duplicate My Day tiles on call

- On Call: the signed-out 'Hospital numbers are for signed-in members' card becomes one slim line
  ('Sign in to see your hospital's numbers' + Sign in) in the same place on every hub page. Crisis
  lines are untouched.
- New WorkSetupRow ('Finish setting up', one line + chevron, dismissible on this device) at the top
  of On Call, Teaching and CPD first pages while setup is incomplete; opens the existing setup page.
- New WorkEmptyLine (a sentence plus at most one real action); On Call 'Not set up for this
  hospital' lines keep their words and gain the Service handbook link; the empty Shift lists sheet
  says so instead of showing nothing.
- My Day quick tiles while on call: Playbook and Contacts replace the hero's Log a call and Handover.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Mws6schjKQbpCQqQzPMKSL
@BigSimmo BigSimmo self-assigned this Oct 12, 2026
@supabase

supabase Bot commented Oct 12, 2026

Copy link
Copy Markdown

This pull request has been ignored for the connected project sjrfecxgysukkwxsowpy because there are no changes detected in supabase directory. You can change this behaviour in Project Integrations Settings ↗︎.


Preview Branches by Supabase.
Learn more about Supabase Branching ↗︎.

@coderabbitai

coderabbitai Bot commented Oct 12, 2026 •

Copy link
Copy Markdown
Contributor

Important

  • 🔍 Trigger review

This repository does not receive automatic reviews because it has fewer than 10 stars.

⚙️ Run configuration
  • Configuration used: Organization UI
  • Review profile: ASSERTIVE
  • Plan: Advanced
  • Run ID: 06b4fe7c-6e83-4777-a9a4-f8f3d2804d6c

  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@codeant-ai

codeant-ai Bot commented Oct 12, 2026 •

Copy link
Copy Markdown

🏁 CodeAnt Quality Gate Results

Commit: 01f278eb
Scan Time: 2026-10-12 19:25:49 UTC

✅ Overall Status: PASSED

Quality Gate Details

Quality Gate Status Details
Secrets ✅ PASSED 0 secrets found
Duplicate Code ✅ PASSED 0.0% duplicated
SAST ✅ PASSED No security issues
Bugs ✅ PASSED Rating S: No bugs
IAC ✅ PASSED No IAC issues

View Full Results

@codspeed

codspeed Bot commented Oct 12, 2026 •

Copy link
Copy Markdown

Merging this PR will not alter performance

⚠️ 2 benchmarks spent significant time in system calls

System calls cannot be consistently instrumented, so they are not included in the measure, which understates the real cost. Please switch to the Walltime instrument to accurately measure system calls.

Measurement and system calls

ℹ️ 1 benchmark has no flame graph

The flamegraph could not be generated because too much time was spent in runtime internals, making the visualization not useful for performance analysis.

✅ 8 untouched benchmarks


Comparing claude/site-work-firstrun-xk2j9i (01f278e) with main (31ce40f)

Open in CodSpeed

gitar-bot[bot]
gitar-bot Bot previously approved these changes Oct 12, 2026

@gitar-bot gitar-bot Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Gitar has auto-approved this PR (configure)

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Mws6schjKQbpCQqQzPMKSL
gitar-bot[bot]
gitar-bot Bot previously approved these changes Oct 12, 2026

@gitar-bot gitar-bot Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Gitar has auto-approved this PR (configure)

Copy link
Copy Markdown
Owner Author

Full browser suite on a3490b1 (run 38257829382): Chromium, Firefox, desktop Safari and iPad all passed. The iPhone Safari projects (mobile-webkit, mobile-pwa-standalone) failed six tests. None of them is caused by this PR:

These belong to the known iPhone Safari backlog on main (ledger #9Z197J), which the Safari test-fix work is handling. No fix exists yet to port into this PR. This job is not part of PR required, and I am not re-running it because the failures reproduce across unrelated branches.


Generated by Claude Code

@BigSimmo
BigSimmo marked this pull request as ready for review October 12, 2026 15:24

@greptile-apps greptile-apps Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

BigSimmo has reached the 50-credit limit for trial accounts. To continue receiving code reviews, upgrade your plan.

@codeant-ai

codeant-ai Bot commented Oct 12, 2026 •

Copy link
Copy Markdown

🤖 CodeAnt AI — Review Status

Status Commit Started (UTC) Finished (UTC)
✅ Incremental review completed 01f278e Oct 12, 2026 · 19:10 19:11
✅ Reviewed your PR a3490b1 Oct 12, 2026 · 15:24 15:31

@codeant-ai

codeant-ai Bot commented Oct 12, 2026

Copy link
Copy Markdown

Thanks for using CodeAnt! 🎉

We're free for open-source projects. if you're enjoying it, help us grow by sharing.

Share on X ·
Reddit ·
LinkedIn

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 12, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-12T15:27:49.930332Z a3490b1 Draft marked ready
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@claude

claude Bot commented Oct 12, 2026 •

Copy link
Copy Markdown
Contributor

Claude encountered an error after 2s —— View job


I'll analyze this and get back to you.

@codeant-ai codeant-ai Bot added the size:L This PR changes 100-499 lines, ignoring generated files label Oct 12, 2026
@qodo-code-review

Copy link
Copy Markdown
Contributor

PR Summary by Qodo

Work first visit: slim sign-in line, setup row, shared empty-state line

✨ Enhancement 🧪 Tests 🕐 40+ Minutes

Grey Divider

AI Description

• Replace the full-width "signed-in members" card with a slim WorkSignInLine so crisis lines and
 page content no longer shift down when signed out.
• Add WorkSetupRow ("Finish setting up") to On Call, Teaching and CPD first pages, sharing My
 Day's device-only setup progress, dismissible with Undo.
• Add shared WorkEmptyLine for inline empty states; "Not set up for this hospital" and empty
 shift-list rows now offer a Service handbook link.
• Swap My Day's on-call quick tiles to Playbook and Contacts so they no longer duplicate the hero's
 Log a call and Handover.
• Add DOM tests covering the new empty-line component, setup row and My Day tile behavior.
Diagram

graph TD
  A["On Call / Teaching / CPD pages"] --> B["WorkSignInLine"] --> C["AccountSetupDialog"]
  A --> D["WorkSetupRow"] --> E["useWorkSetupProgress store"]
  A --> F["WorkEmptyLine"] --> G["Service handbook link"]
  H["My Day today cards"] --> I["On-call quick tiles: Playbook, Contacts"]
  E --> J["My Day Set up Work card"]
  subgraph Legend
    direction LR
    _mod([Component]) ~~~ _store[(Shared store)] ~~~ _ext{{External page}}
  end
Loading
High-Level Assessment

Reusing the existing device-only setup progress store and mirroring WorkSetupPromptCard's pattern for the new row is the right approach; it avoids state duplication and keeps dismiss/undo behavior consistent across My Day and the new row. No better alternative (e.g., a new global banner system) was warranted for this scoped UI change.

Files changed (15) +343 / -15

Enhancement (10) +226 / -9
work-empty-line.tsxNew shared WorkEmptyLine inline empty-state component +61/-0

New shared WorkEmptyLine inline empty-state component

• Adds a reusable row-level empty state: a sentence plus an optional single action (link or button), replacing ad-hoc dead-end text like 'Not set up for this hospital'.

src/components/mode-kit/work-empty-line.tsx

work-sign-in-notice.tsxAdd slim WorkSignInLine signed-out notice +39/-1

Add slim WorkSignInLine signed-out notice

• Introduces a compact one-line sign-in prompt with a Sign in button, used instead of the large WorkSignInNotice card to avoid pushing page content down.

src/components/mode-kit/work-sign-in-notice.tsx

handbook-state.tsxSwap full sign-in card for slim WorkSignInLine on On Call +5/-3

Swap full sign-in card for slim WorkSignInLine on On Call

• Replaces WorkSignInNotice with WorkSignInLine and updates the signed-out title copy to 'Sign in to see your hospital's numbers'.

src/components/on-call/kit/handbook-state.tsx

state-label.tsxAdd shared Service handbook action constant +10/-0

Add shared Service handbook action constant

• Exports ON_CALL_SERVICE_HANDBOOK_ACTION, the single real action offered on 'not set up' empty rows, linking to the service handbook page.

src/components/on-call/kit/state-label.tsx

right-now.tsxUse WorkEmptyLine for not-set-up state in Now panel +8/-3

Use WorkEmptyLine for not-set-up state in Now panel

• Replaces the plain paragraph for the not-set-up state with WorkEmptyLine carrying the Service handbook action.

src/components/on-call/now/right-now.tsx

on-call-home.tsxAdd Finish setting up row to On Call home +4/-0

Add Finish setting up row to On Call home

• Renders WorkSetupRow (wrapped in NewWorkModeOnly) above the hospital line on the On Call first page while setup is incomplete.

src/components/on-call/on-call-home.tsx

whos-on-page.tsxWrap My Team not-set-up label in WorkEmptyLine +5/-2

Wrap My Team not-set-up label in WorkEmptyLine

• Adds the Service handbook action to the My Team empty row using the new shared empty-line component.

src/components/on-call/whos-on/whos-on-page.tsx

teaching-today.tsxAdd Finish setting up row to Teaching Today page +5/-0

Add Finish setting up row to Teaching Today page

• Renders WorkSetupRow at the top of the Teaching Today page while setup is incomplete.

src/components/teaching/teaching-today.tsx

cme-dashboard.tsxAdd Finish setting up row to CPD dashboard +4/-0

Add Finish setting up row to CPD dashboard

• Renders WorkSetupRow above the CPD summary/next-step content while setup is incomplete.

src/components/cme/cme-dashboard.tsx

work-setup-row.tsxNew WorkSetupRow component +85/-0

New WorkSetupRow component

• Implements the dismissible 'Finish setting up' row that reads the same device-only setup progress as My Day's Set up Work card and resumes at the stored step.

src/components/work-setup/work-setup-row.tsx

Bug fix (2) +18 / -4
shift-lists.tsxShow empty-state line when no shift lists exist +11/-1

Show empty-state line when no shift lists exist

• Adds WorkEmptyLine to announce when a service has not added shift lists, instead of showing nothing.

src/components/on-call/now/shift-lists.tsx

my-day-today-cards.tsxReplace duplicated on-call quick tiles with Playbook and Contacts +7/-3

Replace duplicated on-call quick tiles with Playbook and Contacts

• Changes MY_DAY_ON_CALL_ACTIONS so the quick tiles offer Playbook and Contacts instead of repeating the hero's Log a call and Handover actions while on call.

src/components/my-day/my-day-today-cards.tsx

Tests (3) +99 / -2
on-call-kit.dom.test.tsxUpdate tests for slim sign-in line wording and markup +4/-2

Update tests for slim sign-in line wording and markup

• Adjusts assertions for the new sign-in title copy and verifies the page-sized empty-state card markup is no longer rendered.

tests/on-call-kit.dom.test.tsx

work-first-run-empty-states.dom.test.tsxNew tests for WorkEmptyLine and My Day quick tiles +61/-0

New tests for WorkEmptyLine and My Day quick tiles

• Adds DOM tests covering WorkEmptyLine's sentence-only and action variants, and verifies My Day's on-call/off-call quick tile labels and hrefs.

tests/work-first-run-empty-states.dom.test.tsx

work-setup-page.dom.test.tsxNew tests for WorkSetupRow behavior +34/-0

New tests for WorkSetupRow behavior

• Adds tests verifying WorkSetupRow resumes at the stored step, works signed out, can be dismissed, and stays hidden once finished or dismissed.

tests/work-setup-page.dom.test.tsx

@qodo-code-review

qodo-code-review Bot commented Oct 12, 2026 •

Copy link
Copy Markdown
Contributor

Code Review by Qodo

🐞 Bugs (0) 📘 Rule violations (0) 🔗 Cross-repo conflicts (0) 📜 Skill insights (0)

Grey Divider


Action required

No findings for this group


Remediation recommended

No findings for this group


Informational

No findings for this group

Grey Divider


Resolved findings

1. Setup row delays crisis contacts ✓ Resolved
Description
OnCallHomeLive places WorkSetupRow after the sign-in notice in TodayShell.status, which
renders before the safety slot containing NowEmergencyPin and NowCrisisLines. When setup is
incomplete, including for signed-out visitors and signed-in doctors, the row and its spacing
separate the notice from the public crisis contacts and push those contacts farther down the page.
Code

src/components/on-call/on-call-home.tsx[R335-337]

+              <NewWorkModeOnly>
+                <WorkSetupRow />
+              </NewWorkModeOnly>
Relevance

●●● Strong

Recent On Call precedents accept preserving safety visibility and correcting ordering that obscures
urgent contacts.

PR-#3225
PR-#3453

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The changed On Call status content places WorkSetupRow after the handbook notice, and TodayShell
renders the entire status slot before safety. Because the emergency pin and crisis lines are in
safety, the setup row appears ahead of them when setup is incomplete, contrary to the stated
expectation that crisis lines remain directly under the sign-in line.

src/components/on-call/on-call-home.tsx[332-345]
src/components/mode-kit/today/today-shell.tsx[329-331]
src/components/mode-kit/today/today-shell.tsx[312-315]
src/components/on-call/on-call-home.tsx[330-345]
src/components/work-setup/work-setup-row.tsx[48-57]
src/components/on-call/on-call-home.tsx[297-305]
src/components/on-call/on-call-home.tsx[331-344]
src/components/mode-kit/today/today-shell.tsx[311-315]
Skill: design-review

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
On Call Now places the setup row between the sign-in notice and public crisis contacts when setup is incomplete, pushing the contacts down, including on a signed-out first visit.

## Fix Focus Areas
- src/components/on-call/on-call-home.tsx[330-345]
- src/components/mode-kit/today/today-shell.tsx[311-331]

## Recommended Fix
Move `<NewWorkModeOnly><WorkSetupRow /></NewWorkModeOnly>` out of the `status` slot and render it after the safety content, while keeping it near the top of On Call home and available when signed out. For example, place it after `NowCrisisLines` in the `safety` fragment or add a `TodayShell` slot that renders after `safety`. Add a test checking that crisis lines follow the sign-in line in DOM order, and verify the signed-out, incomplete-setup layout.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


2. Doctors see an outage without a service ✓ Resolved
Description
NowShiftLists uses handbookReady to choose the confirmed-empty label, but the caller sets it only
when handbook.status is exactly ready. For authenticated users with no services, the hook returns
no-service with an empty item list, so both the row and sheet say “Not available right now” instead
of offering Manage service.
Code

src/components/on-call/now/shift-lists.tsx[R185-188]

+            ) : (
+              <span data-testid="on-call-now-checklists-pending" className="text-xs text-[color:var(--text-muted)]">
+                Not available right now
+              </span>
Relevance

●●● Strong

Recent On Call precedents accept correcting loaded-versus-pending state handling and preserving
actionable empty states.

PR-#3225
PR-#3154

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The caller derives handbookReady strictly from ready status, while the handbook hook defines
no-service as a distinct loaded state and the shared handbook state renders a Manage service action
for it. The changed conditional routes that state into the transient pending branch.

src/components/on-call/now/shift-lists.tsx[183-188]
src/components/on-call/on-call-home.tsx[210-214]
src/components/on-call/use-hospital-handbook.ts[465-473]
src/components/on-call/kit/handbook-state.tsx[75-88]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
The shift-list row treats every non-ready handbook state as unavailable. A confirmed `no-service` state is therefore presented as a transient outage and does not provide the existing Manage service path.

### Fix Focus Areas
- src/components/on-call/now/shift-lists.tsx[183-188]
- src/components/on-call/on-call-home.tsx[210-214]

### Recommended Fix
Pass an explicit handbook state or confirmed-empty flag instead of only `status === "ready"`, and render the confirmed no-service copy and Manage service action for `no-service`. Keep the “Not available right now” copy for loading, signed-out, expired, and unavailable states where the handbook contents are genuinely unconfirmed.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


3. Shift lists row still claims 'Not set up' while loading ✓ Resolved
Description
The new handbookReady prop only changes the sentence inside the sheet. The "Shift lists" row
itself still shows <OnCallStateLabel state={{ kind: "not-set-up" }} /> ("Not set up for this
hospital") whenever hasLists is false. on-call-home passes an empty items array whenever the
handbook is not ready, so while the handbook is loading, signed out or unavailable, the row on the
Now page still says the hospital has no lists. Tapping the row then opens a sheet that says "Shift
lists are not available right now", so the row and the sheet disagree.
Code

src/components/on-call/now/shift-lists.tsx[R126-127]

+  /** False while the handbook is loading, signed out or unavailable: an empty list is then unconfirmed. */
+  readonly handbookReady?: boolean;
Relevance

●●● Strong

Accepted precedent flags loading rows that appear only after data resolves; this row similarly
mislabels unavailable handbook data as not set up.

PR-#3225

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
on-call-home sets handbookItems to [] unless the handbook is ready (line 214) and passes
handbookReady={ready}. In shift-lists, hasLists is then false. The row's subtitle (around lines
172-183) branches only on hasLists and renders the not-set-up label, whose wording is "Not set up
for this hospital" (state-label.tsx). Only the sheet's empty line (lines 208-220) checks
handbookReady.

src/components/on-call/on-call-home.tsx[212-214]
src/components/on-call/now/shift-lists.tsx[172-183]
src/components/on-call/now/shift-lists.tsx[208-220]
src/components/on-call/kit/state-label.tsx[20-24]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The Shift lists row subtitle still says "Not set up for this hospital" when the handbook has not loaded yet (or the visitor is signed out, or the handbook is unavailable). This contradicts the sheet, which now says "Shift lists are not available right now".

## Fix Focus Areas
- src/components/on-call/now/shift-lists.tsx[172-183]
- src/components/on-call/now/shift-lists.tsx[208-220]

## Recommended Fix
In the row's `hasLists ? ... : <OnCallStateLabel .../>` branch, show the not-set-up label only when `handbookReady` is true. Otherwise show a muted "Not available right now" (or nothing). Add a test that checks the row text while the handbook is loading.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


View resolved (1)
4. Unloaded shift lists appear unconfigured ✓ Resolved
Description
NowShiftLists shows “Your service has not added shift lists for this hospital yet” whenever
hasLists is false, but its caller supplies an empty item array whenever the handbook is not ready.
Opening the sheet during loading, or while the handbook is signed out, unavailable, or has no
service, therefore presents an unconfirmed absence of lists as a service setup fact.
Code

src/components/on-call/now/shift-lists.tsx[R205-208]

+          {hasLists ? null : (
+            <WorkEmptyLine
+              className="px-3"
+              testId="on-call-now-checklists-empty"
Relevance

●●● Strong

Recent On Call precedents accept distinguishing unavailable data from genuine empty states.

PR-#3225
PR-#3480

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
On Call home replaces every non-ready handbook's items with an empty array and mounts Shift lists
regardless of readiness; the new message uses only the resulting list count.

src/components/on-call/on-call-home.tsx[214-218]
src/components/on-call/on-call-home.tsx[418-422]
src/components/on-call/now/shift-lists.tsx[125-134]
src/components/on-call/now/shift-lists.tsx[205-212]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The Shift lists sheet claims the service has added no lists even when handbook data has not loaded or is unavailable.

## Fix Focus Areas
- src/components/on-call/now/shift-lists.tsx[125-135]
- src/components/on-call/now/shift-lists.tsx[205-212]
- src/components/on-call/on-call-home.tsx[214-218]
- src/components/on-call/on-call-home.tsx[418-422]

## Recommended Fix
Pass handbook readiness to NowShiftLists and display the definitive empty message and handbook action only when a ready handbook has no lists. Use an appropriate loading or unavailable fallback otherwise.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

Context sources
✅ Compliance rules (platform): 9 rules
✅ Skills: 4 invoked
  ux-review
  frontend-architecture-review
  testing-review
  accessibility-review
✅ Cross-repo context — repo relationships
✅ REVIEW.md
Review mode: Auto: 🚀 Fast: Localized UI condition and regression test with low blast radius.

Grey Divider

Tip of the day
💡 Did you know, you can commit Qodo's fix in one click with committable suggestions (GitHub & GitLab)

More tips ↗ | Customize Qodo ↗ | Qodo docs ↗

Grey Divider

Previous reviews

Review updated until commit 01f278e

Results up to commit a3490b1 🧠 Deep


🐞 Bugs (0) 📘 Rule violations (0) 📎 Requirement gaps (0) 🎨 UX issues (0) 🔗 Cross-repo conflicts (0) 📜 Skill insights (0)


Action required

No findings for this group


Remediation recommended

No findings for this group


Informational

No findings for this group


Resolved findings

1. Setup row delays crisis contacts ✓ Resolved
Description
OnCallHomeLive places WorkSetupRow after the sign-in notice in TodayShell.status, which
renders before the safety slot containing NowEmergencyPin and NowCrisisLines. When setup is
incomplete, including for signed-out visitors and signed-in doctors, the row and its spacing
separate the notice from the public crisis contacts and push those contacts farther down the page.
Code

src/components/on-call/on-call-home.tsx[R335-337]

+              <NewWorkModeOnly>
+                <WorkSetupRow />
+              </NewWorkModeOnly>
Relevance

●●● Strong

Recent On Call precedents accept preserving safety visibility and correcting ordering that obscures
urgent contacts.

PR-#3225
PR-#3453

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The changed On Call status content places WorkSetupRow after the handbook notice, and TodayShell
renders the entire status slot before safety. Because the emergency pin and crisis lines are in
safety, the setup row appears ahead of them when setup is incomplete, contrary to the stated
expectation that crisis lines remain directly under the sign-in line.

src/components/on-call/on-call-home.tsx[332-345]
src/components/mode-kit/today/today-shell.tsx[329-331]
src/components/mode-kit/today/today-shell.tsx[312-315]
src/components/on-call/on-call-home.tsx[330-345]
src/components/work-setup/work-setup-row.tsx[48-57]
src/components/on-call/on-call-home.tsx[297-305]
src/components/on-call/on-call-home.tsx[331-344]
src/components/mode-kit/today/today-shell.tsx[311-315]
Skill: design-review

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
On Call Now places the setup row between the sign-in notice and public crisis contacts when setup is incomplete, pushing the contacts down, including on a signed-out first visit.

## Fix Focus Areas
- src/components/on-call/on-call-home.tsx[330-345]
- src/components/mode-kit/today/today-shell.tsx[311-331]

## Recommended Fix
Move `<NewWorkModeOnly><WorkSetupRow /></NewWorkModeOnly>` out of the `status` slot and render it after the safety content, while keeping it near the top of On Call home and available when signed out. For example, place it after `NowCrisisLines` in the `safety` fragment or add a `TodayShell` slot that renders after `safety`. Add a test checking that crisis lines follow the sign-in line in DOM order, and verify the signed-out, incomplete-setup layout.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


2. Unloaded shift lists appear unconfigured ✓ Resolved
Description
NowShiftLists shows “Your service has not added shift lists for this hospital yet” whenever
hasLists is false, but its caller supplies an empty item array whenever the handbook is not ready.
Opening the sheet during loading, or while the handbook is signed out, unavailable, or has no
service, therefore presents an unconfirmed absence of lists as a service setup fact.
Code

src/components/on-call/now/shift-lists.tsx[R205-208]

+          {hasLists ? null : (
+            <WorkEmptyLine
+              className="px-3"
+              testId="on-call-now-checklists-empty"
Relevance

●●● Strong

Recent On Call precedents accept distinguishing unavailable data from genuine empty states.

PR-#3225
PR-#3480

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
On Call home replaces every non-ready handbook's items with an empty array and mounts Shift lists
regardless of readiness; the new message uses only the resulting list count.

src/components/on-call/on-call-home.tsx[214-218]
src/components/on-call/on-call-home.tsx[418-422]
src/components/on-call/now/shift-lists.tsx[125-134]
src/components/on-call/now/shift-lists.tsx[205-212]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The Shift lists sheet claims the service has added no lists even when handbook data has not loaded or is unavailable.

## Fix Focus Areas
- src/components/on-call/now/shift-lists.tsx[125-135]
- src/components/on-call/now/shift-lists.tsx[205-212]
- src/components/on-call/on-call-home.tsx[214-218]
- src/components/on-call/on-call-home.tsx[418-422]

## Recommended Fix
Pass handbook readiness to NowShiftLists and display the definitive empty message and handbook action only when a ready handbook has no lists. Use an appropriate loading or unavailable fallback otherwise.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Results up to commit 1fe7eb8 🧠 Deep


🐞 Bugs (0) 📘 Rule violations (0) 📎 Requirement gaps (0) 🎨 UX issues (0) 🔗 Cross-repo conflicts (0) 📜 Skill insights (0)


Action required

No findings for this group


Remediation recommended

No findings for this group


Informational

No findings for this group


Resolved findings

1. Shift lists row still claims 'Not set up' while loading ✓ Resolved
Description
The new handbookReady prop only changes the sentence inside the sheet. The "Shift lists" row
itself still shows <OnCallStateLabel state={{ kind: "not-set-up" }} /> ("Not set up for this
hospital") whenever hasLists is false. on-call-home passes an empty items array whenever the
handbook is not ready, so while the handbook is loading, signed out or unavailable, the row on the
Now page still says the hospital has no lists. Tapping the row then opens a sheet that says "Shift
lists are not available right now", so the row and the sheet disagree.
Code

src/components/on-call/now/shift-lists.tsx[R126-127]

+  /** False while the handbook is loading, signed out or unavailable: an empty list is then unconfirmed. */
+  readonly handbookReady?: boolean;
Relevance

●●● Strong

Accepted precedent flags loading rows that appear only after data resolves; this row similarly
mislabels unavailable handbook data as not set up.

PR-#3225

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
on-call-home sets handbookItems to [] unless the handbook is ready (line 214) and passes
handbookReady={ready}. In shift-lists, hasLists is then false. The row's subtitle (around lines
172-183) branches only on hasLists and renders the not-set-up label, whose wording is "Not set up
for this hospital" (state-label.tsx). Only the sheet's empty line (lines 208-220) checks
handbookReady.

src/components/on-call/on-call-home.tsx[212-214]
src/components/on-call/now/shift-lists.tsx[172-183]
src/components/on-call/now/shift-lists.tsx[208-220]
src/components/on-call/kit/state-label.tsx[20-24]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The Shift lists row subtitle still says "Not set up for this hospital" when the handbook has not loaded yet (or the visitor is signed out, or the handbook is unavailable). This contradicts the sheet, which now says "Shift lists are not available right now".

## Fix Focus Areas
- src/components/on-call/now/shift-lists.tsx[172-183]
- src/components/on-call/now/shift-lists.tsx[208-220]

## Recommended Fix
In the row's `hasLists ? ... : <OnCallStateLabel .../>` branch, show the not-set-up label only when `handbookReady` is true. Otherwise show a muted "Not available right now" (or nothing). Add a test that checks the row text while the handbook is loading.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Results up to commit e61209d 🚀 Fast


🐞 Bugs (0) 📘 Rule violations (0) 📎 Requirement gaps (0) 🎨 UX issues (0) 🔗 Cross-repo conflicts (0) 📜 Skill insights (0)


Action required

No findings for this group


Remediation recommended

No findings for this group


Informational

No findings for this group


Resolved findings

1. Doctors see an outage without a service ✓ Resolved
Description
NowShiftLists uses handbookReady to choose the confirmed-empty label, but the caller sets it only
when handbook.status is exactly ready. For authenticated users with no services, the hook returns
no-service with an empty item list, so both the row and sheet say “Not available right now” instead
of offering Manage service.
Code

src/components/on-call/now/shift-lists.tsx[R185-188]

+            ) : (
+              <span data-testid="on-call-now-checklists-pending" className="text-xs text-[color:var(--text-muted)]">
+                Not available right now
+              </span>
Relevance

●●● Strong

Recent On Call precedents accept correcting loaded-versus-pending state handling and preserving
actionable empty states.

PR-#3225
PR-#3154

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The caller derives handbookReady strictly from ready status, while the handbook hook defines
no-service as a distinct loaded state and the shared handbook state renders a Manage service action
for it. The changed conditional routes that state into the transient pending branch.

src/components/on-call/now/shift-lists.tsx[183-188]
src/components/on-call/on-call-home.tsx[210-214]
src/components/on-call/use-hospital-handbook.ts[465-473]
src/components/on-call/kit/handbook-state.tsx[75-88]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
The shift-list row treats every non-ready handbook state as unavailable. A confirmed `no-service` state is therefore presented as a transient outage and does not provide the existing Manage service path.

### Fix Focus Areas
- src/components/on-call/now/shift-lists.tsx[183-188]
- src/components/on-call/on-call-home.tsx[210-214]

### Recommended Fix
Pass an explicit handbook state or confirmed-empty flag instead of only `status === "ready"`, and render the confirmed no-service copy and Manage service action for `no-service`. Keep the “Not available right now” copy for loading, signed-out, expired, and unavailable states where the handbook contents are genuinely unconfirmed.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

Qodo Logo

Comment thread src/components/on-call/on-call-home.tsx Resolved
- Keep crisis contacts above setup
- Guard shift-list empty state by handbook readiness
@qodo-code-review

Copy link
Copy Markdown
Contributor

Qodo Fixer

✅ Committed (2) · ☑ Fixed (2)

Grey Divider

Commits pushed directly to this PR — no separate fix PR opened.

Process — 2 fixed
  • ☑ Fixed: Setup row delays crisis contacts
  • ☑ Fixed: Unloaded shift lists appear unconfigured

@gitar-bot
gitar-bot Bot enabled auto-merge (squash) October 12, 2026 15:28
gitar-bot[bot]

This comment was marked as resolved.

Comment thread src/components/on-call/on-call-home.tsx Resolved
@gitar-bot
gitar-bot Bot dismissed their stale review October 12, 2026 15:29

Auto-approval revoked — new findings require attention.

@codeant-ai

codeant-ai Bot commented Oct 12, 2026 •

Copy link
Copy Markdown

CodeAnt PR Risk: Medium Risk

  • The PR needs attention before merging because the On-call sign-in flow may leave handbook content stale after authentication.
  • The new sign-in line does not use RefreshOnSignIn; verify that handbook content refreshes after a successful sign-in without requiring a reload.

Assessed commit: 01f278eb5510

Copy link
Copy Markdown
Owner Author

The setup-row finding was correct. It is fixed in 2eea4b5: the "Finish setting up" row now sits after the emergency pin and crisis lines, never above them.

I reverted the automated commit b108725 (398fce0) because it went beyond that finding in two ways:

  • It changed where the crisis lines appear. Main moves them to the foot of the page once the hospital's own numbers are on screen, and the commit removed that behaviour. This PR keeps crisis-line placement exactly as it is on main.
  • It added new user-facing shift-list wording. That wording was never reviewed.

Generated by Claude Code

Comment thread src/components/on-call/on-call-home.tsx Resolved
@qodo-code-review

Copy link
Copy Markdown
Contributor

Code review by qodo was updated up to the latest commit 2eea4b5

BigSimmo and others added 2 commits October 12, 2026 23:34
…book loads

While the handbook is loading, signed out or unavailable, the sheet no
longer claims the service has not added shift lists. The setup-row comment
now describes the real order when crisis lines sit at the page foot.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Mws6schjKQbpCQqQzPMKSL
@gitar-bot
gitar-bot Bot enabled auto-merge (squash) October 12, 2026 15:44
gitar-bot[bot]
gitar-bot Bot previously approved these changes Oct 12, 2026

@gitar-bot gitar-bot Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Gitar has auto-approved this PR (configure)

@qodo-code-review

Copy link
Copy Markdown
Contributor

Code review by qodo was updated up to the latest commit 1fe7eb8

…has loaded

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Mws6schjKQbpCQqQzPMKSL
@qodo-code-review

Copy link
Copy Markdown
Contributor

Code review by qodo was updated up to the latest commit e61209d

gitar-bot[bot]
gitar-bot Bot previously approved these changes Oct 12, 2026

@gitar-bot gitar-bot Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Gitar has auto-approved this PR (configure)

…ook action, not an outage line

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Mws6schjKQbpCQqQzPMKSL

@gitar-bot gitar-bot Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Gitar has auto-approved this PR (configure)

@qodo-code-review

Copy link
Copy Markdown
Contributor

Code review by qodo was updated up to the latest commit 162b066

@qodo-code-review

qodo-code-review Bot commented Oct 12, 2026 •

Copy link
Copy Markdown
Contributor

No code changes since the last review — review skipped

Qodo Logo

@gitar-bot

gitar-bot Bot commented Oct 12, 2026

Copy link
Copy Markdown
Contributor
Code Review ✅ Approved 3 closed / 3 findings

🟡 Medium risk · Changing on-call empty states and My Day tiles could confuse users about shift-list availability or make call and handover actions less discoverable.

Work first-visit changes add a slim signed-out sign-in line, a dismissible Finish setting up row, a shared empty-state line, and swap on-call My Day tiles to Playbook, Contacts, Who's on and Remind me. Crisis lines no longer move to the page end when hospital numbers show, and the empty shift-lists sheet now explains that the handbook is still loading rather than blaming the service. No open issues remain.

Auto-approved: No blocking issues found.
Please see Auto-approve Docs for details on setting custom approval criteria.

✅ 3 closed
✅ Bug: Crisis lines no longer move to the page end when hospital numbers show

📄 src/components/on-call/on-call-home.tsx:301-303 📄 src/components/on-call/on-call-home.tsx:334-341 📄 src/components/on-call/on-call-home.tsx:434
On main, numbersOnScreen puts NowCrisisLines in safety only when the hospital has no callable numbers, and in shortcuts (at the end of the page) when it does. This commit deletes that logic and always renders the crisis lines in safety. So for every signed-in reader whose hospital numbers are loaded, the public crisis lines now sit above Right now and the shift tools. That goes against the PR's safety statement that no crisis line was moved, and against the existing placement rule. It also breaks tests/on-call-now.dom.test.tsx:178-191, which expects on-call-now-crisis to come after on-call-now-right-now and on-call-now-shift-tools, and likely tests/on-call-whos-on.dom.test.tsx:105 too. To keep crisis contacts above the setup row without moving them, restore numbersOnScreen. Render WorkSetupRow after the conditional NowCrisisLines in safety, and keep the shortcuts slot that holds the crisis lines.

✅ Bug: Empty shift-lists sheet blames the service while the handbook is loading

📄 src/components/on-call/on-call-home.tsx:423 📄 src/components/on-call/now/shift-lists.tsx:205-213
handbookItems is [] whenever handbook.status !== "ready", which covers loading, signed-out and unavailable. This commit removes the handbookReady prop, so in all of those states hasLists is false and the sheet says "Your service has not added shift lists for this hospital yet." with a Service handbook link. That message is wrong for those states: while loading, the lists may be about to appear, and signed out, the reader simply can't see them yet. To fix it, pass handbookReady={ready} back in and show this line only when the handbook is ready. Otherwise show a neutral line such as "Shift lists are not available right now", as the reverted fix did.

Closed: Bug: Setup row sits above crisis lines once hospital numbers are on screen

📄 src/components/on-call/on-call-home.tsx:340-344 📄 src/components/on-call/on-call-home.tsx:432-438
This commit adds back numbersOnScreen. When it is true, NowCrisisLines moves from safety to shortcuts at the end of the page, but WorkSetupRow stays in safety. A signed-in member who has a ready handbook with callable numbers but hasn't finished setup will therefore see the Finish setting up row above the crisis lines. That breaks the new comment ('After the emergency pin and crisis lines, never above them') and the PR's promise that crisis lines stay above the setup row. One fix is to move the setup row after the crisis lines whenever they are moved, for example by rendering it in shortcuts after the lines when numbersOnScreen is true. The other is to update the comment and PR text so they describe the ordering the page actually uses.

Review coverage

🤖 Auto-approval Approved

📋 Rules No rules evaluated

🧪 Functional validation Not enabled · Set up

Options

Auto-apply is off → Gitar will not commit updates to this branch.
Display: compact → Counting what did not apply, without listing it.

Comment with these commands to change the behavior for this request:

Auto-apply Compact
gitar auto-apply:on         
gitar display:verbose         

Was this helpful? React with 👍 / 👎 | Gitar

@gitar-bot
gitar-bot Bot merged commit e31c11d into main Oct 12, 2026
44 of 45 checks passed
@gitar-bot
gitar-bot Bot deleted the claude/site-work-firstrun-xk2j9i branch October 12, 2026 19:25
gitar-bot Bot pushed a commit that referenced this pull request Oct 13, 2026
…st, one-list Renewals, Work consistency, header fixes (#3519)

* Work: one "Get set up" checklist on My Day, no per-area setup rows (D11)

The design audit (13 Oct 2026, D11, owner decision 4) found each area's
first page spent its top slot on its own "Finish setting up" row. Those
rows are removed from On Call, Teaching and CPD, and My Day's setup card
becomes "Get set up": every setup step with a tick when done and a link
straight to it, plus Start/Resume and Not now as before. Setup progress
and its storage are unchanged.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LoS9GKm4qEqfAWLm5A8wEw

* Work pages: use the standard status shapes (D04)

My Day Week and Month: overdue and passed dates show a red triangle before a
grey word instead of an amber word. Renewals timeline: amber dots only once it
is time to start renewing, grey dots further ahead. CPD rows: open targets use
a grey ring. Assessments: accent words such as Not started are grey, not green.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LoS9GKm4qEqfAWLm5A8wEw

* Honest review labels: sign-off shown only for a named person and date (S6)

Form notes and Chief Psychiatrist standards now say "Signed off by <name>, <date>"
only when the sign-off names a real person with a real date; a product attribution
such as "PsychSift" keeps the existing awaiting-review wording. The specifier
"Source reviewed" green badge becomes a grey "Source checked, not signed off".

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LoS9GKm4qEqfAWLm5A8wEw

* Crisis numbers: one shared card on the answer page and Admin Help, plus Poisons line

The answer crisis banner printed numbers as inline links in a pale info box.
It now uses the same rows as Admin Help: every number visible with its own
48px call link. Overdose or poisoning wording adds the Poisons Information
Centre (13 11 26, checked 2026-10-13 against the WA Poisons Information
Centre page). Poisons is kept out of WA_CRISIS_CONTACTS so the patient
safety plan list is unchanged.

Design audit D02 and S4.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LoS9GKm4qEqfAWLm5A8wEw

* CPD and End of year: one coloured button per screen (D08)

Row actions (Log, Tag one, Mark done, Attach, Copy next, Continue) become grey
pills, a new grey work-button variant, so the docked Log an activity is the
screen's only coloured button, as on Teaching Today.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LoS9GKm4qEqfAWLm5A8wEw

* CPD Log: one docked button, no floating Copy next (D09)

Copy next already sits in the not-marked-copied card above the list, so the
dock keeps only Log an activity, full width. The dock stays sticky in flow, so
the last row is still reachable above it.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LoS9GKm4qEqfAWLm5A8wEw

* CPD Log: test that the dock holds one button (D09)

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LoS9GKm4qEqfAWLm5A8wEw

* MHA clock: plain list, Start clock from form records, renamed MHA time limits

The clock drew a timeline bar per form with no end mark, so forms looked like
running timers while every card said "Time not calculated". The bars are gone;
the list already carries every figure. Timed form records get a Start clock
button that opens the clock with the form (and time, once entered) picked.
The page is renamed "MHA time limits" (clinical wording, awaiting owner
approval in the draft PR).

Design audit D01. No deadline calculation added (S1 needs legal sign-off).

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LoS9GKm4qEqfAWLm5A8wEw

* Work: shared state card on Open shifts, Manage team and Notifications (D13)

Design audit 13 Oct 2026, D13. Manage team's not-a-manager, wrong-team
and failed-read states, and the Notifications page's signed-out, failed
and empty states, now use the shared work state card (the bell's sheet
draws them without the card, as before). Manage team's bare "Try again"
blocks become the shared error state, and signed out gets the shared
sign-in card.

With nobody signed in, Open shifts showed a lone "No teams yet" card
because the server's invented team was hidden; it now shows the example
open shifts, unless example data is switched off.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LoS9GKm4qEqfAWLm5A8wEw

* Answer source marker: invisible 48px tap area, same look and text flow (D05)

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LoS9GKm4qEqfAWLm5A8wEw

* Answer page: key points and answer actions wrap at 320px large text (D17)

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LoS9GKm4qEqfAWLm5A8wEw

* Roster and My Day: the design system's shift codes (D12)

Display codes only (stored kinds unchanged): on call is OC, leave is AL, and
the evening (late) shift is L, everywhere a code is shown, so L no longer means
both leave and late. Labels such as Evening and Leave are unchanged.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LoS9GKm4qEqfAWLm5A8wEw

* Phone menu: default shortcuts become the urgent tools

The phone menu's default shortcuts repeated six rows the page groups list
again below. Until a reader edits their shortcuts, the phone drawer now offers
Crisis numbers (opening the shared call rows in place, loaded on first open),
MHA time limits, Safety plan and Forms. Readers' own pins are unchanged, and
the desktop sidebar keeps the default pins. The current page is then marked
in its group.

Design audit D14.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LoS9GKm4qEqfAWLm5A8wEw

* My Day: hold Today's skeleton until its own reads answer (D16)

Design audit 13 Oct 2026, D16: My Day's Today drew Quick actions and
Needs you first, then the hero and This week arrived about a second
later and pushed them down (layout shift 0.13 to 0.17). Measured on the
audit build: Quick actions moved from y 187 to 426 and Needs you from
276 to 515 in two shifts as the roster and teaching reads answered.

Today now keeps the same loading shape the page already shows until the
roster, teaching and CPD reads have answered, on the first load only; a
later re-read (Try again, a new day) keeps the cards on screen as
before. Nothing else changes.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LoS9GKm4qEqfAWLm5A8wEw

* Large text at 320 px: wrap filter rows and segments (D17)

At large text, CPD Log's filter chips and AI Search's area chips wrap onto
more lines instead of running past the edge; an equal-width segmented control
(Renewals' Soonest, By group, Personal) lets a segment take a second row; and
the Safety plan's Load example and Clear all buttons can wrap as whole items.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LoS9GKm4qEqfAWLm5A8wEw

* Work pills in sentence case (D20)

Status tags (.work-tag and Admin's status tag) no longer force capitals, so
Request it, Not started, 1 to do, Reached and Example · made-up people read as
written. Wording unchanged.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LoS9GKm4qEqfAWLm5A8wEw

* Roster Month: the next-shift line wraps instead of cutting off (D23)

"On call tonight" wrapped onto a second line rather than reading
"On call tonig…" at 390 px.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LoS9GKm4qEqfAWLm5A8wEw

* Privacy: plain words, plain date, no coloured side bars, sentence case (D22)

Design audit 13 Oct 2026, D22.

- "based on the repository's configured behaviour" becomes "based on how
  PsychSift is set up"; "Describes configured behaviour as of" becomes
  "Describes how PsychSift is set up as of". Every privacy statement
  keeps its meaning; nothing is added or removed.
- The date reads "1 September 2026" instead of 01/09/2026.
- The amber band keeps its tint but loses its coloured side bar, and the
  at-a-glance facts lose their coloured left edges.
- Small labels (overview, coverage, before you use, read more, at a
  glance, processing map, on this page, privacy details) are sentence
  case, not capitals.

The page's own sticky header is left as it is.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LoS9GKm4qEqfAWLm5A8wEw

* Say repeated lines once on Work pages (D24)

Notifications: the all-caught-up state no longer repeats "Nothing needs you
right now" under the line that already says it, and the page's hidden header
line is dropped while the band shows it. AI Search: the patient-details
warning card is also the field's description, so the hidden copy beside the
input is gone (the spoken live announcement stays). Playbook: the demo's
shared trigger line shows once at the top instead of on all six cards.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LoS9GKm4qEqfAWLm5A8wEw

* End of year: the domains count is 14 px page text, not 8 px (D25)

The "3/4" inside the domains ring was SVG text at 8px in the drawing's own
units. It is now page text over the ring at the small text size. The rest of
the End of year page already uses text tokens of 12px or more.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LoS9GKm4qEqfAWLm5A8wEw

* Clinical questions: hold back patient details before sending, on the page and in the answer API (S2)

Reuses Work's patient-detail check, reading capitals and a bare age as clinical
content. All 20 high-risk evaluation questions, the retrieval golden queries and
14 everyday questions pass; names with a title, record numbers, beds, dates of
birth and phone numbers are refused. The answer routes return 400 with a plain
message naming the kind of detail only.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LoS9GKm4qEqfAWLm5A8wEw

* Answer sources: a vertical list on phones; library rows open on a tap with one icon (D07)

Desktop keeps the scrolling source rail and both library row actions. The phone
answer page gets a little more bottom room so the last row clears the bottom box,
which is itself unchanged.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LoS9GKm4qEqfAWLm5A8wEw

* Keep the retired setup row for 30 days

Design audit D11 retired the per-area Finish setting up row, which only
landed today (#3495). The 30-day deletion rule keeps the file until
12 Nov 2026; knip ignores it until then.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LoS9GKm4qEqfAWLm5A8wEw

* Answer page: a plain 'Not in your sources' state (D03)

When the library has nothing on a question, the answer page no longer wears a
real answer's chrome. It shows a plain heading, the pipeline's own sentence,
one line on what was searched, then Also in your library and follow-ups.
Copy, Log as CPD, the thumbs up, the dose caution and the unrelated
Documents searched list are hidden; Report a problem stays.

Narrow on purpose: only no_candidates / unsupported reason codes (and the demo
refusal). Fail-closed answers (numeric check, timeout) keep their sources and
caution.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LoS9GKm4qEqfAWLm5A8wEw

* Work and Clinical bands: drop the date line except on My Day, Roster, Open shifts, Teaching and On Call

Owner instruction (13 Oct 2026): remove the date where it is not useful. CPD,
Admin and the Clinical bands no longer draw today's date above the title.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LoS9GKm4qEqfAWLm5A8wEw

* Work page titles name the page (audit D15)

Admin's band title is "Admin", not a greeting; CPD's heading is "CPD", not
"Year"; On Call's heading is "On Call", not "Now"; Assessments is titled
"Assessments", with the rotation moved to the line above.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LoS9GKm4qEqfAWLm5A8wEw

* Answer page: one quiet line on where a question goes (S3)

Under the latest answer, once per page: 'Questions are sent to an overseas AI
service (OpenAI) to search and write answers. Don't include patient details.'
Placed below the answer, not beside the composer, so the search box's measured
height and position do not change. Hidden in demo mode, where nothing is sent.
Draft wording for owner approval; the composer's governed privacy line is
unchanged.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LoS9GKm4qEqfAWLm5A8wEw

* Roster: the L shift reads Late, matching the design-system codes

Josh's design decision 5 (13 Oct 2026): OC on call, L late, AL leave
everywhere. The letters already changed; the word beside L now says Late
instead of Evening. Stored kinds are unchanged.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LoS9GKm4qEqfAWLm5A8wEw

* Format roster calendar test

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LoS9GKm4qEqfAWLm5A8wEw

* Work band corner is the Favourite heart only (audit D18)

Each page tool that sat in the band's top-right corner now sits in the page:
My Day's Quick add (a button at the top of Today; Customise stays in More),
Favourites' Add a work page and Add a number, Roster month's Add, Teaching
Today's Type a check-in code (under the session), Teaching Week's calendar
(already on the week list heading), Assessments' screen action, Renewals'
More actions (beside the views), Admin Help's Add your own (beside the box),
CPD's Customise and Log's Filter (top of the page), and Routines' New routine
(already in the page's dock). ModeBandAction and the band's action slot go.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LoS9GKm4qEqfAWLm5A8wEw

* Work band: the line above the title wraps instead of cutting off (audit D19)

With the date gone from most areas, the line carries page state where a page
already has it (Renewals' "checked 26 Sep", CPD's "Records loaded"), and it
now wraps rather than ending in an ellipsis. Pages with no state leave it empty.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LoS9GKm4qEqfAWLm5A8wEw

* Assessments and Manage team keep their parent's area pill (audit D21)

The top bar's pill reads Teaching on Assessments and Roster on Manage team, as
Open shifts already does; the band title names the sub-area.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LoS9GKm4qEqfAWLm5A8wEw

* Band titles never cut off at 320 px with large text

The Clinical and Work band titles scale with the band's width when enlarged
text would push a one-word title ("Psychiatry") past the edge, and the
Clinical title breaks inside the word as a last resort. Normal text sizes are
unchanged.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LoS9GKm4qEqfAWLm5A8wEw

* Clinical mode tabs: every tab is at least 48 px wide to tap

Short tabs such as Act and Map were 48 px tall but only 21 to 26 px wide,
because the link sat inside the slot's padding. The link now reaches over that
padding (at least 48 px wide); the word and its underline stay where they were.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LoS9GKm4qEqfAWLm5A8wEw

* Renewals and Admin Today: counts as words, one month-grouped list

Renewals showed the same dates three ways: four count tiles, a 12-month dot
timeline and the list. The counts are now small words with their status
shapes (still filters), the timeline is gone, and what needs action is one
list grouped by month, passed first and undated last. Admin Today's three
count tiles become the same words. Josh approved the real-app mockup on
13 Oct 2026 ("yes 10").

Design audit D10.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LoS9GKm4qEqfAWLm5A8wEw

* Offline page: urgent numbers first, privacy line last

The offline page opened with two paragraphs about the cache and signed URLs,
with 000 at the bottom of the first screen. It now leads with one short line,
then Urgent numbers (000, then Poisons Information Centre 13 11 26, then the
shared crisis list) as 48px call links, then On Call numbers saved on this
phone, then the signed-off Act quotes, and the full privacy statement last.
CACHE_VERSION is bumped so installed phones fetch the new page (Josh's yes,
13 Oct 2026); its offline.html hash is re-pinned.

Design audit D06 and S4.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LoS9GKm4qEqfAWLm5A8wEw

* Format answer notice test

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LoS9GKm4qEqfAWLm5A8wEw

* fix: keep search header within its size budget and use the pill radius token

Moves the composer warning wording into the patient-check module so the
search header stays under its no-growth line budget, and swaps a raw
999px radius for the pill token the design-system contract expects.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LoS9GKm4qEqfAWLm5A8wEw

* fix: let QTc millisecond readings, MS and 'pt with' through the clinical patient check

The clinical question check read 'QTc 480 ms' as the title Ms, 'MS on
interferon' as a title and name, and 'pt with renal impairment' as a
patient name, so routine questions could not be asked. Those shapes are
now rewritten before the second reading, like ages; 'Ms Jones' and
'pt John' are still refused. Pinned by new everyday and refusal cases.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LoS9GKm4qEqfAWLm5A8wEw

* fix: keep the title Ms when a number sits before it in a clinical question

The millisecond rewrite matched any case and dropped '4 Ms' in 'Ward 4 Ms
Smith clozapine', leaving a bare surname the check does not catch. Units
are now lowercase only and never before a capitalised word. Pinned by
four new refusal cases.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LoS9GKm4qEqfAWLm5A8wEw

* test: count the overseas note as answer content and expect the phone row's single action

The short-answer scroll check now measures the overseas-processing line
under the answer like the other always-rendered content, and the phone
cross-mode row expects no search button, which the phone layout hides by
design (audit D07).

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LoS9GKm4qEqfAWLm5A8wEw

* Answer page: keep the original phone bottom padding

The extra phone bottom room added for D07 spent the short-answer scroll
guard's budget (a short answer could scroll 30px into empty space). The
original pb-10 stands; the bottom box already hides on scroll.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LoS9GKm4qEqfAWLm5A8wEw

* test: measure the overseas note with the gap above it

The answer stack is space-y-4, so the note adds the stack's 16px gap,
which collapses with its own 4px top margin. Measuring only its box and
margins left 12px counted as phantom scroll. The 8px allowance is unchanged.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LoS9GKm4qEqfAWLm5A8wEw

* Answer actions: keep the row on one line, let the Copy label give way

Wrapping the row (audit D17) added a second 48px row under short phone
answers where the CI fonts run wider. The row stays on one line again and
the Copy label truncates instead, which still keeps Report a problem on
screen at 320px with large text.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LoS9GKm4qEqfAWLm5A8wEw

* fix: Validate queries in summary mode

* fix: Detect bare patient names near clinical content

* fix: 2 findings — Guard all answer-mode searches; Show crisis cards for 

- Guard all answer-mode searches
- Show crisis cards for poisoning wording

* fix: Report the true searched-source count

* fix: Reject future-dated sign-offs

* Revert "fix: Detect bare patient names near clinical content"

This reverts commit 828917f.

* Format sign-off-label.ts

* Load the Clinical patient-detail check only when a question is typed

The check and its Work helpers were downloaded with every page through the
search box, pushing eight pages past the page-size budget. The box and the
Answer path now load it on first use; the server check still refuses
patient details before then.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LoS9GKm4qEqfAWLm5A8wEw

* Let the composer tests wait for the lazily loaded patient check

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LoS9GKm4qEqfAWLm5A8wEw

* Reset the Roster shifts and Assessments size baselines to current main

Owner-approved on 13 Oct 2026: main had already used nearly all of the 10%
room on these two pages (+9.7% and +8.9%). Both now start from a local
production build of main at f4bcb55. Other baselines are unchanged.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LoS9GKm4qEqfAWLm5A8wEw

* fix: Invalidate stale searches before patient checks

* fix: Load patient checks only for Answer mode

* Keep a stale question from taking over, without cancelling the search in flight

Qodo's fix claimed a new request number and aborted the running search
before the patient check. A question the check then holds back would cancel
an answer still streaming and leave its progress on screen, and an empty
Prescribing submit stopped clearing the medicine search. This keeps the
earlier behaviour and only drops a submission that a mode change, Stop or
newer search made stale while the check loaded.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LoS9GKm4qEqfAWLm5A8wEw

* Move the composer's patient check into its own hook to keep the header within budget

The lazy-loaded check pushed master-search-header.tsx 13 lines over its
no-growth budget. Behaviour is unchanged.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LoS9GKm4qEqfAWLm5A8wEw

* Audit review follow-ups: bed number with sex word, AL legend, CPD filter on desktop, failed patient-check download, searched count

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LoS9GKm4qEqfAWLm5A8wEw

* Patient check: keep marked and other place-word numbers out of the age rewrite

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LoS9GKm4qEqfAWLm5A8wEw

* Review follow-ups: calendar action in Other services, cross-year renewals tests require January, role-based setup links, tap token for source marks

* Owner decisions 13 Oct: lowercase ms before capitalised terms is a reading; phones keep a compact Search control on cross-mode rows

* Answer home: show the overseas-processing notice before the first question is sent (owner decision 13 Oct)

* patient check keeps place numbers that look like ms readings; Answer home notice hidden in every resolved demo mode

* fix(clinical-question): keep capitalised place words (RM, CHAIR) from losing their number to the ms rewrite; note source-check cost

---------

Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: qodo-code-review[bot] <151058649+qodo-code-review[bot]@users.noreply.github.com>
Co-authored-by: BigSimmo <BigSimmo@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

🔴 Large blast radius size:L This PR changes 100-499 lines, ignoring generated files 🕐 40+ Minutes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants