BikeControl (SwiftControl)
Use Zwift Click, Zwift Play, Shimano Di2, or any Bluetooth controller with MyWhoosh, Rouvy, Zwift, and more. Free to try on iOS, Android, Windows, and macOS.
Find where to play racket sports in California: tennis, pickleball, padel, beach tennis and more, with honest notes on how complete the data is.
Sports & fitnessPython · HTMLGitHub @abovOnlineOwner unconfirmed
Have you tried it? One tap is enough. No sign-in needed.
No updates detected yet. GitHub releases will appear here.
Owners of public repositories under a personal GitHub account can sign in to verify ownership and manage the introduction themselves. No administrator approval is needed.
Sign in, generate a verification file, and commit it to this repository’s default branch within 30 minutes. Files on other branches or forks do not count. Then check the file below to manage the project without administrator approval. Keep the file to retain your access.
If needed, you will go to sign-in. After signing in, return here and press your chosen verification button again.
Run /nomorevibe verify in your project folder to verify ownership and manage the introduction yourself.
Verify in one minuteAsk about other verification options
California racket-sports data platform: dbt + Snowflake + DuckDB, built as a lead data engineering portfolio project
Taken from the repository README
Loading the full README. The saved excerpt is shown below.
Find where to play, who to play with, and where to watch, for every racket sport in California.
Open the live map: 9,935 venues across California, with an honest panel showing which of the 75 sports have no data yet, and a Watch a match mode for events you can go and see.
CourtConnect is a discovery tool: it helps you find where to play or watch, then sends you to the venue's or organizer's own site. It doesn't sell tickets or take bookings.Read the full README ↗Find where to play, who to play with, and where to watch, for every racket sport in California and Nevada ("CalNeva", ADR 0014).
Open the live map · Data model and lineage (dbt docs)
| Play | Watch |
|---|---|
CourtConnect is a discovery tool for all racket sports: it finds where to play or watch, then sends you to the venue's or organizer's own site. It sells no tickets and takes no bookings or payments.
Tennis, padel, pickleball and squash and dozens of lesser-known and up-and-coming racket sports are booming, but information about where to play is scattered and messy. Court finders each cover one sport, or only places you can book. This project is one free map of all of them, from free park courts and hitting walls to private clubs. It collects the data, cleans it, checks it, and says honestly how complete it is.
A solo, end-to-end data product: Python ingestion, a tested dbt warehouse on DuckDB, a static map, and a gated, agent-assisted refresh. No server, $0 hosting.
llms.txt (below).Not offered, on purpose: bookings, payments, accounts, rankings or paid placement (value proposition, product brief).
Live numbers (2026-10-23): 10,277 venues (CA 9,732, NV 545), 1,650 confirmed, 39 of 82 sports with at least one venue, 80 watch events, 21 social series, 923 hitting walls, 276 link-outs. By sport: docs/coverage_snapshot.md.
verified_on date and evidence note; popups show rules and access as the venue wrote them.docs/market_insights.md).make quality scorecard with freshness SLAs (docs/data_quality.md).make check-websites), not trusted.Rule: a model may rank or suggest; it never writes to the map. Anything inferred is labelled. Full plan: docs/ml_plan.md.
Sources (all open or public): OpenStreetMap (written "OSM" in the docs; same thing, the community-edited open map that knows where courts are), Overture Maps (an open dataset of places and addresses that knows business names), US Census boundaries, and hand-checked seed files that each carry evidence.
| Stage | Where | Gate |
|---|---|---|
| Ingest | ingestion/ | load_raw.py refuses to shrink a table by more than 10% |
| Transform | transform/ | dbt tests, hand-labelled gold set for the place-to-court match |
| Ship | app/, .github/workflows/ | CI on a fixture dataset, export freshness, scorecard no-regression |
Scale (measured 2026-10-28, Overture 2026-10-21.0): the extracts query the 88M-place and 475M-address Overture parquet on S3 in place and fetch about 2% of those themes (743 MB of 39.6 GB); the data we keep is small. Method and caveats: planet-scale benchmark.
No server or API: the map reads one exported file, app/data/venues.json. More: architecture, tools and strategies, case study.
approved label, a GitHub Action opens a PR that edits one seed row, CI gates it, then merge (ADR 0008).make sync-reports imports it as a seed edit (plan, CONTRIBUTING.md).Skills shown: SQL and dbt modelling with tests, entity resolution across messy sources, data-quality scorecards and freshness SLAs, CI/CD gates and GitHub Actions automation, small ML with leave-one-out validation, guard-railed LLM and agent workflows, written decision records (ADRs), and scoping work by cost and risk (privacy, terms of use, honesty).
The map reads one public file, app/data/venues.json (about 2.4 MB, rebuilt about twice a month). Keys are single letters, so read the data dictionary first; app/llms.txt is the short guide for AI tools. Both are published next to the map. A read-only MCP server over the file is proposed, not built (ADR 0023).
NOTICE.md).pip install -r requirements.txt
make demo # extract -> load -> build -> test (extract takes ~15 min)
make app-data # export the map data
make app # open http://localhost:8765
make build runs the dbt seeds, models and tests; it is the main check after any change to transform/. A new checkout without a database: make fresh-db (about a minute; loads the shared raw CSVs and runs the full build). On Windows, view_db.bat opens courtconnect.duckdb read-only in the DuckDB UI (close it before running dbt).
Data lives in seeds under transform/seeds/; edit them, then make build and make app-data.
| To change | Edit |
|---|---|
| The list of sports | The Google Sheet, then make sync-sports (never hand-edit all_racquet.csv) |
| Add a venue no dataset knows | manual_venues.csv |
| Add a link-out (open play, lessons, ...) | venue_actions.csv |
| Add an event to watch | watch_events.csv |
| Confirm or reject an uncertain match | place_sport_overrides.csv |
| Mark an Overture place as closed | closed_places.csv (with evidence) |
| Correct a court count for one sport at a venue | venue_court_counts.csv (with evidence; add the missing sport via manual_venues.csv) |
Details: docs/data_guide.md. Twice-monthly refresh routine: docs/monthly_refresh.md. Decisions: short records in docs/decisions/ (ADRs 0001 to 0026; 0001 is superseded by 0018; 0023 to 0026 are proposed).
NOTICE.md.ingestion/regions.json; see the fork guide.Done:
docs/sport_discovery_plan.md)docs/padel_scan.md)llms.txt and a data dictionary, extra analytics events, a draft-mode refresh agentNext, in order (details in CLAUDE.md "Open, in order"):
docs/feedback_round.md), then rank what to build with the findingsdocs/ml_plan.md)docs/sessions/2026-10-23-load-time.md)