← All research · Back to demo

CLAUDE CODE HANDOFF: Saiakoda Location Intelligence App

What to build

A single-page Vite + React + Leaflet app that combines an interactive map of Tallinn with a full location intelligence dashboard for Saiakoda bakery-café. The map and panels are fully interconnected — clicking a neighborhood on the map highlights it in the panel, toggling a data layer updates both, adjusting scoring weights recolors the map in real-time.

Tech stack

App layout

Split screen: map (left, ~60%) + panel (right, ~40%). Full viewport height. Header bar with layer toggles spanning full width. The panel has tabs that switch between different views.


DATA: Competitors & Signal Locations (26 points)

[
  {"name": "RØST Bakery", "lat": 59.4383, "lng": 24.7548, "type": "bakery", "hood": "Rotermann", "rev": 450000, "tier": "A", "note": "Scandinavian sourdough, always queuing, #29 TripAdvisor"},
  {"name": "Karjase Sai / Barbarea", "lat": 59.452, "lng": 24.721, "type": "bakery", "hood": "Kopli", "rev": 380000, "tier": "A", "note": "Michelin-noted, dual bakery/bistro concept"},
  {"name": "Saiakoda (Härjapea 17)", "lat": 59.4377051, "lng": 24.7162575, "type": "current", "hood": "Pelgulinn", "rev": 74000, "tier": "—", "note": "CURRENT LOCATION. Saturday-only, pre-order window, zero foot traffic"},
  {"name": "Maison François", "lat": 59.437, "lng": 24.744, "type": "bakery", "hood": "Old Town", "rev": 180000, "tier": "A", "note": "François partnership w/ Burman Hotel, Dunkri 8"},
  {"name": "La Boulangerie", "lat": 59.4435, "lng": 24.762, "type": "bakery", "hood": "Sadama", "rev": 220000, "tier": "B", "note": "French-style, Poordi 3, full café"},
  {"name": "SUMI by Põhjala", "lat": 59.4495, "lng": 24.7185, "type": "bakery", "hood": "Krulli", "rev": 200000, "tier": "A", "note": "Opened Jan 2025, French/American pastries + Japanese grill"},
  {"name": "Bekker Pagariäri", "lat": 59.4465, "lng": 24.725, "type": "bakery", "hood": "Kopli", "rev": 150000, "tier": "B", "note": "Mid-premium neighborhood bakery"},
  {"name": "Pagar Võtaks", "lat": 59.435, "lng": 24.753, "type": "bakery", "hood": "Kesklinn", "rev": 80000, "tier": "C", "note": "Only all-organic bakery, counter inside Biomarket"},
  {"name": "The Brick Coffee", "lat": 59.4402, "lng": 24.7295, "type": "coffee", "hood": "Telliskivi", "rev": 180000, "note": "ECT listed, moved across from Apollo/Literata"},
  {"name": "Café KIOSK No1", "lat": 59.44, "lng": 24.728, "type": "coffee", "hood": "Telliskivi", "rev": 120000, "note": "2025 ECT Winner"},
  {"name": "KOKOMO Roasters", "lat": 59.449, "lng": 24.72, "type": "coffee", "hood": "Põhjala", "rev": 160000, "note": "ECT listed, roastery + café"},
  {"name": "Gourmet Coffee", "lat": 59.4385, "lng": 24.785, "type": "coffee", "hood": "Kadriorg", "rev": 130000, "note": "ECT listed, Köleri 8"},
  {"name": "NOP Café", "lat": 59.438, "lng": 24.783, "type": "organic", "hood": "Kadriorg", "rev": 250000, "note": "18+ years organic café, THE benchmark"},
  {"name": "Kalve (Kadriorg)", "lat": 59.4378, "lng": 24.7845, "type": "coffee", "hood": "Kadriorg", "rev": 140000, "note": "Latvian roaster, opened 2025"},
  {"name": "Kalve (Rotermann)", "lat": 59.4388, "lng": 24.756, "type": "coffee", "hood": "Rotermann", "rev": 140000, "note": "Latvian roaster, opened 2025"},
  {"name": "Paper Mill Coffee", "lat": 59.434, "lng": 24.762, "type": "coffee", "hood": "Kesklinn", "rev": 110000, "note": "Roastery, Pärnu mnt area"},
  {"name": "Biomarket (BJT)", "lat": 59.4408, "lng": 24.734, "type": "organic", "hood": "Telliskivi", "rev": 500000, "note": "Inside Balti Jaama Turg, major organic hub"},
  {"name": "Biomarket (Solaris)", "lat": 59.4328, "lng": 24.7445, "type": "organic", "hood": "Kesklinn", "rev": 400000, "note": "Solaris Centre location"},
  {"name": "Kringel", "lat": 59.4295, "lng": 24.737, "type": "organic", "hood": "Uus Maailm", "rev": 60000, "note": "100% plant-based, only specialty food in Uus Maailm"},
  {"name": "CrossFit KeKo", "lat": 59.442, "lng": 24.731, "type": "fitness", "hood": "Kalamaja", "note": "Soo tn 4, exactly the target demo"},
  {"name": "Inbodhi Yoga", "lat": 59.4375, "lng": 24.778, "type": "fitness", "hood": "Kadriorg", "note": "Expat-friendly yoga"},
  {"name": "Reach Studio", "lat": 59.4355, "lng": 24.75, "type": "fitness", "hood": "Kesklinn", "note": "Reformer Pilates, Rotermann area"},
  {"name": "Roseni Pilates", "lat": 59.4385, "lng": 24.7555, "type": "fitness", "hood": "Rotermann", "note": "Pilates studio"}
]

Layer types and their visual treatment:

Revenue data source: EMTA quarterly tax filings + Inforegister annual reports.


DATA: Neighborhoods (10 candidates)

[
  {"id": "pelgulinn", "name": "Pelgulinn", "lat": 59.4377, "lng": 24.7163, "pop500": 6800, "income": 1900, "rent": 11, "traffic": 35, "specialty": 1, "demo": 72, "growth": "emerging", "transit": 65, "note": "15,950 residents, massively underserved, Saiakoda home turf"},
  {"id": "uusmaailm", "name": "Uus Maailm", "lat": 59.4295, "lng": 24.737, "pop500": 5500, "income": 2100, "rent": 13, "traffic": 30, "specialty": 1, "demo": 82, "growth": "emerging", "transit": 70, "note": "Bohemian, sustainability-minded, NO artisan bakery exists"},
  {"id": "nomme", "name": "Nõmme", "lat": 59.392, "lng": 24.692, "pop500": 5200, "income": 2500, "rent": 8, "traffic": 40, "specialty": 0, "demo": 60, "growth": "stable", "transit": 45, "note": "Forest suburb, organic families, zero specialty bakeries"},
  {"id": "kalamaja", "name": "Kalamaja Core", "lat": 59.4445, "lng": 24.735, "pop500": 5100, "income": 2200, "rent": 14, "traffic": 65, "specialty": 3, "demo": 88, "growth": "mature", "transit": 75, "note": "Best audience fit, young professionals + families"},
  {"id": "kadriorg", "name": "Kadriorg", "lat": 59.438, "lng": 24.784, "pop500": 4500, "income": 3200, "rent": 13, "traffic": 55, "specialty": 4, "demo": 85, "growth": "stable_premium", "transit": 70, "note": "NOP proves organic demand, affluent families"},
  {"id": "kopli", "name": "Kopli/Põhjala", "lat": 59.45, "lng": 24.72, "pop500": 3200, "income": 1700, "rent": 9, "traffic": 30, "specialty": 4, "demo": 65, "growth": "emerging", "transit": 55, "note": "Karjase Sai territory, getting crowded"},
  {"id": "kesklinn", "name": "Kesklinn", "lat": 59.433, "lng": 24.745, "pop500": 3800, "income": 2600, "rent": 22, "traffic": 85, "specialty": 3, "demo": 60, "growth": "stable", "transit": 95, "note": "High traffic but generic, not audience-aligned"},
  {"id": "telliskivi", "name": "Telliskivi", "lat": 59.4405, "lng": 24.73, "pop500": 4200, "income": 2400, "rent": 18.5, "traffic": 95, "specialty": 8, "demo": 90, "growth": "mature", "transit": 95, "note": "Peak saturation — 8 specialty spots in 300m"},
  {"id": "noblessner", "name": "Noblessner", "lat": 59.452, "lng": 24.736, "pop500": 1800, "income": 3000, "rent": 18, "traffic": 45, "specialty": 2, "demo": 70, "growth": "rapid", "transit": 50, "note": "2-Michelin-star 180°, 300 new apts incoming"},
  {"id": "rotermann", "name": "Rotermann", "lat": 59.4385, "lng": 24.7555, "pop500": 2800, "income": 2800, "rent": 20, "traffic": 90, "specialty": 5, "demo": 75, "growth": "mature", "transit": 90, "note": "RØST already here, office + tourist mix"}
]

Data sources: Statistics Estonia 100m population grid, Colliers Baltic Market Reports 2025-2026, KV.ee market data, European Coffee Trip listings.


DATA: Available Property Listings (8 real listings, March 2026)

[
  {"name": "Vana-Kalamaja 21", "hoodId": "kalamaja", "lat": 59.4425, "lng": 24.7385, "size": 102.6, "rent": "~€1,100", "sqm": "~€11", "kitchen": true, "fit": 5, "note": "Former Mooni Pagar. Full exhaust + 50A power. Terrace on pedestrian promenade. BEST PICK.", "url": "https://www.kv.ee/uurile-anda-suurte-akendega-avar-aripind-vanakalam-3642145.html"},
  {"name": "Volta Galerii (Uus-Volta 7)", "hoodId": "kalamaja", "lat": 59.4448, "lng": 24.7275, "size": 183.2, "rent": "Ask Endover", "sqm": "~€14-18", "kitchen": true, "fit": 4, "note": "1912 factory, 5.2m ceilings, limestone walls. 2 months free. Explicitly marketed for bakeries.", "url": "https://soov.ee/25744787"},
  {"name": "Volta HUB", "hoodId": "kalamaja", "lat": 59.4455, "lng": 24.729, "size": 152, "rent": "1st mo free", "sqm": "~€12-16", "kitchen": true, "fit": 4, "note": "Kitchen cube, 5m ceilings, sea views. Wise HQ moving nearby.", "url": "https://soov.ee/25638741"},
  {"name": "Kopli 6", "hoodId": "kalamaja", "lat": 59.4418, "lng": 24.7305, "size": 186.5, "rent": "€1,800", "sqm": "€9.65", "kitchen": true, "fit": 3, "note": "2 levels, display windows. Best €/m² in Kalamaja.", "url": "https://uusmaa.ee/pakkumine/10233"},
  {"name": "Manufaktuuri 7", "hoodId": "pelgulinn", "lat": 59.4395, "lng": 24.7205, "size": 55.3, "rent": "€553", "sqm": "€10", "kitchen": false, "fit": 3, "note": "New 2024 build, 78m² terrace, 500+ apts nearby. Cheapest entry point.", "url": "https://www.city24.ee/real-estate/commercials-for-rent/tallinn-pohja-tallinna-linnaosa-manufaktuuri-tn/4276142"},
  {"name": "Kalaranna 8", "hoodId": "kalamaja", "lat": 59.4485, "lng": 24.738, "size": 131.9, "rent": "€1,847", "sqm": "€14", "kitchen": false, "fit": 3, "note": "Premium waterfront. Neighbors: Chin-Chin, Oda, ROO Café.", "url": "https://uusmaa.ee/pakkumine/18074"},
  {"name": "Koidu 101, Uus Maailm", "hoodId": "uusmaailm", "lat": 59.4302, "lng": 24.7385, "size": 63.7, "rent": "2 mo free", "sqm": "Unknown", "kitchen": false, "fit": 2, "note": "Corner unit in Uus Maailm. BUT: 2.6m ceilings (tight!). Needs full buildout.", "url": "https://www.kv.ee/voimalik-tutvuda-uuripinnaga-ka-videovahendusel-20-3219824.html"},
  {"name": "Noblessner Main Square", "hoodId": "noblessner", "lat": 59.4528, "lng": 24.7352, "size": null, "rent": "From €12/m²", "sqm": "€12+", "kitchen": true, "fit": 3, "note": "Historic limestone, high ceilings, kitchen readiness. Near 180°, Põhjala.", "url": "https://soov.ee/25615699"}
]

SCORING MODEL

7 weighted factors, all adjustable via sliders (0-50 range each). Weights are normalized to sum to 1.0 before scoring.

Default weights:

population: 15   // Catchment population within 500m
demo: 20         // Target demographic alignment (0-100 scale, already normalized)
gap: 25          // Competition gap (FEWER competitors = HIGHER score, inverted)
rent: 15         // Rent efficiency (LOWER rent = HIGHER score, inverted)
traffic: 10      // Foot traffic index
transit: 5       // Public transport accessibility
growth: 10       // Neighborhood growth trajectory

Growth trajectory mapping:

emerging: 90, rapid: 85, mature: 50, stable_premium: 60, stable: 40

Normalization: min-max to 0-100 for each factor. demo is already 0-100. specialty and rent are inverted (lower = better).

Composite score = weighted sum of all normalized factors.

Saturation ratio = pop500 / max(specialty, 1). Thresholds:

Rent feasibility = (rent_per_sqm × 60m² × 12) / 180000 × 100. Must be <10-15%.


PANEL TABS

Tab 1: 📊 Neighborhood Scoring

Tab 2: 🗺️ Data Layers

Tab 3: 🏠 Available Spaces

Tab 4: 👥 Target Audience

Tab 5: 📋 Site Visit Checklist

This is the micro-level decision framework for the HUMAN to use on foot. Display as an interactive checklist:

The 10-Point Site Visit Scorecard (rate each 1-10, weighted): | Category | Weight | |----------|--------| | Pedestrian traffic volume at key hours | 20% | | Pedestrian traffic quality (demographic fit) | 10% | | Visibility and sightlines (100m test) | 12% | | Accessibility (entrance level, parking, transit) | 10% | | Co-tenancy and neighboring businesses | 8% | | Competitive landscape | 8% | | Delivery and operational access | 7% | | Lease terms and cost | 10% | | Physical space (layout, oven placement potential) | 8% | | Sun exposure and outdoor seating potential | 7% |

Each item should be a slider (1-10) that the user can score per listing. Calculate weighted total. Minimum threshold: no item below 4, total above 6.5.

Fatal Flaw Checklist (binary yes/no — any YES = disqualify):

  1. Wrong side of a major road with no pedestrian crossing nearby?
  2. Steps UP required to enter? (not street-level)
  3. Past the natural pedestrian turning point? (energy of street dies before reaching you)
  4. On a dead-end street or pedestrian dead zone?
  5. Entrance faces away from main pedestrian flow?
  6. In a wind tunnel between tall buildings?
  7. Both neighbors are blank walls / shuttered / dead?
  8. Area is dead during bakery operating hours (7am-3pm)?
  9. No visibility from 50+ meters on primary approach?
  10. No delivery vehicle access within 50 feet?

Five-Visit Protocol — display as a progress tracker:

Tab 6: 🧠 Methodology


MAP FEATURES

Layers (all toggleable from header bar):

Interactions:

Map defaults:


BONUS: Live Estonian Data Pull (optional, network-dependent)

If you want to add a "Refresh Data" feature that pulls live from Estonian APIs:

  1. Maa-amet Geocoding: https://inaadress.maaamet.ee/inaadress/gazetteer?address=ADDRESS&results=1&output=json Returns viitepunkt_b (lat) and viitepunkt_l (lng)

  2. EMTA Revenue Data: Download CSV from https://ncfailid.emta.ee/eng_tasutud_maksud.csv (~150MB) Columns include registry code, company name, EMTAK code, turnover, employee count

  3. Business Registry: Bulk download from https://avaandmed.ariregister.rik.ee/en/downloading-open-data Contains all companies with EMTAK codes and addresses

  4. OpenRouteService Isochrones: POST https://api.openrouteservice.org/v2/isochrones/foot-walking Free key from openrouteservice.org, 500 isochrones/day Body: {"locations": [[lng, lat]], "range": [300, 600], "range_type": "time"}

  5. BestTime.app: Foot traffic forecasts for Tallinn venues, API access with paid plan


Context

This app is for helping a Belgian artisan baker (François Arnould, runs Saiakoda / François Boulangerie) find the optimal location for a new bakery-café in Tallinn, Estonia. His current bakery is at Härjapea 17 in residential Pelgulinn — Saturday-only, pre-order through a window, zero walk-in traffic. He needs a real café location.

The target audience is NOT generic foodies — it's health-conscious consumers who specifically seek stone-milled, long-fermented, wood-fired sourdough bread for gut health, ancestral health, or clean-ingredient parenting reasons. They cluster around specialty coffee shops, organic food stores, CrossFit/yoga studios, and neighborhoods like Kalamaja, Kadriorg, and Uus Maailm.

The app should feel like a professional location intelligence tool, not a pretty map. Every recommendation must be traceable to data, and every data layer should be toggleable so a human can override the model's assumptions.