Polymorphe Datei-Anhänge (PDF/JPEG/PNG/WebP, Whitelist statt Blacklist - owasp-Grundsatz) an beliebige Ressource, gleiches entitaet_typ/entitaet_id- Muster wie Mangel/Historie. Lokale Ablage (settings.upload_dir, kein Cloud- Zwang, Self-Hosting-Anforderung), server-generierter Dateiname verhindert Path-Traversal/Namenskollisionen. POST /dokumente (multipart), GET /dokumente (Filter Pflicht: entitaet_typ + entitaet_id), GET /dokumente/{id}/download, DELETE /dokumente/{id}. Hochladen: alle Mitarbeiter+, Löschen: Materialverantwortliche+Leitung+Admin. Frontend: wiederverwendbares DokumentePanel (Upload/Liste/Download/Löschen), eingebunden in ObjektSection (je Objekt) und MangelListePage (Fotos zu Mängeln) - weitere Ressourcen (Geräteinstanz, Fahrzeugdetails, Benutzer) können denselben Baustein später einfach wiederverwenden. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KC8HYvv6UkCVYheYiTw9DD
- Vollständiges Ziel-Schema aus Prompt 20 als initiale Migration (inkl. Karte-13-Vorbereitung: UUID-PKs, systemknoten) - Seed-Migration für Hauptserver-Datensatz (Sprintplan E6) - JWT-Login + /auth/me, require_roles-Dependency (Prompt 05 Berechtigungsmatrix) - Tests: health, login/me, Rollen-Ablehnung/-Zulassung (S0-Abnahmekriterien) - Gitea-Actions-CI: install -> migrate -> pytest mit Coverage-Gate 50% Nur Code/Config erzeugt, nicht lokal installiert oder ausgeführt (Deployment-Regel). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01L85hmKbvX7Cqkq47KnQhFt