feat(marketplace): advanced plugin search with FTS, filters, and pagination#83
Merged
feat(marketplace): advanced plugin search with FTS, filters, and pagination#83
Conversation
…nation - Add search utility library (lib/search.ts) with FTS query builder, sanitization, weighted ranking, fallback ILIKE, and param validation - Enhance /api/search route with type/category/rating filters, pagination (page + limit params), and X-Response-Time header for perf monitoring - Extract FilterPanel component for category, type, and trust tier facets - Add SearchBar component with debounced input, suggestion dropdown, keyboard navigation (↑↓ arrows, Enter, Escape), and ARIA attributes - Refactor PluginsPage to use FilterPanel instead of inline sidebar markup Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Add runtime allowlist validation for `scope` and `type` params (H1) - Stop forwarding Supabase error.message to client; log server-side (H2) - Cap query string at 200 chars before tokenization (M1) - Parse and validate `rating` param as float 1–5 at handler boundary (M2) - Fix profile `hasMore`: fetch limit+1 rows and slice, replacing the unreliable `length === limit` heuristic (L4) - Fix `filterByRating` undefined check: use explicit `=== undefined` instead of falsy `!` (components with ratings summing to 0 no longer misclassified as unrated) - Extract `jsonResponse` helper to eliminate duplicate X-Response-Time header computation across profile FTS + fallback paths - Extract `applyRatingFilter` helper to remove duplicated post-filter logic in FTS and ILIKE paths - Remove placeholder Rating/Token Cost/Platform filter sections from FilterPanel — non-functional UI ships nothing to users until the backing API support is wired in Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
dd0efda to
5591a44
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Upgrades the marketplace plugin search from a basic full-text query to a full-featured discovery experience. Adds weighted FTS ranking, multi-facet filtering (type, category, trust tier, rating), pagination, a reusable SearchBar with suggestions, and a FilterPanel component — all wired into the existing
/api/searchroute and plugins page.Changes
lib/search.ts— New search utility library:sanitizeSearchQuery,searchComponents,searchComponentsFallback,validateSearchParams. Handles weighted FTS, ILIKE fallback, pagination, and filter composition.app/api/search/route.ts— Enhanced route:scopeparam (component/profile),type/category/ratingfilters,page/limitpagination,X-Response-Timeheader, structuredpaginationobject in response.app/components/SearchBar.tsx— Reusable client component: debounced input (300 ms default), suggestion dropdown, keyboard navigation (↑↓ Enter Escape), ARIA attributes, loading spinner.app/components/FilterPanel.tsx— Sidebar filter component: category, component type, and trust tier facets as server-rendered<Link>navigation (no client JS required).app/plugins/page.tsx— Replaces inline sidebar markup with<FilterPanel />.app/components/__tests__/SearchBar.test.ts— Smoke test confirming SearchBar is importable and is a function.Test Plan
vitest run— 5/5)/plugins, search for a term, verify suggestions appear with debounce?page=2Notes
FilterPaneluses<Link>for all filter toggles — zero client JS, works with Next.js prefetching.searchComponentsuses a post-query join against theratingstable. Ifaverage_ratingis ever denormalized ontocomponents, the route-levelfilterByRatinghelper can be removed in favor of the.gte()filter already inlib/search.ts.apps/marketplace/apps/marketplace/...) was removed; test is now at the correct path with explicit vitest imports.