Skip to content

fix(assets): image CLS/a11y polish and cache hygiene#1195

Merged
BigSimmo merged 31 commits into
mainfrom
subagent-Asset-Optimization-Implementer-self-b295a5bb
Jul 25, 2026
Merged

fix(assets): image CLS/a11y polish and cache hygiene#1195
BigSimmo merged 31 commits into
mainfrom
subagent-Asset-Optimization-Implementer-self-b295a5bb

Conversation

@BigSimmo

@BigSimmo BigSimmo commented Jul 25, 2026

Copy link
Copy Markdown
Owner

Summary

Scoped asset/image hygiene after review cleanup (no retrieval/ranking changes):

  • Reserve layout for non-PDF source image previews (aspect-[4/3]) to reduce CLS.
  • Announce image load failures with polite ARIA live regions on SignedImage and non-PDF previews.
  • Keep private signed previews on unoptimized next/image; regression-tested so client code never appends Storage width/height/resize query params onto object/sign URLs.
  • Cache unversioned PWA icon routes with daily revalidation (max-age=86400, stale-while-revalidate=604800) instead of year-long immutable.
  • Keep Next’s default minimumCacheTTL (60s); set explicit deviceSizes / imageSizes only.
  • Add npm run check:assets as a no-dependency themed-favicon marker gate (wired into verify:cheap + Static PR). Full SVGO multipass stays deferred to avoid a lockfile-triggered blocking npm audit.

Intentionally not in this tip: SignedImage transform props, committed AVIF/WebP siblings, SVGO-in-CI, year-long immutable icon headers, and a root-layout /icon.svg preload (file-based app/icon.svg already owns the favicon link).

Verification

  • npm run verify:pr-local — Verification not run on this tip: focused local gates below cover the changed surface; hosted CI re-runs the full required aggregate.
  • Focused local: npm run check:assets, npm run brand:check, npm run check:gate-manifest, npm run docs:check-scripts, vitest tests/pwa-manifest.test.ts + tests/signed-image.dom.test.tsx (14 pass).
  • npm run verify:ui — UI verification not run: layout/a11y/cache-header changes only; Production UI hosted job covers browser smoke.
  • npm run eval:retrieval:quality — Verification not run: no retrieval or RAG ranking behaviour change.

RAG impact: no retrieval behaviour change — image preview CLS/a11y markup, PWA icon cache headers, next/image sizing config, and a favicon marker gate only.

Risk and rollout

  • Risk: Low. Preview layout reservation, accessibility announcements, cache headers, and a static favicon marker check.
  • Rollback: Revert the squash merge commit.
  • Provider or production effects: None.

Clinical Governance Preflight

  • Source-backed claims still require linked source verification before clinical use
  • No patient-identifiable document workflow was introduced or expanded without explicit governance approval
  • Supabase target remains Clinical KB Database (sjrfecxgysukkwxsowpy)
  • Service-role keys and private document access remain server-only
  • Demo/synthetic content remains clearly separated from real clinical sources
  • Source metadata, review status, and outdated/unknown-source behavior remain conservative
  • Deployment classification/TGA SaMD impact was checked when clinical decision-support behavior changed

Notes

  • Branch was previously polluted by a dirty checkpoint; tip is synced onto current main with conflict markers removed.
  • Do not reintroduce svgo / lockfile changes in this PR without also clearing the exceljs/brace-expansion audit highs.

@coderabbitai

coderabbitai Bot commented Jul 25, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Warning

Review limit reached

@BigSimmo, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 21 seconds

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 4296fc4f-db47-4cf6-be62-819f7780ec57

📥 Commits

Reviewing files that changed from the base of the PR and between 584deeb and 6fe97ad.

📒 Files selected for processing (9)
  • .github/workflows/ci.yml
  • docs/branch-review-ledger.md
  • next.config.ts
  • package.json
  • scripts/check-assets.mjs
  • src/app/icons/[variant]/route.tsx
  • src/components/document-viewer/non-pdf-source-preview.tsx
  • tests/pwa-manifest.test.ts
  • tests/signed-image.dom.test.tsx
📝 Walkthrough

Walkthrough

This change adds and refreshes AVIF/WebP image assets, configures Next image caching and breakpoints, improves icon delivery and image preview rendering, validates signed URL handling, and records follow-up review outcomes.

Changes

Image optimization

Layer / File(s) Summary
Asset formats and image configuration
next.config.ts, public/demo-documents/*, public/mockups/*
Adds or replaces AVIF and WebP assets and configures image cache TTL, device sizes, and image sizes.
Icon response and preload delivery
src/app/icons/[variant]/route.tsx, src/app/layout.tsx
Adds explicit icon response dimensions and immutable caching, plus high-priority /icon.svg preloading.
Signed and inline image rendering
src/components/clinical-dashboard/signed-image.tsx, src/components/document-viewer/non-pdf-source-preview.tsx, tests/signed-image.dom.test.tsx
Adds accessible failure status semantics, documents signed URL handling, uses fixed-aspect inline previews, and tests that signed URLs receive no transform parameters.
Review ledger updates
docs/branch-review-ledger.md
Appends readiness, triage, debugging, and CI unblock records for PR #1195.

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

Possibly related PRs

Suggested labels: codex

Suggested reviewers: claude

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
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.
Title check ✅ Passed The title is concise and matches the main theme of asset, image, accessibility, and cache-related changes.
Description check ✅ Passed The description follows the required template and includes summary, verification, risk, governance, and notes sections.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch subagent-Asset-Optimization-Implementer-self-b295a5bb

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.

@supabase

supabase Bot commented Jul 25, 2026

Copy link
Copy Markdown

Updates to Preview Branch (subagent-Asset-Optimization-Implementer-self-b295a5bb) ↗︎

Deployments Status Updated
Database Sat, 25 Jul 2026 21:02:02 UTC
Services Sat, 25 Jul 2026 21:02:02 UTC
APIs Sat, 25 Jul 2026 21:02:02 UTC

Tasks are run on every commit but only new migration files are pushed.
Close and reopen this PR if you want to apply changes from existing seed or migration files.

Tasks Status Updated
Configurations Sat, 25 Jul 2026 21:02:05 UTC
Migrations Sat, 25 Jul 2026 21:02:07 UTC
Seeding Sat, 25 Jul 2026 21:02:08 UTC
Edge Functions Sat, 25 Jul 2026 21:02:09 UTC

View logs for this Workflow Run ↗︎.
Learn more about Supabase for Git ↗︎.

BigSimmo added 12 commits July 25, 2026 19:33
Clear the dirty-checkpoint conflict-marker history by merging origin/main.
Remove the silent SignedImage object/sign transform rewrite, and make
check:assets a non-mutating SVGO stability gate.
SVGO multipass stripped the prefers-color-scheme styles from
src/app/icon.svg, failing brand:check and regressing dark-mode tab icons.
Restore brandIconSvg() output and skip that file in check:assets so
brand:check remains the owner of the themed favicon.
knip failed Static PR checks because scripts/optimize-public-images.mjs
imports sharp while it was only pinned via overrides. Add the direct
dependency so check:knip matches the script.
Adding svgo/sharp forced lockfile_changed, which made the pre-existing
exceljs/brace-expansion npm audit highs blocking. Remove check:assets CI
wiring, the unused optimize-public-images script, and restore package
manifest/lockfile to main so Safety stays advisory. Runtime asset fixes
remain.
@github-actions

github-actions Bot commented Jul 25, 2026

Copy link
Copy Markdown
Contributor

CI triage

CI failed on this PR. Automated classification of the 3 failed job(s):

  • Static PR checksneeds investigation: inspect the failing step and uploaded diagnostics; rerun only after classifying the cause.
  • Production UIneeds investigation: inspect the failing step and uploaded diagnostics; rerun only after classifying the cause.
  • PR requiredneeds investigation: inspect the failing step and uploaded diagnostics; rerun only after classifying the cause.

Compared with main CI run #5589 (success).

Classification is evidence routing, not permission to ignore a failure. Exact quarantined Playwright identities remain governed by the flake ledger.

@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)
public/demo-documents/clozapine-table.avif (1)

1-1: 🚀 Performance & Scalability | 🔵 Trivial | ⚡ Quick win

Connect the pre-encoded demo assets to the source catalog.

The supplied consumers still reference PNG paths, so these AVIF/WebP files are not demonstrably used by the demo previews. Verify there is no extension-selection layer; otherwise update the catalog/renderer to serve optimized variants with a fallback.

  • public/demo-documents/clozapine-table.avif#L1-L1: wire the AVIF variant into clozapine preview selection or remove it.
  • public/demo-documents/clozapine-table.webp#L1-L1: wire the WebP fallback into clozapine preview selection or remove it.
  • public/demo-documents/risk-flow.avif#L1-L1: wire the AVIF variant into risk-flow preview selection or remove it.
  • public/demo-documents/risk-flow.webp#L1-L1: wire the WebP fallback into risk-flow preview selection or remove it.
🤖 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 `@public/demo-documents/clozapine-table.avif` at line 1, The clozapine and
risk-flow optimized assets are not connected to demo preview selection. Update
the source catalog/renderer to serve AVIF first, WebP as fallback, and retain
PNG fallback where needed for clozapine-table.avif lines 1-1,
clozapine-table.webp lines 1-1, risk-flow.avif lines 1-1, and risk-flow.webp
lines 1-1; if no extension-selection layer exists, remove these unused assets
instead.
src/components/document-viewer/non-pdf-source-preview.tsx (1)

142-149: 🚀 Performance & Scalability | 🔵 Trivial | ⚡ Quick win

Keep this signed preview on an explicit image-optimization path.

The changed production TSX path still renders raw <img>, which bypasses Next Image features and can trigger @next/next/no-img-element. Prefer next/image with fill and unoptimized after verifying the signed host is allowed by images.remotePatterns, or document a targeted lint exception. (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/document-viewer/non-pdf-source-preview.tsx` around lines 142 -
149, Update the preview image in the non-PDF source preview component to use
next/image with fill and unoptimized while preserving the signedUrl, title,
error handler, and existing visual classes; verify the signed host is permitted
by images.remotePatterns, or add a narrowly scoped lint exception if it cannot
be configured.

Source: Coding guidelines

src/app/layout.tsx (1)

94-96: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Prefer the supported resource-hint path over a manual root <head>.

Next.js guidance says root layouts should not manually manage head elements, and its resource-hint documentation demonstrates preload APIs instead. Move this into the project’s preload-resource component or verify the current Next.js 16 behavior and deduplication guarantees before retaining it. (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/app/layout.tsx` around lines 94 - 96, Replace the manual root layout head
link in the layout component with the project’s supported preload-resource
component or Next.js preload API for /icon.svg. If retaining the current
approach, first verify Next.js 16 deduplication behavior and ensure the
implementation preserves a single high-priority SVG preload.

Source: Coding guidelines

🤖 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 `@docs/branch-review-ledger.md`:
- Line 25: Move the 2026-07-25 PR `#1195` record from its current position near
the top of Review Records to after the existing final record. Preserve the row
content unchanged and maintain the ledger’s append-only chronological ordering
so check:branch-review-ledger accepts it.

In `@src/app/icons/`[variant]/route.tsx:
- Around line 38-40: Update the cache policy for the versionless icon responses
in the route handler serving the [variant] icons: remove immutable one-year
caching and use a shorter revalidation policy. Only retain long-lived immutable
caching if the manifest URLs are changed to include a content hash or version.

---

Nitpick comments:
In `@public/demo-documents/clozapine-table.avif`:
- Line 1: The clozapine and risk-flow optimized assets are not connected to demo
preview selection. Update the source catalog/renderer to serve AVIF first, WebP
as fallback, and retain PNG fallback where needed for clozapine-table.avif lines
1-1, clozapine-table.webp lines 1-1, risk-flow.avif lines 1-1, and
risk-flow.webp lines 1-1; if no extension-selection layer exists, remove these
unused assets instead.

In `@src/app/layout.tsx`:
- Around line 94-96: Replace the manual root layout head link in the layout
component with the project’s supported preload-resource component or Next.js
preload API for /icon.svg. If retaining the current approach, first verify
Next.js 16 deduplication behavior and ensure the implementation preserves a
single high-priority SVG preload.

In `@src/components/document-viewer/non-pdf-source-preview.tsx`:
- Around line 142-149: Update the preview image in the non-PDF source preview
component to use next/image with fill and unoptimized while preserving the
signedUrl, title, error handler, and existing visual classes; verify the signed
host is permitted by images.remotePatterns, or add a narrowly scoped lint
exception if it cannot be configured.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: f95cd135-fce8-41c8-91f0-2bb4508e1cd7

📥 Commits

Reviewing files that changed from the base of the PR and between 3dae971 and 584deeb.

📒 Files selected for processing (17)
  • docs/branch-review-ledger.md
  • next.config.ts
  • public/demo-documents/clozapine-table.avif
  • public/demo-documents/clozapine-table.webp
  • public/demo-documents/risk-flow.avif
  • public/demo-documents/risk-flow.webp
  • public/mockups/crisp-white-colour-system-desktop.avif
  • public/mockups/crisp-white-colour-system-desktop.webp
  • public/mockups/crisp-white-colour-system-mobile.avif
  • public/mockups/crisp-white-colour-system-mobile.webp
  • public/mockups/premium-colour-system-mobile.avif
  • public/mockups/premium-colour-system-mobile.webp
  • src/app/icons/[variant]/route.tsx
  • src/app/layout.tsx
  • src/components/clinical-dashboard/signed-image.tsx
  • src/components/document-viewer/non-pdf-source-preview.tsx
  • tests/signed-image.dom.test.tsx

Comment thread docs/branch-review-ledger.md
Comment thread src/app/icons/[variant]/route.tsx
BigSimmo added 3 commits July 26, 2026 01:07
Turn check:assets into a real no-dep themed-favicon marker gate and wire
it into verify:cheap + static-pr CI. Drop the redundant root-layout icon
preload (app/icon.svg already owns the favicon link). Announce non-PDF
preview failures with the same polite status live region as SignedImage.
@BigSimmo BigSimmo changed the title feat: asset and image optimization remediation fix(assets): image CLS/a11y polish and cache hygiene Jul 25, 2026
@BigSimmo
BigSimmo merged commit c612c88 into main Jul 25, 2026
19 checks passed
@BigSimmo
BigSimmo deleted the subagent-Asset-Optimization-Implementer-self-b295a5bb branch July 25, 2026 21:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant