LeagueFinder
In developmentA provenance-based directory of organized adult recreation, including meeting times and organizer registration links.
At a glance
- Outcome: Builds a directory of organized adult recreation where every published fact traces to retained source bytes. Stores each field as an evidence-linked, time-bounded assertion and applies versioned publication contracts before publishing. Builds the participant-facing surface last.
- Status: Remains in development for a Portland–Vancouver pilot. Nothing is live; no serving projection, search page, or activity page exists. Parsing reads one field from one source, and no collection runs on a schedule.
- Role: Built solo.
- Stack & libraries: Uses Django 5.2 LTS, PostgreSQL/PostGIS,
httpx,lxml/selectolax, and locally stored content-addressed evidence keyed like the planned object store. GitHub Actions builds Docker images to GHCR; Celery and Redis run without any defined task. Planned permission-gated browser collection has no Playwright dependency;browser_allowedisfalseon all 83 manifests. - Limitations: Has not launched. Keeps completed source review separate from zero participant coverage. Has collected one source by code and defined, audited, or measured no coverage cell.
Directory model
Indexes identifiable organizers running joinable activities at courts, gyms, fields, rinks, and trails. Models organizers, activity series, offerings, occurrences, venues, registration windows, observations, and review decisions; the public site projects that graph. Addresses information scattered across organizer sites, half from last season, plus aggregators that do not identify stale facts or March registration closures.
Defines an activity offering as the selectable record. Shares successive seasons
through activity_series, represents dated sessions as occurrence, and nests each
selectable division as a leaf under at most one container.
Validated that pre-inventory rule against 21 hand-annotated leaf offerings from nine program pages. Found 0 of 4 single-child containers against a reopen threshold above 10%, and 10 leaves in the busiest organizer-season against a threshold above 40. Kept the rule; the pre-collection example modeled two volleyball divisions instead of the real season’s five.
Provenance and publication
Stores every field value in one append-only assertion table with a typed value,
authority class, valid period, and expiry. Adds support when the same value reappears
because the database allows one open claim per value. Preserves original observed_at
during parser replay, uses the replay clock separately, and supersedes corrections
without deleting replaced rows. Makes assertion counts track change, not collection frequency.
Rejected tables per value kind and shadow tables per entity because each would duplicate publication, conflict, expiry, reviewer explanation, and projection logic. Requires evidence for every published field. Withholds rather than cancels occurrences with expired evidence; suppresses unresolved contradictions. Separates lifecycle, registration, verification, and publication states. Leaves registration and payment on organizer sites.
Release gates
Does not detect staleness automatically. Defines no verified_at, schedules no
revisit, and measures recency absolutely, so a 2023 season page is not stale merely
because it describes 2023. Does not compare runs, leaving count drift, field drift,
and disappeared listings undetected. Requires loud staleness plus measured coverage
and freshness before expansion; no coverage cell exists.
Access review
Completed dated attempt reports for all 83 sources: 39 open for collection, 31 requiring permission, 4 manual-records routes, 8 blocked, and 1 implemented. Blocks eight because vendor terms prohibit systematic retrieval, including major league-management and event platforms used by custom-domain league sites.
Treats 39 reviews without obstacles as reviews, not collectors; code has collected one source. Limits the pilot to one metro and participants rather than operators. Requires measured coverage, freshness, and maintenance cost before expansion.