OLaNouKay : ce qu'un guide local des Antilles impose au code
TL;DR
OLaNouKay répond à trois questions, en Guadeloupe et en Martinique : où manger un bokit, quelle plage, quelle rivière. Le site réunit des fiches de lieux, une carte, des classements par commune et un tableau de bord commerçant.
La commande et le paiement ne sont pas ouverts. Ce texte décrit ce que le produit a imposé au code.
Ce que fait le produit
Le produit se découpe en deux surfaces : une application web pour découvrir les lieux, un tableau de bord pour les commerçants. Côté découverte, on trouve :
- Les fiches : photos, description, horaires et menu du jour quand le commerçant en publie un.
- Les classements : des listes par commune et par catégorie, comme
/gp/baie-mahault/bokit, triées par nombre de vues puis par nom. - La carte : des repères colorés par catégorie, avec filtres.
- Lokal Now : la page
/lokal-nowliste les lieux ouverts à cet instant, du plus proche de la fermeture au plus éloigné.
Le tableau de bord couvre le menu du jour, le stock, les promotions, les événements et les statistiques.
En juin 2026, j'ai retiré la carte de la barre de navigation. L'onglet Bokit l'a remplacée : le produit se lance sur ce seul plat, et la carte reste accessible depuis l'accueil.
Des données de lieux qu'il ne faut pas inventer
Un guide local vaut ce que valent ses fiches, et les miennes passent par des outils séparés selon la donnée manquante.
Le script d'import prend une liste de noms et de communes, puis interroge Google Places pour les coordonnées, l'adresse, les horaires, le téléphone et les photos. Il travaille en deux temps :
planlit sans pouvoir écrire et range chaque ligne : à importer, déjà présente, introuvable, fermée, hors de l'archipel ou hors catalogue.applycrée les fiches du plan relu et saute celles qui existent. Relancer le script après une coupure ne crée donc pas de doublon.
La classification ne se fie pas aux seuls types de Google, qui ne connaissent ni le bokit ni le food truck. Le libellé de ma liste prime quand il est plus précis. Aucune description n'est reprise : les fiches importées arrivent avec un texte vide.
Le géocodage Mapbox demande un autre garde-fou. Sans emprise imposée, une rue « La Savane » pouvait se résoudre près de Bayonne. Chaque requête porte donc la boîte géographique du territoire, et le script remplit uniquement les coordonnées absentes.
Le pire défaut venait de l'affichage. Une fiche sans horaires montrait « 11h · 22h », et une fiche sans équipements déclarés annonçait terrasse, livraison, carte bleue et wifi. Plages et rivières comprises. Désormais, les horaires absents s'affichent « Non renseignés » et le bloc d'équipements disparaît.
Une carte qui ne charge que dans le navigateur
La carte repose sur mapbox-gl, une bibliothèque qui a besoin du navigateur. Le composant se charge donc sans rendu serveur, et son code importe mapbox-gl à l'initialisation. Les fiches, elles, sont rendues côté serveur et figurent au plan du site.
Les repères sont des éléments HTML construits à la main. Un bug m'a imposé une règle de structure : Mapbox écrit sa propre transformation sur l'élément extérieur pour positionner le repère. Un zoom au survol posé au même endroit l'écrasait et envoyait les repères en haut à gauche de la carte. Le zoom vit maintenant sur un élément intérieur.
L'heure locale de « ouvert maintenant »
Tout calcul d'ouverture passe par un décalage fixe de quatre heures, parce que la Guadeloupe reste à UTC-4 toute l'année. Le calcul retire ce décalage de l'instant courant, puis lit l'heure en UTC :
const d = new Date(epochMs - GUADELOUPE_UTC_OFFSET_MS)
return d.getUTCHours() * 60 + d.getUTCMinutes()
La première version de la fonction planifiée updateIsOpen lisait getHours(). Le serveur tourne en UTC, et le paramètre timeZone de la planification règle seulement le déclenchement. Une fiche ouverte de 11:00 à 22:00 l'aurait été de 07:00 à 18:00 sur place. Aucune fiche n'avait encore d'horaires : j'ai corrigé le défaut en octobre 2026 avant qu'il produise un effet.
Le deuxième piège vient des services de nuit. Une entrée 18:00 → 02:00 ouvre un jour et ferme le lendemain, donc openStateAt vérifie deux choses : le service du jour et la fin de celui de la veille. Avant ce passage, la fonction planifiée marquait fermé en permanence un service 18:00 → 00:00. Onze cas de test couvrent ce calcul.
Deux autres choix en découlent :
- Deux lectures :
updateIsOpenécrit le champisOpentoutes les 15 minutes, alors que/lokal-nowrecalcule l'état à chaque requête, sans cache statique. - Une copie assumée : les Cloud Functions ne résolvent pas le paquet partagé à l'exécution. Le calcul y existe en double, avec un commentaire qui exige de garder les deux versions alignées.
La fonction parcourt toutes les fiches actives sans filtre de territoire : le même décalage s'applique aux lieux de Martinique.
Deux langues d'interface et une canonique par version
L'interface existe en français et en anglais avec next-intl, sans version espagnole. Le français reste à la racine et l'anglais vit sous /en, ce qui a conservé les adresses françaises existantes.
Cette structure a produit un bug de référencement. Les pages codaient en dur leur canonique vers le chemin français : la version anglaise se déclarait donc copie de l'autre, sans balise de langue. Résultat constaté : /en/gp/bokit sortait sur des recherches françaises. La fonction alternatesFor donne maintenant à chaque version sa propre canonique et annonce l'autre en hreflang.
Ce qui n'est pas ouvert
Le dépôt contient plus de code que le site n'en met en service, et l'écart mérite d'être écrit :
- Commande et paiement : les fonctions Stripe et l'écran de paiement existent, mais le paiement par carte n'a jamais été testé de bout en bout. Rien n'est présenté comme livré tant que ce test n'est pas passé.
- Votes : le code des campagnes existe, les campagnes ne sont pas lancées. Il reste à empêcher un script de voter en boucle avec des adresses inventées.
- Martinique : le référentiel couvre ses 34 communes et le catalogue de départ contient 11 bokits, mais les pages par commune n'existent que sous
/gp, et l'import Google filtre sur l'emprise de la Guadeloupe.
Au 1er novembre 2026, le dépôt est en version 0.3.8.