Phase 2 stand bisher nur als acht Stichpunkte im Epic. Jetzt je Meilenstein eine Datei mit Ziel, Aufgaben und Akzeptanzkriterien, dazu im Tracker gespiegelt: #48 bis #55, zusammen 76 h geschaetzt. Die Reihenfolge ist nicht beliebig. M15 fuehrt die Quellenart ein, die M16 braucht; M17 legt die Zusammensetzung fest, auf der M18 aufsitzt. Die anderen vier haengen an nichts und koennen jederzeit dazwischen. Drei Entscheidungen fallen vor dem Code und stehen je Meilenstein als erste Aufgabe mit Empfehlung: - Wie ein Baustein die Unveraenderlichkeit einer veroeffentlichten Version ueberlebt (Verweis im Entwurf, tiefe Kopie beim Veroeffentlichen). Ein Lauf sieht weiterhin konkrete Schritte und muss nichts lernen. - Wo Anhaenge liegen (Dateisystem, Metadaten in der Datenbank) -- mit der Folge, dass Compose-Stand, native Installation und sicherung.md ein Volume brauchen. Eine Sicherung, die nur die Datenbank mitnimmt, verliert ab dort Daten. - Was eine Selbstauskunft zeigt: Titel, Status, Zeitraum, Geraet, aber keine Schritte, Notizen, Kommentare oder Anhaenge. In einem Lauf stehen Arbeitsnotizen ueber Menschen; eine Selbstauskunft ist keine Akteneinsicht. Refs #2
55 lines
3.2 KiB
Markdown
55 lines
3.2 KiB
Markdown
# #032 M19 – Anhänge und Fotos an Schritten
|
||
|
||
**Status:** offen
|
||
**Im Tracker:** [#52](https://git.wilde-server.de/florian.wilde/Laufzettel/issues/52)
|
||
**Meilenstein:** v0.2.0
|
||
**Labels:** phase-2, backend, frontend, infra
|
||
**Geschätzt:** 10 h **Tatsächlich:** –
|
||
|
||
## Ziel
|
||
|
||
„Seriennummer fotografiert“, „Typenschild“, „Zustand bei Übergabe“, „Rechnung abgelegt“ — manches
|
||
lässt sich nicht abhaken, es muss gezeigt werden. Ein Schritt soll Dateien und Fotos aufnehmen
|
||
können, am Handy direkt aus der Kamera.
|
||
|
||
## Zu entscheiden
|
||
|
||
- [ ] **Dateien im Dateisystem, Metadaten in der Datenbank** — Empfehlung. Ein Pfad aus der
|
||
Umgebung (`ANHAENGE_PFAD`), darunter nach Kunde und Lauf gegliedert. Gegen `bytea` in Postgres
|
||
spricht die Sicherung: ein `pg_dump` mit Fotos ist nach einem Jahr kein `pg_dump` mehr, das
|
||
jemand einspielt. Gegen S3 spricht, dass diese Anwendung selbst gehostet läuft und keinen
|
||
Objektspeicher voraussetzen soll.
|
||
**Folge, die mitgeplant werden muss:** der Compose-Stand und die native Installation brauchen
|
||
ein Volume, und `docs/betrieb/sicherung.md` muss beides nennen. Eine Sicherung, die nur die
|
||
Datenbank mitnimmt, verliert ab hier Daten — das ist genau die Art Zusage, die dieses Projekt
|
||
sonst teuer bezahlt hat.
|
||
- [ ] **Keine Verkleinerung auf dem Server im ersten Schritt.** Ein Handyfoto hat heute 3–6 MB; eine
|
||
Obergrenze (etwa 10 MB je Datei, 20 Dateien je Lauf) ist ehrlicher als eine Umwandlung, die
|
||
Metadaten verliert und eine Bildbibliothek ins Projekt zieht.
|
||
|
||
## Aufgaben
|
||
|
||
- [ ] Modell `Anhang`: `schrittergebnisId`, `kundeId`, Dateiname, Medientyp, Größe, Prüfsumme,
|
||
`erstelltVonId`, `erstelltAm`; Datei daneben im Dateisystem
|
||
- [ ] Hochladen über einen Route Handler mit `rechtErforderlich` — kein Weg daran vorbei, und
|
||
**jeder** Abruf prüft Recht und Mandant, auch der des Bildes selbst
|
||
- [ ] Grenzen: Medientypen auf Bilder und PDF, Größe je Datei und Anzahl je Lauf, beides in der
|
||
Umgebung einstellbar; eine abgewiesene Datei nennt den Grund
|
||
- [ ] Am Handy direkt aus der Kamera (`capture="environment"`), am Rechner aus dem Dateiwähler
|
||
- [ ] **Der Archiv-Schreibschutz gilt auch hier**: an einem archivierten Lauf kommt kein Anhang mehr
|
||
dazu und keiner weg. `laufMussVeraenderbarSein` sitzt an genau einer Stelle — dort anschließen
|
||
- [ ] Druckansicht: Bilder als Miniaturen mit Dateinamen, PDF nur als Zeile
|
||
- [ ] `docs/betrieb/sicherung.md`, `docker-compose.yml`, `deploy/install.sh`: Volume, Rechte,
|
||
Sicherung **und** Rückspielung
|
||
- [ ] Anleitung Kapitel 02 und 08
|
||
|
||
## Akzeptanzkriterien
|
||
|
||
- [ ] Test: Anhang an einem Schritt hochladen, in der Abarbeitung und im Druck sichtbar
|
||
- [ ] Test: an einem archivierten Lauf wird das Hochladen abgewiesen
|
||
- [ ] Test: ein Anhang eines fremden Kunden ist über seine Adresse **nicht** abrufbar
|
||
- [ ] Test: eine zu große Datei und ein falscher Medientyp werden mit Grund abgewiesen
|
||
- [ ] Test: `docker-compose.yml` hat ein Volume für die Anhänge, und `sicherung.md` nennt es (wie
|
||
`tests/betriebsstand.test.ts` es für die Datenbank schon prüft)
|
||
- [ ] Sicherung und **Rückspielung** einmal wirklich gefahren, nicht nur beschrieben
|