
Real Estate Investor Dashboard
Playwright scraper, Supabase, and a Next.js dashboard that replaced 88 tabs and a spreadsheet with one filterable view.
Real estate investor specializing in foreclosures
Lean acquisition operation targeting sheriff sale properties before they hit the open market. A VA was manually checking 88 county sites and logging results in a spreadsheet. The process was inconsistent, error-prone, and hard to scale.
88 individual county sites
Three distinct patterns: realforeclose.com subdomains, county portals, and JavaScript-rendered sites
VA spent 3 to 4 hours per day clicking through county sites, still missed listings
Playwright scraper + Supabase database + Next.js dashboard
88-county config file drives all scrape targets, one row per county, no code changes to add counties
Three scraper strategies unified behind a single orchestration loop: httpx + BeautifulSoup for realforeclose.com, custom selectors for county portals, Playwright for JS-gated sites
Listings upsert on (county_slug, case_number), with scrape_runs logged per county for health monitoring
Auto-enrichment runs after each scrape: geocoding, Street View, Zillow via Apify, with Firecrawl as URL discovery fallback
Next.js dashboard reads from Supabase: listings, county health, saved lists, and batch enrichment retry from the error log
Modal runs the scraper and enrichment API. Listings land in Supabase. The Next.js dashboard is read-only against the database.
Modal
Scraper runtime and FastAPI enrichment endpoint
Playwright
Headless Chromium for JS-rendered county sites
httpx + BeautifulSoup
Static HTML county sites and realforeclose.com
Supabase
PostgreSQL with RLS, listings, counties, scrape_runs, enrichment_errors
Next.js
App Router, TypeScript, Tailwind, shadcn/ui
Google Maps
Geocoding and Street View
Apify
Zillow property data actor
Firecrawl
Zillow URL discovery fallback
79 of 88 counties in production (89.8%), login-walled counties auto-flagged inactive
Daily automated scrape replaces manual VA county checks
One dashboard to filter listings by county, sale date, and bid amount instead of jumping between tabs and spreadsheets
Property enrichment at scale without per-listing Zillow lookups