Mindestbestaende-Seite ist jetzt nach Lagerort gegliedert statt nach Artikel -
"Ueberall (egal wo)" zuerst, danach die Lagerorte. Es gibt keine automatische
Leerzeile je Artikel mehr; angelegt wird ueber "+ hinzufuegen" im jeweiligen
Abschnitt, dann steht der Ort schon fest und es fehlen nur Ziel und Menge.
Das Zeilenmodell faellt damit von vier Faellen auf zwei, und weil der Server
einheitlich Basiseinheiten liefert, bleibt genau eine Umrechnung uebrig statt
der drei gegenlaeufigen von vorher.
Gruppen: neue Spalte "Obergruppen" mit Mehrfachauswahl (GroupParentSelect).
Bewusst kein Baum - CategorySelect und die tree-Prop der DataTable koennen nur
einen Elternteil und wuerden eine Gruppe mit zwei Obergruppen doppelt anzeigen.
Die eigene Gruppe und ihre Untergruppen sind in der Auswahl gesperrt, damit die
Ringregel sichtbar wird, bevor der Server sie ablehnt. Produktzahl zeigt
transitiv und direkt ("12 (3 direkt)"), dazu Badges fuer Untergruppen und eine
Warnung, wenn eine Gruppe mit Untergruppen keine Einheit hat - sonst summiert
sie Gramm und Stueck zu einer sinnlosen Zahl.
Einkaufsliste: "Gesamt" heisst "Ueberall", Gruppen zeigen ihre mitgezaehlten
Untergruppen, und eine Fussnote benennt die eine Stelle, die sich nicht
verrechnen laesst (zwei Obergruppen mit gemeinsamer Untergruppe).
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Vorrania – Selfhostbare Vorrats- und Gegenstandsverwaltung
Ein selbst gehosteter Dienst, um sowohl deinen Lebensmittelvorrat als auch allgemeine Gegenstände (Haushalt, Elektronik, Kleidung, Verbrauchsmaterial …) zu verwalten: Ein-/Auslagern per Barcode, Chargen mit MHD, Einzelstücke mit eigener UID/QR, Mindestbestände, automatische Einkaufsliste, verschachtelte Lagerorte, Gruppen, Kategorien und Dashboards – mit Web-UI und nativer iOS-App, die beide dieselbe REST-API nutzen.
Was Vorrania verwaltet
Lebensmittel laufen als Chargen mit Mindesthaltbarkeitsdatum. Beim Auslagern wird automatisch die zuerst ablaufende Charge entnommen (FEFO).
Gegenstände kennen drei Arten:
- Menge je Lagerort – reines Zählen (z. B. Unterhosen, Batterien).
- Einzelstücke – jedes Exemplar mit eigener UID/QR, Kaufdatum, Garantie, Bezugsquelle und Beleg (z. B. Powerbank, Kamera).
- Verbrauchsgegenstand – wie ein Lebensmittel als Charge mit Menge und Einheit geführt (z. B. Sonnencreme in ml), nur ohne eindeutigen Code.
Features
- Barcode-Lookup über Open Food Facts und Open Products Facts mit lokalem Fallback; unbekannte Produkte selbst anlegen, Bild wird automatisch geholt.
- Chargen mit MHD & FEFO, Mengen in Packungen oder Teilmengen (Basiseinheit Stück / Gramm / Milliliter plus Packungsgröße/Gebinde).
- Lagerorte beliebig verschachtelt (Keller → Regal 2 → Fach A), mit QR-Etiketten, Inhaltsansicht („was liegt hier?“), Umlagern und Entfernen mit Grund. Chargen und Einzelstücke sind einem Lagerort zugeordnet.
- Kategorien verschachtelt und pro Typ (Lebensmittel/Gegenstand); für Gegenstände mit eigenen Feldern (z. B. Kapazität, Größe, Farbe).
- Gruppen rechnen Bestände mehrerer Marken/Artikel zusammen (z. B. „5 kg Mehl“) mit eigenem Mindestbestand und Einheit.
- Mindestbestände je Produkt und Gruppe – gesamt und je Lagerort – mit zentraler Übersichtsseite, daraus die automatische Einkaufsliste und Ablaufwarnung für bald ablaufende Chargen.
- Übergreifende Listen für Produkte (getrennt Lebensmittel/Gegenstände), Einzelstücke und Chargen – filter-, sortier- und spaltenkonfigurierbar; bei Chargen lässt sich der Lagerort mehrerer auf einmal setzen.
- Dashboards mit konfigurierbaren Karten und Diagrammen, Verlauf (wer hat wann was ein-/ausgelagert), Stammdaten (Einheiten, Gebinde, Shops) und Import/Export.
- Mehrbenutzer mit Rollen: Admin verwaltet Stammdaten und Benutzer, Nutzer lagert nur ein/aus und sieht Bestände; alle Bewegungen werden protokolliert.
In der iOS-App zusätzlich
- Scannen von Barcode, MHD/Datum per Texterkennung (auch nur Tag+Monat ohne Jahr bei Frischware), Lagerort-QR und Name/Marke per Text-Scan.
- Foto direkt beim Anlegen (Kamera/Galerie), Push-Benachrichtigungen bei ablaufenden Produkten, lokale Dashboards und Home-Screen-Schnellaktionen.
Details zur App: ios/README.md.
Architektur
| Teil | Technik |
|---|---|
| Backend | Python · FastAPI · SQLAlchemy |
| DB | PostgreSQL (SQLite für Tests/lokal) |
| Web-UI | React · Vite (via nginx ausgeliefert) |
| iOS | Native SwiftUI-App (VisionKit-Scanner) |
| Deploy | Docker Compose · install.sh |
backend/ FastAPI-App + Tests
web/ React/Vite SPA
ios/ Native SwiftUI-App (XcodeGen-Projekt)
deploy/ docker-compose.yml, install.sh, update.sh, .env.example
docs/ Roadmap
Das Schema wird beim Start per idempotenter ALTER TABLE-Migration in
backend/app/main.py nachgezogen (kein Alembic).
Installation (selfhosted, Linux)
Voraussetzung: eine Linux-Maschine (Server, NAS, Raspberry Pi …). Docker wird bei Bedarf automatisch installiert.
git clone https://git.scarriffle.com/Scarriffle/vorrania.git
cd vorrania/deploy
chmod +x install.sh
./install.sh # interaktiv – fragt Port & Admin-Passwort
# oder vollautomatisch mit generiertem Admin-Passwort:
# ./install.sh --yes
Ist das Gitea-Repo privat, fragt
git clonenach Benutzername + Access-Token. Fallsgitfehlt:apt update && apt install -y git.
Nach dem Start:
- Web-UI:
http://<server-ip>:8080(Port konfigurierbar) - Anmeldung mit dem im Installer angezeigten Admin-Benutzer/Passwort.
Die iOS-App wird mit derselben Adresse verbunden (http://<server-ip>:8080).
Aktualisieren
cd vorrania/deploy
./update.sh # holt den neuesten Stand aus Git und baut neu
./update.sh --prune # zusätzlich alte Images aufräumen
./update.sh --no-pull # nur neu bauen, ohne git pull
Das Skript ist von überall aufrufbar, nutzt die vorhandene deploy/.env und
prüft am Ende, ob das Backend wieder erreichbar ist.
Verwaltung:
cd deploy
docker compose logs -f # Logs ansehen
docker compose down # stoppen
docker compose up -d # starten
Die Konfiguration liegt in deploy/.env (Passwörter, Port, JWT-Secret). Für den
Produktivbetrieb bitte hinter einen HTTPS-Reverse-Proxy (z. B. Caddy/Traefik) stellen.
Entwicklung (ohne Docker)
Backend:
cd backend
python -m venv .venv && source .venv/bin/activate
pip install -r requirements.txt
# lokale SQLite-DB nutzen:
export DATABASE_URL="sqlite:///./vorrania.db"
uvicorn app.main:app --reload
API-Doku dann unter http://localhost:8000/docs.
Web:
cd web
npm install
npm run dev # http://localhost:5173, proxyt /api → localhost:8000
iOS: siehe ios/README.md (XcodeGen-Projekt, xcodegen generate).
Tests:
cd backend
pip install -r requirements.txt
DATABASE_URL="sqlite://" pytest
Weiteres
Fahrplan und Ideen: docs/ROADMAP.md.