Dossier technique à destination des élus, directions des systèmes d'information, développeurs et décideurs publics souhaitant comprendre l'architecture, les principes de souveraineté et de résilience d'UrbaFood. UrbaFood est un logiciel libre en développement : ce dossier distingue ce qui est implémenté aujourd'hui de l'architecture cible, signalée comme « prévu » ou « architecture cible ».
UrbaFood n'est pas une simple application de commande en ligne. C'est une infrastructure logicielle pensée comme un service public : open source, auditée, hébergée localement, et gouvernée par la collectivité qui la déploie.
Stack full-stack NestJS (API REST) + Next.js (interface web) + PWA React (application mobile coursiers). Reverse proxy Nginx devant un HAProxy terminant le TLS. Déployable chez un hébergeur de la collectivité ou en auto-hébergement municipal.
Interface web progressive (PWA) : catalogue de restaurants, panier, suivi de commande en temps réel, compte citoyen avec historique. Aucun traceur publicitaire tiers. Audit d'accessibilité RGAA : prévu.
Espace dédié : gestion du menu, tableau de bord commandes en temps réel, statistiques de chiffre d'affaires, connexion optionnelle à Google Business Profile pour import automatique de la fiche établissement.
Application web installable sur Android/iOS sans passer par les stores. Service Worker Workbox pour fonctionnement partiel hors-ligne. Interface mobile-first : disponibilité, commandes disponibles, livraison active, gains en temps réel.
Interface d'administration : validation des restaurants, gestion des coursiers, suivi des commandes (rôle ADMIN). Prévu : rapports financiers, open data configurable, rôles granulaires (agent instructeur, élu, DSI, auditeur).
API REST documentée (OpenAPI/Swagger), endpoints sécurisés par JWT pour les acteurs de l'écosystème. Prévu : endpoints publics de données ouvertes, interopérabilité avec les SI municipaux (annuaire, identité numérique).
Prévu : intégration d'un prestataire de paiement (par exemple Stripe Connect), versement direct aux restaurants après déduction de la commission, alternative par virement SEPA. Le paiement en ligne n'est pas encore implémenté.
Workflow de statuts : PENDING → CONFIRMED → PREPARING → READY → PICKED_UP → DELIVERED. Prévu : notifications push ou SMS à chaque changement de statut.
Géolocalisation HTML5 native dans la PWA coursier, sans SDK propriétaire. Sans dépendance à Google Maps. Le coursier consulte les commandes prêtes et choisit celles qu'il accepte. Prévu : calcul des distances via OpenStreetMap (Nominatim) et attribution par proximité.
Prévu : notifications push (Web Push API) pour la PWA coursiers et e-mails via un serveur SMTP configurable par la collectivité, sans dépendance à un prestataire d'emailing externe.
Déployable sur infrastructure municipale existante, offre qualifiée SecNumCloud, ou cloud français (OVHcloud, Scaleway, Outscale). Aucune dépendance obligatoire à AWS ou Azure. Build Docker reproductible.
Authentification JWT (access 15 min + refresh 7j). Mots de passe hashés Argon2. Chiffrement AES-256-GCM des tokens OAuth. Rate limiting Nginx + NestJS Throttler. Conçu selon les principes du RGPD et du Privacy by Design ; hébergement en UE ; droit à l'effacement : prévu (suppression logique en place).
Restaurants ──────────────────────────────────────┐
↓
┌─────────────────────────────┐
│ Plateforme privée │
│ (siège hors territoire) │
└────────────┬────────────────┘
│
┌────────────────────────────┼────────────────────┐
↓ ↓ ↓
Actionnaires Données citoyens Hébergement
(dividendes) hors territoire cloud tiers
Commission : jusqu'à 30 % (Uber Eats France, formule Standard)
Gouvernance : fonds d'investissement privés
Transparence : selon l'opérateur Restaurants ──┐
Livreurs ────┼──→ Infrastructure publique locale
Citoyens ────┘ │
│
┌────────────────────┼────────────────────┐
↓ ↓ ↓
Données sur Hébergement Gouvernance
le territoire souverain municipale
(propriété (datacenter (conseil
publique) local) municipal)
Commission : 1 % par défaut, paramétrable
Gouvernance : élus + DSI + citoyens
Transparence : comptes publics, code ouvert Internet (HTTPS:443)
↓
┌───────────────────────────────────────────────────────────┐
│ HAProxy (SSL termination, certificat Let's Encrypt) │
└─────────────────────────┬─────────────────────────────────┘
↓ (réseau interne chiffré)
┌───────────────────────────────────────────────────────────┐
│ Nginx (reverse proxy, rate limiting 100 req/min API) │
│ │
│ /api/* → Backend NestJS :3000 │
│ /coursier-app/* → PWA Coursiers :80 │
│ /* → Frontend Next.js :3001 │
└─────────────────────────┬─────────────────────────────────┘
↓
┌───────────────────────────────────────────────────────────┐
│ Backend NestJS (API REST, TypeORM) │
│ │
│ Auth JWT ── Restaurants ── Orders ── Couriers │
│ ↓ ↓ ↓ ↓ │
│ Redis (cache, sessions, queues) │
│ MariaDB 11.5 (données persistantes, UTF8MB4, InnoDB) │
│ ↓ │
│ Worker (queue emails + cron jobs) │
└───────────────────────────────────────────────────────────┘
Tous les containers : Docker Compose · réseau bridge isolé
Données : volumes persistants · backup automatisé (mariadb-dump)
Déployable sur : OVHcloud · Scaleway · Outscale · Baremetal municipalUne blockchain publique comme Ethereum est inadaptée aux collectivités : coûts de transaction variables et imprévisibles, gouvernance hors de portée démocratique, dépendance à des acteurs privés spéculatifs. UrbaFood propose une architecture décentralisée sous maîtrise publique, sans cryptomonnaie.
Chaque nœud (serveur municipal, terminal CCAS, équipement de commerce) communique directement avec ses voisins via un protocole léger. Pas de point central unique défaillant.
Mairie, CCAS, bibliothèque, office de commerce, marché couvert : chaque équipement public peut héberger un nœud. Plus le réseau est dense, plus la résilience est élevée.
Les applications des coursiers et restaurateurs fonctionnent comme des nœuds légers : ils valident et propagent les transactions sans stocker l'intégralité de l'historique.
Commandes, réputation et paiements répliqués sur plusieurs nœuds. Si un serveur tombe, les données restent accessibles via les réplicas locaux, sans interruption de service.
Architecture cible, non implémentée. Registre distribué des transactions (commandes, paiements, livraisons). Immuable et auditable par les élus et le DSI. Aucune cryptomonnaie : les unités sont des euros, traçables via Stripe.
Proof of Authority : seuls les nœuds autorisés par la municipalité valident les blocs. Faible consommation énergétique. Architecture cible, non implémentée.
┌──────────────────────────┐
│ Nœud principal │
│ Mairie / DSI │
│ (validateur primaire) │
└──────────┬───────────────┘
│
┌──────────────────────┼──────────────────────┐
↓ ↓ ↓
┌─────────────────┐ ┌──────────────────┐ ┌─────────────────┐
│ Nœud CCAS │ │ Nœud Office │ │ Nœud Médiathèq │
│ (validateur) │ │ de commerce │ │ (validateur) │
└────────┬────────┘ └────────┬─────────┘ └───────┬─────────┘
│ │ │
┌─────┴─────┐ ┌─────┴─────┐ ┌─────┴─────┐
↓ ↓ ↓ ↓ ↓ ↓
App App App App App App
Citoyen Restaurant Citoyen Coursier Citoyen Restaurant
Légende :
─── Connexion P2P chiffrée (TLS mutuel)
↓ Nœud léger (lecture + propagation, sans stockage complet)
Les validateurs forment le comité de consensus (PoA municipal)
Frais de transaction : 0 EUR (réseau privé, aucun gas fee)
Cryptomonnaie : aucune — devise : euro via Stripe / SEPAEn déléguant la livraison alimentaire à des plateformes privées, les collectivités cèdent non seulement une part de la valeur économique locale, mais aussi la maîtrise de données stratégiques — habitudes de consommation, fréquentation des commerces, données personnelles des citoyens — sans garantie sur leur hébergement ni leur utilisation.
25 à 30 % de commission : un restaurant réalisant 500 000 € de CA annuel via plateforme transfère 125 000 à 150 000 € vers des actionnaires extérieurs. Sur dix restaurants, c'est 1 à 1,5 M€ qui quittent le territoire chaque année.
Les plateformes agrègent les données de consommation pour affiner leur modèle publicitaire, vendre des études de marché et orienter leurs propres offres (dark kitchens, marques fantômes). La collectivité n'a aucun accès à ces données produites par ses citoyens.
Une fois les restaurants intégrés et les habitudes citoyennes formées, la collectivité ne peut plus reprendre la main sans provoquer une rupture de service. C'est le mécanisme classique du lock-in par réseau : plus il est grand, plus la dépendance est forte.
| Critère | Plateforme centralisée | UrbaFood décentralisé |
|---|---|---|
| Propriété des données | ❌ Plateforme privée (hors territoire) | ✅ Collectivité territoriale |
| Hébergement | ❌ Infrastructure choisie par l'opérateur | ✅ Infrastructure souveraine (FR / UE certifiée) |
| Commission | ❌ jusqu'à 30 % (formule Standard d'Uber Eats France, grille publique 2026) | ✅ 1 % par défaut, paramétrable |
| Gouvernance | ❌ Conseil d'administration privé | ✅ Objectif : gouvernance publique délibérée |
| Transparence financière | ❌ Selon l'opérateur | ✅ Objectif : comptes publics et open data |
| Résilience | ❌ Point de défaillance unique | ✅ Architecture cible : réseau distribué multi-nœuds |
| Auditabilité | ❌ Code propriétaire, boîte noire | ✅ Code open source, auditable à tout moment |
| Interopérabilité | ❌ API fermée, écosystème verrouillé | ✅ OpenAPI 3.0, standards ouverts |
| Coût de sortie | ❌ Rupture de service totale | ✅ Migration progressive sans perte de données |
| Évolutivité | ❌ Dépendante des décisions de l'éditeur | ✅ Fork et personnalisation libres |
| Contrôle démocratique | ❌ Aucun recours pour les citoyens | ✅ Délibération, audit, recours administratif |
| RGPD | ❌ Transferts hors UE fréquents | ✅ Hébergement UE, DPA signé, registre tenu |
| Dépendance fournisseur | ❌ Totale (lock-in contractuel) | ✅ Nulle (logiciel libre, multi-hébergeurs) |
| Emploi local | ❌ Emplois délocalisés, pas de retombée locale | ✅ DSI municipal, prestataires locaux, coursiers |
Un service public numérique doit continuer à fonctionner même en cas de panne partielle. UrbaFood est conçu pour maintenir la continuité de service face aux défaillances techniques, aux changements de prestataires et aux dégradations de connectivité.
Prévu (architecture cible) : réplication des données sur plusieurs nœuds distincts, pour qu'une panne de serveur reste transparente pour les utilisateurs.
Nginx et Docker Compose surveillent la santé des services toutes les 30 secondes. Redémarrage automatique en cas de défaillance détectée.
Prévu : basculement du reverse proxy vers un nœud secondaire (directive upstream max_fails), lorsqu'un second nœud sera déployé.
Une fois publié sous licence libre, le code pourra être repris par la collectivité, selon les termes de sa licence, sans négociation avec un éditeur.
Documentation technique publiée sur /docs ; documentation d'exploitation complète : en cours.
Format SQL standard (MariaDB). Export complet en un seul commandement. Importable sur tout hébergeur compatible MySQL/MariaDB sans transformation.
Prévu : un module de paiement interchangeable (Stripe, Mollie, Adyen ou virement SEPA).
Le docker-compose.yml fonctionne sur OVHcloud, Scaleway, Outscale ou un serveur baremetal municipal sans modification de code.
Prévu : envoi d'e-mails via un SMTP interne ou souverain, configurable par variables d'environnement.
L'application coursier fonctionne partiellement hors-ligne grâce à Workbox : consultation des livraisons en cours, mise en cache des données récentes.
Les mises à jour de statut (commande livrée, disponibilité) sont mises en file d'attente localement et synchronisées dès le retour de la connexion.
En mode décentralisé, les nœuds d'un même réseau local (LAN/WiFi municipal) communiquent entre eux sans transiter par Internet.
Un smart contract est un programme qui s'exécute automatiquement selon des règles définies à l'avance, sans qu'aucune partie puisse les modifier unilatéralement une fois déployé. Dans l'architecture cible d'UrbaFood (non implémentée à ce jour), ils garantiraient l'équité des paiements et la transparence des évaluations sans nécessiter de tiers de confiance central.
Le citoyen valide son panier. Le montant est séquestré (escrow) — ni le restaurant ni la plateforme ne peuvent y accéder avant livraison. Contrat instancié sur le registre distribué.
Le restaurant confirme la commande dans le délai imparti (ex. 5 min). Sans confirmation dans les temps, le contrat s'annule automatiquement et le paiement est remboursé.
Le coursier marque la commande livrée. Le contrat libère automatiquement : 98 % au restaurant, 1 % à la caisse municipale. Trace immuable sur le registre distribué.
// Pseudo-code — contrat de commande
contract OrderContract {
state : PENDING | CONFIRMED | PREPARING | DELIVERED | CANCELLED
escrow : montant bloque jusqu'a confirmation de livraison
on confirm_by_restaurant() -> state = CONFIRMED
on delivery_confirmed() -> release_payment() -> state = DELIVERED
on timeout(5min, PENDING) -> refund_citizen() -> state = CANCELLED
on timeout(48h, CONFIRMED) -> arbitration() -> state = DISPUTED
}Transfert automatique vers le compte Stripe Connect du restaurant dès validation de la livraison. Relevé mensuel généré automatiquement. La grille tarifaire est publique et inscrite dans le contrat.
Rémunération calculée selon la grille tarifaire publiée (distance, type de véhicule). La formule de calcul est inscrite dans le contrat et non modifiable unilatéralement par l'opérateur.
Architecture cible : 1 % prélevé sur chaque transaction, affecté au fonctionnement du service (maintenance, support). Rapport public envisagé.
Seul un citoyen ayant effectivement reçu une commande peut noter le restaurant et le coursier. La preuve est fournie par le hash de la transaction liée. Impossible de générer de fausses notes.
Score calculé sur les 90 derniers jours (pondération décroissante). Un incident isolé n'affecte pas définitivement un acteur. Score récupérable pour les commerces qui améliorent leur service.
Détection des patterns anormaux (séquences de notes similaires, délai suspect). Les anomalies sont signalées pour révision manuelle par le modérateur municipal. Sanctions décidées par délibération.
Avec une commission de 1 % par défaut, contre jusqu'à 30 % (formule Standard d'Uber Eats France, grille publique 2026), UrbaFood vise à laisser davantage de marge aux restaurateurs.
Logiciel libre (licence en cours de définition) : une fois le code publié, la collectivité pourra l'auditer, le modifier et le transmettre à d'autres communes, selon les termes de la licence. Fin du cycle des renouvellements de licences et des dépendances à un éditeur unique.
Prévu : accès aux données d'activité économique locale : fréquentation des restaurants, zones de livraison, tendances de consommation. Données précieuses pour piloter la politique commerciale et soutenir les commerces en difficulté.
Coursiers, agents de validation et accompagnement des restaurateurs : des activités exercées localement.
La plateforme valorise les producteurs locaux via des filtres dédiés (circuits courts, bio, label local). Objectif : un algorithme de mise en avant transparent et délibéré collectivement.
Objectif : rapports financiers publics, open data sur les commissions perçues et leur usage, registre des décisions de gouvernance publié.
« UrbaFood n'est pas un projet de niche. C'est la démonstration qu'une collectivité peut, avec des moyens raisonnables et une approche open source, reprendre la maîtrise de son infrastructure économique numérique — exactement comme elle possède ses routes, ses écoles et ses réseaux d'eau. »
UrbaFood est porté par le projet associatif UrbanAppsLab. Échangeons sur vos besoins : les retours des collectivités orientent le développement. Sans engagement.