Backend: Einzelstücke (Items) mit UID je Gegenstand

Gegenstands-Produkte koennen als Einzelstuecke gefuehrt werden (Product.individual):
jedes physische Stueck ist ein Item mit eigener kurzer UID (fuer QR), eigenem
Lagerort, Kaufdatum, Garantie, Bezugsquelle und Notiz. So laesst sich dasselbe
Modell mehrfach getrennt fuehren (Powerbank 2024 + 2025).

Neu: models.Item + Product.individual (+Migration), Schemas, services/items.py
(UID-Erzeugung, Anreicherung), routers/items.py (CRUD, /items/by-uid/{uid} zur
QR-Aufloesung, /items/{id}/remove mit Grund als Bewegung). current_stock zaehlt
bei Einzelstueck-Produkten die Items. Tests + HTTP-Smoke gruen.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Scarriffle
2026-07-26 00:26:15 +02:00
parent 68e27c1868
commit 5ce4411d1e
8 changed files with 326 additions and 2 deletions

View File

@@ -14,6 +14,7 @@ from .routers import (
dashboard,
field_definitions,
groups,
items,
locations,
maintenance,
package_types,
@@ -81,6 +82,9 @@ def _ensure_schema() -> None:
"ALTER TABLE movements ADD COLUMN IF NOT EXISTS location_id INTEGER "
"REFERENCES locations(id) ON DELETE SET NULL",
"ALTER TABLE movements ADD COLUMN IF NOT EXISTS reason VARCHAR(16)",
# Einzelstück-Verwaltung (Items mit UID/QR) je Produkt.
"ALTER TABLE products ADD COLUMN IF NOT EXISTS individual BOOLEAN "
"NOT NULL DEFAULT FALSE",
]
with engine.begin() as conn:
for stmt in stmts:
@@ -154,3 +158,4 @@ app.include_router(maintenance.router)
app.include_router(dashboard.router)
app.include_router(shops.router)
app.include_router(field_definitions.router)
app.include_router(items.router)