Skip to content

perf(ui): content-first detail pages + loading & motion quick wins#1024

Merged
BigSimmo merged 9 commits into
mainfrom
claude/site-audit-quick-wins-21v9gb
Jul 21, 2026
Merged

perf(ui): content-first detail pages + loading & motion quick wins#1024
BigSimmo merged 9 commits into
mainfrom
claude/site-audit-quick-wins-21v9gb

Conversation

@BigSimmo

@BigSimmo BigSimmo commented Jul 21, 2026

Copy link
Copy Markdown
Owner

Summary

Site-audit "quick wins" across perceived speed, loading, and motion smoothness. All changes are UI/asset-level — no RAG/retrieval, clinical content, governance, auth, or data changes.

Content-first detail pages (were spinner/skeleton-first)

  • Medications, Services, and Forms detail pages now render the public fixture record server-side as a fallbackRecord and swap in the owner-aware live record in place — reusing the existing differentials pattern. First meaningful paint no longer waits on a client round-trip. SSR and the initial client render both start from the same fallback, so there is no hydration mismatch; owner-only slugs (absent from the public snapshot) keep the existing loading path.
  • Medication hook: dropped cache: "no-store" so public responses honour the API's public, max-age=300, s-maxage=3600, stale-while-revalidate headers (owner responses stay private, no-store via Vary: Authorization). Matches the sibling registry/differential hooks.

Loading / assets

  • Geist_Mono preload: false — the mono face never appears in initial/LCP text, so it no longer competes for a critical-path preload on every route (still loads on-demand via swap).
  • next.config images: enable AVIF→WebP and allow Supabase Storage signed-URL remotePatterns for future next/image use.

Motion smoothness (animate the compositor, not layout)

  • Therapy-compass knob: transform instead of left.
  • Upload progress bar: transform: scaleX() instead of width.
  • Settings header: dropped the permanent will-change: transform.
  • Global :active 1px press scoped to button/summary (was nudging every inline <a>, including citation/body links).

Deliberately not included (reclassified as architectural, not a quick win): lifting the formulation/specifiers catalogue data off the client bundle — those features run client-side local search with no API backing, so moving the data server-side would need new endpoints or per-keystroke round-trips.

RAG impact: no retrieval behaviour change — no files under the protected retrieval/ranking/selection/eval surfaces were touched.

Verification

  • npm run verify:pr-local
    • Ran individually and green: typecheck, lint, full offline unit suite (npm run test — 3028 passing), check:design-system-contract, check:type-scale, check:icon-scale. One unrelated pre-existing flake (pdf-extraction-budget.test.ts, a Python child-process deadline test) fails identically on a pristine tree with these changes stashed.
    • Verification not run: production build was not run in-session (change adds an images config + font preload flag) — deferred to CI.
  • npm run verify:ui when UI/styling/reduced-motion changed
    • UI verification not run: deferred to CI (needs dev server + Chromium). Hydration-safety reasoned: SSR and the initial client render both start from the fallbackRecord; reduced-motion is unaffected (all touched animations keep their motion-reduce/motion-safe guards and the global reduced-motion reset).

Risk and rollout

  • Risk: Low. Render-timing / asset / motion only. The content-first fallback shows the same public snapshot record the API already serves publicly; owner data still loads and swaps in. next/image has no production consumers today (mockups are dev-only), so the images config is inert in prod until adopted.
  • Rollback: Revert the single commit.
  • Provider or production effects: None.

Clinical Governance Preflight

  • Source-backed claims still require linked source verification before clinical use — unchanged
  • No patient-identifiable document workflow introduced or expanded
  • Supabase target remains Clinical KB Database (sjrfecxgysukkwxsowpy) — untouched
  • Service-role keys and private document access remain server-only — untouched
  • Demo/synthetic content remains clearly separated from real clinical sources — unchanged
  • Source metadata, review status, and outdated/unknown-source behavior remain conservative — the SSR governance badge is derived identically to the public API (deriveGovernanceFromSections)
  • Deployment classification/TGA SaMD impact checked — no clinical decision-support behaviour changed (render timing only)

Notes

  • Origin: full-site audit for "big easy wins" (performance/design/smoothness). Bundle hygiene, a11y, reduced-motion, forced-colors, answer streaming, and API caching were audited and found already well-handled; these are the genuine remaining wins up to the "big but not easy" tier.

🤖 Generated with Claude Code

https://claude.ai/code/session_01UbhUVWVJRwDibC2YtJ6aRX


Generated by Claude Code

Summary by CodeRabbit

  • Performance

    • Improved image optimization with AVIF output and WebP fallback for supported sources.
    • Optimized font preloading to reduce impact on initial page load.
    • Improved upload progress bar animation smoothness.
    • Adjusted catalog request caching to better align with existing behavior.
  • Bug Fixes

    • Public form, service, and medication pages can show available content immediately while data loads.
    • Improved medication record fallback and “not found”/loading behavior to avoid incorrect intermediate states.
    • Refined mobile settings header styling and slider animations for smoother interaction.

Site-audit quick wins across perceived speed, loading, and motion. No
behaviour change to RAG/retrieval or clinical content.

Content-first detail pages (was: spinner/skeleton-first):
- Medications, Services and Forms detail pages now render the public
  fixture record server-side as a fallback and swap in the owner-aware
  live record in place, reusing the differentials `fallbackRecord`
  pattern. SSR and the initial client render both start from the
  fallback, so there is no hydration mismatch.
- Drop `cache: "no-store"` from the medication hook so public responses
  honour the API's CDN/browser cache headers (matches the sibling
  registry/differential hooks).

Loading / assets:
- `Geist_Mono` `preload: false` — the mono face is never in LCP text, so
  stop preloading it on every route (still loads on-demand via swap).
- next.config `images`: enable AVIF then WebP; allow Supabase Storage
  signed-URL remotePatterns for future next/image use.

Motion smoothness (animate the compositor, not layout):
- Therapy-compass knob: animate `transform` instead of `left`.
- Upload progress bar: `transform: scaleX()` instead of `width`.
- Settings header: drop the permanent `will-change: transform`.
- Global `:active` press: scope the 1px nudge to buttons/summary, not
  every `<a>` (it was nudging inline citation/body links).

Verified: typecheck, lint, design-system contract, type-scale,
icon-scale and the full offline unit suite pass.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UbhUVWVJRwDibC2YtJ6aRX
@supabase

supabase Bot commented Jul 21, 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 Jul 21, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 2a65c300-97d8-41b3-b64a-a6e47b322fc3

📥 Commits

Reviewing files that changed from the base of the PR and between 586fcfd and 1fe6c81.

📒 Files selected for processing (4)
  • next.config.ts
  • src/app/medications/[slug]/page.tsx
  • src/components/clinical-dashboard/medication-record-page.tsx
  • src/components/registry-record-loader.tsx
🚧 Files skipped from review as they are similar to previous changes (4)
  • src/app/medications/[slug]/page.tsx
  • next.config.ts
  • src/components/registry-record-loader.tsx
  • src/components/clinical-dashboard/medication-record-page.tsx

📝 Walkthrough

Walkthrough

Changes

Server-rendered fallback records were added for form, service, and medication detail pages. Medication rendering now shows fallback content while fetching. Image formats, Supabase image sources, caching, font loading, progress animation, active styles, header transforms, and therapy compass animations were updated.

SSR rendering and UI behavior

Layer / File(s) Summary
Registry fallback loading
src/app/forms/[slug]/page.tsx, src/app/services/[slug]/page.tsx, src/components/forms/form-detail-client.tsx, src/components/services/service-detail-client.tsx, src/components/registry-record-loader.tsx
Form and service routes pass retrieved records through client loaders, which render fallback content while requests remain loading.
Medication SSR fallback rendering
src/app/medications/[slug]/page.tsx, src/components/clinical-dashboard/medication-record-page.tsx
Medication records and derived governance data are passed from the server, and the detail view prioritizes fetched or fallback data over the loading skeleton.
Asset delivery and request caching
next.config.ts, src/app/layout.tsx, src/components/clinical-dashboard/use-medication-catalog.ts
AVIF/WebP image output, Supabase Storage image patterns, deferred mono-font loading, and default fetch caching are configured.
Interaction and animation behavior
src/app/globals.css, src/components/clinical-dashboard/DocumentManagerPanel.tsx, src/components/clinical-dashboard/settings-dialog.tsx, src/components/therapy-compass/therapy-compass.css
Button active styling, upload progress, sticky header transforms, and clinician knob movement are updated.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Sequence Diagram(s)

sequenceDiagram
  participant MedicationPage
  participant MedicationRecordPage
  participant useMedicationDetail
  participant MedicationRecordDetail
  MedicationPage->>MedicationRecordPage: provide fallback record and governance
  MedicationRecordPage->>useMedicationDetail: request medication detail
  MedicationRecordPage->>MedicationRecordDetail: render fetched or fallback record
Loading

Possibly related PRs

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarizes the PR's main UI performance focus across content-first detail pages and motion/loading optimizations.
Description check ✅ Passed The description follows the template and covers summary, verification, risk/rollout, clinical governance, and notes with concrete details.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch claude/site-audit-quick-wins-21v9gb

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

@BigSimmo
BigSimmo marked this pull request as ready for review July 21, 2026 00:59
@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.
To continue using code reviews, add credits to your account and enable them for code reviews in your settings.

@BigSimmo
BigSimmo enabled auto-merge (squash) July 21, 2026 00:59

@coderabbitai coderabbitai 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.

Actionable comments posted: 2

🧹 Nitpick comments (3)
src/app/medications/[slug]/page.tsx (1)

35-48: 🎯 Functional Correctness | 🔵 Trivial

Run the required clinical readiness checks before handoff.

This change alters first-render clinical content and governance. Run the narrow medication-domain check, npm run check:production-readiness, and the clinical governance preflight under Node 24.x/npm 11.x.

As per coding guidelines, clinical output changes require the smallest relevant domain check, production-readiness validation, and clinical governance preflight.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/app/medications/`[slug]/page.tsx around lines 35 - 48, Run the required
validation for the first-render clinical content changes in the medication page:
execute the narrow medication-domain check, npm run check:production-readiness,
and the clinical governance preflight using Node 24.x with npm 11.x before
handoff.

Source: Coding guidelines

src/components/clinical-dashboard/medication-record-page.tsx (1)

508-520: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

Add regression coverage for fallback state transitions.

Cover fallback content during loading, replacement by live data, and behavior when the live request fails or returns no record.

As per coding guidelines, add the smallest relevant behavior test and run the narrowest validation for the touched surface.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/components/clinical-dashboard/medication-record-page.tsx` around lines
508 - 520, Add focused regression tests for the medication record page’s
conditional rendering around MedicationRecordDetail, LoadingPanel, and the error
fallback: verify loading displays fallback content, live record data replaces
it, and failed or empty requests display the expected error or “Medication not
found.” message. Keep the tests scoped to these state transitions and run the
narrowest relevant test validation.

Source: Coding guidelines

src/components/clinical-dashboard/use-medication-catalog.ts (1)

39-44: 🔒 Security & Privacy | 🔵 Trivial

Verify that shared caching does not bypass the registry rate limiter.

Removing no-store allows HTTP cache behavior, while the supplied API contract advertises s-maxage=3600 for public fixtures. A shared cache may serve later requests without executing /api/medications, bypassing consumeSubjectApiRateLimit despite the route comment stating every caller must pass it. If that guarantee is required, enforce limiting at the edge or remove shared cacheability; verify the deployed cache topology before relying on this change. (nextjs.org)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/components/clinical-dashboard/use-medication-catalog.ts` around lines 39
- 44, Verify the deployed cache topology around the medication catalog fetch and
registry route before retaining the default cache mode. Ensure shared-cache hits
cannot bypass the route’s consumeSubjectApiRateLimit guarantee; if that cannot
be enforced at the edge, restore non-shared caching in the fetch used by the
medication catalog hook.

Source: MCP tools

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@next.config.ts`:
- Around line 57-61: Update the remotePatterns Supabase image allowlist in
next.config.ts to replace the wildcard hostname with the exact production
project host, adding the explicitly configured staging host only when required.
Preserve the existing /storage/v1/object/** pathname scope, and configure search
only if signed URLs need query strings.

In `@src/components/registry-record-loader.tsx`:
- Around line 65-73: Prevent SSR fixture governance from being treated as
authoritative: in src/components/registry-record-loader.tsx lines 65-73, mark
fallback verification provisional or neutral until live governance
reconciliation; in src/app/medications/[slug]/page.tsx lines 41-45, remove the
hard-coded locally_reviewed status from authoritative fallback governance; and
in src/components/clinical-dashboard/medication-record-page.tsx lines 478-493,
suppress or neutralize fallback governance whenever live data is unavailable,
including request failures.

---

Nitpick comments:
In `@src/app/medications/`[slug]/page.tsx:
- Around line 35-48: Run the required validation for the first-render clinical
content changes in the medication page: execute the narrow medication-domain
check, npm run check:production-readiness, and the clinical governance preflight
using Node 24.x with npm 11.x before handoff.

In `@src/components/clinical-dashboard/medication-record-page.tsx`:
- Around line 508-520: Add focused regression tests for the medication record
page’s conditional rendering around MedicationRecordDetail, LoadingPanel, and
the error fallback: verify loading displays fallback content, live record data
replaces it, and failed or empty requests display the expected error or
“Medication not found.” message. Keep the tests scoped to these state
transitions and run the narrowest relevant test validation.

In `@src/components/clinical-dashboard/use-medication-catalog.ts`:
- Around line 39-44: Verify the deployed cache topology around the medication
catalog fetch and registry route before retaining the default cache mode. Ensure
shared-cache hits cannot bypass the route’s consumeSubjectApiRateLimit
guarantee; if that cannot be enforced at the edge, restore non-shared caching in
the fetch used by the medication catalog hook.
🪄 Autofix (Beta)

✅ Autofix completed


ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: e41de96c-06aa-43ca-ae34-91a0adbf5ad6

📥 Commits

Reviewing files that changed from the base of the PR and between 5bd7e8d and 586fcfd.

📒 Files selected for processing (14)
  • next.config.ts
  • src/app/forms/[slug]/page.tsx
  • src/app/globals.css
  • src/app/layout.tsx
  • src/app/medications/[slug]/page.tsx
  • src/app/services/[slug]/page.tsx
  • src/components/clinical-dashboard/DocumentManagerPanel.tsx
  • src/components/clinical-dashboard/medication-record-page.tsx
  • src/components/clinical-dashboard/settings-dialog.tsx
  • src/components/clinical-dashboard/use-medication-catalog.ts
  • src/components/forms/form-detail-client.tsx
  • src/components/registry-record-loader.tsx
  • src/components/services/service-detail-client.tsx
  • src/components/therapy-compass/therapy-compass.css

Comment thread next.config.ts Outdated
Comment thread src/components/registry-record-loader.tsx
@coderabbitai

coderabbitai Bot commented Jul 21, 2026

Copy link
Copy Markdown
Contributor

Note

Autofix is a beta feature. Expect some limitations and changes as we gather feedback and continue to improve it.

Fixes Applied Successfully

Fixed 3 file(s) based on 2 unresolved review comments.

Files modified:

  • next.config.ts
  • src/app/medications/[slug]/page.tsx
  • src/components/clinical-dashboard/medication-record-page.tsx

Commit: aa7f03fb238e8315bd0529675b323205092072bf

The changes have been pushed to the claude/site-audit-quick-wins-21v9gb branch.

Time taken: 8m 22s

coderabbitai Bot and others added 6 commits July 21, 2026 01:18
Fixed 3 file(s) based on 2 unresolved review comments.

Co-authored-by: CodeRabbit <noreply@coderabbit.ai>
…ance reconciles

Completes the content-first governance fix for services/forms. CodeRabbit's
autofix addressed the medications path (fallback governance no longer asserts a
hard-coded "locally_reviewed" status, and it is dropped on fetch failure) but
did not touch RegistryRecordLoader.

During the provisional (loading) paint, RegistryRecordLoader now renders the
public fixture record with `verification.locallyVerified` forced false, so a
stale "locally verified" badge cannot flash in before the `ready` branch
reconciles it against authoritative live governance. Mirrors the medications fix
and the differentials reference pattern (content-first, but verification/review
status only from authoritative data).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UbhUVWVJRwDibC2YtJ6aRX
@BigSimmo
BigSimmo merged commit 2250af0 into main Jul 21, 2026
19 checks passed
@BigSimmo
BigSimmo deleted the claude/site-audit-quick-wins-21v9gb branch July 21, 2026 01:45
BigSimmo added a commit that referenced this pull request Jul 22, 2026
…solve #15) (#1057)

* test(clinical): content-first + governance-badge regression tests (#15)

Cover the content-first transitions flagged in #1024's CodeRabbit review for
the two record loaders, locking in the clinical-safety invariant that no
authoritative verification badge is asserted before live governance reconciles:

- registry-record-loader.dom.test.tsx (8 tests): fallback paint during loading,
  the fixture-flag neutralization on the provisional paint, spinner when no
  fallback, live swap-in reconciling the badge on/off against governance,
  passthrough when governance is absent, and not_found / unauthorized states.
- medication-record-page.dom.test.tsx (6 tests): fallback paint vs skeleton,
  live swap-in, error-empty panel, and the governance-drop-on-error invariant
  (a fixture "Reviewed" badge must not persist after an error) contrasted with
  the in-flight loading state that trusts the SSR governance.

Test-only; no source/behaviour change. 14/14 pass under the jsdom project.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* docs(issues): resolve #15 — content-first regression tests added

Move #15 to Resolved/archive; covered by the two new jsdom suites in this PR.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants