Quick Start: Apply Enhanced Filtering Migration¶
Prerequisites¶
You need Supabase credentials to apply this migration. If you don't have a Supabase project yet:
- Create a Supabase project at https://supabase.com/dashboard
- Get your credentials from: Project Settings → API
You'll need:
- SUPABASE_URL (e.g., https://abcdefgh.supabase.co)
- SUPABASE_SERVICE_ROLE_KEY (starts with eyJ...)
- DATABASE_URL (optional, for direct PostgreSQL access)
Option 1: Automated Setup (Recommended)¶
Step 1: Configure Environment¶
# Copy example file
cp .env.example .env
# Edit .env and set your credentials
nano .env # or use your preferred editor
Required variables in .env:
SUPABASE_URL=https://your-project.supabase.co
SUPABASE_SERVICE_ROLE_KEY=eyJhbGciOiJI...
DATABASE_URL=postgresql://postgres:[PASSWORD]@db.your-project.supabase.co:5432/postgres
Step 2: Run Setup Script¶
This script will: - ✓ Check your environment configuration - ✓ Test database connection - ✓ Apply the migration - ✓ Verify the migration succeeded - ✓ Run automated tests
Option 2: Manual Migration¶
Step 1: Configure Environment¶
export SUPABASE_URL="https://your-project.supabase.co"
export SUPABASE_SERVICE_ROLE_KEY="your-service-role-key"
export DATABASE_URL="postgresql://postgres:[PASSWORD]@db.your-project.supabase.co:5432/postgres"
Step 2: Apply Migration via psql¶
Or via Supabase CLI:
Step 3: Verify Migration¶
-- Check indexes were created
SELECT indexname FROM pg_indexes
WHERE tablename = 'judgments'
AND indexname LIKE 'idx_judgments_%'
ORDER BY indexname;
-- Check functions exist
\df public.search_judgments_hybrid
\df public.get_judgment_facets
-- Test search function
SELECT id, title, combined_score
FROM search_judgments_hybrid(
search_text := 'test',
search_language := 'polish',
result_limit := 5
);
-- Test facets function
SELECT facet_type, facet_value, facet_count
FROM get_judgment_facets()
LIMIT 10;
Step 4: Run Verification Script¶
# Install dependencies
pip install supabase loguru requests
# Run verification
python3 scripts/verify_filtering_implementation.py
Option 3: Docker-based Migration¶
If you're using Docker:
Step 1: Ensure .env file exists¶
Step 2: Run migration via Docker¶
# Start database service
docker compose up -d postgres # if using local postgres
# Or connect to Supabase and run migration
docker compose run --rm backend bash -c "
psql \$DATABASE_URL -f /app/../supabase/migrations/20260209000002_extend_judgments_filtering.sql
"
Verification Checklist¶
After applying the migration, verify:
-
7 new indexes created:
Expected: 7 -
Polish/English FTS indexes:
Expected: 2 -
Functions exist:
Expected: 2 -
Test search works:
Expected: No errors (may return 0 or more results) -
Test facets works:
Expected: Number of facet rows (0+ depending on data)
Troubleshooting¶
Error: "relation 'judgments' does not exist"¶
Solution: Run the base migration first:
Error: "function already exists"¶
Solution: Drop existing functions and reapply:
psql $DATABASE_URL -c "DROP FUNCTION IF EXISTS public.search_judgments_hybrid CASCADE"
psql $DATABASE_URL -c "DROP FUNCTION IF EXISTS public.get_judgment_facets CASCADE"
psql $DATABASE_URL -f supabase/migrations/20260209000002_extend_judgments_filtering.sql
Error: "index already exists"¶
Solution: Migration uses CREATE INDEX IF NOT EXISTS, so this shouldn't happen. If it does:
# Drop and recreate
psql $DATABASE_URL -c "DROP INDEX IF EXISTS public.idx_judgments_case_type"
# Then rerun migration
Connection Issues¶
Check 1: Verify DATABASE_URL format
echo $DATABASE_URL
# Should be: postgresql://postgres:[PASSWORD]@db.project.supabase.co:5432/postgres
Check 2: Test connection
Check 3: Check firewall/network
What Gets Created¶
Indexes (9 total):¶
idx_judgments_case_type- B-tree, partialidx_judgments_decision_type- B-tree, partialidx_judgments_outcome- B-tree, partialidx_judgments_court_level- B-tree, partialidx_judgments_cited_legislation- GIN arrayidx_judgments_jurisdiction_court_level_date- B-tree compositeidx_judgments_case_type_date- B-tree compositeidx_judgments_full_text_search_pl- GIN, Polish stemmingidx_judgments_full_text_search_en- GIN, English stemming
Functions (2 total):¶
search_judgments_hybrid()- Hybrid search with 11 filtersget_judgment_facets()- Facet aggregation
Storage Impact:¶
- ~200-300MB additional space (for 100k judgments)
- ~15-20% increase in total database size
Next Steps¶
After successful migration:
-
Deploy Backend:
-
Test API Endpoints:
-
Update Frontend (optional):
- Modify search store to pass filters to backend
- Remove client-side filtering
- Use facets for dynamic filter UI
Support¶
- Documentation:
FILTERING_IMPLEMENTATION_SUMMARY.md - Detailed Checklist:
MIGRATION_CHECKLIST.md - Verification Script:
scripts/verify_filtering_implementation.py - Setup Script:
scripts/setup_and_migrate.sh
Rollback¶
If you need to rollback:
# Drop new functions
psql $DATABASE_URL -c "DROP FUNCTION IF EXISTS public.search_judgments_hybrid CASCADE"
psql $DATABASE_URL -c "DROP FUNCTION IF EXISTS public.get_judgment_facets CASCADE"
# Drop new indexes
psql $DATABASE_URL -c "
DROP INDEX IF EXISTS public.idx_judgments_case_type;
DROP INDEX IF EXISTS public.idx_judgments_decision_type;
DROP INDEX IF EXISTS public.idx_judgments_outcome;
DROP INDEX IF EXISTS public.idx_judgments_court_level;
DROP INDEX IF EXISTS public.idx_judgments_cited_legislation;
DROP INDEX IF EXISTS public.idx_judgments_jurisdiction_court_level_date;
DROP INDEX IF EXISTS public.idx_judgments_case_type_date;
DROP INDEX IF EXISTS public.idx_judgments_full_text_search_pl;
DROP INDEX IF EXISTS public.idx_judgments_full_text_search_en;
"
# Restore old English-only FTS index
psql $DATABASE_URL -c "
CREATE INDEX idx_judgments_full_text_search ON public.judgments
USING gin(to_tsvector('english', coalesce(title, '') || ' ' || coalesce(summary, '') || ' ' || coalesce(full_text, '')));
"
Ready to migrate? Choose your preferred option above and follow the steps!