SportMatch — Find Your Sports Partner in Ho Chi Minh City
A geo-aware listing platform for badminton and pickleball players to find teammates and join games — featuring a hybrid data pipeline (manual posts + LLM-extracted from Vietnamese social posts), PostGIS spatial search, and a React map interface. Built solo in one month.
Challenge
Building a multi-service pipeline in Go + Rails that reliably extracts structured match listings from unstructured Vietnamese social media text, geocodes short Vietnamese addresses to GPS coordinates, and serves them on a real-time map — all within a solo 1-month build with no prior Go production experience.
Solution
Designed a Go scraper that feeds raw Facebook post text to an LLM constrained to a strict JSON schema; validated every output in Go before HMAC-signed ingest to Rails. Used PostGIS `geography(Point,4326)` with a geocoding cache table to make radius queries fast and API costs predictable. Built the map UI as a React island mounted inside the Rails layout (esbuild + jsbundling-rails) with Google Maps clustering by sport.
Impact Metrics
Comparison before and after implementation.
Listing Ingestion
Manual only
→
Automated Go + LLM pipeline + manual hybrid
Geocoding Cost
1 API call per listing
→
>80% cache hit after week 1
Map Query
N/A
→
PostGIS ST_DWithin radius search
Key Achievements
LLM Extraction Pipeline
Go service converts raw Vietnamese Facebook posts to validated structured JSON using an LLM constrained to a strict schema — including skill level slug mapping and timezone-aware UTC time resolution.
PostGIS Spatial Search
Radius-based listing discovery using geography(Point,4326) and a GIST index — players find games within X metres of their location in a single SQL query.
HMAC-Secured Ingest
Cryptographically signed ingest endpoint (shared HMAC secret) ensures only the trusted Go scraper can push listings into Rails — no public API key to rotate.
Geocoding Cache
PostGIS-backed geocoding cache eliminates redundant Google API calls for popular courts — the same court address is geocoded once and reused across all future listings.