Auf vielen Verpackungen steht nur "09/2026". Bisher liess sich ausschliesslich
ein Tagesdatum erfassen, was zu erfundener Genauigkeit fuehrte.
Entwurf: best_before bleibt ein echtes DATE, damit FEFO, die Ablauf-Abfragen
und alle bestehenden Sortierungen unveraendert weiterlaufen. Eine Monatsangabe
wird auf den Monatsletzten gelegt - die uebliche Lesart bei Lebensmitteln, und
die sichere Richtung, weil nicht zu frueh aussortiert wird. Zusaetzlich merkt
sich jede Charge in best_before_precision, wie genau die Angabe war; davon
haengt allein die Anzeige ab. Am Produkt steht in date_precision, welche
Genauigkeit dort ueblich ist (Voreinstellung der Eingabe, z.B. Konserven).
Bewusst als VARCHAR statt als DB-Enum gespeichert: So laesst sich die Spalte
auf bestehenden Tabellen per ADD COLUMN IF NOT EXISTS nachziehen, ohne vorher
einen neuen Postgres-Typ anzulegen. Beide Spalten haben ein Server-Default
'day', damit vorhandene Chargen unveraendert gueltig bleiben.
Export/Import bleiben verlustfrei: Das JSON-Backup fuehrt beide Felder mit. Die
CSV bekommt bewusst keine neue Spalte, damit die Datei in Excel unveraendert
bedienbar bleibt - stattdessen wird eine Monatsangabe als "09/2026" geschrieben
und beim Import an der Schreibweise wieder erkannt ("09/2026", "2026-09",
"09.2026"); tagesgenaue Formate werden weiterhin gelesen.
Beim Korrigieren einer Charge werden MHD und Genauigkeit gemeinsam ausgewertet,
sonst bliebe ein auf Monat umgestellter Wert auf dem alten Tag stehen.
Getestet: 40 pytest-Tests gruen (17 neue zu Monatsletztem, Schaltjahr,
Einlagern, Export-Schreibweise und Import-Erkennung). Zusaetzlich ein
Durchlauf ueber die echte API: Produkt mit Monatsvorgabe anlegen und aendern,
Sammel-Einlagern mit gemischten Genauigkeiten, Chargen wieder auslesen.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Beim Einlagern stand in der Chargenzeile eine nackte 1 ohne Beschriftung. Das
las sich wie eine Nummerierung der Charge, war aber das Mengenfeld. Die Zeile
hat jetzt links die Beschriftung "Menge", der Wert steht rechtsbuendig; die 1
bleibt als Vorgabe, weil meistens genau ein Stueck eingelagert wird. Beim
Auslagern war dieselbe Zeile ebenso unbeschriftet und ist jetzt gleich aufgebaut.
Anmeldung: Das Token wanderte bisher immer dauerhaft in den Schluesselbund.
Der neue Haken "Angemeldet bleiben" laesst sich abwaehlen - dann gilt die
Anmeldung nur, solange die App laeuft, und es bleibt nichts auf dem Geraet
zurueck. Die Wahl wird gemerkt, damit der Haken beim naechsten Mal richtig steht.
Dabei ist aufgefallen, dass der Benutzername nirgends gespeichert wurde: Nach
einem Neustart stand im Menue nur noch "Angemeldet als" ohne Namen. Er wird
jetzt zusammen mit dem Token abgelegt und beim Abmelden wieder entfernt.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Auslagern-Kachel: "arrow.up.from.line" existiert als SF Symbol nicht, deshalb
blieb das Icon leer und man sah nur die eingefaerbte Kachelflaeche. Ersetzt
durch "arrow.up.to.line", das Gegenstueck zum "arrow.down.to.line" beim
Einlagern. Alle uebrigen im Projekt verwendeten Symbolnamen wurden gegen die
Symbolliste des Systems geprueft und sind gueltig.
App-Icon: Das mitgelieferte AppIcon.icon (Icon-Composer-Format) wird als
Ressource eingebunden und ueber ASSETCATALOG_COMPILER_APPICON_NAME gesetzt.
Die Icon-Eintraege landen korrekt in der selbstgepflegten Info.plist.
Barcode-Erkennung, nachdem ein dunkelgruener Code auf weiss nicht gelesen wurde:
- Aufloesung auf 1920x1080 statt der Voreinstellung, damit kontrastarme und
kleine Codes ueberhaupt sauber aufgeloest werden.
- Dauerhafter Autofokus mit Beschraenkung auf den Nahbereich; weiches
Nachfuehren aus, da es hier nur verzoegert.
- Antippen stellt gezielt auf eine Stelle scharf und misst dort die Belichtung.
- Licht-Schalter in der Navigationsleiste beider Scan-Bildschirme; beim
Verlassen wird das Licht sicher wieder ausgeschaltet.
- Mehr Symbologien (ITF-14, DataMatrix, PDF417, Aztec, Code93). Es werden nur
die Typen gesetzt, die die Kamera meldet - sonst wirft AVFoundation zur
Laufzeit.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Ohne Team-ID bricht ein Build gegen "generic/platform=iOS" beim Signieren ab.
Mit CODE_SIGN_STYLE=Automatic und der Team-ID laeuft der Geraetebuild durch und
wird mit dem vorhandenen Entwicklerzertifikat und dem Team-Provisioning-Profil
signiert. Wer mit einem anderen Apple-Konto baut, ersetzt die Team-ID.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Die App war bisher nie durch einen Compiler gelaufen. Mit Xcode 26.6 baut sie
jetzt fehler- und warnungsfrei gegen das iOS-16-Deployment-Target.
Info.plist: Der "info:"-Block in project.yml hat die handgepflegte
Sources/Info.plist bei jedem "xcodegen generate" ueberschrieben und dabei
Schluessel verloren, die nur in der Datei standen - insbesondere
NSAppTransportSecurity/NSAllowsLocalNetworking. Ohne diese Ausnahme haette die
App den Server im Heimnetz per http:// ueberhaupt nicht erreichen koennen.
Die Datei ist jetzt die einzige Quelle: project.yml verweist nur noch per
INFOPLIST_FILE darauf und nimmt sie aus den Sources heraus. Die Bundle-Keys,
die vorher nur die erzeugte Fassung hatte (CFBundleExecutable,
CFBundleIdentifier, CFBundlePackageType ...), stehen nun in der Datei selbst.
ProductViews: onChange(of:) wurde in der zweiwertigen iOS-17-Form verwendet und
war damit ein harter Fehler - auf die einwertige Form umgestellt.
ProjectGoodApp: application(_:performActionFor:) als async-Fassung reicht das
nicht-Sendable UIApplicationShortcutItem ueber eine Actor-Grenze. Das ist heute
eine Warnung und im Swift-6-Sprachmodus ein Fehler; jetzt die Variante mit
Completion-Handler.
Der dritte Verdacht hat sich nicht bestaetigt: AudioServicesPlaySystemSound in
ScannerView uebersetzt ohne zusaetzliches "import AudioToolbox", weil
AVFoundation es bereits mitbringt. Deshalb dort keine Aenderung.
Das erzeugte ProjectGood.xcodeproj wandert in .gitignore, da project.yml es
vollstaendig beschreibt.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Die Einkaufsliste war ueber /shopping-list und /shopping-list/groups schon
abrufbar, aber nur mit einem Login-JWT, das nach 7 Tagen ablaeuft - fuer HA
unpraktisch.
- Neue Tabelle api_tokens (Name, SHA-256-Hash, Ersteller, zuletzt genutzt).
Der Klartext wird nur einmal beim Anlegen zurueckgegeben.
- get_current_user akzeptiert jetzt JWT ODER API-Token im Authorization-Header;
bei Nutzung wird last_used_at fortgeschrieben.
- Endpunkte /api-tokens (Admin): auflisten, erzeugen, widerrufen.
- Einstellungsseite: Tokens verwalten inkl. einmaliger Anzeige und einem
aufklappbaren Konfigurationsbeispiel fuer Home Assistant.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
MHD wurde in den Ansichten noch roh als YYYY-MM-DD ausgegeben. Jetzt:
- Neue Einstellung date_format (23.12.2026 | 23.12.26 | 23. Dezember 2026 |
2026-12-23 | 12/23/2026) mit Live-Beispiel auf der Einstellungsseite.
- SettingsProvider stellt Format und formatDate() app-weit bereit und laedt die
Einstellungen nach dem Login.
- Verwendet in Uebersicht (bald ablaufend), Produktdetail (Chargen) und
Auslagern (Chargenauswahl). Datumsfelder zur Eingabe bleiben ISO, wie es das
HTML-Datumsfeld verlangt.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
iOS (neu, ios/):
- SwiftUI-App: Login (Server + Keychain-Token), Kamera-Scanner (EAN/UPC/Code128),
Einlagern mit mehreren Chargen und eigenem MHD, Auslagern mit Chargenauswahl
oder FEFO, Artikelsuche, Anlegen mit Open-Food-Facts-Vorbefuellung.
- Home-Screen-Shortcuts: Schnellaktionen (langer Druck) und URL-Schema
projectgood://checkin | ://checkout fuer eigene Symbole via Kurzbefehle.
- project.yml (XcodeGen) + README mit Build-Anleitung. NICHT kompiliert - auf
diesem Rechner ist kein Xcode vorhanden.
Import-Modi (wie besprochen sinnvoll):
- add (Standard, nichts loeschen), replace_listed (Bestaende der in der Datei
genannten Produkte ersetzen - fuer Inventur), replace_all (alles ersetzen).
Geleerte Bestaende werden als Korrektur-Bewegung protokolliert; die Oberflaeche
fragt bei den zerstoerenden Modi nach.
Anzeige:
- "Bald ablaufend"/"Abgelaufen" zeigen jetzt das Gebinde ("1 Glas") mit der
Basiseinheit klein darunter (ExpiringItem liefert die Einheiten mit).
- MHD als Zeitspanne mit korrektem Numerus: "in 3 Tagen", "in 1 Woche",
"vor 2 Wochen", dazu heute/morgen/gestern.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Barcodes:
- Neue Tabelle barcodes (code, note, product_id ODER group_id). Damit lassen sich
einem Produkt mehrere Codes geben und einer Gruppe beliebig viele Marken
zuordnen (z.B. alle Mehlmarken zu "Mehl"). Je Code eine Notiz wie
"Mehl bei Aldi".
- Lookup loest jetzt auch Alias-Codes auf; ist ein Code einer Gruppe zugeordnet,
liefert die API group_id/group_name zurueck. Beim Anlegen aus einem Scan wird
diese Gruppe automatisch gesetzt (Vorrang vor dem Kategorie-Rateversuch).
- Endpunkte: POST/DELETE /products/{id}/barcodes und /groups/{id}/barcodes.
- Web: wiederverwendbare BarcodeList-Komponente, eingebunden im Produktformular
und auf der Gruppen-Seite.
Gruppen:
- Namen lassen sich jetzt direkt in der Tabelle aendern (PATCH war vorhanden,
nur die Oberflaeche fehlte).
UI-Fix: Auswahlfelder in Tabellen richten sich nach ihrem Text statt nach der
Zellenbreite (Gruppen-/Benutzer-Dropdowns waren abgeschnitten).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Export:
- GET /export/stock.csv - eine Zeile je Charge, Semikolon-getrennt mit BOM,
direkt in Excel/LibreOffice bearbeitbar; Mengen in der Artikeleinheit.
- GET /export/backup.json - vollstaendiges Backup (Einheiten, Gruppen,
Lagerorte, Produkte, Chargen), Referenzen ueber Namen statt IDs.
Import:
- POST /import/stock (Admin, Datei-Upload). Erkennt CSV oder JSON automatisch.
Arbeitet ausschliesslich additiv: unbekannte Produkte/Gruppen/Lagerorte/
Einheiten werden angelegt, Chargen ergaenzt - nichts wird geloescht.
Mengen koennen in Gebinde ("Glas") oder Einheiten ("Gramm") angegeben werden,
Datum als YYYY-MM-DD oder TT.MM.JJJJ. Fehlerhafte Zeilen werden uebersprungen
und im Ergebnis gemeldet; jeder Import wird als Bewegung protokolliert.
Frontend: neue Seite "Import / Export" (Verwaltung) mit Download-Buttons,
Datei-Upload, Ergebniszusammenfassung und einer Beschreibung der CSV-Spalten.
api.js kann jetzt Datei-Downloads mit Auth-Header und FormData-Uploads.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
MovementOut liefert jetzt package_size, package_label sowie Name/Faktor der
Anzeigeeinheit mit. Die Verlauf-Tabelle zeigt die Bewegung als Leitangabe in
Gebinden (z.B. "1 Glas") und darunter klein die Basiseinheit ("195 g").
Ohne Gebinde/abweichende Einheit bleibt es bei einer Zeile.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- buildUnitOptions verwendet product.package_label als Beschriftung der
Gebinde-Option (Wert bleibt intern "package").
- Beim Auswaehlen eines Artikels ist das Gebinde vorbelegt, wenn eine
Packungsgroesse hinterlegt ist.
- Auslagern: Chargen-Dropdown und Hinweis zeigen die Menge in der Artikeleinheit
(z.B. "MHD 2026-12-23 - 1 Glas") statt in der Basiseinheit.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Das datalist-Eingabefeld sah anders aus als die uebrigen Auswahlfelder im
Produktformular. Jetzt ein einheitliches <select>: leerer Standardwert
"Packung (Standard)" plus gaengige Bezeichnungen (Glas, Tuete, Flasche, Dose,
Tube, Becher, Beutel, Karton, Riegel, Rolle). Ein bereits gespeicherter
abweichender Wert bleibt als Option erhalten.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Neues Feld products.package_label: pro Artikel einstellbar, wie das Gebinde
heisst (Packung, Glas, Tuete, Flasche, Dose, Tube, ...) - Eingabe mit
Vorschlagsliste, frei ueberschreibbar. Migration per ADD COLUMN IF NOT EXISTS.
- Produkttabelle: Spalte "Packungen" heisst jetzt "Einheiten (ist / soll)" und
zeigt Bestand und Mindestbestand als "11 / 12 Glas"; die separate Spalte
"Mindest" entfaellt. Das "niedrig"-Badge sitzt jetzt dort.
- Die Bezeichnung wird ueberall verwendet (Chargenanzeige, Einheiten-Umschalter
beim Bearbeiten, Mindestbestand-Auswahl, Umrechnungshinweis).
- Speichern/Abbrechen im Chargen-Editor sind jetzt gleich breit (.btn-pair).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Eingaben haben global width:100% und schrumpften im Flex-Layout zusammen
(Mindestbestand-Einheit abgeschnitten, Chargen-Bearbeitung winzig).
- .field-inline: Zahlenfelder wachsen (min 78px), Einheiten-Dropdowns behalten
ihre Textbreite (min 132px).
- In Tabellenzellen brechen die Felder bei wenig Platz um statt zu quetschen.
- Einengende Inline-maxWidth entfernt; Menge-/MHD-Spalte mit Mindestbreite.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Anzeige getauscht - oben gross die Packungszahl, darunter klein die Menge in der
Produkteinheit (z.B. "10 Pkg" / "1.945 Gramm"). Ohne Packungsgroesse bleibt die
Produkteinheit die Leitangabe. Das Bearbeiten startet passend in Packungen; per
Umschalter laesst sich weiterhin in der Produkteinheit eingeben.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Beim Bearbeiten einer Charge steht neben dem Mengenfeld ein Umschalter
(z.B. Gramm <-> Packung(en)); der Wert wird beim Wechsel umgerechnet und beim
Speichern korrekt in die Basiseinheit zurueckgerechnet.
- Umstaendlicher Hinweistext unter der Mindestmenge entfernt.
- Redundanter Fusstext unter den Chargen ("Mengen in ...") entfernt; es bleibt
nur die knappe Umrechnung "1 Packung = 195 g".
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Holt den neuesten Stand aus Git und baut die Container neu. Findet seinen
eigenen Pfad (von ueberall aufrufbar), nutzt die vorhandene deploy/.env,
erkennt docker compose v1/v2 und prueft am Ende /api/health.
Optionen: --prune (alte Images aufraeumen), --no-pull (nur neu bauen).
Bei fehlgeschlagenem git pull gibt es einen Hinweis auf lokale Aenderungen.
Im Repo direkt als ausfuehrbar markiert; README ergaenzt.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Die Produkt-Einheit bietet bewusst alle Einheiten an (sie legt die Art fest),
der Mindestbestand nur die passender Art. Das sah nach einem Fehler aus, war aber
gewollt - jetzt sichtbar gemacht:
- Produkt-Einheit nach Anzahl/Gewicht/Volumen gruppiert (optgroup).
- Mindestbestand mit Hinweistext auf die Art und "Packung(en) a <Groesse>".
- baseShort wird aus der gewaehlten Einheit abgeleitet (funktioniert auch bei
neuen Produkten).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Produktformular: Auswahl aller verwalteten Einheiten passender Art (plus
Packungen), inkl. Umrechnung beim Wechsel.
- Die gewaehlte Erfassungseinheit wird gespeichert (products.min_stock_unit_id /
min_stock_in_packages) und exakt so wieder angezeigt - vorher wurde sie aus der
Produkteinheit abgeleitet.
- ProductOut liefert min_stock_display + min_stock_unit_label; Produkttabelle
zeigt den Mindestbestand damit in der erfassten Einheit mit Einheit dahinter.
- Migration: ADD COLUMN IF NOT EXISTS fuer die zwei neuen Spalten.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Korrektur zum vorigen Commit: Anzeige und Bearbeitung der Chargen richten sich
nach der im Produkt eingestellten Einheit. Als Untermenge stehen darunter die
Basiseinheit (falls abweichend) und die Packungen (falls Packungsgroesse gesetzt).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Ist eine Packungsgroesse hinterlegt, sind Anzeige UND Bearbeitung der Chargen in
Packungen; die Basiseinheit (z.B. Gramm) steht nur noch als Untermenge darunter.
Ohne Packungsgroesse bleibt die Produkteinheit massgeblich. Produktkopf nennt
ebenfalls zuerst die Packungen.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Chargen werden in der Produkteinheit angezeigt, darunter die Zweitangabe
(Basiseinheit falls abweichend und/oder Packungen).
- Bearbeiten laeuft jetzt ebenfalls in der Produkteinheit (mit Einheit neben dem
Feld) und rechnet beim Speichern in die Basiseinheit um - vorher zeigte die
Bearbeitung einen anderen Wert als die Anzeige.
- Produktkopf zeigt den Bestand zusaetzlich in Packungen.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- .field-inline: Labels ohne eigenen margin-bottom, sonst rutschen daneben
stehende Buttons (z.B. "Nachschlagen") optisch nach unten. Abstand traegt jetzt
die Reihe selbst; verschachtelt in Label/Tabellenzelle bleibt er aus.
- Produkttabelle: Mindestbestand wird in der Produkteinheit mit nachgestellter
Einheit angezeigt (zusaetzlich der Packungswert, falls Packungsgroesse gesetzt).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Einheiten (neu):
- Tabelle units (name, kind=count|weight|volume, factor, is_builtin); eingebaut
Stueck/Gramm/Kilogramm/Milliliter/Liter, Admin kann eigene anlegen (z.B. Pfund=500g).
- Bestaende bleiben intern in kanonischer Basis (Stueck/Gramm/Milliliter);
Product.display_unit_id und Group.min_stock_unit_id als nullable FKs.
- Neuer Umrechnungs-Service (services/conversion.py) ersetzt die feste Einheitenlogik;
Ein-/Auslagern und Gruppen-Mindestbestand rechnen ueber den Faktor.
- Gruppen-Mindestbestand mit Einheit; Gruppenbestand summiert nur Produkte
passender Art. Neue Verwaltungsseite "Einheiten" (Admin).
- Schonende Migration beim Start: ADD COLUMN IF NOT EXISTS (Postgres), damit
bestehende Installationen ihre Daten behalten.
Chargen:
- PATCH /lots/{id} und DELETE /lots/{id}: Menge/MHD korrigieren, Charge loeschen
(wird als Korrektur-Bewegung protokolliert). Bearbeitung im Produktdetail.
Auslagern:
- Optionales lot_id: gezielt aus einer bestimmten Charge/MHD abbuchen statt FEFO;
Auswahl-Dropdown in der Auslagern-Seite.
Sonstiges: Roadmap aktualisiert, Tests fuer die Umrechnung.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Problem: min_stock wird in Basiseinheiten verglichen. Bei einem 190g-Glas (base
gram, package 190) bedeutete "min 2" 2 Gramm statt 2 Glaeser -> Produkt tauchte
nie auf der Einkaufsliste auf.
Fix:
- Produktformular: Mindestbestand wahlweise in Basiseinheit ODER Packungen
eingebbar (mit Umrechnung); Default Packungen bei Packungsprodukten.
- ShoppingItem liefert package_size; Einkaufsliste/Dashboard zeigen Bedarf in
Packungen (+ Basiseinheit in Klammern) via amountText().
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Einlagern:
- Barcode-Erkennung dreiteilig: bekannt -> direkt Menge; unbekannt aber in OFF
-> "Anlegen & einlagern" inline; gar nicht gefunden -> manuell anlegen.
- Mehrere Chargen pro Vorgang: je Zeile eigene Menge + eigenes MHD
(z.B. 5 Glaeser mit unterschiedlichen Daten). Neuer Endpoint /stock/checkin/batch.
Produkte/OFF:
- OFF-Fuellmenge (quantity) wird in Basiseinheit + Packungsgroesse geparst
(kg->g, l->ml, cl/dl); parse_quantity + Tests.
- Produktformular uebernimmt Barcode aus ?barcode= und schlaegt automatisch nach,
fuellt Packungsgroesse; gemeinsame offUtils (guessGroup/suggestionToProduct).
Lagerorte:
- Baum jetzt rekursiv ueber beliebig viele Ebenen (Schrank->Fach->Kiste->...).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Die v2-API liefert kein status:1-Feld (nur code+product) und antwortet mit
HTTP 404 bei Nicht-Treffern; unser Code prueft aber auf status==1 -> selbst
vorhandene Produkte wurden als "unbekannt" gemeldet. Umstellung auf die v0-API
(status 1/0, HTTP 200), plus robustes JSON-Parsing und follow_redirects.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Der Login-Endpunkt nutzt OAuth2PasswordRequestForm (Form-Data); FastAPI
benoetigt dafuer python-multipart. Fehlte in requirements.txt -> RuntimeError
beim Import von auth.py -> Backend-Restart-Loop -> 502.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Verhindert, dass 'chmod +x install.sh' lokal als Aenderung erscheint und
kuenftige 'git pull' mit "local changes would be overwritten" blockiert.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
passlib 1.7.4 vertraegt sich schlecht mit bcrypt 4.x und kann beim Hashen des
Admin-Passworts im Startup (ensure_first_admin) crashen -> Backend-Container in
Restart-Loop -> 502 in der Web-UI. hash_password/verify_password nutzen jetzt
bcrypt direkt (mit 72-Byte-Grenze). passlib aus requirements entfernt.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- install.sh: ensure_example legt .env.example an falls fehlend; env_hint weist
klar auf die anpassbare .env hin; wait_for_backend pollt /api/health und meldet
502-Ursachen mit Log-Hinweis.
- web/api.js: HTML-Fehlerseiten (z.B. nginx 502) nicht mehr roh anzeigen,
stattdessen verständliche Meldung.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Neue Helfer ensure_curl + pkg_install (apt/dnf/yum/apk/pacman/zypper) mit
sudo-Erkennung; wird vor der Docker-Installation aufgerufen.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Anzeigename, Paketname, Token-Key, DB-/Volume-Namen auf project_good
- README Clone-Abschnitt mit git.scarriffle.com/Scarriffle/project-good
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>