Zammad → GitHub Issue
Erstellt aus einem Zammad-Ticket ein strukturiertes GitHub Issue auf einsatzleitsoftware.ghe.com.
Workflow
Schritt 1: Zammad-Ticket auslesen
Lies das Zammad-Ticket gemäß ~/.claude/skills/zammad-read/SKILL.md aus. Analysiere den Inhalt und bestimme die Kategorie:
- •Bug: Fehlerbeschreibung, unerwartetes Verhalten, Absturz
- •Feature: Neue Funktionalität, Erweiterung
- •Verbesserung: Optimierung bestehender Funktionen
Internes vs. externes Ticket bestimmen
Prüfe das Feld organization des Tickets:
- •Intern: Organisation ist
"Eifert Systems GmbH"→ Ticket stammt von einem eigenen Mitarbeiter - •Extern: Jede andere Organisation → Ticket stammt von einem Kunden
Merke dir den Wert von customer (Name des Erstellers) — dieser wird bei internen Tickets in der Referenz verwendet.
GitHub-Account des Erstellers prüfen (nur bei internen Tickets)
Bei internen Tickets prüfen, ob der Ersteller einen GitHub-Account auf der GHE-Instanz hat. Dazu die Mitgliederliste der Organisation abfragen:
GH_HOST=einsatzleitsoftware.ghe.com gh api '/orgs/edp/members' --jq '.[].login'
Den Login anhand des Namens aus dem Zammad-Ticket zuordnen (z.B. "hendrik.eifert@..." → hendrik-eifert). Falls ein passender Account gefunden wird, diesen für die Referenz im Issue-Body verwenden (siehe Referenz-Varianten).
Schritt 2a: Daten vom Server abrufen
Parallel alle Metadaten prefetchen (bevor der User gefragt wird):
Repos (MCP):
mcp__github__search_repositories(query: "org:edp", perPage: 50)
Issue Types (MCP):
mcp__github__list_issue_types(owner: "edp")
Assignees (Bash — kein MCP-Äquivalent):
GH_HOST=einsatzleitsoftware.ghe.com gh api '/orgs/edp/members' --jq '.[].login'
Projects (Bash — kein MCP-Äquivalent):
GH_HOST=einsatzleitsoftware.ghe.com gh api graphql -f query='
query {
organization(login: "edp") {
projectsV2(first: 20) {
nodes { id number title }
}
}
}
' --jq '.data.organization.projectsV2.nodes[] | "\(.number): \(.title)"'
Labels werden hier NICHT abgefragt — sie hängen vom gewählten Repo ab (→ Schritt 2c).
Schritt 2b: Repo auswählen
AskUserQuestion mit:
- •Vorgeschlagenes Repo
(Empfohlen)— basierend auf Ticket-Inhalt - •2 weitere wahrscheinliche Repos
- •
Abbruch
Repo ist Pflichtfeld → kein "Kein Wert setzen". Weitere Repos via "Other".
Bei "Abbruch": Skill bricht sofort ab mit Meldung "Skill abgebrochen."
Schritt 2c: Labels abrufen und pro Kategorie auswählen
- •Labels für gewähltes Repo fetchen:
GH_HOST=einsatzleitsoftware.ghe.com gh label list -R edp/<repo> --json name,description --limit 100
- •Labels am
:aufteilen →kategorie:wert - •
merge:*Labels ausschließen (werden automatisch vom Server gesetzt) - •Pro Kategorie eine
AskUserQuestion:- •Vorschlag
(Empfohlen)falls einer sinnvoll, sonst ohne - •Alle Werte der Kategorie als Optionen
- •
Kein Wert setzen - •Bei >4 Optionen: die wahrscheinlichsten 2-3 + "Kein Wert setzen", Rest via "Other"
- •Vorschlag
Beispiel für priority-Kategorie (3 Labels):
- •
priority:prioritized (Empfohlen) - •
priority:release - •
priority:unprioritized - •
Kein Wert setzen
Labels ohne : werden einzeln als eigene Frage behandelt (z.B. "Label security setzen?" → Ja/Nein).
Bei "Abbruch" (via "Other"): Skill bricht sofort ab mit Meldung "Skill abgebrochen."
Schritt 2d: Type auswählen
Falls der User einen Type als Argument mitgegeben hat → diesen Schritt überspringen.
AskUserQuestion mit verfügbaren Types:
- •Vorschlag
(Empfohlen)basierend auf Ticket-Analyse (Bug/Feature/Verbesserung) - •Weitere Types
- •
Kein Wert setzen
Bei "Abbruch" (via "Other"): Skill bricht sofort ab mit Meldung "Skill abgebrochen."
Schritt 2e: Assignee auswählen
AskUserQuestion:
- •
tim-rudorf (Empfohlen)— immer Default - •2 weitere Org-Mitglieder
- •
Kein Wert setzen
Bei "Abbruch" (via "Other"): Skill bricht sofort ab mit Meldung "Skill abgebrochen."
Schritt 2f: Project auswählen
AskUserQuestion mit verfügbaren Projects:
- •Vorschlag
(Empfohlen)basierend auf Inhalt - •Weitere Projects
- •
Kein Wert setzen
Typische Zuordnung:
- •Feature/Bug für aktuelle Entwicklung → aktuelles Release-Project (z.B. "Release 2026.1.0")
- •Grundlegende Architekturthemen → "Go edp:server" o.ä.
Bei "Abbruch" (via "Other"): Skill bricht sofort ab mit Meldung "Skill abgebrochen."
Schritt 3: Entwurf präsentieren
Vor dem Erstellen eine strukturierte Übersicht mit AskUserQuestion anzeigen:
Issue-Entwurf ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ Repo: edp/<repo> Type: <type> Assignee: <assignee> Labels: <label1>, <label2>, ... Project: <project> Herkunft: intern (<mitarbeiter>) / extern (<organisation>) Titel: <titel> Body: ────── <vollständiger Body> ──────
Optionen: "Erstellen", "Ändern", "Abbrechen".
Bei "Ändern": User gibt an welches Feld → nur diese Frage erneut stellen (Schritt 2b-2f je nach Feld).
Schritt 4: Issue erstellen
Nach Bestätigung das Issue erstellen:
4a: Issue erstellen (MCP)
Issue per MCP-Tool erstellen. Der type-Parameter setzt den Issue-Type direkt — kein separater GraphQL-Schritt nötig. Felder mit "Kein Wert setzen" weglassen:
mcp__github__issue_write( method: "create", owner: "edp", repo: <repo>, title: <titel>, body: <body>, labels: [<label1>, <label2>], assignees: [<assignee>], type: <type> )
4b: Project zuordnen (Bash — kein MCP-Äquivalent)
Falls ein Project gewählt wurde:
GH_HOST=einsatzleitsoftware.ghe.com gh issue edit <nr> -R edp/<repo> --add-project "<project>"
Nach dem Erstellen die Issue-URL dem User anzeigen.
Schritt 5: Zammad-Ticket benachrichtigen und ggf. schließen
Da das Issue aus einem Zammad-Ticket erstellt wurde, ist die Zammad-Ticketnummer aus Schritt 1 bereits bekannt.
5a: Internen Kommentar schreiben
Gemäß ~/.claude/skills/zammad-write/SKILL.md einen internen Kommentar in das Zammad-Ticket schreiben:
- •Ticketnummer: Die
<ticket_number>aus Schritt 1 - •Body:
Ein GitHub Issue wurde zu diesem Thema eröffnet: <issue-url> (Issue #<nummer> in edp/<repo>) - •Intern:
true
Die Bestätigung per AskUserQuestion aus dem /zammad-write Skill überspringen — der User hat das Issue bereits in Schritt 3 bestätigt. Stattdessen den Kommentar direkt absenden und das Ergebnis dem User anzeigen (Zammad-Ticketnummer + Hinweis dass kommentiert wurde).
5b: Internes Ticket schließen
Wenn das Ticket intern ist (Organisation = "Eifert Systems GmbH"), das Zammad-Ticket nach dem Kommentar auf Status "closed" setzen:
source ~/.env
BASE="${ZAMMAD_HOST%/}"
AUTH="Authorization: Token token=${ZAMMAD_TOKEN}"
curl -s -X PUT \
-H "$AUTH" \
-H "Content-Type: application/json" \
--data '{"state": "closed"}' \
"$BASE/api/v1/tickets/<ticket_id>" > /tmp/z_close.json \
&& jq '{id, number, title, state}' /tmp/z_close.json
Bei externen Tickets das Ticket nicht schließen — es bleibt offen für weitere Kundenkommunikation.
Fehlertoleranz: Falls das Zammad-Ticket nicht gefunden wird oder die API fehlschlägt, den Fehler dem User anzeigen aber den Skill nicht abbrechen — das GitHub Issue wurde bereits erfolgreich erstellt.
Issue-Struktur
Titel
Prägnant, beschreibend, ohne Präfix-Tags. Maximal ~70 Zeichen.
Body — Bug
## Beschreibung <Klare, zusammenfassende Beschreibung des Problems in 2-4 Sätzen.> ## Hintergrund <Kontext: Wer ist betroffen, in welchem Bereich tritt das auf, warum ist es relevant.> ## Schritte zur Nachstellung 1. ... 2. ... 3. ... ## Erwartetes Verhalten <Was sollte passieren.> ## Tatsächliches Verhalten <Was passiert stattdessen.> ## Referenz <siehe Referenz-Varianten unten>
Body — Feature / Verbesserung
## Beschreibung <Klare, zusammenfassende Beschreibung der Anforderung in 2-4 Sätzen.> ## Hintergrund <Kontext: Wer ist betroffen, in welchem Bereich tritt das auf, warum ist es relevant.> ## Anforderungen - [ ] ... - [ ] ... ## Referenz <siehe Referenz-Varianten unten>
Referenz-Varianten
Je nach Herkunft des Tickets unterschiedliche Formulierung:
- •
Externes Ticket (Kundenrückmeldung):
codeBasierend auf Kundenrückmeldung via Zammad: `EDP#<ticket_number>`
- •
Internes Ticket (eigener Mitarbeiter):
- •Mit GitHub-Account:
code
Internes Ticket von @<github_login>: `EDP#<ticket_number>`
- •Ohne GitHub-Account:
code
Internes Ticket von <mitarbeiter_name>: `EDP#<ticket_number>`
- •Mit GitHub-Account:
Regeln für den Inhalt
- •Deutsche Sprache, professioneller Ton
- •Kein Hinweis auf AI oder automatische Erstellung
- •Kein Copy-Paste von Kunden-Mails — Inhalt wird in eigenen Worten zusammengefasst und fachlich aufbereitet
- •Fachlich präzise, keine Füllwörter
- •Echte Umlaute (ä, ö, ü, ß) verwenden — niemals ASCII-Umschreibungen (ae, oe, ue, ss)
- •Bug vs. Feature/Verbesserung bestimmt welche Sektionen genutzt werden
GHE-Spezifika
- •GitHub-Abfragen bevorzugt über MCP-Tools (
mcp__github__*) - •Nur
GH_HOST=einsatzleitsoftware.ghe.comvor verbleibendengh-Befehlen setzen (org members, projects, labels, project assign) - •User-Login:
tim-rudorf - •Org:
edp - •Alle Metadaten (Repos, Types, Projects, Labels) werden live abgefragt, nie hardcoded
Skill-Optimierung
Nach Abschluss dieses Skills kurz bewerten, ob Optimierungsbedarf besteht:
- •Empfehlung "ja": Fehler aufgetreten, Workarounds nötig, Befehle wiederholt, User-Korrekturen
- •Empfehlung "nein": Reibungsloser Lauf wie dokumentiert
Per AskUserQuestion fragen:
Skill abgeschlossen. Soll die Skill-Dokumentation optimiert werden? Empfehlung: {ja — [kurzer Grund] | nein — Lauf war reibungslos}
Optionen: "Ja, optimieren", "Nein"
Bei "Ja": skill-optimize mit Skill-Name zammad-to-issue ausführen.