perf(images): optimize private signed previews through next/image (#014)#1071
Conversation
SignedImage backed DocumentImage + SourceImage with a raw <img> that loaded the full-resolution Supabase scan just to fill a small 4:3 thumbnail. Route it through next/image so the optimizer resizes to preview dimensions and transcodes to AVIF/WebP, realizing the images config #1024 added (which was inert until now). - fill + sizes="(max-width: 768px) 92vw, 320px" matches the fixed-aspect frame and caps the srcset to preview widths. - Deferred IntersectionObserver load, fade-in on decode, and retry-on-error are all preserved; the lightbox keeps its own raw <img> for full-resolution zoom. - The signed ?token= query is optimizable because next.config images.remotePatterns pins the project host without a search restriction; a non-allow-listed host is rejected (400). Measured on a demo preview: 79,558 B PNG -> 9,966 B AVIF (~87% smaller); full-resolution clinical scans stand to save more. Governance: the optimizer fetches the signed URL server-side and caches the optimized bytes app-side (minimumCacheTTL); documented in the PR clinical-governance preflight. No auth/access-control change — the signed URL remains the capability and the client still obtains it through the auth-gated /signed-url endpoint. Updated the two signed-image tests to assert the next/image-optimized src (/_next/image?url=…) instead of a raw src. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01UbhUVWVJRwDibC2YtJ6aRX
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
📝 WalkthroughWalkthrough
ChangesSignedImage rendering
Estimated code review effort: 2 (Simple) | ~10 minutes Possibly related PRs
Suggested labels: 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
|
This pull request has been ignored for the connected project Preview Branches by Supabase. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: bac7df072b
ℹ️ 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".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
|
@codex resolve actionable Codex review findings for this pull request and current head using the repository instructions. This is the pull request's single automatic repair pass: do not perform a fresh review, create new standalone findings, or request another review. Work only the existing unresolved Codex threads on the current head. Always fix P0 and P1 findings. For P2 and lower findings, fix only clear, scoped, low-risk issues; otherwise disposition them with a concise reason. After fixing or dispositioning a thread, reply in that thread with as the first line, followed by a concise summary; that marker authorizes the workflow to close that exact thread. If human input or new authorization is required, do not use the marker and leave the thread open with the blocker. Finish only after every actionable thread is fixed or dispositioned and closed, or explicitly left open for a human decision. Do not update the branch from main, address unrelated reviews, broaden scope, or create more than one scoped fix commit. Do not use external APIs, paid services, credentials, dependency changes, or broad refactors unless explicitly authorized. Add targeted tests where behavior changes and run the narrowest relevant validation. |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 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 `@src/components/clinical-dashboard/signed-image.tsx`:
- Around line 131-148: Update the private preview handling in the signed-image
component around the next/image Image element to prevent optimized bytes from
outliving the signed URL: either disable optimization for bearer-backed URLs or
configure the optimizer cache TTL below the signed-URL lifetime. Preserve the
existing preview sizing and loading behavior.
🪄 Autofix (Beta)
✅ Autofix completed
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro Plus
Run ID: 9dd8a460-38c7-46b2-89b9-0cdcd8faa691
📒 Files selected for processing (3)
src/components/clinical-dashboard/signed-image.tsxtests/signed-image.dom.test.tsxtests/signed-image.test.ts
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: bac7df072b
ℹ️ 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".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 38aef19bd6
ℹ️ 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".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
|
Note Autofix is a beta feature. Expect some limitations and changes as we gather feedback and continue to improve it. Fixes Applied SuccessfullyFixed 1 file(s) based on 1 unresolved review comment. Files modified:
Commit: The changes have been pushed to the Time taken: |
Fixed 1 file(s) based on 1 unresolved review comment. Co-authored-by: CodeRabbit <noreply@coderabbit.ai>
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 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 55-58: The next.config.ts image optimizer configuration must not
use minimumCacheTTL as a signed-URL expiry boundary. Update the SignedImage
preview flow and its related image configuration so optimized private previews
are auth-aware/non-caching, or ensure their cache lifetime is explicitly bounded
by the signed URL’s remaining lifetime rather than relying on minimumCacheTTL.
🪄 Autofix (Beta)
✅ Autofix completed
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro Plus
Run ID: 528f7b22-478f-4fed-a9b3-9cfea1e4041f
📒 Files selected for processing (1)
next.config.ts
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 28f8570ce7
ℹ️ 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".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
|
Note Autofix is a beta feature. Expect some limitations and changes as we gather feedback and continue to improve it. Fixes Applied SuccessfullyFixed 2 file(s) based on 1 unresolved review comment. Files modified:
Commit: The changes have been pushed to the Time taken: |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 6ebadcc7cb
ℹ️ 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".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
Fixed 2 file(s) based on 1 unresolved review comment. Co-authored-by: CodeRabbit <noreply@coderabbit.ai>
CI triageCI failed on this PR. Automated classification of the 2 failed job(s):
Compared with main CI run #4469 (success). Classification is evidence routing, not permission to ignore a failure. Exact quarantined Playwright identities remain governed by the flake ledger. |
|
@codex please resolve and fix the merge conflict and commit and push jt to this branch and PR |
|
Summary
Testing
|
Drop minimumCacheTTL as a false expiry cap and mark SignedImage unoptimized so bearer URLs never enter the unauthenticated /_next/image cache. Update tests to assert direct src values. Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Summary
Realizes ledger item #14.
SignedImage(the shared renderer behindDocumentImageandSourceImage) loaded the full-resolution Supabase scan through a raw<img>just to fill a small 4:3 thumbnail. This routes it throughnext/image, so the optimizer resizes to preview dimensions and transcodes to AVIF/WebP — cashing in theimagesconfig #1024 added, which was inert until now.fill+sizes="(max-width: 768px) 92vw, 320px"matches the fixed-aspect frame and caps thesrcsetto preview widths (no full-width variant fetched).IntersectionObserverload, fade-in on decode, and retry-on-error are all preserved. The zoom lightbox keeps its own raw<img>for full-resolution pan/zoom — intentionally not optimized.?token=query is optimizable becausenext.configimages.remotePatternspins the exact project host without asearchrestriction; a non-allow-listed host is rejected with 400.Measured (demo preview, running app):
79,558 BPNG →9,966 BAVIF (~87% smaller) /12,766 BWebP. Full-resolution clinical scans stand to save more in absolute terms, especially in multi-image evidence galleries.RAG impact: no retrieval behaviour change — this is image-preview rendering only; no retrieval/ranking/selection/eval or answer-generation code touched.
Verification
npm run typecheck— cleannpm run lint— clean (raw-<img>eslint-disable removed; the rule is now satisfied bynext/image)npm run test(focused) —tests/signed-image.test.ts+tests/signed-image.dom.test.tsx5/5 pass (deferred load, cache-seeded paint, retry→recover, lightbox open/close); updated the two exact-srcassertions to thenext/image-optimizedsrc(/_next/image?url=…).npm run ensure):GET /_next/image?url=%2Fdemo-documents%2Fclozapine-table.png&w=640&q=75→200 image/avif9,966 B (WebP 12,766 B); a non-allow-listed host →400. Nonext/imagewarnings indev-server.log.npm run verify:ui): the visual frame is unchanged (same 4:3object-containframe, fade-in), the swap is proven functionally above, and there is no focused evidence-image UI spec; CI runs the unit suite. The one path not exercisable in-sandbox is the optimizer fetching a real<ref>.supabase.cosigned URL server-side (needs live Supabase) — see Risk.Risk and rollout
onErrordrops to the existing retry/failure state rather than breaking. Demo images (same-origin) optimize locally and are exercised by CI.remotePatterns(host +/storage/v1/object/**, unrestrictedsearch) permits it and the token rides in the URL (no header forwarding needed), but worth a post-merge glance in staging/prod that real previews transcode.<img>restored).Clinical Governance Preflight
/signed-urlauth gateClinical KB Database(sjrfecxgysukkwxsowpy) — unchangedminimumCacheTTL, 4h default) — a new at-rest location for optimized private-preview content. Access is not widened: the signed URL remains the bearer capability, obtained only through the auth-gated/signed-urlendpoint. This is the behaviour perf(ui): content-first detail pages + loading & motion quick wins #1024'sremotePatternscomment already scoped to "private document/image previews"./demo-documents/*and optimize locally; unchangedNotes
Generated by Claude Code
Summary by CodeRabbit