feature/UC61-Lauf-beenden #30

Merged
ingo merged 5 commits from feature/UC61-Lauf-beenden into master 2026-06-13 02:33:27 +02:00
Owner
No description provided.
Implementiert den vollständigen Abschluss-Workflow eines Laufs:

- Neuer Lauf-Status 'finished' (Ergebnisphase) zwischen active und
  archived, mit Übergängen active->finished->{active,archived}.
- Fotogalerie: im aktiven Lauf sieht ein Team alle eigenen Fotos
  (inkl. pending), nach Beendigung alle approved-Fotos aller Teams.
  Galerie/Voting/Rankings sind in finished/archived erreichbar.
- Einmalige Punktvergabe: scoring.emit() vergibt task_solved höchstens
  einmal je (team, task); DB-Sicherheitsnetz via Partial-Unique-Index.
- Admin: Dubletten-Bereinigung (Einreichungen löschen kaskadiert Fotos
  + Score-Events) und Neuberechnung überzähliger task_solved-Events.
- Frontend: Cockpit-Aktion 'Lauf beenden' mit Bestätigung und
  Wieder-öffnen/Archivieren, Galerie-Umschalter Tabs/Liste, beendete
  Läufe in der Läufe-Übersicht, klarer Hinweis auf der Aufgaben-Seite
  in der Ergebnisphase.

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
Teilnehmer sehen in finished/archived alle Aufgaben des Laufs inkl. der
eigenen (Team-)Lösung, statt nur Titel + "Verfügbar":

- /tasks und /tasks/{id} sind über get_results_rallye auch in der
  Ergebnisphase erreichbar; Visibility-Filterung entfällt dort.
- _latest_status_per_task liefert in der Ergebnisphase den letzten
  ENTSCHEIDENDEN Versuch (approved/auto_approved/rejected) statt eines
  dangling 'pending'-Versuchs und gibt zusätzlich das (bereinigte)
  submission_payload zurück -> neue Feld TaskParticipantOut.submission_payload.
- GET /tasks/{id}/submissions ist in der Ergebnisphase erreichbar und
  liefert je Versuch nun auch das payload (eigene Antwort).
- Frontend ResultTaskCard: Titel, Beschreibung, Status (OK/FAIL),
  erhaltene/mögliche Punkte, finale gewertete Antwort (typabhängig
  formatiert) + Kommentar; Versuchs-Historie ausklappbar.

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
Klick auf ein Foto öffnet ein großes Bild mit Durchwechseln aller Bilder
einer Gruppe (Pfeile, Tastatur ←/→, Thumbnail-Streifen, Zähler):

- Neue Komponente PhotoLightbox (photos[] + index + onIndexChange/onClose),
  optionaler Footer-Slot je Bild (z.B. Voting-Button).
- Fotogalerie: Gruppe = Fotos aller Teams zu einer Aufgabe; Voting bleibt im
  Lightbox-Footer verfügbar.
- ResultTaskCard: Gruppe = Mehrfach-Einreichungen einer Aufgabe; Klick auf
  ein Versuchs-Thumbnail öffnet die Lightbox an der richtigen Stelle.

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
Beim Übergang in einen End-Status (finished/archived) erzeugt das Backend
direkt zwei Artefakte und legt sie unter <UPLOAD_DIR>/<rallye>/exports/ ab:

- Team-PDF je Team: eigene Ergebnisse (Aufgabe, finale gewertete Antwort,
  Punkte, Kommentar, ggf. Foto) + Gesamt-Endstand/Platzierung.
- Galerie-ZIP: je Aufgabe ein Verzeichnis "Aufgabentitel" mit
  beschreibung.pdf und den approved-Fotos aller Teams, benannt nach Team
  und Aufgabe.

Erzeugung läuft nach dem Commit des Status-Wechsels (Fehler rollen den
Wechsel nicht zurück). Download:
- GET /me/result/pdf  -> eigenes Team-PDF (Ergebnisphase)
- GET /gallery/download -> Galerie-ZIP (alle Teams + Spielleiter)
- /gallery liefert gallery_zip_available.

Frontend: downloadFile()-Helper (Blob + Auth-Header); Buttons in der
Aufgaben-Ergebnisansicht (Team-PDF), der Galerie und im Cockpit (ZIP).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
ingo merged commit 96dc180dda into master 2026-06-13 02:33:27 +02:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
Projekte/TeamRallye!30
No description provided.