feat(lager): Warehouse-Epic Kern (WH-001..004+007)
CI / backend-tests (push) Successful in 1m56s
CI / frontend-build (push) Successful in 18s

Lagerort-Hierarchie (organisation/standort/gebaeude/raum/lager, self-referenzierend),
Lagerplätze mit eindeutigem Code, Bestand je Lagerplatz+Material, Ein-/Auslagerung
mit lückenlosem Materialbewegungsprotokoll (append-only, analog Lagerbewegung
auf Objekt-Ebene, hier aber Material-/Lagerplatz-fein).

- Migration 0019: 4 neue Tabellen (lagerort, lagerplatz, bestand, materialbewegung)
- Backend: CRUD Lagerort/Lagerplatz, Bestandsabfrage, Ein-/Auslagern-Endpunkte,
  Negativbestand vorab abgefangen (kein DB-Constraint-Exception-Pfad, gleiches
  Muster wie objekte.py-Fix vom 2026-09-05)
- Frontend: neuer Admin-Tab "Lager" (Lagerort/-platz-Verwaltung, Bestand+Buchung
  je Lagerplatz)
- 2 neue Tests, 139 Tests weiterhin grün

WH-005 (Umlagerung) und WH-006 (Inventur) bewusst zurückgestellt - Kern zuerst,
laut Nutzer-Entscheidung.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CVgbozhYmuEhiEJHffRXCV
This commit is contained in:
2026-09-05 21:42:37 +02:00
co-authored by Claude Sonnet 5
parent ca0befd4a0
commit f7367f6df3
11 changed files with 918 additions and 0 deletions
+4
View File
@@ -11,6 +11,7 @@ import { FachSection } from "./admin/FachSection";
import { HistorieSection } from "./admin/HistorieSection";
import { KategorieSection } from "./admin/KategorieSection";
import { LagerbewegungSection } from "./admin/LagerbewegungSection";
import { LagerSection } from "./admin/LagerSection";
import { RolleSection } from "./admin/RolleSection";
import { KontrollverantwortungSection } from "./admin/KontrollverantwortungSection";
import { MaterialSection } from "./admin/MaterialSection";
@@ -34,6 +35,7 @@ type Tab =
| "zustaendigkeit"
| "personal"
| "lagerbewegungen"
| "lager"
| "rollen";
// Deckt sich mit den require_roles()-Gates der jeweiligen Backend-Endpunkte
@@ -65,6 +67,7 @@ const TABS: { key: Tab; label: string; rollen: ("administration" | "materialvera
label: "Lagerbewegungen",
rollen: ["administration", "materialverantwortlicher", "leitungsverantwortlicher"],
},
{ key: "lager", label: "Lager", rollen: ["administration", "materialverantwortlicher"] },
{ key: "rollen", label: "Rollen & Rechte", rollen: ["administration"] },
];
@@ -225,6 +228,7 @@ export function AdminPage() {
{aktiverTab === "lagerbewegungen" && (
<LagerbewegungSection objekte={objekte} standorte={standorte} onFehler={setFehler} />
)}
{aktiverTab === "lager" && <LagerSection materialien={materialien} onFehler={setFehler} />}
{aktiverTab === "rollen" && <RolleSection benutzer={benutzer} onFehler={setFehler} />}
{aktiverTab === "eskalation" && <EskalationSection onFehler={setFehler} />}
{aktiverTab === "personal" && (