From 9041b24384bd7af0cce0482086af550874e19f78 Mon Sep 17 00:00:00 2001 From: Gilles Soulier Date: Sun, 24 May 2026 05:30:53 +0200 Subject: [PATCH] =?UTF-8?q?chore:=20Phase=201=20compl=C3=A8te=20=E2=80=94?= =?UTF-8?q?=20socle=20technique=20HomeHub=20op=C3=A9rationnel?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Corrige le seed pour vérifier l'existence des tables avant insertion (évite l'échec au démarrage si les migrations n'ont pas encore été appliquées) - Ajuste le port frontend de 3000 à 3001 (port 3000 occupé sur l'hôte) - Migrations Alembic : schémas notes, shopping, todos créés avec succès - Seed : 114 produits et 9 magasins chargés - Endpoint /api/health : {"status":"ok"} - Tests : 6/6 passent (health + media) Co-Authored-By: Claude Sonnet 4.6 --- backend/app/data/seed.py | 58 +++++++++++++++++++++++++++------------- docker-compose.yml | 2 +- 2 files changed, 40 insertions(+), 20 deletions(-) diff --git a/backend/app/data/seed.py b/backend/app/data/seed.py index 6a12991..780e8a2 100644 --- a/backend/app/data/seed.py +++ b/backend/app/data/seed.py @@ -6,7 +6,8 @@ import asyncio import json from pathlib import Path -from sqlalchemy import select +from sqlalchemy import select, text +from sqlalchemy.exc import ProgrammingError from app.core.database import AsyncSessionLocal from app.models.shopping import Product, Store @@ -15,27 +16,46 @@ DATA_DIR = Path(__file__).parent async def run_seed() -> None: - async with AsyncSessionLocal() as session: - count = await session.scalar(select(Store).limit(1)) - if count is not None: - print("Seed déjà chargé — rien à faire.") - return + try: + async with AsyncSessionLocal() as session: + # Vérifier que la table existe avant de faire le seed + try: + result = await session.execute( + text( + "SELECT COUNT(*) FROM information_schema.tables " + "WHERE table_schema = 'shopping' AND table_name = 'stores'" + ) + ) + table_exists = result.scalar() > 0 + except Exception: + table_exists = False - stores_raw = json.loads((DATA_DIR / "seed_stores.json").read_text()) - for s in stores_raw: - session.add(Store(name=s["name"], location=s.get("location"))) + if not table_exists: + print("Seed ignoré — les migrations Alembic n'ont pas encore été appliquées.") + return - products_raw = json.loads((DATA_DIR / "seed_products.json").read_text()) - for p in products_raw: - session.add(Product( - name=p["name"], - category=p.get("category"), - default_unit=p.get("default_unit"), - frequency_score=p.get("frequency_score", 0), - )) + count = await session.scalar(select(Store).limit(1)) + if count is not None: + print("Seed déjà chargé — rien à faire.") + return - await session.commit() - print(f"Seed : {len(stores_raw)} magasins, {len(products_raw)} produits chargés.") + stores_raw = json.loads((DATA_DIR / "seed_stores.json").read_text()) + for s in stores_raw: + session.add(Store(name=s["name"], location=s.get("location"))) + + products_raw = json.loads((DATA_DIR / "seed_products.json").read_text()) + for p in products_raw: + session.add(Product( + name=p["name"], + category=p.get("category"), + default_unit=p.get("default_unit"), + frequency_score=p.get("frequency_score", 0), + )) + + await session.commit() + print(f"Seed : {len(stores_raw)} magasins, {len(products_raw)} produits chargés.") + except ProgrammingError as e: + print(f"Seed ignoré — tables non disponibles (migrations requises) : {e}") if __name__ == "__main__": diff --git a/docker-compose.yml b/docker-compose.yml index 7a70420..c7d9b21 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -30,7 +30,7 @@ services: frontend: build: ./frontend ports: - - "3000:80" + - "3001:80" depends_on: - backend