Skip to content

feat(marketplace): advanced plugin search with FTS, filters, and pagination#83

Merged
siracusa5 merged 2 commits intomainfrom
feat/marketplace-advanced-search
Apr 6, 2026
Merged

feat(marketplace): advanced plugin search with FTS, filters, and pagination#83
siracusa5 merged 2 commits intomainfrom
feat/marketplace-advanced-search

Conversation

@siracusa5
Copy link
Copy Markdown
Collaborator

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/search route 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: scope param (component/profile), type/category/rating filters, page/limit pagination, X-Response-Time header, structured pagination object 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

  • Local tests pass (vitest run — 5/5)
  • CI checks pass
  • Manual: load /plugins, search for a term, verify suggestions appear with debounce
  • Manual: apply type/category/trust filter via sidebar, verify URL params update and results narrow
  • Manual: verify pagination — scroll past 20 results or pass ?page=2

Notes

  • FilterPanel uses <Link> for all filter toggles — zero client JS, works with Next.js prefetching.
  • Rating filter in searchComponents uses a post-query join against the ratings table. If average_rating is ever denormalized onto components, the route-level filterByRating helper can be removed in favor of the .gte() filter already in lib/search.ts.
  • The misplaced test from the auto-claude run (apps/marketplace/apps/marketplace/...) was removed; test is now at the correct path with explicit vitest imports.

@siracusa5 siracusa5 added the enhancement New feature or request label Apr 6, 2026
siracusa5 and others added 2 commits April 6, 2026 15:15
…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>
@siracusa5 siracusa5 force-pushed the feat/marketplace-advanced-search branch from dd0efda to 5591a44 Compare April 6, 2026 19:15
@siracusa5 siracusa5 merged commit 018a4aa into main Apr 6, 2026
17 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant