Support-Tickets¶
Stand: 02.10.2026 · Welle 1
Mit Support-Tickets melden alle angemeldeten Nutzer direkt aus LLARS einen Fehler, einen Wunsch, eine Frage oder ein Lob — mit Screenshots, Dateien und einer Sprachnotiz. LLARS schickt dabei automatisch mit, auf welcher Seite und mit welcher Version das Ticket entstand. Admins bearbeiten die Tickets auf einem Board, und der Betreiber beantwortet sie mit Unterstützung von KI-Agenten, die jede Änderung mit Vorher- und Nachher-Bildern im Ticket belegen.
Jedes Ticket hat eine Kennung wie T-12. Sie wird nie neu vergeben und lässt sich in Gesprächen und Mails gut nennen.
Ein Ticket erstellen¶
Der Knopf „Ticket erstellen" sitzt in der App-Bar oben rechts, links neben Ihrem Namen. Schneller geht es mit dem Tastenkürzel ⌘⇧F (Mac) bzw. Strg+Umschalt+F (Windows, Linux) — von jeder Seite aus. Unten links im Dialog führt „Meine Tickets" zu Ihren bisherigen Tickets und Antworten. Ein offener Entwurf bleibt beim Wechsel erhalten.
Im Dialog füllen Sie aus:
| Feld | Hinweis |
|---|---|
| Titel | Ein Satz, worum es geht (höchstens 200 Zeichen). |
| Beschreibung | Was Sie getan haben, was passiert ist und was Sie erwartet hätten. |
| Kategorie | Fehler · Wunsch · Frage · Lob |
| Dringlichkeit | Niedrig · Mittel · Hoch · Blocker (Blocker = Sie kommen nicht weiter) |
| Anhänge | Bilder, PDFs, Text- und Audiodateien, höchstens 5 auf einmal |
| Sprachnotiz | Bis zu 2 Minuten Sprache statt Tippen |
Anhänge hinzufügen — vier Wege führen zum selben Ergebnis:
- Datei wählen über den Knopf im Anhangbereich,
- Einfügen mit ⌘V bzw. Strg+V, etwa einen Screenshot aus der Zwischenablage,
- Ziehen und Ablegen einer Datei auf das Formular,
- „Seite aufnehmen": LLARS fotografiert die aktuelle Seite ohne den Dialog,
ohne Hinweise und Meldungen und hängt das Bild als
screenshot-….pngan. Das Bild verlässt Ihren Browser erst mit dem Absenden des Tickets.
Sprachnotiz: Ein Klick startet die Aufnahme (der Browser fragt einmal nach dem Mikrofon), ein zweiter beendet sie; nach 2 Minuten endet sie von selbst. Ist auf dem Server ein Transkriptionsmodell eingerichtet, erscheint die Notiz später auch als Text im Ticket. Ohne Modell bleibt sie abspielbar.
Mitgeschickter Kontext: Beim Öffnen des Dialogs merkt sich LLARS die aktuelle Seite (Route), die LLARS-Version, die Fenstergröße, den Browser, die Sprache und das Farbschema. Sie sehen diese Angaben aufklappbar im Dialog. Sie helfen, den Fehler genau dort nachzustellen, wo er auftrat.
Absenden mit dem Knopf oder mit ⌘↩ bzw. Strg+Enter. Brechen Sie ab, bleibt Ihr Entwurf erhalten; erst ein erfolgreich gesendetes Ticket leert das Formular. Nach dem Senden bestätigt LLARS die Kennung: „Ticket T-12 ist angekommen".
Bilder bearbeiten¶
Ein Klick auf die Vorschau eines angehängten Bildes öffnet es im Vollbild. Dort bearbeiten Sie es, bevor Sie das Ticket senden — etwa um Namen unkenntlich zu machen oder auf die Stelle zu zeigen, um die es geht.
| Werkzeug | Was es tut |
|---|---|
| Verpixeln | Ziehen Sie ein Rechteck auf; der Bereich wird unwiderruflich verpixelt. Der gelbe Rand zeigt nur, wo Sie schon verpixelt haben, und landet nicht im Bild. |
| Stift | Freihand zeichnen, mit der Maus oder dem Finger. |
| Rechteck | Eine Stelle einrahmen. |
| Pfeil | Vom Anfang bis zur Spitze ziehen. |
| Text | An die Stelle klicken, tippen und mit Enter übernehmen. |
| Radiergummi | Entfernt eine Markierung (Stift, Rechteck, Pfeil, Text). Verpixelung und Zuschnitt nehmen Sie mit „Rückgängig" zurück. |
| Zuschneiden | Den Ausschnitt aufziehen und mit „Zuschneiden anwenden" übernehmen; danach arbeiten Sie im Ausschnitt weiter. |
Für Stift, Rechteck, Pfeil und Text wählen Sie eine von vier Farben. Rückgängig und Wiederholen (auch mit ⌘Z bzw. Strg+Z und ⌘⇧Z bzw. Strg+Y) gelten für jeden Schritt, auch für den Zuschnitt. Alles zurücksetzen holt das ursprünglich angehängte Bild zurück, auch wenn Sie es schon einmal bearbeitet und gespeichert haben.
Speichern übernimmt das Ergebnis in den Anhang. Die Vorschau trägt dann das Kennzeichen „bearbeitet", und die Zahl der Anhänge bleibt gleich. Ist das Bild als PNG größer als 10 MB, speichert LLARS es als JPEG und weist Sie darauf hin. Abbrechen oder Escape verwirft die Änderungen seit dem Öffnen; der Dialog „Ticket erstellen" bleibt dabei offen, und solange der Editor offen ist, sendet ⌘↩ nichts. Die Bearbeitung geschieht ganz in Ihrem Browser: Nichts verlässt Ihren Rechner, bevor Sie auf „Ticket senden" klicken.
Meine Tickets¶
Unter Meine Tickets (/tickets, erreichbar über die Home-Kachel, den
Menüeintrag oben rechts und den Link im Erstellen-Dialog) stehen alle Tickets,
die Sie erstellt haben oder für die Sie zuständig sind. Der Badge am
App-Bar-Knopf „Ticket erstellen" zählt ungesehene Änderungen an Ihren
Tickets.
Ein Klick öffnet das Ticket-Detail (/tickets/T-12):
Die feste Leiste am unteren Rand blättert mit Zurück und Weiter durch die Tickets in der Reihenfolge der Liste, aus der Sie gekommen sind; die Pfeiltasten ← und → funktionieren ebenso, solange Sie keinen Text eingeben oder einen Dialog geöffnet haben. Zur Liste führt Sie zu dieser Liste zurück; bei einem direkt geöffneten Ticket verwendet LLARS die zuletzt aktualisierten Tickets, auf die Sie Zugriff haben.
- Der Verlauf zeigt alle Ereignisse und Kommentare in zeitlicher Reihenfolge, mit Vorschaubildern der Anhänge. Bilder öffnen sich groß, Sprachnotizen lassen sich abspielen.
- Unten schreiben Sie einen Kommentar, auch mit Anhängen.
- Bei einem offenen Ticket können Sie die Erledigung bestätigen. Auf Erledigt können Sie noch antworten oder es mit einer kurzen Begründung wieder öffnen. Nach 14 Tagen ohne neuen menschlichen Kommentar seit der Erledigung schließt das System das Ticket automatisch. Im Detail steht das voraussichtliche Abschlussdatum.
Änderungen erscheinen sofort, ohne dass Sie die Seite neu laden müssen.
Was die Status bedeuten¶
| Status | Bedeutung |
|---|---|
| Neu | Das Ticket ist angekommen und noch nicht angenommen. |
| In Arbeit | Jemand kümmert sich darum; der Kommentar sagt, was gebaut wird. |
| Rückfrage | Das Ticket wartet auf Sie — meist auf eine Antwort oder eine Entscheidung. |
| Erledigt | Umgesetzt und mit Bildern belegt. Sie können noch antworten oder wieder öffnen. Nach 14 Tagen ohne menschlichen Kommentar folgt automatisch „Abgeschlossen“. |
| Abgelehnt | Wird nicht umgesetzt; der letzte Kommentar nennt den Grund. |
| Abgeschlossen | Archivierter Abschluss. Sie können das Ticket lesen, aber nicht mehr kommentieren oder wieder öffnen. Erstellen Sie für ein neues Anliegen ein neues Ticket. Das Support-Team kann es bei Bedarf wieder öffnen. |
Tickets werden nie gelöscht. Auch abgelehnte und abgeschlossene Tickets bleiben lesbar. Ein automatischer Abschluss löst keinen ungesehenen Hinweis aus.
Das Ticket-Board (Admin)¶
Admins öffnen das Board über die Home-Kachel „Support-Tickets"
(/admin/tickets).
- Drei Ansichten: Liste (sortierbar nach Nummer, Titel, Kategorie, Dringlichkeit, Status, Zuständig und Aktualisiert), Kanban (eine Spalte je Arbeitsstatus; eine Karte zu ziehen ändert den Status, das Karten-Menü „Status setzen" leistet dasselbe per Tastatur) und Karten (mit Titelbild und Auszug). Die gewählte Ansicht merkt sich der Browser.
- Abgeschlossen erscheint in Liste und Karten mit eigenem Zähler und Filter, aber nicht als Kanban-Spalte. Nur das System setzt diesen Status.
- Filter und Zähler: Status, Kategorie, Zuständig („mir zugewiesen",
„niemand", eine Person) und Volltextsuche in Titel und Beschreibung. Die
Zähler zeigen, wie viele Tickets je Status vorliegen. Abgelehnte Testtickets
mit
[SMOKE …]oder[E2E …]im Titel sind standardmäßig ausgeblendet und werden nicht mitgezählt. Mit „Testläufe anzeigen“ erscheinen sie wieder; noch offene Testtickets bleiben immer sichtbar. - Zuständigkeit: Genau eine Person ist zuständig. „Mir zuweisen", eine
Person wählen oder die Zuständigkeit entfernen — zuständig sein können nur
Mitglieder des Support-Teams (Recht
feature:tickets:manage). Die zuständige Person sieht das Ticket und darf Status, Dringlichkeit und Kategorie ändern. - Status, Dringlichkeit und Kategorie ändern Sie im Detail. Jede Änderung steht danach im Verlauf, wahlweise mit einem Kommentar.
- „Entscheidung nötig": Ein Punkt vor der Kennung und ein eigener Filter zeigen Tickets, bei denen ein Mensch etwas entscheiden muss; oben im Detail steht der Satz, um den es geht. Sobald ein Mensch am Ticket handelt (Kommentar, Statuswechsel, Anhang), verschwindet die Markierung von selbst.
- Titelbild: Ein Bildanhang kann als Titelbild der Karte dienen.
Änderungen anderer Admins und des KI-Agenten erscheinen live; zusätzlich fragt das Board alle 30 Sekunden und beim Zurückkehren in den Tab nach.
Für Entwickler¶
Datenmodell¶
Alle Tabellen entstehen per create_all() in app/db/models/support_ticket.py.
Benutzer stehen als Username ohne Fremdschlüssel in den Tabellen, damit der
Verlauf das Löschen eines Kontos überlebt.
| Tabelle | Inhalt |
|---|---|
support_tickets |
Titel, Beschreibung, category, priority, status, creator_username, assignee_username, context_json, decision_needed/decision_text, cover_attachment_id, Zeitstempel inkl. resolved_at |
support_ticket_attachments |
kind (screenshot/audio/file), bereinigter filename, serverseitig bestimmter mime_type, size_bytes, sha256, content als LONGBLOB (deferred), origin (creator/admin/agent), Transkript-Felder, optional comment_id |
support_ticket_comments |
author_username, author_type (human/agent/system), body (1–20 000 Zeichen) |
support_ticket_events |
Der Verlauf: actor_username, actor_type, action (created, commented, attached, status_changed, priority_changed, category_changed, assigned, decision_flagged, decision_cleared, cover_changed, transcribed, agent_accessed), details_json |
Werte in DB und API sind englisch, die Anzeige läuft über i18n:
status = new, in_progress, needs_reply, done, rejected, closed ·
category = bug, feature, question, praise ·
priority = low, medium, high, blocker.
API¶
Alle Routen liegen unter /api/tickets und akzeptieren eine Sitzung (Bearer)
oder den System-Admin-API-Key im Header X-API-Key. Antworten haben die
Form {"success": true, …}, Fehler {"success": false, "error": "…"}. Die
Kennung <ref> darf T-12, t-12 oder 12 sein.
| Methode & Pfad | Recht | Zweck |
|---|---|---|
POST /api/tickets |
view | Anlegen: JSON ohne Dateien oder multipart mit title, description, category, priority, context (JSON-String) und bis zu 5 × files → 201 |
GET /api/tickets |
view | Liste mit status, category, priority, assignee=me\|none\|<user>, q, scope=mine\|all, decision=1, page, per_page (≤ 100), sort=updated_desc\|created_desc\|priority, optional hide_tests=1 (nur abgelehnte Testtickets ausblenden) |
GET /api/tickets/stats |
view | Zähler je Status, eigene Rückfragen und offene Tickets, decision_needed |
GET /api/tickets/assignees |
manage | Mögliche Zuständige |
GET /api/tickets/<ref> |
view | Detail mit attachments, comments, events |
PATCH /api/tickets/<ref> |
view | status, priority, category, assignee, decision_needed, decision_text, cover_attachment_id, optional comment |
POST /api/tickets/<ref>/comments |
view | Kommentar als JSON {body} oder multipart mit files → 201 |
POST /api/tickets/<ref>/attachments |
view | Anhänge (files, bis zu 5) → 201 |
GET /api/tickets/<ref>/attachments/<id> |
view | Datei; ?inline=1 nur für Bild, Audio und PDF |
GET /api/tickets/<ref>/events |
view | Verlauf |
Beispiele mit dem lokalen System-Key (der Wert steht in der .env unter
SYSTEM_ADMIN_API_KEY und gehört nicht in die Kommandozeilen-Historie anderer):
KEY=<aus .env> # SYSTEM_ADMIN_API_KEY
BASE=http://localhost:55080
# Offene Tickets mit „Entscheidung nötig"
curl -s "$BASE/api/tickets?scope=all&decision=1" -H "X-API-Key: $KEY" | jq '.tickets[] | {ref, title, status}'
# Ein Ticket mit Verlauf
curl -s "$BASE/api/tickets/T-12" -H "X-API-Key: $KEY" | jq '.ticket | {ref, status, events: (.events | length)}'
# Kommentar mit Screenshot
curl -s -X POST "$BASE/api/tickets/T-12/comments" -H "X-API-Key: $KEY" \
-F "body=Der Knopf ist wieder da, siehe Bild." -F "files=@t12-nachher-hell.png;type=image/png"
# Status setzen, mit Kommentar
curl -s -X PATCH "$BASE/api/tickets/T-12" -H "X-API-Key: $KEY" -H "Content-Type: application/json" \
-d '{"status": "in_progress", "comment": "Wird gebaut."}'
Ein Aufruf mit dem System-Key gilt als KI-Agent: Kommentare und Ereignisse
tragen author_type/actor_type = agent, und ein lesender Detail-Zugriff
schreibt höchstens einmal je Ticket und Stunde das Ereignis agent_accessed.
Rechte¶
| Permission | Rollen | Darf |
|---|---|---|
feature:tickets:view |
researcher, evaluator, chatbot_manager, ijcai_reviewer | Tickets erstellen, eigene und zugewiesene sehen und kommentieren; als Ersteller die Erledigung bestätigen (done) oder mit Kommentar wieder öffnen (new) |
feature:tickets:manage |
admin | Alle Tickets sehen und ändern, zuweisen, „Entscheidung nötig" setzen, Board |
Ein fremdes Ticket antwortet mit 404, nicht mit 403, damit sich
Ticketnummern nicht ausprobieren lassen. Die feineren Regeln prüft
TicketService in app/services/tickets/.
Live-Updates (Socket.IO)¶
Der Client sendet tickets:join und landet im Raum tickets_user_<username>,
mit manage zusätzlich in tickets_admin; tickets:leave verlässt sie. Der
Server sendet tickets:created und tickets:updated mit {ticket, event} an
das Admin-Board, den Ersteller und die zuständige Person. Als Rückfall fragt
das Frontend alle 30 Sekunden und bei Tab-Rückkehr nach.
Transkription¶
Aufnehmen geht immer; transkribiert wird nur, wenn die Umgebungsvariable
TICKET_TRANSCRIPTION_MODEL gesetzt ist. Sie nennt ein OpenAI-kompatibles
/audio/transcriptions-Modell im Format der LLM-Modell-Ids und läuft über
LLMClientFactory. Der Status eines Audio-Anhangs geht von pending über
running nach done oder failed; ohne Modell steht er auf unavailable.
Limits und Allowlist¶
| Grenze | Wert |
|---|---|
| Datei | höchstens 10 MiB |
| Dateien je Upload | 5 |
| Dateien je Ticket | 30 |
| Titel | 200 Zeichen |
| Beschreibung, Kommentar | 20 000 Zeichen |
Erlaubt sind PNG, JPEG, WebP, GIF, PDF, Text, Markdown, CSV, JSON sowie Audio
als WebM, Ogg, MP4/M4A und WAV. Bilder und PDF bestimmt der Server anhand der
ersten Bytes, nie anhand der Angabe des Browsers; SVG und HTML sind verboten.
Downloads tragen X-Content-Type-Options: nosniff,
Content-Security-Policy: sandbox und Cache-Control: private, no-store.
Dateien im Repo¶
app/db/models/support_ticket.py # Tabellen
app/routes/tickets/ # Blueprint /api/tickets
app/services/tickets/ # TicketService, Validierung, Transkription
app/socketio_handlers/events_tickets.py # tickets:join/leave
llars-frontend/src/lib/tickets.js # Konstanten, Ref-Parser, ticketsApi
llars-frontend/src/components/tickets/ # Dialog, Verlauf, Anhänge, Board-Bausteine
llars-frontend/src/views/Tickets/ # Meine Tickets, Detail, Admin-Board
.claude/skills/tickets/SKILL.md # Skill /tickets
scripts/agenten/ # tickets.py, screenshot.mjs, README.md
scripts/ci/smoke_test_tickets.sh # Smoke-Rundlauf (SMOKE_TICKETS)
Für KI-Agenten¶
Der Betreiber arbeitet Tickets mit dem Claude-Code-Skill /tickets ab
(.claude/skills/tickets/SKILL.md). Der Ablauf: alles lesen (Beschreibung,
Bilder, Transkripte, Kommentare), das Ticket mit einem Kommentar annehmen,
Vorher-Bilder machen, Designfragen als Vorschläge klären, von Agenten bauen
lassen, die Arbeit mit Tests prüfen, auf die Testinstanz deployen,
Nachher-Bilder machen, mit Belegen kommentieren und den Status setzen.
Kommentare stehen in der Sprache des Tickets, in kurzen ganzen Sätzen, und
nennen die angehängten Bilder beim Namen.
scripts/agenten/tickets.py — die Kommandozeile zur API, nur mit der
Python-Standardbibliothek:
python3 scripts/agenten/tickets.py --env local list
python3 scripts/agenten/tickets.py --env local show T-12 --download <scratchpad>/tickets/T-12
python3 scripts/agenten/tickets.py --env local status T-12 in_progress --comment "Wird gebaut."
python3 scripts/agenten/tickets.py --env local comment T-12 "…" --file t12-nachher-hell-1440.png
python3 scripts/agenten/tickets.py --env local decision T-12 "Bitte A oder B wählen."
Weitere Befehle sind attach, assign und classify. --env wählt die
Instanz (local, dev, prod) und damit die Schlüsselvariable der .env
(SYSTEM_ADMIN_API_KEY, DEV_ADMIN_API_KEY, PRODUCTION_ADMIN_API_KEY). Das
Skript gibt den Schlüssel nie aus und prüft Dateien, Größen und Textlängen vor
dem ersten Netzaufruf.
scripts/agenten/screenshot.mjs — Belegbilder einer angemeldeten Seite mit
Playwright, hell oder dunkel, Desktop oder Handy, wahlweise mit nummerierten
roten Rahmen:
node scripts/agenten/screenshot.mjs --env local --user evaluator --path /tickets \
--dark --mobile --out <scratchpad>/t12-vorher-dunkel-390.png
Die Dateinamen folgen dem Muster t12-vorher-hell-1440.png bzw.
t12-nachher-dev-dunkel-390.png. Beide Werkzeuge beschreibt
scripts/agenten/README.md vollständig. Der
Smoke-Test scripts/ci/smoke_test_tickets.sh fährt nach jedem Deploy einen
Rundlauf durch die API; sein Ticket trägt [SMOKE …] im Titel und endet als
„Abgelehnt", weil es keinen Löschweg gibt.
Das Admin-Board blendet solche abgeschlossenen Testläufe standardmäßig aus;
die API-Liste ohne hide_tests=1 und „Meine Tickets“ enthalten sie weiterhin.
Testläufe lösen auch keinen beigen Ungesehen-Punkt und keine Snackbar aus.
Geplant¶
Diese Punkte sind bewusst nicht Teil von Welle 1:
- E-Mail-Benachrichtigung bei Rückfragen und Erledigung.
- Automatische Kategorisierung neuer Tickets durch ein Sprachmodell.
Eine Löschfunktion für Tickets gibt es nicht und ist auch nicht geplant.