Skip to content

perf(ui): speed up search and interactive catalogue surfaces#1138

Merged
BigSimmo merged 28 commits into
mainfrom
cursor/search-interactive-perf-af54
Jul 24, 2026
Merged

perf(ui): speed up search and interactive catalogue surfaces#1138
BigSimmo merged 28 commits into
mainfrom
cursor/search-interactive-perf-af54

Conversation

@BigSimmo

@BigSimmo BigSimmo commented Jul 24, 2026

Copy link
Copy Markdown
Owner

Summary

Low-risk client-only performance pass for search and interactive catalogue surfaces. No RAG/retrieval/ranking behaviour changes.

  • Differential catalogue: debounce + AbortController + auth-keyed LRU; clear matches on auth change; clear entire LRU on 401
  • useDeferredValue ranking on services/forms/formulation/therapy-compass + ClinicalDashboard registry search (extracted hook)
  • Cleared live query restores full catalogue immediately; therapy-compass defers query text only (live filter chips/flags)
  • Document results progressive reveal with identity-based window reset + selection-aware expand
  • Memoized RelatedDocumentsPanel with stable useEventCallback handlers
  • Sheet focus-restore skips scheduling on true unmount (layout mount flag)

Test plan

  • Focused Vitest (differential 401 cache clear, deferred registry, sheet, therapy bindings)
  • Hosted Static PR / Unit coverage / Build / Production UI / PR required
  • Merged latest main (incl. branch-review ledger guard fix: prevent branch review ledger merge conflicts #1154)
  • Bugbot + CodeRabbit findings addressed; 0 unresolved review threads

RAG impact: no retrieval behaviour change — client-only search UX caching/deferral; no rag/ranking/order edits.

Open in Web Open in Cursor 

Summary by CodeRabbit

  • New Features

    • Search results now load progressively with a “Show more” option for large result sets.
    • Search typing is more responsive across dashboards, forms, services, formulation, and therapy experiences.
    • Previously viewed searches can load faster through improved result reuse.
  • Bug Fixes

    • Prevented stale or misleading results and empty states from appearing while searches update.
    • Improved handling of cleared searches, authentication changes, cancelled requests, and unauthorized sessions.
  • Tests

    • Added coverage for deferred search behavior, cancellation, caching, authentication changes, and progressive result loading.

Add differential-search debounce/abort/LRU parity with universal search,
defer local catalogue ranking with useDeferredValue, progressively reveal
document result cards, memoize related documents during answer streaming,
and harden the universal typeahead cache with a larger TTL-backed LRU.

Co-authored-by: BigSimmo <BigSimmo@users.noreply.github.com>
@supabase

supabase Bot commented Jul 24, 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 24, 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: 56 minutes

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: dbb955d0-d97c-434c-981c-cc57d71ec2b6

📥 Commits

Reviewing files that changed from the base of the PR and between ff4b293 and 9f28e83.

📒 Files selected for processing (1)
  • docs/branch-review-ledger.md
📝 Walkthrough

Walkthrough

Search ranking is deferred across multiple interfaces, dashboard document results progressively reveal cards, differential and universal searches gain cache controls, and tests cover deferred clearing, cancellation, authentication changes, and cache isolation.

Changes

Search performance and result delivery

Layer / File(s) Summary
Deferred registry ranking and search input
src/components/ClinicalDashboard.tsx, src/components/clinical-dashboard/use-deferred-registry-search.ts, src/components/forms/..., src/components/services/..., src/components/formulation/..., src/components/therapy-compass/..., tests/client-performance-boundaries.test.ts, tests/use-deferred-registry-search.dom.test.tsx
Dashboard registry ranking and multiple catalog searches now use deferred queries, clear results during empty or lagging states, and gate empty-state rendering until ranking catches up.
Progressive document result rendering
src/components/clinical-dashboard/document-search-results.tsx, src/components/clinical-dashboard/document-results.tsx, src/components/ClinicalDashboard.tsx
Document cards render in a bounded visible window with selection-aware expansion and a “Show more” control; related documents are memoized and dashboard handlers are updated.
Debounced and expiry-aware search caches
src/components/clinical-dashboard/use-differential-catalog.ts, src/components/clinical-dashboard/use-universal-search.ts, tests/use-differential-search.dom.test.tsx, tests/use-universal-search-stream.dom.test.tsx
Differential catalog requests are debounced, abortable, auth-keyed, and cached with TTL/LRU behavior; universal search cache reads and writes become expiry-aware.
Performance boundary and review records
tests/client-performance-boundaries.test.ts, docs/branch-review-ledger.md
Tests verify ranker placement and the ledger records the PR review, bugfix, babysit, and closeout entries.

Estimated code review effort: 4 (Complex) | ~60 minutes

Sequence Diagram(s)

sequenceDiagram
  participant User
  participant SearchSurface
  participant DeferredSearch
  participant Registry
  participant Ranker
  User->>SearchSurface: type query
  SearchSurface->>DeferredSearch: pass live query
  DeferredSearch->>Registry: load records
  DeferredSearch->>Ranker: rank deferred query
  Ranker-->>DeferredSearch: ranked matches
  DeferredSearch-->>SearchSurface: matches and status
Loading
sequenceDiagram
  participant User
  participant DifferentialSearch
  participant Cache
  participant DiagnosisCatalog
  participant PresentationCatalog
  User->>DifferentialSearch: change query
  DifferentialSearch->>Cache: check auth-keyed entry
  DifferentialSearch->>DiagnosisCatalog: fetch diagnosis matches
  DifferentialSearch->>PresentationCatalog: fetch presentation matches
  DiagnosisCatalog-->>DifferentialSearch: diagnosis payload
  PresentationCatalog-->>DifferentialSearch: presentation payload
  DifferentialSearch->>Cache: store combined results
  DifferentialSearch-->>User: update matches and status
Loading

Possibly related PRs

Suggested labels: codex

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Description check ⚠️ Warning Summary and test plan are present, but the template’s Verification, Risk and rollout, Clinical Governance Preflight, and Notes sections are missing. Add the missing template sections, including required verification checkboxes, risk/rollback details, governance preflight items, and a brief notes section.
Docstring Coverage ⚠️ Warning Docstring coverage is 33.33% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title is concise and accurately summarizes the main client-side performance work on search and interactive catalogue surfaces.
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 unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch cursor/search-interactive-perf-af54

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.

Move services/forms deferred ranking out of ClinicalDashboard into
use-deferred-registry-search so the maintainability no-growth budget
passes, and update the client performance boundary contract.

Co-authored-by: BigSimmo <BigSimmo@users.noreply.github.com>
@BigSimmo
BigSimmo marked this pull request as ready for review July 24, 2026 05:34
BigSimmo and others added 4 commits July 24, 2026 13:34
Append the branch-review ledger row for the search/interactive
performance pass on cursor/search-interactive-perf-af54.

Co-authored-by: BigSimmo <BigSimmo@users.noreply.github.com>
…com/bigsimmo/database into cursor/search-interactive-perf-af54

Co-authored-by: BigSimmo <BigSimmo@users.noreply.github.com>
Update the branch-review ledger row after Chromium UI verification
completed successfully for the search interactive performance pass.

Co-authored-by: BigSimmo <BigSimmo@users.noreply.github.com>
@github-actions

github-actions Bot commented Jul 24, 2026

Copy link
Copy Markdown
Contributor

CI triage

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

  • Unit coverageneeds 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 #4690 (success).

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

cursoragent and others added 13 commits July 24, 2026 05:47
Clear differential matches on auth identity change, keep selected
document cards visible under progressive reveal, and gate deferred
catalogue ranking so empty deferred queries cannot flash full-library
or false-empty states. Also fix Prettier on the universal-search test.

Co-authored-by: BigSimmo <BigSimmo@users.noreply.github.com>
Append the follow-up ledger row for the P1/P2 fixes on the search
interactive performance PR.

Co-authored-by: BigSimmo <BigSimmo@users.noreply.github.com>
Bring the feature branch current with origin/main before CI babysit.

Co-authored-by: BigSimmo <BigSimmo@users.noreply.github.com>
Clearing the live composer now restores the services catalogue and
clears dashboard/forms registry matches immediately, so deferred query
lag cannot keep stale filtered results on screen.

Co-authored-by: BigSimmo <BigSimmo@users.noreply.github.com>
Ledger the Bugbot clear-fix and main merge for PR #1138.

Co-authored-by: BigSimmo <BigSimmo@users.noreply.github.com>
Clear pending rAF/timeout focus restores when a Sheet unmounts so
jsdom teardown cannot throw ReferenceError: document is not defined
during unit coverage.

Co-authored-by: BigSimmo <BigSimmo@users.noreply.github.com>
Ledger the green hosted PR-required result for the search interactive
performance babysit.

Co-authored-by: BigSimmo <BigSimmo@users.noreply.github.com>
Keep the babysit branch current so GitHub merge state stays CLEAN.

Co-authored-by: BigSimmo <BigSimmo@users.noreply.github.com>
Absorb the latest main tip so the PR is no longer behind.

Co-authored-by: BigSimmo <BigSimmo@users.noreply.github.com>
Bring the babysit branch current again while main is moving quickly.

Co-authored-by: BigSimmo <BigSimmo@users.noreply.github.com>
Keep PR #1138 review ledger rows and the #1137 search-chrome
behaviour notes from main so the branch is mergeable again.

Co-authored-by: BigSimmo <BigSimmo@users.noreply.github.com>
Short-circuit empty live query before ranking against lagging
deferredQuery so builder and home match services/registry clear UX.

Co-authored-by: BigSimmo <BigSimmo@users.noreply.github.com>
Co-authored-by: BigSimmo <BigSimmo@users.noreply.github.com>

@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: 5

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/components/ui/sheet.tsx (1)

227-251: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Cancel pending restoration when reopening the sheet.

When open changes from false to true before the previous close’s restore callback runs, React runs the old effect cleanup first, so the new open effect already has an intact restoreFocusCleanupRef. A reopened sheet can then be moved back to the prior focus target; call restoreFocusCleanupRef.current?.() in the open branch before scheduling focusFrame.

Proposed fix
  useEffect(() => {
    if (!open) return;
+   restoreFocusCleanupRef.current?.();

    const explicitReturnElement = returnFocusRef?.current ?? null;
🤖 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/ui/sheet.tsx` around lines 227 - 251, In the open branch of
the sheet focus effect, call restoreFocusCleanupRef.current?.() before
scheduling focusFrame so any pending restoration from the previous close is
cancelled when reopening. Keep the existing restoration cleanup and focus
scheduling behavior unchanged otherwise.
🤖 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/document-results.tsx`:
- Around line 141-143: Update the ClinicalDashboard call site that renders
RelatedDocumentsPanel to pass the existing useEventCallback-wrapped handlers for
scopeOnlyDocument and handleTagSearch instead of creating fresh functions
inline. Keep RelatedDocumentsPanel’s memoization unchanged and preserve the
existing callback behavior.

In `@src/components/clinical-dashboard/document-search-results.tsx`:
- Around line 883-900: Update resultsSignature in the result-window state logic
to include the identities and ordering of sortedMatches, not just
sortedMatches.length. Ensure different result IDs or order produce a new
signature so visibleCountState resets to minimumVisibleForSelection, while
unchanged results retain the existing selection-expansion behavior.

In `@src/components/clinical-dashboard/use-differential-catalog.ts`:
- Around line 159-168: Update the 401 handling in the differential-search flow
to invalidate the current differentialSearchCache entry for cacheKey before
setting the unauthorized state. Ensure subsequent renders of the same query and
authSignature cannot reuse stale cached matches, while preserving the existing
authStatus handling and unauthorized state updates; add a regression test
covering a cached success followed by a 401 and a repeated query.

In `@src/components/formulation/formulation-builder-page.tsx`:
- Around line 224-228: Update visibleMechanisms in formulation-builder-page.tsx
to return canonical searchFormulationMechanisms results with an empty query when
query.trim() is empty, before evaluating deferredQuery. In bindings.tsx, update
the clear-search options to use the live search options with query set to empty
instead of spreading deferredSearch, so clearSearch() immediately removes stale
tags and flags.

In `@src/components/ui/sheet.tsx`:
- Around line 131-136: Consolidate the unmount cancellation with the open/focus
lifecycle effect: remove the standalone empty-dependency useEffect that invokes
restoreFocusCleanupRef.current and invoke that cleanup from the cleanup returned
by the [open, ...] effect after assigning the ref. Preserve focus restoration
for normal close while ensuring scheduled restoration and retries are canceled
during teardown.

---

Outside diff comments:
In `@src/components/ui/sheet.tsx`:
- Around line 227-251: In the open branch of the sheet focus effect, call
restoreFocusCleanupRef.current?.() before scheduling focusFrame so any pending
restoration from the previous close is cancelled when reopening. Keep the
existing restoration cleanup and focus scheduling behavior unchanged otherwise.
🪄 Autofix (Beta)

❌ Autofix failed (check again to retry)

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: 1c9582ef-4448-4981-95cc-447ee15a5da4

📥 Commits

Reviewing files that changed from the base of the PR and between be3a9fe and 3499aae.

📒 Files selected for processing (17)
  • docs/branch-review-ledger.md
  • src/components/ClinicalDashboard.tsx
  • src/components/clinical-dashboard/document-results.tsx
  • src/components/clinical-dashboard/document-search-results.tsx
  • src/components/clinical-dashboard/use-deferred-registry-search.ts
  • src/components/clinical-dashboard/use-differential-catalog.ts
  • src/components/clinical-dashboard/use-universal-search.ts
  • src/components/forms/forms-search-results-page.tsx
  • src/components/formulation/formulation-builder-page.tsx
  • src/components/formulation/formulation-home-page.tsx
  • src/components/services/services-navigator-page.tsx
  • src/components/therapy-compass/bindings.tsx
  • src/components/ui/sheet.tsx
  • tests/client-performance-boundaries.test.ts
  • tests/use-deferred-registry-search.dom.test.tsx
  • tests/use-differential-search.dom.test.tsx
  • tests/use-universal-search-stream.dom.test.tsx

Comment thread src/components/clinical-dashboard/document-results.tsx
Comment thread src/components/clinical-dashboard/document-search-results.tsx Outdated
Comment thread src/components/clinical-dashboard/use-differential-catalog.ts
Comment thread src/components/formulation/formulation-builder-page.tsx
Comment thread src/components/ui/sheet.tsx
@BigSimmo
BigSimmo enabled auto-merge (squash) July 24, 2026 07:04
@coderabbitai

coderabbitai Bot commented Jul 24, 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.

Cannot run autofix: This PR has merge conflicts.

Please resolve the conflicts with the base branch and try again.

Alternatively, use @coderabbitai resolve merge conflict to automatically resolve the conflicts.

@BigSimmo

Copy link
Copy Markdown
Owner Author

@codex resolve merge conflicts please.

Resolve ledger conflict with #1143. Clear differential LRU on 401,
reset document progressive-reveal by result ids, pass stable Related
Documents callbacks, restore therapy/formulation clear via live state,
and make Sheet focus-restore skip on unmount via layout mount flag.

Co-authored-by: BigSimmo <BigSimmo@users.noreply.github.com>
@chatgpt-codex-connector

Copy link
Copy Markdown

Summary

Testing

  • git diff --cached --check
  • ⚠️ npm run verify:cheap (blocked by environment/tooling limitation: Unable to resolve tsx/cli from /workspace/Database or its Git worktrees.)

View task →

@chatgpt-codex-connector

Copy link
Copy Markdown

Summary

Testing

  • git diff --cached --check
  • npm run check:migration-role
  • ⚠️ npm run typecheck — could not run because node_modules/typescript/bin/tsc is missing in this checkout.
  • ⚠️ npm ci — environment limitation: project requires Node 24.x/npm 11.x, but this environment has Node v20.20.2/npm 11.4.2.

View task →

@BigSimmo
BigSimmo disabled auto-merge July 24, 2026 07:14
cursoragent and others added 8 commits July 24, 2026 07:20
…tive-perf-af54

Co-authored-by: BigSimmo <BigSimmo@users.noreply.github.com>
Filter chip toggles were deferred with the search string, so Reviewed
only and tags lagged behind aria-pressed until useDeferredValue caught up.

Co-authored-by: BigSimmo <BigSimmo@users.noreply.github.com>
…tive-perf-af54

Co-authored-by: BigSimmo <BigSimmo@users.noreply.github.com>
Co-authored-by: BigSimmo <BigSimmo@users.noreply.github.com>
…tive-perf-af54

Co-authored-by: BigSimmo <BigSimmo@users.noreply.github.com>
# Conflicts:
#	src/components/ui/sheet.tsx

Co-authored-by: BigSimmo <BigSimmo@users.noreply.github.com>
Resolve sheet.tsx focus-restore conflict by keeping main's
restoreTimersRef/unmountingRef approach (already covered by
sheet.dom.test.tsx). No RAG/ranking behaviour change.
@BigSimmo
BigSimmo merged commit f01dcb6 into main Jul 24, 2026
16 checks passed
@BigSimmo
BigSimmo deleted the cursor/search-interactive-perf-af54 branch July 24, 2026 11:11
cursor Bot pushed a commit that referenced this pull request Jul 24, 2026
Record merge of origin/main into fix-physics-animation-audit after the PR went CONFLICTING behind #1138.

Co-authored-by: BigSimmo <BigSimmo@users.noreply.github.com>
cursor Bot pushed a commit that referenced this pull request Jul 25, 2026
…and reduced-motion presets (#1142)

* fix(ui): remediate spring physics animations, GPU layer compositing, and reduced-motion presets

* docs: record PR #1142 review entry in branch review ledger

* fix(ui): tokenize remaining W3C ease transitions with design tokens

* docs: ledger Run PR conflict sweep for #1142

* docs: ledger conflict resolution for #1142

Record merge of origin/main into fix-physics-animation-audit after the PR went CONFLICTING behind #1138.

Co-authored-by: BigSimmo <BigSimmo@users.noreply.github.com>

* docs: ledger re-sync sweep for PR #1142

* test(ui): guard phone reserve transition timing

* docs: record PR 1142 maintenance

* fix(docs): append PR #1142 ledger rows at end

Move the misplaced spring-physics review records out from under the
table header / mid-history so they append after the final existing row,
restoring the branch-review-ledger append-only contract.

Co-authored-by: BigSimmo <BigSimmo@users.noreply.github.com>

* docs: pin ledger placement-fix row to published HEAD

Co-authored-by: BigSimmo <BigSimmo@users.noreply.github.com>

---------

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: BigSimmo <BigSimmo@users.noreply.github.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.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