From 4e7a863431de4e001f4bd5b35751ba3064478cf6 Mon Sep 17 00:00:00 2001 From: Gilles Soulier Date: Sun, 24 May 2026 15:28:43 +0200 Subject: [PATCH] =?UTF-8?q?feat(shopping):=20sch=C3=A9mas=20Pydantic=20lis?= =?UTF-8?q?tes=20et=20articles=20+=20volume=20dev=20backend?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/app/schemas/shopping.py | 91 +++++++++++++++++++++++++++++++++ docker-compose.yml | 1 + 2 files changed, 92 insertions(+) create mode 100644 backend/app/schemas/shopping.py diff --git a/backend/app/schemas/shopping.py b/backend/app/schemas/shopping.py new file mode 100644 index 0000000..31e3c4b --- /dev/null +++ b/backend/app/schemas/shopping.py @@ -0,0 +1,91 @@ +import uuid +from datetime import datetime, date +from decimal import Decimal +from typing import Literal +from pydantic import BaseModel, ConfigDict, Field, model_validator + + +class StoreResponse(BaseModel): + model_config = ConfigDict(from_attributes=True) + id: uuid.UUID + name: str + location: str | None + + +class ProductResponse(BaseModel): + model_config = ConfigDict(from_attributes=True) + id: uuid.UUID + name: str + brand: str | None + category: str | None + default_unit: str | None + frequency_score: int + + +class ListItemCreate(BaseModel): + product_id: uuid.UUID | None = None + custom_name: str | None = None + quantity: Decimal | None = None + unit: str | None = None + + @model_validator(mode='after') + def must_have_name(self) -> 'ListItemCreate': + if not self.product_id and not self.custom_name: + raise ValueError('product_id ou custom_name requis') + return self + + +class ListItemUpdate(BaseModel): + is_checked: bool | None = None + quantity: Decimal | None = None + unit: str | None = None + price_recorded: Decimal | None = None + + +class ListItemResponse(BaseModel): + id: uuid.UUID + product_id: uuid.UUID | None + custom_name: str | None + display_name: str + quantity: Decimal | None + unit: str | None + is_checked: bool + price_recorded: Decimal | None + carried_over: bool + sort_order: int | None + + +class ShoppingListCreate(BaseModel): + name: str | None = None + store_id: uuid.UUID | None = None + week_date: date | None = None + + +class ShoppingListUpdate(BaseModel): + name: str | None = None + store_id: uuid.UUID | None = None + status: Literal['draft', 'active', 'done'] | None = None + + +class ShoppingListResponse(BaseModel): + model_config = ConfigDict(from_attributes=True) + id: uuid.UUID + name: str | None + store_id: uuid.UUID | None + week_date: date | None + status: str + created_at: datetime + item_count: int + checked_count: int + + +class ShoppingListDetailResponse(BaseModel): + id: uuid.UUID + name: str | None + store_id: uuid.UUID | None + week_date: date | None + status: str + created_at: datetime + item_count: int + checked_count: int + items: list[ListItemResponse] diff --git a/docker-compose.yml b/docker-compose.yml index a44858e..a26cab7 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -20,6 +20,7 @@ services: UPLOAD_DIR: /uploads CORS_ORIGINS: http://localhost:3001,http://localhost:3000 volumes: + - ./backend/app:/app/app - uploads:/uploads ports: - "8000:8000"