01
Le Défi
Les apps de découverte de cafés sont soit des annuaires sans âme, soit des silos d'avis fermés. Je voulais construire un vrai produit social — follows, feed, listes partagées, top 3 — autour de la culture café à Paris, et le shipper en solo : design, développement mobile, backend, notifications push, soumission aux stores et analytics. La difficulté : couvrir toute la surface produit — auth (Apple/Google), carte interactive avec clustering, feed temps réel, outils de modération, deep links et un mode invité qui convertit.
02
La Solution
Développée avec React Native + Expo (routing par fichiers via Expo Router) sur un backend Supabase : Postgres avec row-level security, storage, RPCs et triggers d'auth. React Query gère le cache et les optimistic updates sur le feed, les avis, les listes et les follows. La carte regroupe des centaines de cafés via supercluster, les profils affichent un podium top 3 et des listes partageables, et un système de perks récompense les early members avec des offres en swipe-to-claim. Publiée sur les deux stores via EAS, instrumentée avec PostHog et Sentry, localisée FR/EN, avec universal links et une page web publique par café.
// Map clustering — rebuild index only when cafés change,
// re-query clusters when the visible region moves
export function useClusters({ cafes, region, radius = 60 }: Options) {
const index = useMemo(() => {
if (!cafes?.length) return null;
const sc = new Supercluster<PointProps, ClusterProps>({
radius,
maxZoom: 16,
minPoints: 3,
});
sc.load(
cafes.map((cafe) => ({
type: "Feature",
geometry: {
type: "Point",
coordinates: [cafe.longitude, cafe.latitude],
},
properties: { cafe },
}))
);
return sc;
}, [cafes, radius]);
const clusters = useMemo(() => {
if (!index || !region) return [];
const zoom = Math.round(Math.log2(360 / region.latitudeDelta));
return index.getClusters(regionToBbox(region), zoom);
}, [index, region]);
return { clusters, index };
}↳ Hook de clustering carte basé sur Supercluster — l'index n'est reconstruit que si la liste des cafés change, les déplacements de la carte ne déclenchent qu'une re-query bbox peu coûteuse





