Verwendungsstatus: Backend fuer "getragen / in Reinigung / in Reparatur"

Einzelstuecke hatten bisher keinen Zustand - der Lagerort sagt, wohin ein
Stueck gehoert, aber nicht, woran es gerade ist. Neue Tabelle item_usages
nach dem Vorbild von item_loans: ein Zeitraum je Zustand, ended_at NULL
heisst "laeuft noch", und ein Teilindex laesst nur einen laufenden zu.

"Verfuegbar" wird bewusst nicht gespeichert - keine offene Zeile IST
verfuegbar, wie bei lots.opened_on und beim Verleih. Damit kostet der
Ruhezustand nichts und die Tabelle fuellt sich nicht mit Rauschen.
Abgeschlossene Zeilen bleiben stehen, sie sind der Verlauf.

Eigener Endpunkt (PUT /items/{id}/verwendung) und ausdruecklich nicht
PATCH /items/{id}: Das ist Admins vorbehalten, und die App schickt dort
immer alle Felder mitsamt null - jedes Speichern wuerde den Status
stillschweigend zuruecksetzen. Umstellen darf deshalb jeder angemeldete
Benutzer, wie Verleihen.

Der Zustand aendert den Bestand nicht und schreibt keine Bewegung: ein
getragenes Hemd ist weiterhin im Haushalt, anders als ein verliehenes.

Sichtbar nur bei Kategorien mit usage_tracking. Ein Haken an einer
Oberkategorie wandert in den Unterbaum, weil die Garderobe als
Kategoriebaum ja schon existiert. Die Markierung fahrt in beiden
Sicherungswegen mit; der Verlauf nicht, weil Einzelstuecke dort
ueberhaupt nicht vorkommen.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Scarriffle
2026-10-20 21:47:02 +02:00
co-authored by Claude Opus 5
parent 8c752e3d1f
commit 98e2d18142
10 changed files with 691 additions and 6 deletions
+8
View File
@@ -32,6 +32,7 @@ from .routers import (
transfer,
units,
users,
verwendung,
views,
)
from .seed import (
@@ -244,6 +245,12 @@ def _ensure_schema() -> None:
# Oberkategorie -> globale Einstellung), siehe services/vererbung.py.
"ALTER TABLE products ADD COLUMN IF NOT EXISTS open_days INTEGER",
"ALTER TABLE categories ADD COLUMN IF NOT EXISTS open_days INTEGER",
# Verwendungsstatus an Einzelstuecken dieser Kategorie (Kleidung,
# Werkzeug). Aus, solange niemand sie setzt - bestehende Kategorien
# aendern sich also nicht. Die Tabelle item_usages selbst kommt aus
# create_all, nur Spalten brauchen diesen Weg hier.
"ALTER TABLE categories ADD COLUMN IF NOT EXISTS usage_tracking "
"BOOLEAN NOT NULL DEFAULT FALSE",
]
with engine.begin() as conn:
# Zuerst die Lagerort-ID auf den Code umstellen (einmalig, idempotent),
@@ -338,3 +345,4 @@ app.include_router(shops.router)
app.include_router(field_definitions.router)
app.include_router(items.router)
app.include_router(loans.router)
app.include_router(verwendung.router)