Case study
Gatto
UI Dev AI
Real places, picked by real experts: designed, coded and shipped solo, end to end.
This UI is 100% AI-generated, deliberately: on this project I'm validating a product thesis, not my pixel-perfect. My UI craft shows in the other projects.
- Role
- Solo founder: product, data, AI, iOS, web, growth
- Period
- Ongoing · live on the App Store
- Context
- Paris & Lille, repositioned for international travellers
- Tools & stack
- Swift / SwiftUI · Supabase (PostgreSQL) · n8n · Apify · GPT-5 · Claude Haiku · Next.js
A must-visit validated by every guide and a tourist trap no professional would recommend can have exactly the same Google Maps rating: 4.58. The algorithm cannot see the difference. A local can, but it took them years and dozens of disappointing meals to feel it.
Gatto makes that difference visible: the platform cross-references more than 70 independent editorial sources (Michelin, Gault&Millau, Le Fooding, Time Out, 50 Best and dozens more) to surface only the places experts converge on without ever consulting each other.
The problem
Ratings don’t measure quality; they measure popularity, and popularity can be bought. Tourist traps disguised as popular spots (high rating, many reviews, zero professional sources) and undisclosed sponsored recommendations pollute exactly the tools we use to choose where to eat.
The decisions
Letting go of the mockups
The tension. I started the way a designer starts: wanting mockups. But solo, every week spent in Figma is a week without an answer to the only question that matters at first: does the idea hold?
The choice. AI-centred design: generate, test, throw away. Testing my ideas and the product itself before giving them too much time. Same logic for the system: no design system, a UI kit. This is build mode; a design system would be a waste of time.
What it cost. The UI, precisely. Gatto’s is AI-generated and it shows: decent, not fantastic. That’s the deal I made: until the product thesis is proven, every hour of pixel-perfect is an hour stolen from validation. I save the craft for projects where it pays off; here, the polished UI will come when the product has earned its designer.
Source the experts, not the crowds
The tension. Build a base of genuinely good places, with no editorial team and without reproducing the very bias I’m fighting.
The options. Manual curation (doesn’t scale) · a single API like Google’s (reproduces precisely the popularity bias) · aggregating dozens of editorial sources.
The choice. A source-first pipeline: every place scanned through the SERP, out of which 70+ editorial sources emerged, and a Signal Index based on convergence: counting the distinct providers that recommend a place, not raw mention volume.
What it cost. Running every place through an LLM is expensive. Places under 4.3 on Google are not scanned. I accept the irony: I filter by the very rating I am fighting, and a few gems slip past me, in the name of viability.
Two AI pipelines on n8n, no custom backend
The choice. Two self-hosted n8n pipelines rather than a bespoke backend. The first ingests places: the city is meshed into H3 hexagons and swept through Google Places. The second scans mentions: every place is searched in the Google SERP, and every editorial mention that surfaces is classified by GPT-5 (is this place genuinely recommended, or just cited in passing?), then Claude Haiku generates tags and summaries. Two models, two jobs, each on its strength. And above the database, two multi-agent systems: one writes editorial content from our data, the other hunts for new places.
What was genuinely hard. Not the code: the economics. Sorting 70+ sources that are not worth the same. Optimising every scraping request across AI APIs, Apify, Groq. Fetching and keeping Google Places data fresh without burning the budget, because Google is precisely designed to prevent it. And endless iterations on the scanner prompt: the line between “genuinely recommended” and “just cited in passing” lives in a few sentences of instructions.
What it cost. Whole evenings hunting down why nothing was updating, and a discipline kept ever since: distrust silent success as much as loud failure.
Never display the score
The tension. A “96/100” is instantly readable, satisfying, a dopamine hit. It’s the obvious UI. And it’s a trap.
The choice. Internal score only. A number invites gaming, implies false precision, and becomes legally radioactive next to a restaurant’s name. Instead: qualitative signals: tier labels (Must-visit, Hidden Gem), convergence counters (“12 critics keep talking about this place”), rankings. Same discipline in language: “suspicious popularity” rather than “tourist trap”.
What it cost. Harder to communicate, less spectacular at first glance, more design work to make the qualitative credible.
Promoting an app nobody searches for
The tension. Building the app was almost the easy part. Getting it discovered is another story: an expert-recommendation app is not a query people type.
What failed. I burned budget on Apple Search Ads before understanding the real problem: nobody searches for what I wanted to sell. People type “best restaurant…”, and that query belongs to Google Maps.
The choice. Going where people actually discover places: TikTok and Instagram. Social content is generated from the database, with hard numbers like “37% of Paris’s best-rated places on Google are cited by no guide at all”: the data promotes the product that holds it.
What it cost. An Apple Ads budget turned into tuition fees, and a lesson engraved: you can’t buy search intent that doesn’t exist.
First numbers (2026). Around 100,000 views on TikTok, 15,000 on Instagram, 400 recurring monthly visitors on the site, 40 App Store installs. Awareness is building; converting views into installs is the open front, and I’d rather write it than dress it up.
What it produced
The iOS app is live on the App Store: a map by quality tier, detailed Signal Index pages, favourites. The gatto.city site is SEO-first: browsing is public and indexable; the paywall only guards active planning tools.
- scored places
- 5,700+
- editorial mentions
- 40,000+
- sources cross-referenced
- 70+
What I would do differently
Lock a sharp positioning earlier. The international-traveller pivot (“real places, picked by real experts”) came late; a lot of content written for a Parisian audience, then shelved.
Ship the number-free UX from day one instead of debating it. It was the right decision, made too slowly.
Track indexing from the start. Discovering late that only a fraction of URLs are indexed is a crawl-budget lesson you pay dearly for.
Kill your favourite features when they serve no one. The Share Extension, which I saw as the key growth mechanism, brought nothing: removed.