Techoship

Hospitality discovery · 2025

Local Discovery Platform

Two problems that are the same problem: nobody can find anywhere good tonight, and the bar three streets away is empty.

  • Flutter
  • NestJS
  • Dart
  • Mobile App Development
  • Google Maps API
Local Discovery Platform — Hospitality discovery

Two problems that are the same problem: nobody can find anywhere good tonight, and the bar three streets away is empty. People browse what is actually running now — live happy hours, unexpired deals, tonight's events — and search by feeling rather than cuisine. The best of it comes from other people: anyone can build a guide and others follow them for it. Venues are already listed, so the map is useful on day one. An owner claims theirs, a human approves it, and from then on they run their own hours, deals, events and ad spend. Roughly 120,000 lines across four repositories.

Local Discovery Platform — A two-sided product

A two-sided product

One side is discovery: what is on near you right now, filtered by mood rather than category — cosy, rooftop, late, dog friendly, date night.

The other is a self-service product for venues: opening hours, happy hours by day, deals with end dates, events, tags and photos, plus the analytics to see whether any of it worked.

Both live in the same Flutter app across 56 screens, with the roles separated internally and a switch-account screen between them. Behind both sits a Flutter Web console of 69,000 lines — a public landing page, and an operations console for the team.

Local Discovery Platform — The social layer is the reason to open it

The social layer is the reason to open it

A list of nearby restaurants is a utility. You open it when you are hungry and forget it the rest of the time — which is the retention problem every local-discovery product actually has.

People trust a list a person made. Anyone can build a guide — best rooftops, cheap eats near the university, where to take your parents — and others follow them for it. Scouts have profiles with followers, saved places and their published guides, and a guide surfaces on the venue page too, so a place gets discovered through somebody's recommendation rather than only through search.

Search runs on vibes alongside category and distance, because nobody thinks "I want Italian" — they think "somewhere quiet" or "somewhere still open".

Local Discovery Platform — Claim, don't create

Claim, don't create

Most two-sided products launch empty and wait for supply. Here venues exist as claimable listings before any owner signs up, so the map is useful on launch day and the owner's job is to prove a place is theirs rather than type it in from scratch.

An owner searches, claims, and the request sits pending until a human approves or denies it — with a notification either way, and every decision written to an audit trail naming who did it and when. The console can also create a venue by hand when an owner genuinely cannot find theirs.

Then an eight-step guided setup covers country and region, business name, location on a map, activities and type, price range, opening hours, description and photos. Google Places autocomplete, place details and reverse geocoding handle addressing, so a venue lands where it actually is.

Local Discovery Platform — What the venue gets back

What the venue gets back

A venue that cannot tell whether the app brought anyone in will stop maintaining its page within a month. So the business side is built around measurement — business views and event views counted separately, likes and clicks apart from views, all scoped daily, weekly, monthly or annually.

The gap between the numbers is the useful part. Views without clicks means the page is the problem. No views at all means the listing is.

On top of that sits a promotion product: a venue sets a daily ad spend and sees ad clicks and total spend against it, with event promotion tracked as its own separate budget. Stripe handles the charging.

Local Discovery Platform — Automation, and a second backend migration

Automation, and a second backend migration

Seven scheduled jobs keep the platform from going quiet: a weekly digest for people, weekly analytics and a monthly summary for venues, event reminders, nudges for half-finished profiles, email verification follow-ups and push-token cleanup. Each run is recorded, the endpoint sits behind its own guard, and any job can be triggered by hand.

The original backend was Python with APScheduler — 36 files and 5,764 lines over six months. It is retired. The live API is NestJS with its own scheduler, sixteen controllers including a dedicated account-deletion endpoint, still gaining features.

That is the second time I have moved a live product from a Python backend to NestJS — the other was a staffing marketplace carrying payments. Two different products, both with real users, moved between stacks without interrupting either. Happy to talk through how those migrations were sequenced.