📋 Introduction
OK Cuisine Pro est une Progressive Web Application (PWA) de gestion HACCP complète pour les cuisines professionnelles. Elle permet de gérer la traçabilité alimentaire, le suivi des températures, le nettoyage, les réceptions, l'inventaire, et bien plus — le tout avec un assistant vocal unique sur le marché.
index.html), et JavaScript gère l'affichage des différentes "pages" en montrant/cachant des sections.
🏗️ Architecture Globale
Structure des Fichiers
// Structure du projet 📁 okcuisine.pro/ ├── 📄 index.html // Structure SPA (35 pages) ├── 📄 manifest.json // Configuration PWA ├── 📄 sw.js // Service Worker (cache offline) ├── 📁 css/ │ └── 📄 style.css // Styles (~3000 lignes) └── 📁 js/ ├── 📄 app.js // Noyau application ├── 📄 storage.js // Persistance données (124 fonctions) ├── 📄 crypto.js // Chiffrement AES-256-GCM ├── 📄 permissions.js// Gestion des 7 rôles ├── 📄 ui.js // Interface utilisateur ├── 📄 voice.js // Reconnaissance vocale (69 fonctions) ├── 📄 voice-ai.js // IA vocale (55 fonctions) └── ... // 40+ autres modules
Diagramme d'Architecture
┌─────────────────────────────────────────────────────────────────────┐ │ COUCHE PRÉSENTATION │ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌────────────┐ │ │ │ index.html │ │ style.css │ │ ui.js │ │keyboard.js │ │ │ │ (Structure) │ │ (Styles) │ │ (Modales, │ │(Raccourcis)│ │ │ │ │ │ │ │ Toasts) │ │ │ │ │ └─────────────┘ └─────────────┘ └─────────────┘ └────────────┘ │ └─────────────────────────────────────────────────────────────────────┘ │ ▼ ┌─────────────────────────────────────────────────────────────────────┐ │ COUCHE LOGIQUE MÉTIER │ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ │ │Températ. │ │Nettoyage │ │Réceptions│ │Inventaire│ │ Agents │ │ │ └──────────┘ └──────────┘ └──────────┘ └──────────┘ └──────────┘ │ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ │ │ Audit │ │Simulateur│ │Formation │ │Allergènes│ │ PAI │ │ │ └──────────┘ └──────────┘ └──────────┘ └──────────┘ └──────────┘ │ │ ... + 30 autres modules │ └─────────────────────────────────────────────────────────────────────┘ │ ▼ ┌─────────────────────────────────────────────────────────────────────┐ │ COUCHE DONNÉES │ │ ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ │ │ │ storage.js │ │ crypto.js │ │ permissions.js │ │ │ │ (localStorage) │ │ (AES-256-GCM) │ │ (7 rôles) │ │ │ └─────────────────┘ └─────────────────┘ └─────────────────┘ │ └─────────────────────────────────────────────────────────────────────┘ │ ▼ ┌─────────────────────────────────────────────────────────────────────┐ │ COUCHE VOCALE │ │ ┌─────────────────────────┐ ┌─────────────────────────┐ │ │ │ voice.js │ │ voice-ai.js │ │ │ │ (Web Speech API) │ │ (IA conversationnelle) │ │ │ │ - Wake word detection │ │ - Analyse intentions │ │ │ │ - Flux conversationnels│ │ - Extraction entités │ │ │ │ - Synthèse vocale │ │ - Questions analytiques│ │ │ └─────────────────────────┘ └─────────────────────────┘ │ └─────────────────────────────────────────────────────────────────────┘
Pattern de Communication entre Modules
- Objets globaux : Chaque module est un objet global (
const Temperatures = {...}) accessible partout - Storage centralisé : Toutes les données passent par
Storage.js - Événements custom :
okc-storage-changenotifie les changements de données - Appels directs : Un module peut appeler un autre (ex:
UI.toast())
⚙️ App.js — Noyau de l'Application
Le fichier app.js est le cœur de l'application. Il gère l'authentification, la navigation, et l'initialisation de tous les autres modules.
Objet Principal
const App = { // État de l'utilisateur connecté currentUser: null, // Objet utilisateur {id, nom, role, initiales, pin} currentPage: 'dashboard', // Page active // Authentification PIN pinBuffer: '', // Chiffres saisis selectedUserId: null, // Utilisateur en cours de connexion pinAttempts: {}, // Compteur tentatives par user lockedUntil: {}, // Timestamp de déblocage par user // Configuration sécurité MAX_PIN_ATTEMPTS: 3, // Tentatives avant blocage LOCKOUT_MS: 5 * 60 * 1000, // Durée blocage (5 min) IDLE_TIMEOUT_MS: 5 * 60 * 1000, // Déconnexion inactivité (5 min) // ... méthodes }
Fonctions Principales
Workflow d'Authentification
_renderLoginUsers() génère les cartes utilisateurs depuis Storage.getUsers()selectUser(userId) → affiche clavier PINpinInput(digit) × 4 → auto-submit à 4 chiffrespinSubmit() compare Storage.hashPin(input) avec user.pinHashCrypto.init(pin, userId) dérive la clé et déchiffre les données sensibles_login() active le vocal, configure les permissions, affiche le dashboard💾 Storage.js — Couche de Persistance
Le module Storage est le gestionnaire centralisé de toutes les données. Il utilise localStorage pour persister les informations et intègre le chiffrement pour les données sensibles.
Principe de Base
localStorage est une API du navigateur qui permet de stocker des données texte de façon permanente. Les données persistent même après fermeture du navigateur. Limite : ~5-10 MB selon le navigateur.
const Storage = { PREFIX: 'okc_', // Préfixe pour éviter les collisions // Méthode de base pour sauvegarder save(name, data) { // Si donnée sensible → chiffrement AES-256 if (Crypto.isSensitive(name)) { Crypto.updateAndEncrypt(name, data); return; } // Sinon → JSON simple localStorage.setItem('okc_' + name, JSON.stringify(data)); }, // Méthode de base pour charger load(name, defaultValue) { if (Crypto.isSensitive(name)) { return Crypto.getCached(name, defaultValue); } const raw = localStorage.getItem('okc_' + name); return raw ? JSON.parse(raw) : defaultValue; } }
Clés de Stockage Principales
| Clé | Contenu | Chiffré | Module |
|---|---|---|---|
okc_config |
Configuration globale + utilisateurs | ❌ | Config |
okc_temp_{date} |
Relevés température du jour | ❌ | Temperatures |
okc_ccp_{date} |
Contrôles CCP (cuisson, refroid.) | ❌ | Temperatures |
okc_net_{date} |
Enregistrements nettoyage du jour | ❌ | Nettoyage |
okc_rec_{date} |
Réceptions marchandises du jour | ❌ | Receptions |
okc_inventaire |
Liste des produits en stock | ❌ | Inventaire |
okc_alertes |
Alertes actives et résolues | ❌ | Alertes |
okc_journal_{date} |
Journal d'activité du jour | ❌ | Journal |
okc_pai_enfants |
PAI avec noms enfants + pathologies | ✅ AES-256 | PAI |
okc_tiac |
Incidents intoxication + victimes | ✅ AES-256 | TIAC |
okc_rgpd_* |
Consentements, registre DPO | ✅ AES-256 | RGPD |
okc_keyring |
DEK chiffrées par utilisateur | ❌ (contient clés chiffrées) | Crypto |
Fonctions de Hash PIN
/** * Génère un hash irréversible pour le PIN * Utilisé pour stocker les PIN de façon sécurisée */ hashPin(pin) { const salt = 'okc_2025_v1'; // Salt constant const combined = salt + pin; let hash = 0; // Algorithme de hash simple mais suffisant pour des PIN 4 chiffres for (let i = 0; i < combined.length; i++) { const char = combined.charCodeAt(i); hash = ((hash << 5) - hash) + char; hash = hash & 0xFFFFFFFF; // 32-bit integer } return 'h' + Math.abs(hash).toString(16); }
Pattern d'Utilisation (exemple Températures)
// 1. LECTURE — Récupérer les températures du jour getTemperatures(date) { const key = 'temp_' + (date || this.today()); return this.load(key, []); // [] si pas de données } // 2. ÉCRITURE — Ajouter un relevé addTemperature(entry) { const key = 'temp_' + this.today(); const list = this.load(key, []); // Enrichir l'entrée avec métadonnées entry.id = this.uid(); // ID unique entry.timestamp = new Date().toISOString(); entry.date = this.today(); entry.user = App.currentUser?.nom || 'Inconnu'; list.push(entry); this.save(key, list); // Journaliser l'action Journal.log('temperature', `Temperature ${entry.zone}: ${entry.valeur}°C`); return entry; }
🔐 Crypto.js — Chiffrement AES-256-GCM
Le module Crypto gère le chiffrement des données sensibles (PAI, TIAC, RGPD) conformément aux exigences de l'article 9 du RGPD sur les données de santé.
Architecture Cryptographique
┌─────────────────────────────────────────────────────────────┐ │ ARCHITECTURE CHIFFREMENT │ ├─────────────────────────────────────────────────────────────┤ │ │ │ PIN Utilisateur (4 chiffres) │ │ │ │ │ ▼ │ │ ┌─────────────────┐ │ │ │ PBKDF2 │ 100 000 itérations │ │ │ SHA-256 │ + Salt (16 bytes, unique) │ │ └────────┬────────┘ │ │ ▼ │ │ ┌─────────────────┐ │ │ │ KEK │ Key Encryption Key (256-bit) │ │ │ (par user) │ Dérivée du PIN — en mémoire │ │ └────────┬────────┘ │ │ │ │ │ ▼ │ │ ┌─────────────────┐ ┌─────────────────┐ │ │ │ KEYRING │────▶│ DEK │ │ │ │ (localStorage) │ │ Data Encryption │ 256-bit │ │ │ DEK chiffrée │ │ Key (mémoire) │ │ │ └─────────────────┘ └────────┬────────┘ │ │ │ │ │ ▼ │ │ ┌─────────────────┐ │ │ │ AES-256-GCM │ │ │ │ IV = 12 bytes │ │ │ └────────┬────────┘ │ │ │ │ │ ▼ │ │ ┌─────────────────┐ │ │ │ Données Chiffrées│ │ │ │ (localStorage) │ │ │ └─────────────────┘ │ │ │ └─────────────────────────────────────────────────────────────┘
Données Chiffrées (8 clés)
| Clé | Données | Justification RGPD |
|---|---|---|
pai_enfants |
PAI avec noms enfants + pathologies | Art. 9 — Données de santé |
pai_alertes |
Alertes allergies avec identités | Art. 9 — Données de santé |
tiac |
Incidents intoxication + victimes | Art. 9 — Données de santé |
rgpd_consentements |
Consentements nominatifs | Art. 7 — Preuves consentement |
rgpd_registre |
Registre des traitements | Art. 30 — Registre DPO |
rgpd_dpo |
Coordonnées DPO | Protection contact |
rgpd_archived_users |
Anciens utilisateurs | Droit à l'oubli |
allergene_plats |
Plats + allergènes déclarés | Traçabilité sanitaire |
Fonctions Principales
👥 Permissions.js — Gestion des Rôles
Les 7 Rôles
| Rôle | Niveau | Description | Fonction de test |
|---|---|---|---|
| admin | 1 | Superutilisateur — Toutes permissions | isManager() ✅ |
| gestionnaire | 2 | Gestion utilisateurs + configuration | isManager() ✅ |
| directeur | 3 | Même droits que gestionnaire | isManager() ✅ |
| chef | 4 | Accès complet cuisine/HACCP | isChef() ✅ |
| remplacant | 5 | Identique chef + briefing auto | isChef() ✅ |
| second | 6 | Accès limité (consultation) | isSecondOrAbove() ✅ |
| commis | 7 | Vue profil uniquement | Aucune |
Matrice des Accès aux Pages
const pageRoles = { // Opérations quotidiennes 'dashboard': 'all', // Tout le monde 'temperatures': ['admin','gestionnaire','directeur','chef','remplacant','second'], 'nettoyage': 'all', 'receptions': ['admin','gestionnaire','directeur','chef','remplacant','second'], 'inventaire': ['admin','gestionnaire','directeur','chef','remplacant','second'], // Sécurité alimentaire 'allergenes': ['admin','gestionnaire','directeur','chef','remplacant'], 'pai': ['admin','gestionnaire','directeur','chef','remplacant'], 'tiac': ['admin','gestionnaire','directeur','chef','remplacant'], // Gestion système 'rgpd': ['admin','gestionnaire','directeur'], 'config': 'all', // Lecture pour tous, écriture contrôlée // ... 25+ autres pages }
Mode Vue Essentielle (Admin)
// Pages affichées en mode essentiel essentialPages: [ 'dashboard', 'agents', 'stock-entretien', 'calendrier', 'audit', 'journal', 'archivage-dlc', 'config' ]
🎨 UI.js — Interface Utilisateur
Le module UI centralise les utilitaires d'interface : sidebar, toasts, modales, navigation visuelle, badges.
Fonctions Principales
UI.toast(message, type, duration)UI.openModal(title, body, footer)UI.confirm(title, message)UI.showPage(page)UI.escapeHTML(str)UI.temperatureStatus(val, min, max)Exemple : UI.confirm()
// Utilisation avec async/await async function deleteItem(id) { const confirmed = await UI.confirm( 'Confirmer la suppression', 'Êtes-vous sûr de vouloir supprimer cet élément ?' ); if (confirmed) { Storage.removeItem(id); UI.toast('Élément supprimé', 'success'); render(); } }
🌡️ Modules HACCP
Températures (temperatures.js)
Gestion des relevés de température de stockage et des Points Critiques de Contrôle (CCP).
Deux types de relevés :
| Type | Description | Limites |
|---|---|---|
| Stockage | Relevés frigos, chambres froides | Configurables par zone (ex: 0-4°C) |
| CCP Cuisson | Contrôle température à cœur | ≥63°C (viande), ≥70°C (porc), ≥74°C (volaille) |
| CCP Refroidissement | Refroidissement rapide | 63°C → <10°C en <2h |
| CCP Remise temp. | Réchauffage | <10°C → >63°C en <1h |
Workflow de relevé :
Nettoyage (nettoyage.js)
Suivi des nettoyages et désinfections avec checklist par zone.
Vues selon le rôle :
| Rôle | Vue | Fonctionnalités |
|---|---|---|
| Admin / Chef | Vue complète | Tableau détaillé, statistiques, multi-zones |
| Commis | Checklist simplifiée | Clic sur zone → marquage terminé |
Réceptions (receptions.js)
Contrôle des marchandises à réception conforme CE 852/2004.
Champs du formulaire :
🎤 Assistant Vocal
L'assistant vocal permet d'utiliser l'application mains libres — essentiel en cuisine professionnelle.
Voice.js — Reconnaissance Vocale
Wake Word Detection
// Variantes reconnues pour activer l'assistant _matchWakeWord(text) { const variants = [ 'ok cuisine', 'okay cuisine', 'aucune cuisine', // Erreur fréquente Google 'oh cuisine', 'hockey cuisine', // Autre erreur 'o cuisine', 'ok cousine' ]; return variants.some(v => text.includes(v)); }
Flux Conversationnels (18 flux)
| Commande | Flux | Étapes |
|---|---|---|
| "température" / "frigo" | flowTemperature | Zone → Valeur → Confirmation |
| "cuisson" | flowCCPCuisson | Produit → Température → Conformité |
| "nettoyage" | flowNettoyage | Zones → Produit → Confirmation |
| "réception" | flowReception | Fournisseur → Produit → Température → Conformité |
| "étiquette" / "J+3" | flowEtiquette | Produit → Origine → Auto-calcul DLC J+3 |
| "minuteur 45 minutes" | flowTimer | Durée → Label → Alarme programmée |
| "menu du jour" | — | Lecture vocale du menu |
VoiceAI.js — Intelligence Conversationnelle
Questions Analytiques
Extraction d'Entités
// Exemples d'extraction automatique // Dates "demain" → { date: '2026-03-11', label: 'demain' } "mardi prochain" → { date: '2026-03-17', label: 'mardi' } "le 15" → { date: '2026-03-15', label: '15 mars' } // Températures "moins 22 virgule 5" → -22.5 "4 degrés" → 4 // Heures "14h30" → '14:30' "midi" → '12:00'
📱 PWA — Progressive Web App
Manifest.json
{
"name": "OK Cuisine — Assistant HACCP Vocal",
"short_name": "OK Cuisine",
"description": "Application HACCP vocale pour cuisines professionnelles.",
"start_url": "/index.html",
"display": "standalone", // Sans barre navigateur
"orientation": "any", // Portrait ou paysage
"background_color": "#0f0f1a",
"theme_color": "#1a1a2e",
"lang": "fr"
}
Service Worker (sw.js)
const CACHE_NAME = 'ok-cuisine-v34'; const URLS_TO_CACHE = [ '/', '/index.html', '/css/style.css', '/js/app.js', // ... 48 fichiers au total ]; // Stratégie : Network First, Cache Fallback self.addEventListener('fetch', event => { event.respondWith( fetch(event.request) .then(response => { // Succès réseau → mise en cache if (response.ok) { const clone = response.clone(); caches.open(CACHE_NAME).then(cache => { cache.put(event.request, clone); }); } return response; }) .catch(() => { // Échec réseau → cache return caches.match(event.request); }) ); });
📦 Modules de Gestion
Inventaire (inventaire.js)
Gestion complète du stock alimentaire avec suivi DLC et alertes automatiques.
Zones de Stockage
const ZONES_STOCKAGE = { 'frigo': { label: 'Réfrigérateur', temp: '0-4°C', icon: '❄️' }, 'chambre-froide': { label: 'Chambre froide positive', temp: '0-4°C', icon: '🧊' }, 'congelateur': { label: 'Congélateur', temp: '-18°C', icon: '⬜' }, 'reserve-seche': { label: 'Réserve sèche', temp: '15-25°C', icon: '📦' }, 'legumerie': { label: 'Légumerie', temp: '10-15°C', icon: '🥬' } }
Statuts DLC avec Code Couleur
| Statut | Condition | Badge | Action |
|---|---|---|---|
| Périmé | DLC dépassée | PÉRIMÉ | Retrait immédiat obligatoire |
| Critique | DLC ≤ 2 jours | J-1 | Utiliser prioritairement |
| Proche | DLC ≤ 5 jours | J-3 | Planifier utilisation |
| OK | DLC > 5 jours | OK | Aucune action |
Fonctions Principales
Agents (agents.js)
Gestion du personnel, des secteurs d'affectation et des comptes utilisateur.
48 Secteurs Prédéfinis
const DEFAULT_SECTORS = [ // Écoles 'École A', 'École B', 'École C', ..., // Collèges 'Collège Centre', 'Collège Nord', ..., // Autres 'EHPAD', 'Crèche municipale', 'Centre de loisirs', ... // Total : 48 secteurs ]
Groupes Prédéfinis
Workflow Création Utilisateur
Crypto.addUserToKeyring(pin, agentId) pour accès données chiffréesArchivage vs Suppression
Stock Entretien (stock-entretien.js)
Gestion des commandes internes de fournitures/équipements entre agents et managers.
Workflow Commande Interne
✅ Audit & Conformité
Audit (audit.js) — Score /100
Système de scoring automatique basé sur les données saisies dans l'application.
Calcul du Score
function calculateScore() { let score = 0; const today = Storage.today(); // Températures (25 points max) const temps = Storage.getTemperatures(today); if (temps.length >= 3) score += 15; // Complétion if (temps.every(t => t.conforme)) score += 10; // Conformité // Nettoyages (20 points max) const nets = Storage.getNettoyages(today); if (nets.length >= 5) score += 20; // Réceptions (15 points max) const recs = Storage.getReceptions(today); if (recs.length > 0 && recs.every(r => r.conforme)) score += 15; // Traçabilité (15 points max) if (hasValidDLC()) score += 15; // Allergènes (15 points max) if (hasAllergenDeclarations()) score += 15; // Formation (10 points max) if (hasTrainedStaff()) score += 10; return score; // /100 }
Interprétation
| Score | Note | Signification |
|---|---|---|
| 90-100 | A | Excellent — Prêt pour contrôle DDPP |
| 75-89 | B | Bon — Quelques améliorations mineures |
| 60-74 | C | Satisfaisant — Actions correctives requises |
| <60 | D | Insuffisant — Mesures urgentes |
Simulateur DDPP (simulateur.js)
Simulation d'inspection officielle avec 87 questions réparties en 14 sections.
Les 14 Sections
Exemple de Question
{
"section": 7,
"question": "Les températures des produits sont-elles vérifiées à réception ?",
"ref_reglementaire": "CE 852/2004 Annexe II Chap. IX",
"criticite": "majeure",
"options": [
{ "label": "Oui, systématiquement", "score": 4 },
{ "label": "Parfois", "score": 2 },
{ "label": "Non", "score": 0 }
]
}
Notation Finale
- A — Très satisfaisant (aucune NC majeure)
- B — Satisfaisant (NC mineures corrigibles)
- C — À améliorer (NC majeures présentes)
- D — Non conforme (fermeture administrative possible)
🎓 Modules de Formation
Formation de Base (formation.js)
Quiz HACCP interactifs avec suivi de progression.
Caractéristiques
Formation 14h Pro (fp-module-01.js → 07.js)
Formation professionnelle conforme à la réglementation sur l'hygiène alimentaire (14h obligatoires).
Les 7 Modules
| Module | Titre | Durée | Contenu |
|---|---|---|---|
| FP-01 | Dangers alimentaires | 2h | Microbiologie, chimiques, physiques |
| FP-02 | Réglementation | 2h | Paquet Hygiène, normes françaises |
| FP-03 | Plan HACCP | 2h | 7 principes, 12 étapes, CCP |
| FP-04 | Bonnes Pratiques | 2h | BPH, marche en avant, 5M |
| FP-05 | Nettoyage-Désinfection | 2h | TACT, protocoles, contrôles |
| FP-06 | Gestion des allergènes | 2h | 14 allergènes, cross-contact, PAI |
| FP-07 | Traçabilité & rappels | 2h | Lots, retraits, gestion crise |
Structure d'un Module
const FPModule01 = { metadata: { id: 'fp-01', title: 'Dangers alimentaires', duration: 120, // minutes prerequisites: [] // Aucun pour le 1er }, sections: [ { title: 'Les dangers microbiologiques', content: `...HTML du cours...`, quiz: [ { question: 'Quelle bactérie cause le botulisme ?', options: ['Salmonella', 'Clostridium botulinum', 'E. coli'], correct: 1, explanation: 'Clostridium botulinum produit une toxine mortelle...' } ] } ], render() { /* Affichage du module */ }, submitQuiz() { /* Validation des réponses */ } }
Centre de Formation (centre-formation.js)
Tableau de bord administrateur pour suivre les formations de toute l'équipe.
Fonctionnalités
- Vue globale de la progression de chaque agent
- Export PDF des attestations
- Relance automatique des formations expirées (rappel tous les 3 ans)
- Statistiques de complétion par secteur/groupe
⚠️ Sécurité Alimentaire
Allergènes (allergenes.js)
Déclaration et suivi des 14 allergènes à déclaration obligatoire (Règlement UE 1169/2011).
Les 14 Allergènes Obligatoires
Déclaration par Plat
// Structure d'un plat avec allergènes { "id": "plat_001", "nom": "Gratin dauphinois", "allergenes": ["lactose", "gluten"], "ingredients": ["pommes de terre", "crème", "lait"], "traces_possibles": ["oeufs"], // Cross-contact "date_declaration": "2026-03-10", "declarant": "Chef Martin" }
PAI — Projet d'Accueil Individualisé (pai.js)
Gestion des régimes alimentaires spéciaux pour enfants avec allergies/intolérances.
Structure d'un PAI
{
"id": "pai_001",
"enfant": {
"prenom": "Lucas",
"nom": "D.", // Nom tronqué
"classe": "CM1",
"etablissement": "École Jean Moulin"
},
"allergies": ["arachides", "fruits_coque"],
"protocole": "PAI avec kit d'urgence",
"contacts_urgence": [...],
"date_validite": "2026-09-01",
"medecin": "Dr. Martin"
}
Alertes Menu-PAI
Le module menu-pai-crosscheck.js croise automatiquement les menus du jour avec les PAI actifs et génère des alertes si un plat contient un allergène concerné.
TIAC — Toxi-Infection Alimentaire (tiac.js)
Enregistrement et suivi des incidents de toxi-infection alimentaire collective.
Workflow de Déclaration TIAC
🔧 Autres Modules
journal_{date}).