Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 13 additions & 5 deletions src/app/actions/issues.ts
Original file line number Diff line number Diff line change
Expand Up @@ -130,19 +130,27 @@ export async function getIssuesPage(filters: IssueFilter): Promise<Result<Issues
const from = (page - 1) * PAGE_SIZE;
const to = from + PAGE_SIZE - 1;

let query = service
.from('issues')
const isSearch = !!filters.search?.trim();

// Cast to any to avoid complex union type builder errors between rpc and from
let query: any = isSearch
? service.rpc('search_issues', { search_query: filters.search!.trim() })
: service.from('issues');

query = query
.select(
'id, repo_full_name, github_issue_number, title, difficulty, xp_reward, labels, state, url, fetched_at',
{ count: 'exact' },
)
.eq('state', filters.state ?? 'open')
.order('fetched_at', { ascending: false })
.range(from, to);

if (filters.search?.trim()) {
query = query.ilike('title', `%${filters.search.trim()}%`);
// When searching via RPC, results are naturally ordered by rank (from the SQL function).
// Otherwise, we order by fetched_at descending.
if (!isSearch) {
query = query.order('fetched_at', { ascending: false });
}

if (filters.difficulty) {
query = query.eq('difficulty', filters.difficulty);
}
Expand Down
17 changes: 17 additions & 0 deletions supabase/migrations/0012_issues_fts.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
-- Migration to add FTS column, index, and RPC for searching and ranking
ALTER TABLE issues ADD COLUMN fts tsvector
GENERATED ALWAYS AS (to_tsvector('english', coalesce(title, '') || ' ' || coalesce(body_excerpt, ''))) STORED;

CREATE INDEX issues_fts_idx ON issues USING GIN(fts);

-- Function to allow PostgREST to search issues and sort by ts_rank
CREATE OR REPLACE FUNCTION search_issues(search_query text)
RETURNS SETOF issues
LANGUAGE sql
STABLE
AS $$
SELECT *
FROM issues
WHERE fts @@ plainto_tsquery('english', search_query)
ORDER BY ts_rank(fts, plainto_tsquery('english', search_query)) DESC;
$$;
Loading