Files
kleiderboerse/Plan-Verbesserungen.md
T
StefanandClaude Opus 5 c748013e4a Plan fuer Verbesserungen aus der Durchsicht vom 13.09.2026
Vorabpruefung der Branches und Tests ist enthalten. Nichts davon ist
umgesetzt - der Plan haelt nur fest, was gefunden wurde.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GR4bNaj9GtRu57J4Niii8o
2026-09-13 20:54:09 +02:00

96 lines
3.4 KiB
Markdown

# Plan: Verbesserungen
Erstellt am 13.09.2026 nach einer Durchsicht des gesamten Repos, parallel zur
Kantone-App. Ergänzt `Plan.md`, der den ursprünglichen Aufbau beschreibt.
**Noch nichts davon ist umgesetzt.**
## Vorabprüfung (13.09.2026, erledigt)
| | |
|---|---|
| Arbeitsverzeichnis | sauber |
| Offene Branches | **keine** |
| Tests | **81 grün in 12 Sekunden** |
| Letzter Tag | v1.0.0 |
**Der CI-Lauf zu v1.0.0 wurde nie bestätigt.** Der Tag wurde einmal auf dem
Server gelöscht und danach auf `e0212cf` neu gesetzt. Vor dem nächsten
Release prüfen, ob in der Registry tatsächlich ein Image liegt.
## Zum Zustand des Codes
Die Durchsicht hat wenig ergeben, und das ist das Ergebnis: Escaping, CSRF,
Token-Vergleich in konstanter Zeit, Bild-Upload mit Inhaltsprüfung statt
Endung, bewusst vermiedenes N+1, CHECK-Constraints in der Datenbank statt
nur in Python — das ist alles vorhanden und richtig gemacht.
Die Punkte unten sind Ergänzungen, keine Korrekturen.
---
## P1 — Keine Sicherung der Datenbank
Der wichtigste offene Punkt, und hier wiegt er schwerer als bei der
Kantone-App: In `kleiderboerse.sqlite` stecken Einträge und in `uploads/`
die dazugehörigen Fotos. **Beides ist nicht wiederherstellbar** — anders als
die Kantonsdaten, die sich neu importieren liessen.
`docker-compose.betrieb.yml` sieht keinen Sicherungsschritt vor.
Ein `cp` der laufenden Datei genügt nicht; sie kann mitten in einer
Schreiboperation erwischt werden. Richtig ist `sqlite3 ... ".backup ..."`
oder `VACUUM INTO`, beide konsistent auch bei laufendem Zugriff.
**Vorgehen**
1. Täglicher Lauf, sieben Stände, danach rollierend überschreiben.
2. **Die Bilder gehören dazu** — eine Datenbank ohne `uploads/` ist wertlos.
3. Einmal einen Stand tatsächlich zurückspielen und prüfen, dass die
Galerie danach vollständig ist. Eine ungetestete Sicherung ist keine.
Punkt 3 ist kein Formalismus: Am 13.09.2026 ist Jellyfin auf demselben
Netzwerk an einer Datenbank-Migration hängengeblieben. Dass es dort
Sicherungen gab, war der einzige Grund, warum die Lage beherrschbar blieb.
## P2 — Antworten werden nicht komprimiert
`app/main.py` bindet keine `GZipMiddleware` ein. Jede HTML- und
HTMX-Antwort geht unkomprimiert über die Leitung — bei einer Galerie mit
vielen Kacheln merkbar, besonders über Mobilfunk.
```python
from fastapi.middleware.gzip import GZipMiddleware
app.add_middleware(GZipMiddleware, minimum_size=1000)
```
## P2 — Statische Dateien ohne Cache-Dauer
```python
app.mount("/static", StaticFiles(directory=...), name="static")
```
Ohne `max_age` werden `htmx.min.js`, `theme.js` und die beiden
Swagger-Dateien bei jedem Aufruf neu verhandelt. Eine lange Cache-Dauer
setzen und bei Änderungen einen Versionsanhänger an die URL hängen.
Für die hochgeladenen Bilder gilt dasselbe — die Dateinamen sind zufällig
erzeugt und ändern sich nie, die dürfen dauerhaft im Cache bleiben.
## P4 — Zwei Filterspalten ohne Index
`crud.items_suchen()` filtert unter anderem nach `gender` und `season`.
Beide Spalten haben keinen Index; `status`, `size` und `category_id` haben
einen.
Bei den zu erwartenden Stückzahlen ist das ohne praktische Bedeutung — der
Vollständigkeit halber notiert, nicht als Handlungsbedarf.
---
## Reihenfolge
1. Sicherungen einrichten, inklusive Bilder, mit einer echten Rückspielprobe
2. GZip und Cache-Dauer — zusammen wenige Zeilen
3. Rest nach Bedarf