Dinnr est une application web complète de gestion des réservations pour restaurants, propulsée par l'intelligence artificielle. Elle se compose de trois parties :
Tout le code s'exécute dans le navigateur. Les données sont stockées localement via localStorage. Aucun serveur, aucune base de données externe.
| Composant | Technologie | Rôle |
|---|---|---|
| Interface | HTML + JavaScript vanilla | Aucune dépendance, fonctionne partout |
| Graphiques | Chart.js 4.4 | 4 graphiques analytiques |
| Icônes | Tabler Icons 3.0 | 1000+ icônes vectorielles |
| Intelligence artificielle | un modèle de langage | Compréhension langage naturel |
| STT navigateur | Web Speech API | Reconnaissance vocale démo |
| TTS navigateur | Web Speech Synthesis | Voix synthétique démo |
| STT production | Twilio Speech Recognition (Deepgram) | Transcription appels téléphoniques |
| TTS production | Amazon Polly (Lea-Neural) | Voix française naturelle |
| Téléphonie | Twilio Voice | Réception/émission appels |
| Serveur | Node.js + Express | Pont Twilio ↔ IA |
| Déploiement | Railway / Render / Heroku | Hébergement serveur |
Affiché au démarrage. Montre les réservations du jour, le taux d'occupation midi/soir, les risques no-show détectés par l'IA, et les rappels J-1 à envoyer.
Scoring no-show — chaque réservation reçoit un score calculé sur 4 critères : historique d'annulations du client, absence de numéro de téléphone, groupe de 8 personnes ou plus, grand groupe sans acompte. Score ≥ 3 = risque élevé affiché en rouge.
Vue hebdomadaire. Navigation par semaine. Chaque jour affiche les réservations sous forme de tuiles colorées (or = midi, vert = soir). Cliquer une tuile ouvre le formulaire d'édition. Le + en bas de chaque jour pré-remplit la date.
Tableau complet avec filtres : texte libre, date, statut (confirmé / en attente / annulé), service (midi / soir), niveau de risque IA. Chaque ligne affiche le canal d'origine (direct, TheFork, Google, WhatsApp, Voice Bot...), l'acompte versé, et le régime alimentaire signalé.
12 tables réparties sur 3 zones : Terrasse (T1–T3), Salle principale (T4–T9), Espace privé (T10–T12). Sélectionnez une date et un service pour voir l'occupation en temps réel. Le bouton Auto-assignation IA affecte automatiquement les tables libres aux réservations sans table, en commençant par les plus grands groupes (algorithme glouton).
Une table affiche le symbole ⚠ si le client a déclaré une allergie ou un régime spécial.
Quand le restaurant est complet, les clients peuvent être inscrits sur liste d'attente. Dès qu'une table se libère, cliquez Notifier pour envoyer un SMS automatique (simulé dans la démo, réel avec Twilio connecté).
Grille hebdomadaire avec 6 employés et 7 jours. Chaque cellule peut contenir un shift : Midi, Soir, Double, Repos, ou Congé. Cliquer une cellule fait défiler les types en boucle.
Génération automatique IA — le bouton Générer auto crée le planning en tenant compte des réservations de la semaine. Règles appliquées :
Chaque employé peut pointer son arrivée et son départ. L'heure est enregistrée automatiquement. Le cumul d'heures sur 7 jours glissants est calculé et affiché. Un QR code (statique dans la démo) permettrait en production de pointer via smartphone.
Document généré automatiquement avant chaque service, regroupant :
Construit automatiquement depuis l'historique des réservations. Chaque client dispose d'une fiche avec le nombre de visites, le total de couverts, la date de dernière visite, le régime alimentaire habituel, et des notes libres modifiables. Le statut VIP est attribué manuellement.
4 graphiques Chart.js mis à jour en temps réel :
Interface de chat connectée à un modèle de langage via le service d'IA. Le système sait :
Quand l'IA confirme une réservation, il inclut un bloc <RES>{...}</RES> dans sa réponse. L'application détecte ce bloc, crée la réservation automatiquement et affiche une notification.
Fonctionne entièrement dans Chrome grâce à deux APIs natives :
La conversation est envoyée à l'IA avec le même mécanisme que le chat. En production, ces deux composants sont remplacés par Twilio et Amazon Polly.
/voice/incoming.<Gather input="speech">./voice/respond avec un score de confiance.<Say voice="Polly.Lea-Neural"> suivi d'un nouveau <Gather> pour continuer la conversation.<RES>{...}</RES>, la réservation est sauvegardée et un SMS de confirmation est envoyé automatiquement au numéro du client via twilio.messages.create().| Situation | Comportement du serveur |
|---|---|
| Silence du caller | Twilio timeout → demande de répéter, puis raccroche après 2 tentatives |
| Confiance STT < 30% | Le serveur demande de répéter sans envoyer à l'IA |
| Erreur du service d'IA | Message d'erreur vocal + raccrochage + log serveur |
| Numéro de téléphone non reconnu | Le SMS de confirmation est skippé, la réservation est quand même sauvegardée |
| Session inactive > 1h | Nettoyage automatique en mémoire (timer toutes les 10 min) |
dinnr-server.zip. Copiez .env.example en .env et remplissez vos clés.https://dinnr-server-prod.railway.app. Copiez-la dans la variable BASE_URL.https://votre-url.railway.app/api/health dans le navigateur. Vous devez voir {"status":"ok",...}.| Variable | Valeur | Obligatoire |
|---|---|---|
| CLE_API_IA | sk-ant-api03-… | Oui |
| TWILIO_ACCOUNT_SID | ACxxxxxxxx… | Oui |
| TWILIO_AUTH_TOKEN | xxxxxxxx… | Oui |
| TWILIO_PHONE_NUMBER | +33XXXXXXXXX | Oui |
| BASE_URL | https://votre-app.railway.app | Oui |
| RESTAURANT_NAME | Le Jardin Doré | Non |
| MIDI_OPEN / MIDI_CLOSE | 12:00 / 14:30 | Non |
| SOIR_OPEN / SOIR_CLOSE | 19:00 / 22:30 | Non |
| PORT | 3000 (Railway l'override automatiquement) | Non |
https://votre-app.railway.app/voice/incoming — méthode POST.https://votre-app.railway.app/voice/status — méthode POST.| Service | Statut démo | Pour activer en production |
|---|---|---|
| Lightspeed POS | Connecté (simulé) | Clé API Lightspeed → lier via OAuth2 sur le dashboard Lightspeed |
| Google Reserve | Connecté (simulé) | Google My Business → Réservations → activer un partenaire de réservation |
| TheFork | Connecté (simulé) | Contacter TheFork Pro → activer l'API synchronisation |
| WhatsApp Business | Connecté (simulé) | Meta Business → créer un numéro WhatsApp Business → API via Twilio ou 360Dialog |
| Twilio SMS | Connecté (simulé) | Activé automatiquement quand le serveur est déployé avec les variables Twilio |
| Stripe | Sandbox | Créer un compte Stripe → clé secrète → intégrer stripe.paymentIntents.create() dans le serveur |
| Zelty / Tiller / Adyen | Non connecté | Demander l'accès API à chaque fournisseur |
Dans l'application HTML, toutes les données sont stockées uniquement dans votre navigateur via localStorage — aucun serveur tiers ne les reçoit. Seuls les messages envoyés à l'agent IA passent par le service d'IA, conformément à (notre politique de confidentialité).
Oui. Les fichiers HTML s'ouvrent sur mobile. La reconnaissance vocale du Voice Bot fonctionne sur Chrome Android. Pour iOS, Safari ne supporte pas encore pleinement la Web Speech API — utiliser la saisie texte à la place.
Non. Toutes les réservations, le planning, les notes clients et la clé API sont sauvegardés dans localStorage. Ils persistent entre les sessions. Exception : vider le cache ou utiliser une fenêtre privée efface les données.
Oui. Le switcher en haut de la sidebar permet de basculer entre 3 établissements. Chaque restaurant a ses propres données isolées dans localStorage. Pour ajouter un 4ème restaurant, modifiez le tableau RESTOS dans le code JavaScript.
Le serveur expose un endpoint GET /api/reservations qui retourne toutes les réservations créées par Voice Bot en JSON. Vous pouvez l'appeler depuis l'application HTML pour synchroniser les données. Une version future de Dinnr intégrera cette synchronisation automatiquement.
Dans la démo navigateur (Web Speech API), les performances dépendent du navigateur. En production avec Twilio (Deepgram), la reconnaissance est nettement plus robuste sur les accents français, belges et québécois. La confiance minimale est réglée à 30% dans le serveur — en dessous, Dinnr demande de répéter.
Remplacez la voix Amazon Polly par ElevenLabs pour une qualité supérieure. Il faut modifier server.js : au lieu de passer du texte dans <Say>, générez un fichier audio MP3 via l'API ElevenLabs, hébergez-le temporairement (ex: S3 ou tmpfiles.org), et utilisez <Play> dans le TwiML. La latence augmente légèrement (~500ms supplémentaires).
Oui. Dans server.js, changez language: 'fr-FR' en en-US, es-ES, etc. sur les blocs <Gather>. Modifiez également la voix Polly (ex: Polly.Joanna pour l'anglais américain) et les instructions de l'IA pour la langue cible.