diff --git a/backend/app/main.py b/backend/app/main.py index efb4592..298df88 100644 --- a/backend/app/main.py +++ b/backend/app/main.py @@ -179,6 +179,11 @@ def _ensure_schema() -> None: # Verbrauchsgegenstand: Gegenstand wie ein Lebensmittel führen (Chargen). "ALTER TABLE products ADD COLUMN IF NOT EXISTS bulk BOOLEAN " "NOT NULL DEFAULT FALSE", + # Zeitpunkt der letzten Änderung an den Stammdaten (für „Zuletzt geändert"). + # Nullable anlegen und Altbestände auf created_at zurücksetzen; neue Zeilen + # füllt die ORM-Spalte (default/onupdate). + "ALTER TABLE products ADD COLUMN IF NOT EXISTS updated_at TIMESTAMPTZ", + "UPDATE products SET updated_at = created_at WHERE updated_at IS NULL", # Kaufpreis (in Rappen/Cent) und Währung am Einzelstück. "ALTER TABLE items ADD COLUMN IF NOT EXISTS price_cents INTEGER", "ALTER TABLE items ADD COLUMN IF NOT EXISTS currency VARCHAR(3)", diff --git a/backend/app/models.py b/backend/app/models.py index f95b7a9..9167631 100644 --- a/backend/app/models.py +++ b/backend/app/models.py @@ -258,6 +258,11 @@ class Product(Base): bulk: Mapped[bool] = mapped_column(Boolean, nullable=False, default=False) created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), default=_now) + # Zeitpunkt der letzten Änderung an den Stammdaten des Artikels (nicht am + # Bestand). Wird bei jedem ORM-UPDATE der Zeile automatisch nachgezogen. + updated_at: Mapped[datetime] = mapped_column( + DateTime(timezone=True), default=_now, onupdate=_now + ) group: Mapped[Group | None] = relationship(back_populates="products") category: Mapped[Category | None] = relationship() diff --git a/backend/app/schemas.py b/backend/app/schemas.py index 7535b7e..bc8a28e 100644 --- a/backend/app/schemas.py +++ b/backend/app/schemas.py @@ -355,6 +355,7 @@ class ProductOut(BaseModel): individual: bool = False bulk: bool = False created_at: datetime + updated_at: datetime | None = None # angereichert: stock: float = 0.0 expired_count: int = 0 diff --git a/backend/tests/test_gegenstaende.py b/backend/tests/test_gegenstaende.py index 0585561..cfaeee7 100644 --- a/backend/tests/test_gegenstaende.py +++ b/backend/tests/test_gegenstaende.py @@ -331,3 +331,20 @@ def test_verbrauchsgegenstand_unter_mindestbestand(db): db.commit() # Unter dem Mindestbestand -> gehört auf die Einkaufsliste (wie ein Lebensmittel). assert current_stock(db, product.id) < product.min_stock + + +# ---- Zuletzt geändert ---- + +def test_updated_at_wird_bei_aenderung_nachgezogen(db): + import time + product = Product(name="Alt") + db.add(product) + db.commit() + db.refresh(product) + erst = product.updated_at + assert erst is not None + time.sleep(0.01) + product.name = "Neu" + db.commit() + db.refresh(product) + assert product.updated_at > erst