Portfolio / Ops & Systèmes / ghostkitchen

Une dark kitchen,
construite avant le jour J.

Le client est venu nous voir avant l'ouverture — il planifiait une dark kitchen à cinq marques sur une seule ligne de préparation, et cherchait un système capable de tenir dès le lancement. La commande était claire : chaque marque devait ressembler à sa propre boutique pour le client, mais la cuisine, l'admin et la comptabilité devaient fonctionner comme une seule opération. On a construit toute la stack sur cette base, prête le jour d'ouverture.

ClientGhostKitchen (pré-lancement)
PérimètreCatalogue · Cuisine · Admin · Livraison
Marques au lancement2 prêtes · 3 pré-câblées
Délai5 semaines · 2026
Ce qu'on a construit

Une stack de commande multi-tenant déguisée en cinq boutiques distinctes.

Chaque marque a sa propre page catalogue, sa couleur, son suivi de statut, son fil Instagram. Pour le client, ça ressemble à une boutique ciblée. En coulisses, c'est une seule base de données, un seul tableau de bord cuisine et un seul journal comptable — tagués par marque sur chaque ligne, pour que les chiffres soient justes dès la première clôture mensuelle.

Module 01

Catalogue par marque

Menu style fil Instagram par marque — posts carrousel, double-tap, stepper d'ajout au panier, champ de notes. Chaque marque a sa propre URL, palette et ton. Le client tape le lien bio Instagram ou TikTok de la marque, atterrit sur sa vitrine et voit une boutique, pas cinq.

Marque proprePWARupture de stock
Module 02

Paiement géolocalisé

La géolocalisation en direct calcule les frais de livraison par rapport à la pin de la cuisine avant que le client confirme. Paiement par tunai / QRIS / virement. La commande arrive en cuisine dès que le QRIS est validé.

QRISGéofenceSans support
Module 03

Tableau de bord cuisine

Un seul écran sur la ligne de préparation. Chaque commande en file, bordée de couleur par marque. Les postes font glisser : en attente → en cuisine → prêt. Comptages en direct en haut. Pas de tickets papier, pas de commandes perdues.

Tag marque3 phasesDirect
Module 04

Suivi de statut en direct

Cinq phases — passée, payée, en cuisine, en livraison, arrivée. Le client voit la marque qu'il a commandée, pas « dark kitchen ». Mis à jour automatiquement depuis les actions du tableau de bord cuisine. L'URL de statut reste dans leur navigateur pour pouvoir la rouvrir au lieu d'appeler.

5 phasesLien ré-ouvrable
Module 05

Admin par marque

Tableau de bord propriétaire. Filtrer par marque, par phase, par date. Voir les commandes actives, le comptage du jour, l'historique, la répartition des revenus par marque. Une vue pour gérer les cinq marques — sans changer d'appli.

Filtre marqueHistorique
Module 06

Finance à coûts partagés

Suivi des revenus par marque avec répartition des coûts partagés (loyer, personnel, gaz, emballage). P&L mensuel par marque calculé automatiquement. Suivi du budget marketing pour connaître le coût par client par marque — le seul chiffre qui décide de ce qu'on lance ensuite.

P&L par marqueCAC

Cinq marques, une seule ligne de préparation. Deux actives le jour d'ouverture ; trois pré-câblées en base.

● La demande

« Chaque marque doit ressembler à sa propre boutique. »

Le client voulait lancer avec deux marques et en avoir trois autres pré-câblées en base pour plus tard. Chaque marque avait son propre positionnement, sa palette et son audience — un client qui commande un bowl coréen ne devrait jamais savoir que la même cuisine envoie aussi du geprek. La surface client devait lire comme une marque unique et ciblée dès le premier tap.

Mais refaire le build cinq fois était hors de question. Il fallait un shell qui porte cinq visages — propre à lancer une nouvelle marque en une journée, pas en un sprint.

« Le client tape le lien bio en attendant une boutique. Il doit voir une boutique, pas une galerie marchande. » — brief fondateur
9:41●●● ▮ 4G
B
Bap Bowl
Bols coréens · Ouvert
Panier · 1
Bols Accompagnements Boissons
Bulgogi Bowl · telur ½
Rp 38.000
+
Spicy Pork Bap
Rp 42.000
+
● Ce qu'on a construit

Un framework de catalogue, six habillages de marque.

Un seul shell PWA rend la vitrine. Un slug de marque dans l'URL charge les bons tokens de couleur, la typographie, les produits et les textes au démarrage — même code, boutique différente. Le client tape le lien bio Instagram ou TikTok d'une marque, atterrit sur sa vitrine ciblée, ne voit jamais les autres.

Lancer une nouvelle marque pour le client, c'est maintenant une ligne en base, une couleur et une liste de produits. Geprek 28 et Sego Sambel ont été livrés en semaine 2 ; Bap Bowl, Nasgor Mas et Tumis Bunda sont pré-câblés pour quand le client décide de les activer.

9:41●●● ▮ 4G
G
Geprek 28
Sambal d'abord · Ouvert
Panier · 2
Geprek Paket Minuman
Geprek Paha · sambal lvl 3
Rp 24.000
+
Paket Geprek + Es Teh
Rp 28.000
+
● La demande

« Le jour J, le cuisinier ne peut pas deviner à quelle marque appartient chaque commande. »

Le risque que les fondateurs ont signalé d'emblée : avec une seule équipe de préparation pour cinq marques, le contexte de marque disparaît entre la commande et l'assiette. Un ticket « nasi + sambal + ayam » pouvait appartenir à Geprek 28, Sego Sambel ou Nasgor Mas — et une boîte livrée sous la mauvaise marque en semaine de lancement, ça se sait vite et loin.

La surface cuisine devait rendre la marque impossible à rater, même en plein service, même lors du premier service que l'équipe a jamais effectué.

Dapur
4 antri 3 masak 2 siap
Geprek 28 #284
2× Geprek paha
1× Es teh
17:44 Masak
Bap Bowl #285
1× Bulgogi bowl
extra telur · pedas 2
17:45 Masak
Sego Sambel #286
1× Sego sambel daging
17:47 Antri
Nasgor Mas #287
3× Nasgor spesial
17:48 Siap
● Ce qu'on a construit

Tickets étiquetés par marque, glissement en trois phases.

Chaque ticket sur l'écran cuisine porte une barre gauche colorée — une couleur par marque. Le nom de la marque est affiché en gras en haut. Impossible de lire un ticket sans savoir à quelle commande il appartient.

Tap pour avancer : antri → masak → siap. Le suivi de statut du client se met à jour instantanément. La puce de file de marque de l'admin décrémente d'une unité. Une tablette, trois glissements, pas d'écran secondaire à synchroniser — le personnel peut l'apprendre en une après-midi.

9:41●●● ▮ 4G
B
Bap Bowl · #285
Estimasi 18 menit
Direct
Pesanan diterima
17:31 · QRIS confirmed
Antrian dapur
17:32 · #285 di queue
Sedang dimasak
17:45 · station 2
+ 6 menit
3
Berangkat antar
menunggu
4
Tiba di tempat
menunggu
● La demande

« On doit savoir quelle marque gagne vraiment de l'argent. »

Cuisine partagée, personnel partagé, gaz partagé, fournisseur d'emballage partagé. Le chiffre d'affaires par marque est trivial — additionner les reçus. Le bénéfice par marque, c'est le chiffre difficile. Les fondateurs voulaient le voir dès le premier mois, pas après un an à tâtonner.

L'enjeu : la décision « lance-t-on la quatrième marque ? » doit reposer sur un chiffre, pas un ressenti. Cela signifiait intégrer la répartition des coûts partagés dans le système avant même que la première commande n'arrive.

« Si on ne peut pas voir la marge par marque, on pilote à l'aveugle sur laquelle faire grandir. » — brief fondateur
9:41●●● ▮ 4G
$
P&L par marque
Direct · réparti automatiquement
Mois
G
Geprek 28
part des commandes · 53%
marge suivie
S
Sego Sambel
part des commandes · 47%
marge suivie
B
Bap Bowl
pré-câblé · en attente de lancement
T
Tumis Bunda
pré-câblé · en attente de lancement
● Ce qu'on a construit

brand_id à chaque couche, répartition intégrée à la clôture mensuelle.

Chaque commande, ticket, ligne de statut et écriture comptable porte le brand_id dès l'instant où il est écrit. Les coûts partagés (loyer, gaz, personnel de base) sont auto-répartis selon la part de commandes de chaque marque ce mois-là. Les coûts spécifiques à une marque (SKUs d'emballage, ingrédients tagués à une marque) tombent directement dans le bon livre de comptes.

La dépense marketing est rattachée à une marque et une campagne — le coût par client se calcule seul à partir du journal des commandes. L'admin par marque donne au propriétaire un seul écran pour tout lire.

Admin · Direct
17:48 · 11 aktif
Geprek 28
Antri4
Sego Sambel
Antri3
Bap Bowl
Antri2
#284Geprek 28 Masak 17:44
#285Bap Bowl Masak 17:45
#286Sego Sambel Antri 17:47
#287Nasgor Mas Siap 17:48
Comment ça s'est passé

Cinq semaines, marque d'abord.

On n'a pas commencé par la base de données. On a commencé par une page catalogue maquettée pour une des marques de lancement, sur téléphone, qu'on a mise devant les fondateurs — est-ce qu'un client croirait que c'est une vraie boutique ? Une fois que ça a passé, on a travaillé à rebours vers la cuisine et l'admin.

  1. Semaines 1–2 · Shells de marque

    Framework de vitrine client d'abord — un shell PWA, tokens de thème par marque, catalogue style IG, paiement géolocalisé, suivi de statut. Câblé avec les photos et textes des deux marques de lancement.

  2. Semaine 3 · Cuisine & admin

    Tableau de bord cuisine construit autour du flux de préparation que les fondateurs avaient sur papier. Testé sur le sol de la vraie cuisine avec le chef et les fondateurs, l'écran a été refait deux fois. Les tickets colorés par marque viennent de cette visite.

  3. Semaines 4–5 · Finance + remise

    Répartition des coûts partagés, P&L par marque, suivi CAC. Test à blanc avec des commandes test de bout en bout — flux client, flux cuisine, flux admin, clôture comptable. Remis avec les catalogues QR prêts à activer à l'ouverture.

Prêt au lancement

Périmètre du jour J, remis.

Voilà ce que les fondateurs trouvent le jour d'ouverture. Les chiffres en exploitation (CAC, marge par marque, débit) viendront quand la cuisine tourne — on les publiera quand des données réelles seront derrière.

2
Marques prêtes le jour J
Geprek 28 + Sego Sambel · catalogues, prix, suivis de statut tous actifs
3
Marques pré-câblées
Bap Bowl, Nasgor Mas, Tumis Bunda — à activer quand les fondateurs sont prêts
5 sem
Brief à remise
vitrine client, cuisine, admin, finance — une seule mission
1 jour
Pour lancer une 6e marque
nouvelle ligne, nouveaux tokens de thème, nouvelle liste produits — même chemin de code
100%
Couverture brand_id
commandes, tickets, écritures comptables — rien sans tag en base
0
Abonnements SaaS nécessaires
tourne sur l'infrastructure déjà propriété des fondateurs — pas de facture mensuelle à l'échelle
Sous le capot

Construit léger, sur du matériel déjà en place.

Architecture

Un shell, thème de marque au rendu

La vitrine client est une seule PWA. Un slug de marque dans l'URL charge les tokens de thème (couleurs, typographie, textes), la liste produits et la destination de commande au démarrage. Nouvelle marque = nouvelle ligne en table brands, nouvelle liste produits, c'est parti.

Vanilla JS · CSS tokens · service-worker · manifest par marque
Stack

Frontend statique · backend PHP / MySQL

Hébergé sur le même setup XAMPP que le propriétaire utilise déjà pour le reste de l'opération. Pas d'étape de build, pas de Docker, pas de réinvention. Lisible par n'importe qui — l'écran cuisine doit continuer à fonctionner quand le développeur dort.

XAMPP · PHP 8 · MySQL 8 · Swiper · Vanilla PWA
Flux de commande

Tagué par marque à chaque couche

Chaque commande, ticket, ligne de statut et écriture comptable porte le brand_id. La cuisine filtre dessus, l'admin filtre dessus, la finance alloue dessus. Il n'existe aucun endroit dans le système où une ligne existe sans savoir à quelle marque elle appartient.

brand_id partout · soft delete · audit log
Surface client

Lien bio d'abord, sans installation

Le client arrive depuis le lien bio Instagram ou TikTok de la marque, ouvre une PWA, commande, paie en QRIS, suit l'URL de statut. Pas de store, pas de connexion. Le social de la marque fait le travail marketing ; la vitrine n'a qu'à convertir.

PWA · lien bio IG / TikTok · QRIS · panier localStorage
Surface cuisine

Une tablette, trois glissements

Une tablette Android fixée au mur sur la ligne de préparation. Les tickets arrivent en continu, bordés de couleur. Tap pour avancer parmi trois états. Comptages en direct en haut pour que le cuisinier connaisse la profondeur de la file sans rien ouvrir.

Android · PWA plein écran · mises à jour long-poll
Finance

Répartition des coûts partagés par part de commandes

Loyer, gaz et personnel de base sont répartis chaque mois selon la part de commandes totales de chaque marque. Les coûts spécifiques (SKUs d'emballage, ingrédients tagués à une seule marque) tombent directement dans le bon livre de comptes. Formule lisible par le propriétaire visible sur chaque ligne.

clôture mensuelle · P&L par marque · lien CAC
Suivant → Mikro Farm

Vous gérez plusieurs marques
depuis un seul endroit ?

Appel de cadrage gratuit. On l'a fait pour nous-mêmes — on sait ce qui mord au deuxième mois.