Schritt 1: Fundament der Lebensmittel-Lagerverwaltung (Pantry)

Backend (FastAPI + PostgreSQL): Chargen mit MHD, FEFO-Auslagern,
Einheiten-Umrechnung (Stueck/g/ml + Packungen), Open-Food-Facts-Lookup
mit lokalem Fallback, JWT-Auth mit Rollen (Admin/Nutzer), erster Admin
beim Setup, Einkaufsliste, Ablaufwarnung, Lagerorte, pytest fuer FEFO.

Web-UI (React/Vite): Login, Dashboard, Ein-/Auslagern, Produkte,
Lagerorte, Benutzerverwaltung, Einkaufsliste - rollenabhaengig.

Deploy: docker-compose + install.sh (Docker-Autoinstall, Secrets),
README und Roadmap fuer Schritt 2 (iOS) und Schritt 3.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Scarriffle
2026-07-22 09:14:14 +02:00
commit 639126468f
57 changed files with 3460 additions and 0 deletions

38
web/src/units.js Normal file
View File

@@ -0,0 +1,38 @@
// Anzeige-Helfer für Einheiten (müssen zu backend/app/models.py::BaseUnit passen).
export const BASE_UNITS = [
{ value: "piece", label: "Stück" },
{ value: "gram", label: "Gramm (g)" },
{ value: "milliliter", label: "Milliliter (ml)" },
];
export const BASE_UNIT_SHORT = {
piece: "Stk",
gram: "g",
milliliter: "ml",
};
export function unitShort(baseUnit) {
return BASE_UNIT_SHORT[baseUnit] || baseUnit;
}
// Auswahlmöglichkeiten für Menge beim Ein-/Auslagern eines Produkts.
export function unitOptions(product) {
const opts = [{ value: baseUnitToInput(product.base_unit), label: unitShort(product.base_unit) }];
if (product.package_size) {
opts.push({ value: "package", label: `Packung (${product.package_size} ${unitShort(product.base_unit)})` });
}
return opts;
}
// Das Backend akzeptiert 'g', 'ml', 'piece'/'st' etc. als Basiseinheit-Eingabe.
export function baseUnitToInput(baseUnit) {
if (baseUnit === "gram") return "g";
if (baseUnit === "milliliter") return "ml";
return "piece";
}
export function fmt(n) {
if (n == null) return "";
return Number(n).toLocaleString("de-DE", { maximumFractionDigits: 2 });
}