← Projects

A.03 / Project — AI-Assisted Development

Riviera Locals

An idea that started as a UX bootcamp prototype years ago, finally turned into a real product.

April 2026 · Live View live site ↗
Riviera Locals homepage
01

Where it came from

Moving around means starting from zero each time. New city, new country: you need an accountant, a lawyer, maybe a doctor, someone to fix the washing machine. Finding them is harder than it sounds, especially when you don't speak the language well and don't know who to trust.

I've been through this more than once. The need for something like Riviera Locals never felt abstract. It felt personal.

The fun part: I'd designed this once before. Years earlier, during my UX bootcamp, one of my projects was Nuutown: a service directory and booking platform for expats to find what they need in a new city. The research was solid. The prototype looked good. I got good feedback. And then it sat there, because the gap between a prototype and a working product was still too large to close without engineering support.

Riviera Locals is Nuutown, finally built. Same problem, same target audience, years later, with tools that let me ship it.

02

Codex for code, Claude for words

The stack: Supabase for the backend, Astro for the frontend. I used Codex for the coding work this time, keeping Claude for writing and copywriting. Same general approach as the boulder gym directory, but with more confidence in the tools and more attention paid to design. Previous projects had a "functional first, pretty later" quality. This one I cared about how it looked from the start.

The MVP includes filters by city and category, individual business profile pages, and a guide section built to rank for local search terms. The kind of thing that would have taken months a few years ago.

03

Gathering the data

The data question was where this got interesting. I'm already on the Riviera, which was a real advantage. I spent time in regional Facebook groups where expats ask for recommendations: who to call for tax advice, which English-speaking doctor people trust, which plumber shows up. I saved those posts, copy-pasted them into an LLM, and used it to extract the initial dataset. It's scrappy. It also works.

From there, the workflow is a two-step process. A crawling tool gathers listings and extracts reviews. Then an LLM reads the resulting CSVs and pulls out specific information: contact details, service coverage, languages spoken, signals about quality.

The filtering part took real thought. The goal is to avoid false positives. Language detection is a good example. The system analyses reviews to determine whether a business serves English-speaking clients. That sounds simple until you try to build it: a review that says "they don't speak English" is a negative signal, not a positive one. Getting that distinction right required careful prompt design and quite a bit of iteration. Negative signals that read superficially like positive ones will corrupt the data quietly, and you won't notice until someone emails to say the listing is wrong.

It was a lot of work to design an effective system. It was also genuinely fun. This kind of problem, deciding what counts, how to handle ambiguity, where to draw the line, sits right at the intersection of data design and product thinking. I enjoyed working through it.

04

One directory, two ways to search it

The data model question was harder than it looked. A directory needs to be searchable two ways at once: by location and by category. You want "accountants in Nice" and "all services in Antibes" to both work cleanly. The answer in Supabase was a relational structure: a services table, a categories table, and a locations table, linked through junction records. Once the model was right, filtering fell into place.

One thing I had to think carefully about was how different service categories relate to geography differently. A plumber needs to be in or near your city. A tax accountant who works remotely doesn't. Building a search that handles both correctly means the system has to understand category-level rules about regionality, not just filter by location field. Getting that logic right was a meaningful design decision.

There were also decisions about what data to keep, what to display, and how to handle the different profile tiers I plan to introduce. The basic listings are live. Richer profiles, with more detail and featured placement, come later. Getting the data model right now means those tiers can be added without restructuring everything.

One structural difference from the boulder gym directory: individual profile pages for each listing, not just a card in a filterable list. I'm curious to see how Google reacts to that. Each profile is indexable content about a specific business. Over time, that's a different SEO surface area than a single directory page with entries on it.

05

The multi-model workflow

Like the EVSolarNC project, this one relied on more than one AI system. The split became fairly natural over time: Codex for the coding, Gemini for research and data gathering, Claude for writing and copywriting. Each does what it's good at.

When I got stuck on a design decision, I used them differently: less to produce output, more as a thinking partner to reach a conclusion. Describing a problem clearly enough to ask a good question about it usually helped me think through it, regardless of what came back. Sometimes the most useful thing an AI does is ask you to be more specific.

06

A community I'm part of, not a keyword gap

I didn't choose this niche because of high search volume. I chose it because I wanted to build something genuinely useful, for a community I'm part of, in a place I live. That's a different starting point than most directory projects.

Directory plays take time. You build the structure, add listings, wait for Google to catch up, refine the content. There's no shortcut to that. I'm fine with it. The site solves a real problem, and the data system is good enough that improving it over time is a process rather than a rebuild.

More listings, an expanding guide section, and eventually building out the business side. How local services find their way onto the platform, and what they get from being there, is still the question I haven't fully answered.

Nuutown sat as a prototype for years, waiting on engineering support that never arrived. Riviera Locals is proof the gap between prototype and product finally closed.

← All projects rivieralocals.com ↗