Project File / 02 / Local utility
The Okanagan had plenty to do. Finding it was the problem.
A weekly local-events guide built around one opinionated answer to a messy question: what should we actually do tonight?

The Okanagan does not have an events shortage. It has an events-information problem.
The good listings are spread across tourism pages, venue calendars, social posts, ticket platforms, and sites that look like they were last redesigned during the Vancouver Olympics. Search hard enough and you can find something. The point of a local guide is that you should not have to.

02.01
A week is a product shape
Most event products begin with a database and ask the user to filter it. OKLetsGo begins with Monday and ends with Sunday. Each day has three practical modes: a night out, a grown-up plan, and something family-friendly.
That format forces curation. It cannot hide weak recommendations behind infinite scroll. Every slot has to earn its place, and an empty slot is more honest than filler.
Editorial ruleThe job is not to contain every event. The job is to make a useful week.
02.02
The glamorous part is a dedupe function
Under the bright cards is the unphotogenic work that makes local data usable. Source fetchers pull raw listings. The pipeline normalizes them into one event shape, scores confidence, detects likely duplicates, enriches venues and images, then sends candidates into review.
The admin is its own product: candidate queue, asset review, source controls, manual entry, staged approvals, publish batches, rollback, newsletter drafts, and an internal archive of previous weeks.
A Discord button can send a scraped event into the ingestion endpoint. That sounds like a tiny convenience until you have reviewed the same event in three different formats before coffee.
02.03
Automation still needs an editor
The pipeline can collect and clean. It cannot decide whether a technically valid listing is worth someone giving up a Friday night. That remains a taste problem.
The system uses two review stages around asset generation before a batch can publish. The newsletter is generated from the same approved week, which means the website and email do not quietly disagree about reality.
02.04
Then the database sent a bill-shaped error
During the writing of this case study, Neon exhausted its data-transfer quota and the public homepage returned a 500. That is the sort of detail polished case studies tend to edit out. It is also the useful part.
A public guide should not disappear because its database is having a financial boundary. The fix was a graceful failure path: when database initialization fails, serve the bundled seed week instead of an application error. The guide remains useful, and the paid infrastructure decision can happen separately.
Failure modeDatabase unavailable now means a usable static week, not a white server-error page.
What survived
Three things I would carry into the next build
- Curation is a product decision, not missing automation.
- Local data gets useful after normalization, not collection.
- If the database is optional to the reader, failure should be optional too.