{"openapi":"3.0.3","info":{"title":"Miou Miou API","description":"API REST pour l'application Miou Miou (commandes client + back-office). Authentification JWT Bearer pour les routes admin.","version":"1.0.0","contact":{"name":"Miou Miou"}},"servers":[{"url":"https://webservice.mioumiou.ci","description":"Ce serveur"}],"tags":[{"name":"Status","description":"Santé du service"},{"name":"Auth","description":"Authentification admin"},{"name":"Menu","description":"Produits, variantes et images"},{"name":"Categories","description":"Catégories du menu"},{"name":"Customers","description":"Clients (admin)"},{"name":"Tables","description":"Tables du restaurant"},{"name":"Orders","description":"Commandes"},{"name":"Stats","description":"Statistiques back-office"}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT"}},"schemas":{"Error":{"type":"object","properties":{"error":{"type":"string"}}},"Health":{"type":"object","properties":{"ok":{"type":"boolean"},"service":{"type":"string"},"version":{"type":"string"},"env":{"type":"string"},"timestamp":{"type":"string","format":"date-time"},"uptimeSec":{"type":"integer"},"api":{"type":"object","properties":{"ok":{"type":"boolean"},"status":{"type":"string","enum":["up","down"]},"port":{"type":"integer"}}},"database":{"type":"object","properties":{"ok":{"type":"boolean"},"status":{"type":"string","enum":["up","down"]},"latencyMs":{"type":"integer"},"host":{"type":"string"},"port":{"type":"integer"},"database":{"type":"string"},"error":{"type":"string"}}}}},"LoginRequest":{"type":"object","required":["login","password"],"properties":{"login":{"type":"string","example":"admin"},"password":{"type":"string","example":"admin"}}},"LoginResponse":{"type":"object","properties":{"token":{"type":"string"},"user":{"type":"object","properties":{"id":{"type":"integer"},"email":{"type":"string"},"name":{"type":"string"},"role":{"type":"string"}}}}},"MenuItem":{"type":"object","properties":{"id":{"type":"integer"},"name":{"type":"string"},"description":{"type":"string"},"price":{"type":"number"},"categoryId":{"type":"integer"},"available":{"type":"boolean"},"images":{"type":"array","items":{"type":"object"}},"variants":{"type":"array","items":{"type":"object"}}}},"OrderCreate":{"type":"object","properties":{"type":{"type":"string","enum":["dine-in","takeaway","delivery"]},"payment":{"type":"string"},"customerName":{"type":"string"},"customerPhone":{"type":"string"},"tableId":{"type":"integer","nullable":true},"items":{"type":"array","items":{"type":"object","properties":{"menuItemId":{"type":"integer"},"qty":{"type":"integer"},"options":{"type":"array","items":{"type":"object"}}}}}}}}},"paths":{"/api/health":{"get":{"tags":["Status"],"summary":"État API + base de données","responses":{"200":{"description":"Statut (HTTP 200 même si DB down — champ ok=false)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Health"}}}},"503":{"description":"Service indisponible (si ?strict=1 et DB down)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Health"}}}}}}},"/api/auth/login":{"post":{"tags":["Auth"],"summary":"Connexion admin","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LoginRequest"}}}},"responses":{"200":{"description":"JWT + utilisateur","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LoginResponse"}}}},"401":{"description":"Identifiants invalides","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/auth/me":{"get":{"tags":["Auth"],"summary":"Utilisateur courant","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Profil admin"},"401":{"description":"Non authentifié"}}}},"/api/menu":{"get":{"tags":["Menu"],"summary":"Liste des produits","parameters":[{"name":"categoryId","in":"query","schema":{"type":"integer"}},{"name":"available","in":"query","schema":{"type":"boolean"}}],"responses":{"200":{"description":"Liste menu","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/MenuItem"}}}}}}},"post":{"tags":["Menu"],"summary":"Créer un produit","security":[{"bearerAuth":[]}],"responses":{"201":{"description":"Produit créé"},"401":{"description":"Non authentifié"}}}},"/api/menu/{id}":{"get":{"tags":["Menu"],"summary":"Détail produit","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Produit"},"404":{"description":"Introuvable"}}},"put":{"tags":["Menu"],"summary":"Mettre à jour un produit","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Produit mis à jour"},"401":{"description":"Non authentifié"}}},"delete":{"tags":["Menu"],"summary":"Supprimer un produit","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}}],"responses":{"204":{"description":"Supprimé"},"401":{"description":"Non authentifié"}}}},"/api/menu/{id}/images":{"post":{"tags":["Menu"],"summary":"Upload images produit (multipart)","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"type":"object","properties":{"images":{"type":"array","items":{"type":"string","format":"binary"}}}}}}},"responses":{"200":{"description":"Images ajoutées"},"401":{"description":"Non authentifié"}}}},"/api/menu/{id}/images/{imageId}":{"delete":{"tags":["Menu"],"summary":"Supprimer une image produit","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}},{"name":"imageId","in":"path","required":true,"schema":{"type":"integer"}}],"responses":{"204":{"description":"Supprimée"}}}},"/api/menu/{id}/options/{optionId}/images":{"post":{"tags":["Menu"],"summary":"Upload images d'une option de variante","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}},{"name":"optionId","in":"path","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Images ajoutées"}}}},"/api/menu/{id}/options/{optionId}/images/{imageId}":{"delete":{"tags":["Menu"],"summary":"Supprimer une image d'option","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}},{"name":"optionId","in":"path","required":true,"schema":{"type":"integer"}},{"name":"imageId","in":"path","required":true,"schema":{"type":"integer"}}],"responses":{"204":{"description":"Supprimée"}}}},"/api/categories":{"get":{"tags":["Categories"],"summary":"Liste des catégories","responses":{"200":{"description":"Liste"}}},"post":{"tags":["Categories"],"summary":"Créer une catégorie","security":[{"bearerAuth":[]}],"responses":{"201":{"description":"Créée"}}}},"/api/categories/{id}":{"put":{"tags":["Categories"],"summary":"Mettre à jour une catégorie","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Mise à jour"}}},"delete":{"tags":["Categories"],"summary":"Supprimer une catégorie","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}}],"responses":{"204":{"description":"Supprimée"}}}},"/api/customers":{"get":{"tags":["Customers"],"summary":"Liste des clients","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Liste"}}},"post":{"tags":["Customers"],"summary":"Créer un client","security":[{"bearerAuth":[]}],"responses":{"201":{"description":"Créé"}}}},"/api/customers/{id}":{"get":{"tags":["Customers"],"summary":"Détail client","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Client"}}},"put":{"tags":["Customers"],"summary":"Mettre à jour un client","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Mis à jour"}}},"delete":{"tags":["Customers"],"summary":"Supprimer un client","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}}],"responses":{"204":{"description":"Supprimé"}}}},"/api/tables":{"get":{"tags":["Tables"],"summary":"Liste des tables","responses":{"200":{"description":"Liste"}}},"post":{"tags":["Tables"],"summary":"Créer une table","security":[{"bearerAuth":[]}],"responses":{"201":{"description":"Créée"}}}},"/api/tables/{id}":{"put":{"tags":["Tables"],"summary":"Mettre à jour une table","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Mise à jour"}}},"delete":{"tags":["Tables"],"summary":"Supprimer une table","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}}],"responses":{"204":{"description":"Supprimée"}}}},"/api/tables/{id}/status":{"patch":{"tags":["Tables"],"summary":"Changer le statut d'une table","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Statut mis à jour"}}}},"/api/orders":{"get":{"tags":["Orders"],"summary":"Liste des commandes","parameters":[{"name":"status","in":"query","schema":{"type":"string"}},{"name":"type","in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":"Liste"}}},"post":{"tags":["Orders"],"summary":"Créer une commande (public)","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrderCreate"}}}},"responses":{"201":{"description":"Commande créée"}}}},"/api/orders/{id}":{"get":{"tags":["Orders"],"summary":"Détail commande","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Commande"},"404":{"description":"Introuvable"}}},"put":{"tags":["Orders"],"summary":"Mise à jour complète (admin)","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Mise à jour"}}},"patch":{"tags":["Orders"],"summary":"Mise à jour partielle (statut / paiement)","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Mise à jour"}}},"delete":{"tags":["Orders"],"summary":"Supprimer une commande","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}}],"responses":{"204":{"description":"Supprimée"}}}},"/api/stats":{"get":{"tags":["Stats"],"summary":"Statistiques dashboard","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"KPIs"},"401":{"description":"Non authentifié"}}}}}}