Scarriffle dfbc62398d Eigener Rueckfrage-Dialog statt Browsermeldung, Zeitstempel im Export, Notizen an Gruppen-Codes
Rueckfragen liefen bisher ueber window.confirm. Das reisst aus der Oberflaeche,
zeigt den Hostnamen, laesst sich nicht gestalten und die Knoepfe heissen immer
"OK/Abbrechen". Neu ist ein eigener Dialog (src/confirm.jsx) als Provider mit
dem Hook useConfirm. Der Aufruf bleibt so einfach wie vorher, weil er eine
Zusage zurueckgibt:

    if (!(await confirm({ title: "…?", message: "…" }))) return;

Damit sind alle neun Stellen umgestellt: Gruppen, Kategorien, Lagerorte,
Einheiten, Benutzer, API-Tokens, Produkt und Charge loeschen sowie das Ersetzen
beim Import. Jede Rueckfrage hat jetzt einen sprechenden Titel, einen Satz zu
den Folgen und einen benannten Knopf ("Loeschen", "Widerrufen", "Ersetzen")
statt eines nichtssagenden OK. Unwiderrufliche Schritte sind rot.
Kuenftig gilt: keine Browserdialoge mehr.

Export: Dateinamen tragen jetzt Datum und Uhrzeit
(bestand_2026-07-22_2130.csv, project-good-backup_2026-07-22_2130.json). Ohne
Zeitstempel hiessen mehrere Ausleitungen alle gleich und der Browser haengte
(1), (2) an - dann war nicht mehr erkennbar, welche die aktuelle ist. Der
Zeitstempel entsteht an beiden Enden gleich: im Content-Disposition-Kopf des
Backends und im Dateinamen, den der Browser setzt. Im JSON steht zusaetzlich
die Ortszeit neben dem bereits vorhandenen UTC-Zeitpunkt. Die CSV bleibt
inhaltlich unveraendert - eine zusaetzliche Spalte oder Kopfzeile wuerde die
Datei in Excel nur stoeren.

Notizen an Gruppen-Codes: Codes, die beim Zuordnen eines Artikels automatisch
entstehen, hatten bisher keine Moeglichkeit, eine Notiz zu bekommen - die liess
sich nur beim Anlegen von Hand mitgeben. Neu PATCH /groups/{id}/barcodes/{code}
und ein Notizfeld in der Liste, das beim Verlassen speichert. Leeren entfernt
die Notiz.

Getestet: 57 pytest-Tests unveraendert gruen, Web-Build laeuft durch. Gegen die
laufende API geprueft: Zeitstempel in beiden Content-Disposition-Koepfen und im
JSON-Inhalt; Notiz an einem automatisch angelegten Code setzen, aendern und
leeren, unbekannter Code antwortet mit 404. Die Dialoge selbst habe ich nicht
im Browser angeklickt.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-22 21:31:45 +02:00

🥫 Project-Good Selfhostbare Lebensmittel-Lagerverwaltung

Ein selbst gehosteter Dienst zur Verwaltung deines Lebensmittelvorrats: Ein-/Auslagern per Barcode, MHD-/Ablaufverwaltung mit Chargen, Mindestbestände, automatische Einkaufsliste mit Web-UI und (in Vorbereitung) nativer iOS-App.

Dies ist Schritt 1 (Fundament). Der komplette Fahrplan steht in docs/ROADMAP.md.

Features (Schritt 1)

  • Barcode-Lookup über Open Food Facts mit lokalem Fallback (unbekannte Produkte selbst anlegen).
  • Chargen mit MHD: Jedes Einlagern erzeugt eine Charge mit eigenem Mindesthaltbarkeitsdatum. Beim Auslagern wird automatisch die zuerst ablaufende Charge zuerst entnommen (FEFO First Expired, First Out).
  • Einheiten: Basiseinheit Stück / Gramm / Milliliter plus optionale Packungsgröße → Ein-/Auslagern in Packungen oder Teilmengen (z. B. 200 g).
  • Mindestbestände pro Produkt → automatische Einkaufsliste.
  • Ablaufwarnung für bald ablaufende Chargen (Frist konfigurierbar).
  • Lagerorte (flach; Unterlagerorte folgen in Schritt 3).
  • Mehrbenutzer mit Rollen:
    • Admin verwaltet Produkte, Lagerorte, Benutzer, Mindestbestände.
    • Nutzer nur ein-/auslagern und ansehen.
    • Bewegungen werden protokolliert (wer hat wann was ein-/ausgelagert).

Architektur

Teil Technik
Backend Python · FastAPI · SQLAlchemy
DB PostgreSQL
Web-UI React · Vite (via nginx ausgeliefert)
iOS SwiftUI (Schritt 2)
Deploy Docker Compose · install.sh
backend/   FastAPI-App + Tests
web/        React/Vite SPA
deploy/     docker-compose.yml, install.sh, .env.example
docs/       Roadmap

Installation (selfhosted, Linux)

Voraussetzung: eine Linux-Maschine (Server, NAS, Raspberry Pi …). Docker wird bei Bedarf automatisch installiert.

git clone https://git.scarriffle.com/Scarriffle/project-good.git
cd project-good/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 clone nach Benutzername + Access-Token. Falls git fehlt: 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.

Aktualisieren

cd project-good/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:///./project_good.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

Tests:

cd backend
pip install -r requirements.txt
pytest            # prüft FEFO-Abbuchung und Einheiten-Umrechnung

Nächste Schritte

Native iOS-App (Schritt 2) und fortgeschrittene Features (Gruppen-Intelligenz, Unterlagerorte, Push-Benachrichtigungen …) siehe docs/ROADMAP.md.

Description
No description provided
Readme 5.7 MiB
Languages
Swift 32.7%
JavaScript 31.7%
Python 31.4%
CSS 3.4%
Shell 0.7%