From 8bc69bb705920cd5b3156b436f4f3ef2dc38b1f8 Mon Sep 17 00:00:00 2001 From: Gilles Soulier Date: Sun, 24 May 2026 04:45:16 +0200 Subject: [PATCH] chore: structure initiale backend et docker-compose --- .env.example | 3 + backend/app/__init__.py | 0 backend/app/api/__init__.py | 0 backend/app/core/__init__.py | 0 backend/app/data/__init__.py | 0 backend/app/data/seed_products.json | 116 ++++++++++++++++++++++++++++ backend/app/data/seed_stores.json | 11 +++ backend/app/models/__init__.py | 0 backend/app/schemas/__init__.py | 0 backend/app/services/__init__.py | 0 backend/tests/__init__.py | 0 docker-compose.yml | 39 ++++++++++ 12 files changed, 169 insertions(+) create mode 100644 .env.example create mode 100644 backend/app/__init__.py create mode 100644 backend/app/api/__init__.py create mode 100644 backend/app/core/__init__.py create mode 100644 backend/app/data/__init__.py create mode 100644 backend/app/data/seed_products.json create mode 100644 backend/app/data/seed_stores.json create mode 100644 backend/app/models/__init__.py create mode 100644 backend/app/schemas/__init__.py create mode 100644 backend/app/services/__init__.py create mode 100644 backend/tests/__init__.py create mode 100644 docker-compose.yml diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..4e29b25 --- /dev/null +++ b/.env.example @@ -0,0 +1,3 @@ +DATABASE_URL=postgresql+asyncpg://homehub:homehub@db:5432/homehub +UPLOAD_DIR=/uploads +CORS_ORIGINS=http://localhost:3000,http://frontend:3000 diff --git a/backend/app/__init__.py b/backend/app/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/backend/app/api/__init__.py b/backend/app/api/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/backend/app/core/__init__.py b/backend/app/core/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/backend/app/data/__init__.py b/backend/app/data/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/backend/app/data/seed_products.json b/backend/app/data/seed_products.json new file mode 100644 index 0000000..a594d29 --- /dev/null +++ b/backend/app/data/seed_products.json @@ -0,0 +1,116 @@ +[ + { "name": "Aliment poussin", "category": "Animaux", "default_unit": "sac", "frequency_score": 5 }, + { "name": "Baguette", "category": "Boulangerie", "default_unit": "unité", "frequency_score": 8 }, + { "name": "Bière", "category": "Boissons", "default_unit": "pack", "frequency_score": 5 }, + { "name": "Biscotte", "category": "Épicerie sucrée", "default_unit": "paquet", "frequency_score": 5 }, + { "name": "Boule choux", "category": "Légumes", "default_unit": "unité", "frequency_score": 5 }, + { "name": "Briquet", "category": "Divers", "default_unit": "unité", "frequency_score": 3 }, + { "name": "Brugnon", "category": "Fruits", "default_unit": "kg", "frequency_score": 4 }, + { "name": "Café", "category": "Boissons", "default_unit": "paquet", "frequency_score": 8 }, + { "name": "Carotte rouge", "category": "Légumes", "default_unit": "kg", "frequency_score": 6 }, + { "name": "Cartouche CO2", "category": "Divers", "default_unit": "unité", "frequency_score": 2 }, + { "name": "Cervelas", "category": "Charcuterie", "default_unit": "unité", "frequency_score": 4 }, + { "name": "Chair à farcir", "category": "Viandes", "default_unit": "kg", "frequency_score": 3 }, + { "name": "Champignon", "category": "Légumes", "default_unit": "kg", "frequency_score": 5 }, + { "name": "Charcuterie", "category": "Charcuterie", "default_unit": "paquet", "frequency_score": 6 }, + { "name": "Chipolata", "category": "Viandes", "default_unit": "paquet", "frequency_score": 5 }, + { "name": "Chocolat", "category": "Épicerie sucrée", "default_unit": "tablette","frequency_score": 6 }, + { "name": "Chou-fleur", "category": "Légumes", "default_unit": "unité", "frequency_score": 4 }, + { "name": "Citron", "category": "Fruits", "default_unit": "filet", "frequency_score": 6 }, + { "name": "Coca-Cola", "category": "Boissons", "default_unit": "bouteille","frequency_score": 5 }, + { "name": "Coquillage", "category": "Poissons", "default_unit": "kg", "frequency_score": 3 }, + { "name": "Compote", "category": "Épicerie sucrée", "default_unit": "paquet", "frequency_score": 5 }, + { "name": "Cornichon", "category": "Condiments", "default_unit": "bocal", "frequency_score": 4 }, + { "name": "Coude pâte", "category": "Épicerie salée", "default_unit": "paquet", "frequency_score": 5 }, + { "name": "Cracotte", "category": "Épicerie sucrée", "default_unit": "paquet", "frequency_score": 4 }, + { "name": "Crème fraîche", "category": "Produits laitiers", "default_unit": "pot", "frequency_score": 6 }, + { "name": "Croquettes (animaux)", "category": "Animaux", "default_unit": "sac", "frequency_score": 5 }, + { "name": "Dessert pistache", "category": "Produits laitiers", "default_unit": "paquet", "frequency_score": 4 }, + { "name": "Dessert vanille", "category": "Produits laitiers", "default_unit": "paquet", "frequency_score": 4 }, + { "name": "Dos de cabillaud", "category": "Poissons", "default_unit": "kg", "frequency_score": 4 }, + { "name": "Éponge", "category": "Entretien", "default_unit": "paquet", "frequency_score": 3 }, + { "name": "Essence", "category": "Carburant", "default_unit": "L", "frequency_score": 5 }, + { "name": "Farine", "category": "Épicerie salée", "default_unit": "kg", "frequency_score": 4 }, + { "name": "Filet de truite", "category": "Poissons", "default_unit": "kg", "frequency_score": 4 }, + { "name": "Filtre à café", "category": "Divers", "default_unit": "boîte", "frequency_score": 4 }, + { "name": "Fond de veau", "category": "Épicerie salée", "default_unit": "boîte", "frequency_score": 3 }, + { "name": "Fromage bleu", "category": "Produits laitiers", "default_unit": "unité", "frequency_score": 4 }, + { "name": "Fromage brebis frais", "category": "Produits laitiers", "default_unit": "unité", "frequency_score": 4 }, + { "name": "Fromage de tête", "category": "Charcuterie", "default_unit": "tranche","frequency_score": 3 }, + { "name": "Fromage frais", "category": "Produits laitiers", "default_unit": "kg", "frequency_score": 5 }, + { "name": "Bananes", "category": "Fruits", "default_unit": "kg", "frequency_score": 7 }, + { "name": "Kiwi", "category": "Fruits", "default_unit": "filet", "frequency_score": 5 }, + { "name": "Oranges", "category": "Fruits", "default_unit": "filet", "frequency_score": 6 }, + { "name": "Poires", "category": "Fruits", "default_unit": "kg", "frequency_score": 5 }, + { "name": "Gâteau", "category": "Épicerie sucrée", "default_unit": "paquet", "frequency_score": 5 }, + { "name": "Gaz bouteille", "category": "Divers", "default_unit": "unité", "frequency_score": 3 }, + { "name": "Gasoil", "category": "Carburant", "default_unit": "L", "frequency_score": 5 }, + { "name": "Gratin dauphinois", "category": "Épicerie salée", "default_unit": "barquette","frequency_score": 4 }, + { "name": "Haricot vert", "category": "Légumes", "default_unit": "kg", "frequency_score": 5 }, + { "name": "Huile tournesol", "category": "Condiments", "default_unit": "L", "frequency_score": 5 }, + { "name": "Huile tournesol 3L", "category": "Condiments", "default_unit": "bidon", "frequency_score": 3 }, + { "name": "Huile d'olive", "category": "Condiments", "default_unit": "bouteille","frequency_score": 5 }, + { "name": "Îles flottantes", "category": "Produits laitiers", "default_unit": "paquet", "frequency_score": 4 }, + { "name": "Jambon", "category": "Charcuterie", "default_unit": "paquet", "frequency_score": 7 }, + { "name": "Jarret de porc", "category": "Viandes", "default_unit": "kg", "frequency_score": 3 }, + { "name": "Ketchup", "category": "Condiments", "default_unit": "bouteille","frequency_score": 5 }, + { "name": "Lait demi-écrémé", "category": "Boissons", "default_unit": "lot 6", "frequency_score": 8 }, + { "name": "Lardon", "category": "Charcuterie", "default_unit": "paquet", "frequency_score": 7 }, + { "name": "Lard frais", "category": "Charcuterie", "default_unit": "kg", "frequency_score": 4 }, + { "name": "Lard séché", "category": "Charcuterie", "default_unit": "paquet", "frequency_score": 4 }, + { "name": "Lave-vaisselle", "category": "Entretien", "default_unit": "paquet", "frequency_score": 4 }, + { "name": "Lave-vitre", "category": "Entretien", "default_unit": "bouteille","frequency_score": 3 }, + { "name": "Lentilles", "category": "Épicerie salée", "default_unit": "paquet", "frequency_score": 4 }, + { "name": "Lentilles en boîte", "category": "Épicerie salée", "default_unit": "boîte", "frequency_score": 4 }, + { "name": "Lessive", "category": "Entretien", "default_unit": "kg", "frequency_score": 5 }, + { "name": "Nettoyant sol", "category": "Entretien", "default_unit": "bouteille","frequency_score": 4 }, + { "name": "Maïs en boîte", "category": "Épicerie salée", "default_unit": "boîte", "frequency_score": 5 }, + { "name": "Mandarines", "category": "Fruits", "default_unit": "filet", "frequency_score": 5 }, + { "name": "Mayonnaise", "category": "Condiments", "default_unit": "pot", "frequency_score": 5 }, + { "name": "Médicament", "category": "Pharmacie", "default_unit": "boîte", "frequency_score": 3 }, + { "name": "Morue", "category": "Poissons", "default_unit": "kg", "frequency_score": 3 }, + { "name": "Moutarde", "category": "Condiments", "default_unit": "pot", "frequency_score": 5 }, + { "name": "Multiprise", "category": "Électronique", "default_unit": "unité", "frequency_score": 1 }, + { "name": "Nez cuit", "category": "Charcuterie", "default_unit": "unité", "frequency_score": 3 }, + { "name": "Nez de cochon", "category": "Charcuterie", "default_unit": "unité", "frequency_score": 3 }, + { "name": "Pâtes", "category": "Épicerie salée", "default_unit": "paquet", "frequency_score": 7 }, + { "name": "Papier toilette", "category": "Entretien", "default_unit": "paquet", "frequency_score": 6 }, + { "name": "Pastille pour la toux", "category": "Pharmacie", "default_unit": "boîte", "frequency_score": 3 }, + { "name": "Pastille Vichy", "category": "Épicerie sucrée", "default_unit": "tube", "frequency_score": 4 }, + { "name": "Petit pois", "category": "Légumes", "default_unit": "boîte", "frequency_score": 5 }, + { "name": "Pied de cochon cuit", "category": "Charcuterie", "default_unit": "unité", "frequency_score": 3 }, + { "name": "Poisson", "category": "Poissons", "default_unit": "kg", "frequency_score": 5 }, + { "name": "Poitrine roulée séchée", "category": "Charcuterie", "default_unit": "paquet", "frequency_score": 4 }, + { "name": "Poulet", "category": "Viandes", "default_unit": "unité", "frequency_score": 7 }, + { "name": "Poussin", "category": "Viandes", "default_unit": "unité", "frequency_score": 4 }, + { "name": "Prise tripolaire", "category": "Électronique", "default_unit": "unité", "frequency_score": 1 }, + { "name": "Pruneau", "category": "Fruits", "default_unit": "paquet", "frequency_score": 4 }, + { "name": "Quenelle", "category": "Épicerie salée", "default_unit": "boîte", "frequency_score": 4 }, + { "name": "Raisin", "category": "Fruits", "default_unit": "kg", "frequency_score": 5 }, + { "name": "Fromage râpé", "category": "Produits laitiers", "default_unit": "paquet", "frequency_score": 7 }, + { "name": "Résille d'or praliné", "category": "Épicerie sucrée", "default_unit": "paquet", "frequency_score": 3 }, + { "name": "Riz", "category": "Épicerie salée", "default_unit": "kg", "frequency_score": 6 }, + { "name": "Sac poubelle 10L", "category": "Entretien", "default_unit": "rouleau","frequency_score": 4 }, + { "name": "Sac poubelle 30L", "category": "Entretien", "default_unit": "rouleau","frequency_score": 4 }, + { "name": "Salade de fruits", "category": "Fruits", "default_unit": "boîte", "frequency_score": 4 }, + { "name": "Sardine", "category": "Poissons", "default_unit": "boîte", "frequency_score": 5 }, + { "name": "Sauce salade", "category": "Condiments", "default_unit": "bouteille","frequency_score": 5 }, + { "name": "Saucisse à cuire", "category": "Viandes", "default_unit": "paquet", "frequency_score": 5 }, + { "name": "Saucisse de Strasbourg", "category": "Charcuterie", "default_unit": "paquet", "frequency_score": 5 }, + { "name": "Sel", "category": "Condiments", "default_unit": "kg", "frequency_score": 5 }, + { "name": "Sirop cassis", "category": "Boissons", "default_unit": "bouteille","frequency_score": 5 }, + { "name": "Sirop citron", "category": "Boissons", "default_unit": "bouteille","frequency_score": 5 }, + { "name": "Sucre en morceaux", "category": "Épicerie sucrée", "default_unit": "paquet", "frequency_score": 4 }, + { "name": "Sucre en poudre", "category": "Épicerie sucrée", "default_unit": "kg", "frequency_score": 6 }, + { "name": "Tomate", "category": "Légumes", "default_unit": "kg", "frequency_score": 7 }, + { "name": "Tomates concassées", "category": "Épicerie salée", "default_unit": "boîte", "frequency_score": 6 }, + { "name": "Torsade", "category": "Épicerie salée", "default_unit": "paquet", "frequency_score": 4 }, + { "name": "Tranche de lard grillée", "category": "Charcuterie", "default_unit": "paquet", "frequency_score": 4 }, + { "name": "Tranche de lard", "category": "Charcuterie", "default_unit": "paquet", "frequency_score": 5 }, + { "name": "Tranche de rôti", "category": "Charcuterie", "default_unit": "paquet", "frequency_score": 4 }, + { "name": "Truite", "category": "Poissons", "default_unit": "kg", "frequency_score": 4 }, + { "name": "Eau gazeuse Vichy", "category": "Boissons", "default_unit": "bouteille","frequency_score": 5 }, + { "name": "Vinaigre", "category": "Condiments", "default_unit": "bouteille","frequency_score": 4 }, + { "name": "Vinaigrette", "category": "Condiments", "default_unit": "bouteille","frequency_score": 5 }, + { "name": "Yaourt nature", "category": "Produits laitiers", "default_unit": "pack", "frequency_score": 7 } +] diff --git a/backend/app/data/seed_stores.json b/backend/app/data/seed_stores.json new file mode 100644 index 0000000..af5a214 --- /dev/null +++ b/backend/app/data/seed_stores.json @@ -0,0 +1,11 @@ +[ + { "name": "Lidl", "location": null }, + { "name": "Intermarché", "location": null }, + { "name": "Super U", "location": null }, + { "name": "Gamm Vert", "location": null }, + { "name": "Weldom", "location": null }, + { "name": "Cosi", "location": null }, + { "name": "Bricocash", "location": null }, + { "name": "Tinel", "location": null }, + { "name": "Marie Blachère","location": null } +] diff --git a/backend/app/models/__init__.py b/backend/app/models/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/backend/app/schemas/__init__.py b/backend/app/schemas/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/backend/app/services/__init__.py b/backend/app/services/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/backend/tests/__init__.py b/backend/tests/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..7a70420 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,39 @@ +services: + db: + image: postgres:16-alpine + environment: + POSTGRES_USER: homehub + POSTGRES_PASSWORD: homehub + POSTGRES_DB: homehub + volumes: + - db_data:/var/lib/postgresql/data + healthcheck: + test: ["CMD-SHELL", "pg_isready -U homehub"] + interval: 5s + timeout: 5s + retries: 10 + + backend: + build: ./backend + environment: + DATABASE_URL: postgresql+asyncpg://homehub:homehub@db:5432/homehub + UPLOAD_DIR: /uploads + CORS_ORIGINS: http://localhost:3000,http://frontend:3000 + volumes: + - uploads:/uploads + ports: + - "8000:8000" + depends_on: + db: + condition: service_healthy + + frontend: + build: ./frontend + ports: + - "3000:80" + depends_on: + - backend + +volumes: + db_data: + uploads: