← Phase 1 Overview / Food Module
🍜
Module 7 — Phase 1 MVP

Food & Boissons

Association plats/lieux avec photos, classements communautaires, prix et alertes sécurité alimentaire par destination.

Backlog

User Stories

US7.1
En tant qu'utilisateur, je peux associer un plat ou une boisson à un lieu (photo + nom + prix + note)
must 5 pts
US7.2
En tant qu'utilisateur, je vois les photos food d'un lieu en mosaïque avec prix en overlay
must 4 pts
US7.3
En tant qu'utilisateur, je vois le classement "Top 5 plats à essayer" par lieu (note communautaire)
must 4 pts
US7.4
En tant qu'utilisateur, je peux noter un plat (1-5 étoiles) et laisser un commentaire
must 3 pts
US7.5
En tant qu'utilisateur, je peux signaler un plat "À éviter" avec motif (hygiène, goût, rapport qualité/prix)
should 3 pts
US7.6
En tant qu'utilisateur, je peux filtrer les options food par type (végé, vegan, halal, street food)
should 3 pts
US7.7
En tant qu'utilisateur, je vois des alertes sécurité alimentaire associées à un pays/plat
should 4 pts
US7.8
En tant qu'utilisateur, je peux demander au copilote "Où manger végétarien à Lisbonne ?"
must 3 pts
US7.9
En tant que système, les plats populaires d'un lieu remontent dans les recommandations du copilote
should 4 pts
REST API /food

Endpoints API

GET /food/places/:placeId Liste des plats d'un lieu (paginé) public
POST /food/items Ajouter un plat à un lieu 🔒 auth
GET /food/items/:id Détail d'un plat public
POST /food/items/:id/review Noter + commenter un plat 🔒 auth
POST /food/items/:id/flag Signaler "À éviter" 🔒 auth
GET /food/places/:placeId/top Top 5 plats (classés par note) public
GET /food/search ?q=&place_id=&type=&diet= (Typesense) public
GET /food/safety-alerts ?country= — alertes sécurité alimentaire public
Data + Business Logic

Schéma de données & Règles

TABLE food_items
id UUID PRIMARY KEY place_id UUID REFERENCES places(id) added_by UUID REFERENCES users(id) name TEXT NOT NULL description TEXT photo_url TEXT NOT NULL price DECIMAL(8,2) currency CHAR(3) diet_tags TEXT[] -- veggie, vegan, halal, gluten_free avg_rating FLOAT DEFAULT 0.0 review_count INT DEFAULT 0 avoid_flags INT DEFAULT 0 -- nb signalements "à éviter" status ENUM('active','flagged','hidden') created_at TIMESTAMPTZ DEFAULT NOW()
TABLE food_reviews
id UUID PRIMARY KEY food_item_id UUID REFERENCES food_items(id) user_id UUID REFERENCES users(id) rating INT CHECK (rating BETWEEN 1 AND 5) comment TEXT is_avoid_flag BOOLEAN DEFAULT false avoid_reason ENUM('hygiene','taste','price','other') created_at TIMESTAMPTZ DEFAULT NOW() UNIQUE (food_item_id, user_id)
Calcul avg_rating
Trigger PostgreSQL recalcule avg_rating et review_count à chaque INSERT/UPDATE dans food_reviews. Dénormalisé pour éviter les COUNT() coûteux.
🚩
Auto-masquage si trop de signalements
Si avoid_flags ≥ 5 → status passe à "flagged" → ticket modération créé automatiquement. Si ratio avoid_flags/review_count > 0.4 → masqué en attendant modération.
Critères d'acceptation
Photo food uploadée et visible en < 5s
Top 5 plats calculé en temps réel, rafraîchi après chaque nouvelle review
Filtre diet fonctionnel : résultats uniquement du type sélectionné
Signalement "À éviter" : modération notifiée en < 1 min