Skip to content

feat(filters): converge factsheets category filter onto SegmentedControl (PR D) - #1872

Merged
BigSimmo merged 18 commits into
mainfrom
claude/filter-factsheets-composer
Aug 13, 2026
Merged

feat(filters): converge factsheets category filter onto SegmentedControl (PR D)#1872
BigSimmo merged 18 commits into
mainfrom
claude/filter-factsheets-composer

Conversation

@BigSimmo

Copy link
Copy Markdown
Owner

Summary

  • PR D of the filter-contract rollout (docs/filter-contract.md, tracked in #170): factsheets' category dimension converges onto the shared SegmentedControl, sharing one counted option array between the desktop rail and the phone sheet.
  • Corrects a mistaken premise in the plan and in the contract doc itself. Both said factsheets' categories should be "evicted to the composer" like services' quick filters. They verifiably aren't the same shape: filterFactsheets(query, category) ANDs the two, so selecting a category narrows within the current search and preserves q — a real lens (docs/filter-contract.md section 1), not a query-replacing preset. There was nothing here that behaved like a preset to evict. The actual defect matches the original audit finding much more closely: the desktop rail rendered raw <Link> chips while the phone sheet correctly used resultFilterGroup/role="radiogroup" — the two breakpoints agreed on values but disagreed on component, exactly the "same dimension rendered three different ways" drift PR A fixed for the four lens modes. Fixed the same way: one shared, counted option array, SegmentedControl on desktop, ResultFilterSheet on phone.
  • docs/filter-contract.md section 1's own example ("Services' quick filters and factsheets' categories do not filter...") is corrected in the same commit — it was asserting something the code didn't actually do.

What changed

  • src/components/factsheets/factsheets-search-page.tsx — replaced the raw <Link> chip row (filterChips) with a useMemod, counted categoryOptions: ReadonlyArray<ResultFilterOption<string>>, derived from filterFactsheets(query) (query-matched, category-unfiltered) so every option's count answers "how many for this category, at the current query" — including options that aren't currently active, per section 3's counting rule. Desktop now renders SegmentedControl; the phone ResultFilterSheet's resultFilterGroup call and onClearAll now reuse the same categoryOptions array and a shared applyCategory handler instead of duplicating the navigation logic inline.
  • docs/filter-contract.md — corrects section 1's factsheets example, documents the actual fix in the Rollout section, and notes that services (PR C, #1866) is open on a pre-PR-B base and will need a rebase — origin/main picked up PR B (#1858, formulation) and its #309 density-gap row while PR C was in flight.
  • docs/outstanding-issues.md#170 — records factsheets' completion and the current true state of the rollout (PR A + PR B merged, PR C open needing rebase, PR D this one).
  • docs/design-system/{COMPONENTS.md,adoption-manifest.json} — regenerated for the new SegmentedControl consumer (factsheets desktop rail).
  • Tests: tests/factsheets-search-page.dom.test.tsx (new, 5 tests) — shared counted options on both breakpoints, selecting a category preserves q in the pushed href, "Clear filters" preserves q, counts read 0 under a query with zero matches rather than a stale/declared total. Updated tests/ui-smoke.spec.ts's existing factsheets E2E test: the "All" radio's accessible name is now "All (1)" (counted), not the previous plain "All".

Verification

  • npm run test — 6135 passed, 4 skipped, 0 failed
  • npm run lint / npm run typecheck — clean
  • npm run verify:pr-local — all 15 steps green, run against the final diff after formatting
  • npm run check:bundle-budget on a freshly rebuilt .next — production 1300.2 KiB gzip vs 1279.1 KiB baseline (within 10% tolerance), mockups unchanged relative to baseline
  • npm run verify:uinot run: same Playwright chromium/chrome-headless-shell revision mismatch (1234 wanted, 1194 preinstalled in this environment) as PR feat(filters): adopt the lens contract across the four one-of-N modes #1857/feat(filters): make formulation a real facet surface #1858/feat(filters): services adopts the filter contract (PR C) #1866. Delegated to CI's Production UI job.
  • Manual browser proof via a Playwright script against the running dev server: 0px horizontal overflow at 1440/800/390/320px; identical counted option arrays (All 8, Medications 3, Conditions 3, Therapies 1, Tests & procedures 1) on both the desktop rail and phone sheet; selecting a category navigates and preserves q (?q=sertraline&category=Medications); counts correctly narrow under an active query (?q=sertralineAll (1), Medications (1), everything else (0)), confirming they're live, not a declared total.
  • npm run check:outstanding-issues — 307 rows (112 open, 195 archived), no ids deleted from base

Risk and rollout

  • Risk: UI-only change to one mode's filter rail. Does not touch result-filter-control.tsx (no changes to the shared component), so no cross-mode blast radius.
  • Rollback: revert. No data migration, no stored-state change.
  • Provider or production effects: None.

Notes

  • classifyPullRequestFiles returns clinicalRisk: false, operationalRisk: false, ragRanking: false for this diff, so the Clinical Governance Preflight and RAG impact: sections are not required.
  • Services (PR C, #1866) is open on a base that predates PR B (#1858) merging — its own PR body already flagged the expected result-filter-control.tsx conflict; this PR's #170 update records the same thing from the other side.

Generated by Claude Code

…rol (PR D)
factsheets' category dimension is a real lens (filterFactsheets ANDs query
and category, preserving q), not a query-replacing preset -- an earlier
draft of docs/filter-contract.md incorrectly grouped it with services' quick
filters. Corrects that, and fixes the actual defect: the desktop rail used
raw <Link> chips while the phone sheet correctly used resultFilterGroup, so
the two breakpoints agreed on values but disagreed on component. Converges
both onto one shared, counted option array via SegmentedControl, matching
the pattern already used for differentials/medication/applications/
specifiers. Counts are derived from filterFactsheets(query), not a declared
total, so they stay honest under an active search. No scope segment (8
total factsheets).
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01K5c1ZWQUTwmhgXXdVd2wuK
@supabase

supabaseBot commented Aug 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

coderabbitaiBot commented Aug 12, 2026

Copy link
Copy Markdown
Contributor

Warning

Review limit reached

You’ve reached a temporary PR review limit under our Fair Usage Limits Policy.

Your recent review volume is higher than typical usage, so adaptive limits are currently applied.

Next review available in:13 minutes

Your organization has reached its usage spending cap. Adjust your spending cap in the billing tab.

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

Run ID: 8e7e1bbe-48ea-4a66-bfa4-d50e6b133fb9

📥 Commits

Reviewing files that changed from the base of the PR and between e68c286 and 01bd309.

📒 Files selected for processing (5)
  • docs/design-system/COMPONENTS.md
  • docs/design-system/adoption-manifest.json
  • docs/filter-contract.md
  • src/components/factsheets/factsheets-search-page.tsx
  • tests/factsheets-search-page.dom.test.tsx

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

@chatgpt-codex-connectorchatgpt-codex-connectorBot 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit:53a7f17b5e

ℹ️ 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".

Comment threadsrc/components/factsheets/factsheets-search-page.tsx Outdated
@BigSimmo

Copy link
Copy Markdown
OwnerAuthor

@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. The only repository destination is BigSimmo/Database, and the only branch destination is the pull request head branch claude/filter-factsheets-composer at starting commit c67e3e4; never publish fixes to a detached or synthetic work branch and never create a stacked pull request. Use the authenticated GitHub connector to commit each approved fix to BigSimmo/Database:claude/filter-factsheets-composer, then verify that the pull request head contains the published commit before reporting success. 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. For a fixed thread, reply with as the first line and as the second line. For a no-code disposition, use followed by . These result markers authorize the workflow to close that exact thread only after it verifies a fixed commit is the pull request head; a local-only commit is not a fix. If publication or verification fails, do not use either result marker, do not claim success, and leave the thread open with the blocker. If human input or new authorization is required, do the same. 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.

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. You're on a roll.

Reviewed commit:c67e3e4ff3

ℹ️ 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".

@BigSimmo
BigSimmo enabled auto-merge August 12, 2026 19:27
@BigSimmoChatGPT Codex Connector

Copy link
Copy Markdown
OwnerAuthor

@codex Address all currently unresolved inline review comments on this PR against the current GitHub head. Make minimal repository-grounded fixes, add/update focused regression tests, run proportionate verification, and push the fixes to this PR branch. Do not merge, close, rebase, force-push, deploy, or alter auto-merge. Please report the exact commit SHA and test results.

@chatgpt-codex-connector

Copy link
Copy Markdown

Summary

  • Derived factsheet category options from the current query matches, preventing zero-count categories from creating guaranteed empty-result navigation. A selected zero-count category remains visible and disabled so the existing constraint remains understandable. src/components/factsheets/factsheets-search-page.tsxL55-L70
  • Added regression coverage proving zero-count categories are absent from both desktop and phone controls, cannot trigger navigation, and a selected zero-count category remains visible. tests/factsheets-search-page.dom.test.tsxL58-L72tests/factsheets-search-page.dom.test.tsxL88-L95
  • Created local commit 74df3f85c58cdf0d6c0b72b68abb0eab5fd485a3 on claude/filter-factsheets-composer.
  • Publication blocker: the push could not authenticate to GitHub. The remote PR head therefore remains c67e3e4ff3227d58841b6274a7adf5171e4ccfa0, one commit behind the local branch. Because the fix was not published, I did not claim the review thread as resolved or provide fixed-head markers. A PR could not be created or updated without an authenticated GitHub connector/CLI.

Testing

  • npm run test -- tests/factsheets-search-page.dom.test.tsx — 1 test file passed; 6 tests passed.
  • npm run typecheck — completed successfully.
  • npm run format — completed successfully before committing.
  • git diff --check — no whitespace errors.
  • ⚠️npm run test:focused -- tests/factsheets-search-page.dom.test.tsx — repository selector declined focused execution because the original PR already changes test/configuration paths; the exact test file was then run successfully through npm run test -- tests/factsheets-search-page.dom.test.tsx.
  • ⚠️git push origin HEAD:claude/filter-factsheets-composer — blocked by unavailable GitHub credentials: fatal: could not read Username for 'https://github.com': No such device or address.

View task →

Merge the latest main branch into PR #1872 while preserving current shared files and the PR's design-system metadata. Derive category choices from query matches, retain only an already-selected zero-count category as an explained inert state, and add focused DOM regression coverage.
@BigSimmoChatGPT Codex Connector

Copy link
Copy Markdown
OwnerAuthor

@claude Fix the currently unresolved review thread on this PR at the current GitHub head. Category filter options must not allow selecting an unrelated zero-count category under the current query. Derive available options from the query-matched result set or disable zero-count options while keeping any already-selected zero state reachable. Add a regression proving an unrelated zero-count category cannot be activated. Make the smallest repository-consistent fix, run focused tests/format/typecheck as proportionate, push only to this PR branch, and report exact SHA/tests. Do not merge, close, rebase, force-push, deploy, or alter auto-merge.

@github-actions

Copy link
Copy Markdown
Contributor

Hi @BigSimmo — thanks for the @claude mention.

Open this in Claude Code on the web to continue here: https://claude.ai/code

Context: BigSimmo/Database · #1872

Automated backlink from the Claude backlink workflow. Claude Code can pick up the mention and push a scoped fix to the branch.

@claude

claudeBot commented Aug 12, 2026

Copy link
Copy Markdown
Contributor

Claude encountered an error after 2s —— View job


I'll analyze this and get back to you.

Restore repository-standard trailing newlines in the focused factsheets source and DOM regression test.

@BigSimmoBigSimmo left a comment

Copy link
Copy Markdown
OwnerAuthor

Choose a reason for hiding this comment

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

Final Codex review-and-fix summary

  • Final head: eaee186507c458c960275e71de54beecaef26801; base: b850a58166b68fa9cdd9ff6248c5e93e34c87f73. The branch is 5 commits ahead / 0 behind and GitHub reports it mergeable. The final head is a clean merge of current main onto the reviewed repair and has the same tree as the preceding reviewed head, so no additional source delta was introduced by the sync. Auto-merge remains armed and was not altered.
  • Fixed/dispositioned: the reported P2 zero-count-category defect is fixed. Factsheet category choices are derived from the current query matches; unrelated zero-count categories are omitted; an already-selected zero-count category remains visible only as a disabled, explained dead end; navigation is guarded against disabled/absent options. Focused DOM tests cover desktop and phone behaviour, query preservation, dead-end inertness, and zero-result escape behaviour.
  • Review threads: the single actionable Codex thread was replied to with the current fixed head and resolved. No unresolved actionable review thread remains.
  • Independent adversarial pass: I performed a distinct manual pass because a separate review subagent/configured review bot was not available in this environment. I checked the changed component against SegmentedControl and ResultFilterSheet contracts, query/category semantics, disabled-state behaviour, URL preservation, empty states, accessibility naming, and the focused regression tests. No additional high-confidence PR-introduced P0/P1/P2 defect was found. Highest residual risk is visual/browser interaction coverage while Production UI is still pending.
  • Verification: the PR already records npm run test (6135 passed, 4 skipped), lint, typecheck, verify:pr-local, bundle budget, outstanding-issues integrity, and manual browser checks at 1440/800/390/320. The final merge-only head preserves the exact reviewed tree. I did not run provider-backed/live/production tests or Lighthouse.
  • Exact-head required CI: CI run #10138 is currently in progress on eaee1865…; Production UI critical is queued, Build/Safety/Static checks are in progress, so the required aggregate is not yet green and remains pending. Secret Scan on the exact final head is successful. SAST is still in progress. These pending states remain blockers until their required aggregate settles successfully.
  • Earlier Secret Scan failure on the superseded head was infrastructure-related at the Gitleaks install step and skipped the actual scan. I reran that failed job; the new exact final head has a successful Secret Scan.
  • Advisory/external: Supabase preview was skipped because there are no Supabase changes. CodeRabbit hit its review usage/spending limit, so it did not provide a fresh independent review. No code change was made for either advisory condition.
  • Ledger: a review ledger commit already exists in this PR history. I did not create a ledger-only final tip, consistent with repository policy. The required base sync was already performed as the final merge commit; its tree introduced no source changes.
  • No permission blocker prevented review-thread resolution or CI retry. Remaining risk is limited to pending exact-head CI/UI checks.

The PR was not merged. Final merge is left to the user.

@BigSimmo
BigSimmo disabled auto-merge August 12, 2026 21:00
@github-actions

Copy link
Copy Markdown
Contributor

CI triage

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

  • Unit coverageneeds investigation: inspect the failing step and uploaded diagnostics; rerun only after classifying the cause.
  • Static PR checksneeds 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 #10239 (cancelled).

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

@BigSimmo
BigSimmo enabled auto-merge August 12, 2026 21:39
@BigSimmo
BigSimmo disabled auto-merge August 12, 2026 21:51
@BigSimmo
BigSimmo enabled auto-merge August 12, 2026 21:54
@BigSimmo
BigSimmo disabled auto-merge August 12, 2026 22:05
@BigSimmo
BigSimmo enabled auto-merge (squash) August 12, 2026 22:08
@BigSimmo
BigSimmo disabled auto-merge August 12, 2026 22:48
@BigSimmo
BigSimmo enabled auto-merge (squash) August 12, 2026 23:07
@BigSimmo
BigSimmo disabled auto-merge August 12, 2026 23:17
@BigSimmo
BigSimmo enabled auto-merge August 12, 2026 23:38
@BigSimmo
BigSimmo disabled auto-merge August 12, 2026 23:50
@BigSimmo
BigSimmo enabled auto-merge August 13, 2026 00:07
@BigSimmo
BigSimmo merged commit 179ef20 into mainAug 13, 2026
27 of 28 checks passed
@BigSimmo
BigSimmo deleted the claude/filter-factsheets-composer branch August 13, 2026 00:15
Sign up for freeto 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

@BigSimmo@claude