chore: Phase 1 complète — socle technique HomeHub opérationnel
- 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 <noreply@anthropic.com>
This commit is contained in:
+39
-19
@@ -6,7 +6,8 @@ import asyncio
|
|||||||
import json
|
import json
|
||||||
from pathlib import Path
|
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.core.database import AsyncSessionLocal
|
||||||
from app.models.shopping import Product, Store
|
from app.models.shopping import Product, Store
|
||||||
@@ -15,27 +16,46 @@ DATA_DIR = Path(__file__).parent
|
|||||||
|
|
||||||
|
|
||||||
async def run_seed() -> None:
|
async def run_seed() -> None:
|
||||||
async with AsyncSessionLocal() as session:
|
try:
|
||||||
count = await session.scalar(select(Store).limit(1))
|
async with AsyncSessionLocal() as session:
|
||||||
if count is not None:
|
# Vérifier que la table existe avant de faire le seed
|
||||||
print("Seed déjà chargé — rien à faire.")
|
try:
|
||||||
return
|
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())
|
if not table_exists:
|
||||||
for s in stores_raw:
|
print("Seed ignoré — les migrations Alembic n'ont pas encore été appliquées.")
|
||||||
session.add(Store(name=s["name"], location=s.get("location")))
|
return
|
||||||
|
|
||||||
products_raw = json.loads((DATA_DIR / "seed_products.json").read_text())
|
count = await session.scalar(select(Store).limit(1))
|
||||||
for p in products_raw:
|
if count is not None:
|
||||||
session.add(Product(
|
print("Seed déjà chargé — rien à faire.")
|
||||||
name=p["name"],
|
return
|
||||||
category=p.get("category"),
|
|
||||||
default_unit=p.get("default_unit"),
|
|
||||||
frequency_score=p.get("frequency_score", 0),
|
|
||||||
))
|
|
||||||
|
|
||||||
await session.commit()
|
stores_raw = json.loads((DATA_DIR / "seed_stores.json").read_text())
|
||||||
print(f"Seed : {len(stores_raw)} magasins, {len(products_raw)} produits chargés.")
|
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__":
|
if __name__ == "__main__":
|
||||||
|
|||||||
+1
-1
@@ -30,7 +30,7 @@ services:
|
|||||||
frontend:
|
frontend:
|
||||||
build: ./frontend
|
build: ./frontend
|
||||||
ports:
|
ports:
|
||||||
- "3000:80"
|
- "3001:80"
|
||||||
depends_on:
|
depends_on:
|
||||||
- backend
|
- backend
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user