Zwei Defekte, die zusammen das gemeldete Muster ergeben.
1) Es gab keine zentrale Behandlung von HTTP 401. AuthProvider prueft die
Anmeldung EINMAL beim Start; laeuft das Token danach ab, bleibt der Zustand
"angemeldet" stehen, waehrend jede Abfrage scheitert. Seiten mit
.catch(() => {}) (18 Stellen) zeigen dann schlicht nichts, andere eine
englische Servermeldung - genau das "mal gar nichts, mal die Haelfte".
Jetzt raeumt der API-Client bei 401 die Sitzung auf und der Login sagt, dass
sie abgelaufen ist. Beim Anmelden selbst greift das nicht, dort heisst 401
"Passwort falsch".
2) Der Start hatte ein blankes `catch`, das das Token bei JEDEM Fehler loeschte -
auch bei 502 oder weggebrochenem Netz. Wer waehrend eines Server-Neustarts F5
drueckte, war deshalb abgemeldet, obwohl die Sitzung voellig in Ordnung war.
Das duerfte der haeufigere Ausloeser gewesen sein, weil in letzter Zeit oft neu
deployt wurde. Jetzt wird nur bei 401/403 abgemeldet; bei allem anderen bleibt
die Anmeldung liegen und es erscheint "Server nicht erreichbar" mit einem
Knopf zum erneuten Versuchen.
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.