From 1f6ff2ff101d81aff0581aa9c2f702fde1c01195 Mon Sep 17 00:00:00 2001 From: Malaber Date: Sun, 12 Apr 2026 10:18:58 +0200 Subject: [PATCH 01/10] Add TODO file --- README.md | 35 ----------------------------------- TODO | 31 +++++++++++++++++++++++++++++++ 2 files changed, 31 insertions(+), 35 deletions(-) create mode 100644 TODO diff --git a/README.md b/README.md index 0d8e8dc..ff52a51 100644 --- a/README.md +++ b/README.md @@ -53,38 +53,3 @@ While developing, if you want to use the development docker container, it should ```bash $ rails diagram:all_with_engines ``` - - -## Ideen - -- backend könnte "advancing" an ein team mit dranschreiben; das könnte das frontend anzeigen ✅ -- alle funktionen der beamer ansichten müssen per query param gehen; beamer dann headless möglich (raspberry ohne maus/tastatur); noch besser: Beamer ansicht einfach /beamer und das backend entscheidet was geht -- feature im frontend für "team merken" damit man automatisch zur eigenen gruppe/aktuellstes game scrollt -- timer auf dem beamer anzeigen für aktuelle runde ✅ -- filter für "aktuelle runde" für den beamer -- beamer modus (vollbild ohne cursor) ✅ -- qr codes drucken für ergebnisausgabe und auf allen beamern anzeigen -- admin frontend automatisch aktualisieren -- admin frontend anzeigen wie "alt" die daten sind, also wann wurde die seite zuletzt aktualisiert -- näcshte spiele sollten anzeigen wer da spielt (team a / team b) wenns direkt drunter ist und ansonsten "gewinner achtelfinale 3" -- erste playoff spiele sollten "1. gruppe 15 vs 2. gruppe 16" anzeigen -- admin frontend muss tische auch anzeigen -- WICHTIG UND EZ: gruppenphase in der gleichen gruppe sollten erst finale gegeneinander spielen (dazu nicht aus der nächsten gruppe sondern einmal advancing teams von vorne und einmal von hinten, oder offset von hälfte der weiterkommenden teams) ✅ -- beim eintragen einer runde direkt den nächsten tisch anzeigen -- spiel um platz 3 -- edgecase wenn mehr als die hälfte der teams weiterkommen bedenken bzw zumindest abfangen (hier ist gemeint dass es aktuell spezialcode für po2 turniere gibt bei denen immer die hälfte weiterkommt, es sollte aber auch _irgendwie_ für alle turniere funktionieren, ist nur out of scope für bpwstr) -- Timer groß werden lassen als splashscreen wenn er ausläuft -- Flaschenhalter für die Techniktische -- timer end im admin frontend hübsch machen (aktuell hardcoded startwert) -- turniere-match on focus suche markieren -- vollbildansicht anpassen, dass sie auch abstände oben hat (die navbar oben is ja weg) -- damit klarkommen wenn matches aus der reihe gespielt werden (ein match stoppen, anderes match starten, neue matches starten muss entsprechend auch noch funktionieren) -- tabellen im admin fe anzeigen, leute fragen beim ergebnis abgeben nach -- "Live" in "Läuft noch" umgenennen -- funktion timer unset -- alternativer timer der hochzählt, statt runter für viertelfinale etc. -- auf fullscreen matches ansicht die stage anzeigen (8tel, 4tel, etc.) -- direkten vergleich werten, wenn alles gleich ist sonst -- bei gleichstand für stechen einen punkt vergeben (oder sonstwie, absprechen mit bpwstr) -- bug: refresh war kaputt in viertelfinale, halbfinale, finale -- sieger setzen können; letztes spiel beenden können diff --git a/TODO b/TODO new file mode 100644 index 0000000..f44cdff --- /dev/null +++ b/TODO @@ -0,0 +1,31 @@ +- backend könnte "advancing" an ein team mit dranschreiben; das könnte das frontend anzeigen ✅ +- alle funktionen der beamer ansichten müssen per query param gehen; beamer dann headless möglich (raspberry ohne maus/tastatur); noch besser: Beamer ansicht einfach /beamer und das backend entscheidet was geht +- feature im frontend für "team merken" damit man automatisch zur eigenen gruppe/aktuellstes game scrollt +- timer auf dem beamer anzeigen für aktuelle runde ✅ +- filter für "aktuelle runde" für den beamer +- beamer modus (vollbild ohne cursor) ✅ +- qr codes drucken für ergebnisausgabe und auf allen beamern anzeigen +- admin frontend automatisch aktualisieren +- admin frontend anzeigen wie "alt" die daten sind, also wann wurde die seite zuletzt aktualisiert +- näcshte spiele sollten anzeigen wer da spielt (team a / team b) wenns direkt drunter ist und ansonsten "gewinner achtelfinale 3" +- erste playoff spiele sollten "1. gruppe 15 vs 2. gruppe 16" anzeigen +- admin frontend muss tische auch anzeigen +- WICHTIG UND EZ: gruppenphase in der gleichen gruppe sollten erst finale gegeneinander spielen (dazu nicht aus der nächsten gruppe sondern einmal advancing teams von vorne und einmal von hinten, oder offset von hälfte der weiterkommenden teams) ✅ +- beim eintragen einer runde direkt den nächsten tisch anzeigen +- spiel um platz 3 +- edgecase wenn mehr als die hälfte der teams weiterkommen bedenken bzw zumindest abfangen (hier ist gemeint dass es aktuell spezialcode für po2 turniere gibt bei denen immer die hälfte weiterkommt, es sollte aber auch _irgendwie_ für alle turniere funktionieren, ist nur out of scope für bpwstr) +- Timer groß werden lassen als splashscreen wenn er ausläuft +- Flaschenhalter für die Techniktische +- timer end im admin frontend hübsch machen (aktuell hardcoded startwert) +- turniere-match on focus suche markieren +- vollbildansicht anpassen, dass sie auch abstände oben hat (die navbar oben is ja weg) +- damit klarkommen wenn matches aus der reihe gespielt werden (ein match stoppen, anderes match starten, neue matches starten muss entsprechend auch noch funktionieren) +- tabellen im admin fe anzeigen, leute fragen beim ergebnis abgeben nach +- "Live" in "Läuft noch" umgenennen +- funktion timer unset +- alternativer timer der hochzählt, statt runter für viertelfinale etc. +- auf fullscreen matches ansicht die stage anzeigen (8tel, 4tel, etc.) +- direkten vergleich werten, wenn alles gleich ist sonst +- bei gleichstand für stechen einen punkt vergeben (oder sonstwie, absprechen mit bpwstr) +- bug: refresh war kaputt in viertelfinale, halbfinale, finale +- sieger setzen können; letztes spiel beenden können From 928e3cb9c18d8977f9df01b3d331d370a5450892 Mon Sep 17 00:00:00 2001 From: Malaber Date: Sun, 12 Apr 2026 10:21:15 +0200 Subject: [PATCH 02/10] Switch to csv for jira import --- TODO | 31 ------------------------------- TODO.csv | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 32 insertions(+), 31 deletions(-) delete mode 100644 TODO create mode 100644 TODO.csv diff --git a/TODO b/TODO deleted file mode 100644 index f44cdff..0000000 --- a/TODO +++ /dev/null @@ -1,31 +0,0 @@ -- backend könnte "advancing" an ein team mit dranschreiben; das könnte das frontend anzeigen ✅ -- alle funktionen der beamer ansichten müssen per query param gehen; beamer dann headless möglich (raspberry ohne maus/tastatur); noch besser: Beamer ansicht einfach /beamer und das backend entscheidet was geht -- feature im frontend für "team merken" damit man automatisch zur eigenen gruppe/aktuellstes game scrollt -- timer auf dem beamer anzeigen für aktuelle runde ✅ -- filter für "aktuelle runde" für den beamer -- beamer modus (vollbild ohne cursor) ✅ -- qr codes drucken für ergebnisausgabe und auf allen beamern anzeigen -- admin frontend automatisch aktualisieren -- admin frontend anzeigen wie "alt" die daten sind, also wann wurde die seite zuletzt aktualisiert -- näcshte spiele sollten anzeigen wer da spielt (team a / team b) wenns direkt drunter ist und ansonsten "gewinner achtelfinale 3" -- erste playoff spiele sollten "1. gruppe 15 vs 2. gruppe 16" anzeigen -- admin frontend muss tische auch anzeigen -- WICHTIG UND EZ: gruppenphase in der gleichen gruppe sollten erst finale gegeneinander spielen (dazu nicht aus der nächsten gruppe sondern einmal advancing teams von vorne und einmal von hinten, oder offset von hälfte der weiterkommenden teams) ✅ -- beim eintragen einer runde direkt den nächsten tisch anzeigen -- spiel um platz 3 -- edgecase wenn mehr als die hälfte der teams weiterkommen bedenken bzw zumindest abfangen (hier ist gemeint dass es aktuell spezialcode für po2 turniere gibt bei denen immer die hälfte weiterkommt, es sollte aber auch _irgendwie_ für alle turniere funktionieren, ist nur out of scope für bpwstr) -- Timer groß werden lassen als splashscreen wenn er ausläuft -- Flaschenhalter für die Techniktische -- timer end im admin frontend hübsch machen (aktuell hardcoded startwert) -- turniere-match on focus suche markieren -- vollbildansicht anpassen, dass sie auch abstände oben hat (die navbar oben is ja weg) -- damit klarkommen wenn matches aus der reihe gespielt werden (ein match stoppen, anderes match starten, neue matches starten muss entsprechend auch noch funktionieren) -- tabellen im admin fe anzeigen, leute fragen beim ergebnis abgeben nach -- "Live" in "Läuft noch" umgenennen -- funktion timer unset -- alternativer timer der hochzählt, statt runter für viertelfinale etc. -- auf fullscreen matches ansicht die stage anzeigen (8tel, 4tel, etc.) -- direkten vergleich werten, wenn alles gleich ist sonst -- bei gleichstand für stechen einen punkt vergeben (oder sonstwie, absprechen mit bpwstr) -- bug: refresh war kaputt in viertelfinale, halbfinale, finale -- sieger setzen können; letztes spiel beenden können diff --git a/TODO.csv b/TODO.csv new file mode 100644 index 0000000..740fa5d --- /dev/null +++ b/TODO.csv @@ -0,0 +1,32 @@ +Summary,Description,Issue Type,Priority,Labels +Backend: advancing flag for team,"Original: - backend könnte ""advancing"" an ein team mit dranschreiben; das könnte das frontend anzeigen ✅",Story,Medium,backend +Beamer: query param support,"Original: - alle funktionen der beamer ansichten müssen per query param gehen; beamer dann headless möglich (raspberry ohne maus/tastatur); noch besser: Beamer ansicht einfach /beamer und das backend entscheidet was geht",Story,High,frontend beamer +Frontend: remember team,"Original: - feature im frontend für ""team merken"" damit man automatisch zur eigenen gruppe/aktuellstes game scrollt",Story,Medium,frontend +Beamer: show round timer,"Original: - timer auf dem beamer anzeigen für aktuelle runde ✅",Story,Medium,beamer +Beamer: filter current round,"Original: - filter für ""aktuelle runde"" für den beamer",Story,Medium,beamer +Beamer: fullscreen mode,"Original: - beamer modus (vollbild ohne cursor) ✅",Task,Low,beamer +Beamer: QR codes,"Original: - qr codes drucken für ergebnisausgabe und auf allen beamern anzeigen",Story,Medium,beamer backend +Admin: auto refresh,"Original: - admin frontend automatisch aktualisieren",Story,Medium,frontend admin +Admin: data age indicator,"Original: - admin frontend anzeigen wie ""alt"" die daten sind, also wann wurde die seite zuletzt aktualisiert",Story,Low,frontend admin +Matches: next matches labeling,"Original: - näcshte spiele sollten anzeigen wer da spielt (team a / team b) wenns direkt drunter ist und ansonsten ""gewinner achtelfinale 3""",Story,Medium,frontend +Playoff: initial labeling,"Original: - erste playoff spiele sollten ""1. gruppe 15 vs 2. gruppe 16"" anzeigen",Story,Medium,backend frontend +Admin: show tables,"Original: - admin frontend muss tische auch anzeigen",Story,Medium,frontend admin +Tournament: group pairing logic,"Original: - WICHTIG UND EZ: gruppenphase in der gleichen gruppe sollten erst finale gegeneinander spielen (dazu nicht aus der nächsten gruppe sondern einmal advancing teams von vorne und einmal von hinten, oder offset von hälfte der weiterkommenden teams) ✅",Story,High,backend +Matches: auto table assignment,"Original: - beim eintragen einer runde direkt den nächsten tisch anzeigen",Story,Medium,frontend +Tournament: 3rd place match,"Original: - spiel um platz 3",Story,Low,backend +Tournament: edgecase advancing >50%,"Original: - edgecase wenn mehr als die hälfte der teams weiterkommen bedenken bzw zumindest abfangen (hier ist gemeint dass es aktuell spezialcode für po2 turniere gibt bei denen immer die hälfte weiterkommt, es sollte aber auch _irgendwie_ für alle turniere funktionieren, ist nur out of scope für bpwstr)",Task,Low,backend +Timer: splash on end,"Original: - Timer groß werden lassen als splashscreen wenn er ausläuft",Story,Low,frontend beamer +Infra: bottle holders,"Original: - Flaschenhalter für die Techniktische",Task,Low,infra +Admin: timer UI cleanup,"Original: - timer end im admin frontend hübsch machen (aktuell hardcoded startwert)",Task,Low,frontend admin +Search: focus highlight,"Original: - turniere-match on focus suche markieren",Task,Low,frontend +UI: fullscreen spacing,"Original: - vollbildansicht anpassen, dass sie auch abstände oben hat (die navbar oben is ja weg)",Task,Low,frontend +Matches: out-of-order handling,"Original: - damit klarkommen wenn matches aus der reihe gespielt werden (ein match stoppen, anderes match starten, neue matches starten muss entsprechend auch noch funktionieren)",Story,High,backend frontend +Admin: tables + prompts,"Original: - tabellen im admin fe anzeigen, leute fragen beim ergebnis abgeben nach",Story,Medium,frontend admin +Rename: Live -> Läuft noch,"Original: - ""Live"" in ""Läuft noch"" umgenennen",Task,Low,frontend +Timer: unset function,"Original: - funktion timer unset",Task,Low,backend +Timer: count up mode,"Original: - alternativer timer der hochzählt, statt runter für viertelfinale etc.",Story,Low,frontend +Beamer: show stage,"Original: - auf fullscreen matches ansicht die stage anzeigen (8tel, 4tel, etc.)",Story,Low,frontend beamer +Ranking: tie-breaker logic,"Original: - direkten vergleich werten, wenn alles gleich ist sonst",Story,High,backend +Ranking: tie resolution,"Original: - bei gleichstand für stechen einen punkt vergeben (oder sonstwie, absprechen mit bpwstr)",Story,Medium,backend +Bug: playoff refresh broken,"Original: - bug: refresh war kaputt in viertelfinale, halbfinale, finale",Bug,High,frontend +Matches: set winner + end last match,"Original: - sieger setzen können; letztes spiel beenden können",Story,High,backend \ No newline at end of file From 901e6cb790a44101db1a740f2ecdf6711c89c569 Mon Sep 17 00:00:00 2001 From: Malaber Date: Sun, 12 Apr 2026 10:28:41 +0200 Subject: [PATCH 03/10] Add status --- TODO.csv | 64 ++++++++++++++++++++++++++++---------------------------- 1 file changed, 32 insertions(+), 32 deletions(-) diff --git a/TODO.csv b/TODO.csv index 740fa5d..c7711d8 100644 --- a/TODO.csv +++ b/TODO.csv @@ -1,32 +1,32 @@ -Summary,Description,Issue Type,Priority,Labels -Backend: advancing flag for team,"Original: - backend könnte ""advancing"" an ein team mit dranschreiben; das könnte das frontend anzeigen ✅",Story,Medium,backend -Beamer: query param support,"Original: - alle funktionen der beamer ansichten müssen per query param gehen; beamer dann headless möglich (raspberry ohne maus/tastatur); noch besser: Beamer ansicht einfach /beamer und das backend entscheidet was geht",Story,High,frontend beamer -Frontend: remember team,"Original: - feature im frontend für ""team merken"" damit man automatisch zur eigenen gruppe/aktuellstes game scrollt",Story,Medium,frontend -Beamer: show round timer,"Original: - timer auf dem beamer anzeigen für aktuelle runde ✅",Story,Medium,beamer -Beamer: filter current round,"Original: - filter für ""aktuelle runde"" für den beamer",Story,Medium,beamer -Beamer: fullscreen mode,"Original: - beamer modus (vollbild ohne cursor) ✅",Task,Low,beamer -Beamer: QR codes,"Original: - qr codes drucken für ergebnisausgabe und auf allen beamern anzeigen",Story,Medium,beamer backend -Admin: auto refresh,"Original: - admin frontend automatisch aktualisieren",Story,Medium,frontend admin -Admin: data age indicator,"Original: - admin frontend anzeigen wie ""alt"" die daten sind, also wann wurde die seite zuletzt aktualisiert",Story,Low,frontend admin -Matches: next matches labeling,"Original: - näcshte spiele sollten anzeigen wer da spielt (team a / team b) wenns direkt drunter ist und ansonsten ""gewinner achtelfinale 3""",Story,Medium,frontend -Playoff: initial labeling,"Original: - erste playoff spiele sollten ""1. gruppe 15 vs 2. gruppe 16"" anzeigen",Story,Medium,backend frontend -Admin: show tables,"Original: - admin frontend muss tische auch anzeigen",Story,Medium,frontend admin -Tournament: group pairing logic,"Original: - WICHTIG UND EZ: gruppenphase in der gleichen gruppe sollten erst finale gegeneinander spielen (dazu nicht aus der nächsten gruppe sondern einmal advancing teams von vorne und einmal von hinten, oder offset von hälfte der weiterkommenden teams) ✅",Story,High,backend -Matches: auto table assignment,"Original: - beim eintragen einer runde direkt den nächsten tisch anzeigen",Story,Medium,frontend -Tournament: 3rd place match,"Original: - spiel um platz 3",Story,Low,backend -Tournament: edgecase advancing >50%,"Original: - edgecase wenn mehr als die hälfte der teams weiterkommen bedenken bzw zumindest abfangen (hier ist gemeint dass es aktuell spezialcode für po2 turniere gibt bei denen immer die hälfte weiterkommt, es sollte aber auch _irgendwie_ für alle turniere funktionieren, ist nur out of scope für bpwstr)",Task,Low,backend -Timer: splash on end,"Original: - Timer groß werden lassen als splashscreen wenn er ausläuft",Story,Low,frontend beamer -Infra: bottle holders,"Original: - Flaschenhalter für die Techniktische",Task,Low,infra -Admin: timer UI cleanup,"Original: - timer end im admin frontend hübsch machen (aktuell hardcoded startwert)",Task,Low,frontend admin -Search: focus highlight,"Original: - turniere-match on focus suche markieren",Task,Low,frontend -UI: fullscreen spacing,"Original: - vollbildansicht anpassen, dass sie auch abstände oben hat (die navbar oben is ja weg)",Task,Low,frontend -Matches: out-of-order handling,"Original: - damit klarkommen wenn matches aus der reihe gespielt werden (ein match stoppen, anderes match starten, neue matches starten muss entsprechend auch noch funktionieren)",Story,High,backend frontend -Admin: tables + prompts,"Original: - tabellen im admin fe anzeigen, leute fragen beim ergebnis abgeben nach",Story,Medium,frontend admin -Rename: Live -> Läuft noch,"Original: - ""Live"" in ""Läuft noch"" umgenennen",Task,Low,frontend -Timer: unset function,"Original: - funktion timer unset",Task,Low,backend -Timer: count up mode,"Original: - alternativer timer der hochzählt, statt runter für viertelfinale etc.",Story,Low,frontend -Beamer: show stage,"Original: - auf fullscreen matches ansicht die stage anzeigen (8tel, 4tel, etc.)",Story,Low,frontend beamer -Ranking: tie-breaker logic,"Original: - direkten vergleich werten, wenn alles gleich ist sonst",Story,High,backend -Ranking: tie resolution,"Original: - bei gleichstand für stechen einen punkt vergeben (oder sonstwie, absprechen mit bpwstr)",Story,Medium,backend -Bug: playoff refresh broken,"Original: - bug: refresh war kaputt in viertelfinale, halbfinale, finale",Bug,High,frontend -Matches: set winner + end last match,"Original: - sieger setzen können; letztes spiel beenden können",Story,High,backend \ No newline at end of file +Summary,Description,Issue Type,Priority,Status,Labels +Backend: advancing flag for team,"Original: - backend könnte ""advancing"" an ein team mit dranschreiben; das könnte das frontend anzeigen ✅",Story,Medium,To Do,backend +Beamer: query param support,"Original: - alle funktionen der beamer ansichten müssen per query param gehen; beamer dann headless möglich (raspberry ohne maus/tastatur); noch besser: Beamer ansicht einfach /beamer und das backend entscheidet was geht",Story,High,To Do,frontend beamer +Frontend: remember team,"Original: - feature im frontend für ""team merken"" damit man automatisch zur eigenen gruppe/aktuellstes game scrollt",Story,Medium,To Do,frontend +Beamer: show round timer,"Original: - timer auf dem beamer anzeigen für aktuelle runde ✅",Story,Medium,To Do,beamer +Beamer: filter current round,"Original: - filter für ""aktuelle runde"" für den beamer",Story,Medium,To Do,beamer +Beamer: fullscreen mode,"Original: - beamer modus (vollbild ohne cursor) ✅",Task,Low,To Do,beamer +Beamer: QR codes,"Original: - qr codes drucken für ergebnisausgabe und auf allen beamern anzeigen",Story,Medium,To Do,beamer backend +Admin: auto refresh,"Original: - admin frontend automatisch aktualisieren",Story,Medium,To Do,frontend admin +Admin: data age indicator,"Original: - admin frontend anzeigen wie ""alt"" die daten sind, also wann wurde die seite zuletzt aktualisiert",Story,Low,To Do,frontend admin +Matches: next matches labeling,"Original: - näcshte spiele sollten anzeigen wer da spielt (team a / team b) wenns direkt drunter ist und ansonsten ""gewinner achtelfinale 3""",Story,Medium,To Do,frontend +Playoff: initial labeling,"Original: - erste playoff spiele sollten ""1. gruppe 15 vs 2. gruppe 16"" anzeigen",Story,Medium,To Do,backend frontend +Admin: show tables,"Original: - admin frontend muss tische auch anzeigen",Story,Medium,To Do,frontend admin +Tournament: group pairing logic,"Original: - WICHTIG UND EZ: gruppenphase in der gleichen gruppe sollten erst finale gegeneinander spielen (dazu nicht aus der nächsten gruppe sondern einmal advancing teams von vorne und einmal von hinten, oder offset von hälfte der weiterkommenden teams) ✅",Story,High,To Do,backend +Matches: auto table assignment,"Original: - beim eintragen einer runde direkt den nächsten tisch anzeigen",Story,Medium,To Do,frontend +Tournament: 3rd place match,"Original: - spiel um platz 3",Story,Low,To Do,backend +Tournament: edgecase advancing >50%,"Original: - edgecase wenn mehr als die hälfte der teams weiterkommen bedenken bzw zumindest abfangen (hier ist gemeint dass es aktuell spezialcode für po2 turniere gibt bei denen immer die hälfte weiterkommt, es sollte aber auch _irgendwie_ für alle turniere funktionieren, ist nur out of scope für bpwstr)",Task,Low,To Do,backend +Timer: splash on end,"Original: - Timer groß werden lassen als splashscreen wenn er ausläuft",Story,Low,To Do,frontend beamer +Infra: bottle holders,"Original: - Flaschenhalter für die Techniktische",Task,Low,To Do,infra +Admin: timer UI cleanup,"Original: - timer end im admin frontend hübsch machen (aktuell hardcoded startwert)",Task,Low,To Do,frontend admin +Search: focus highlight,"Original: - turniere-match on focus suche markieren",Task,Low,To Do,frontend +UI: fullscreen spacing,"Original: - vollbildansicht anpassen, dass sie auch abstände oben hat (die navbar oben is ja weg)",Task,Low,To Do,frontend +Matches: out-of-order handling,"Original: - damit klarkommen wenn matches aus der reihe gespielt werden (ein match stoppen, anderes match starten, neue matches starten muss entsprechend auch noch funktionieren)",Story,High,To Do,backend frontend +Admin: tables + prompts,"Original: - tabellen im admin fe anzeigen, leute fragen beim ergebnis abgeben nach",Story,Medium,To Do,frontend admin +Rename: Live -> Läuft noch,"Original: - ""Live"" in ""Läuft noch"" umgenennen",Task,Low,To Do,frontend +Timer: unset function,"Original: - funktion timer unset",Task,Low,To Do,backend +Timer: count up mode,"Original: - alternativer timer der hochzählt, statt runter für viertelfinale etc.",Story,Low,To Do,frontend +Beamer: show stage,"Original: - auf fullscreen matches ansicht die stage anzeigen (8tel, 4tel, etc.)",Story,Low,To Do,frontend beamer +Ranking: tie-breaker logic,"Original: - direkten vergleich werten, wenn alles gleich ist sonst",Story,High,To Do,backend +Ranking: tie resolution,"Original: - bei gleichstand für stechen einen punkt vergeben (oder sonstwie, absprechen mit bpwstr)",Story,Medium,To Do,backend +Bug: playoff refresh broken,"Original: - bug: refresh war kaputt in viertelfinale, halbfinale, finale",Bug,High,To Do,frontend +Matches: set winner + end last match,"Original: - sieger setzen können; letztes spiel beenden können",Story,High,To Do,backend \ No newline at end of file From 43beae0d8a8e5866eb3c4c05728cf817f3cf41c2 Mon Sep 17 00:00:00 2001 From: Malaber Date: Sun, 12 Apr 2026 10:40:57 +0200 Subject: [PATCH 04/10] Better csv --- TODO.csv | 64 ++++++++++++++++++++++++++++---------------------------- 1 file changed, 32 insertions(+), 32 deletions(-) diff --git a/TODO.csv b/TODO.csv index c7711d8..a5ce995 100644 --- a/TODO.csv +++ b/TODO.csv @@ -1,32 +1,32 @@ -Summary,Description,Issue Type,Priority,Status,Labels -Backend: advancing flag for team,"Original: - backend könnte ""advancing"" an ein team mit dranschreiben; das könnte das frontend anzeigen ✅",Story,Medium,To Do,backend -Beamer: query param support,"Original: - alle funktionen der beamer ansichten müssen per query param gehen; beamer dann headless möglich (raspberry ohne maus/tastatur); noch besser: Beamer ansicht einfach /beamer und das backend entscheidet was geht",Story,High,To Do,frontend beamer -Frontend: remember team,"Original: - feature im frontend für ""team merken"" damit man automatisch zur eigenen gruppe/aktuellstes game scrollt",Story,Medium,To Do,frontend -Beamer: show round timer,"Original: - timer auf dem beamer anzeigen für aktuelle runde ✅",Story,Medium,To Do,beamer -Beamer: filter current round,"Original: - filter für ""aktuelle runde"" für den beamer",Story,Medium,To Do,beamer -Beamer: fullscreen mode,"Original: - beamer modus (vollbild ohne cursor) ✅",Task,Low,To Do,beamer -Beamer: QR codes,"Original: - qr codes drucken für ergebnisausgabe und auf allen beamern anzeigen",Story,Medium,To Do,beamer backend -Admin: auto refresh,"Original: - admin frontend automatisch aktualisieren",Story,Medium,To Do,frontend admin -Admin: data age indicator,"Original: - admin frontend anzeigen wie ""alt"" die daten sind, also wann wurde die seite zuletzt aktualisiert",Story,Low,To Do,frontend admin -Matches: next matches labeling,"Original: - näcshte spiele sollten anzeigen wer da spielt (team a / team b) wenns direkt drunter ist und ansonsten ""gewinner achtelfinale 3""",Story,Medium,To Do,frontend -Playoff: initial labeling,"Original: - erste playoff spiele sollten ""1. gruppe 15 vs 2. gruppe 16"" anzeigen",Story,Medium,To Do,backend frontend -Admin: show tables,"Original: - admin frontend muss tische auch anzeigen",Story,Medium,To Do,frontend admin -Tournament: group pairing logic,"Original: - WICHTIG UND EZ: gruppenphase in der gleichen gruppe sollten erst finale gegeneinander spielen (dazu nicht aus der nächsten gruppe sondern einmal advancing teams von vorne und einmal von hinten, oder offset von hälfte der weiterkommenden teams) ✅",Story,High,To Do,backend -Matches: auto table assignment,"Original: - beim eintragen einer runde direkt den nächsten tisch anzeigen",Story,Medium,To Do,frontend -Tournament: 3rd place match,"Original: - spiel um platz 3",Story,Low,To Do,backend -Tournament: edgecase advancing >50%,"Original: - edgecase wenn mehr als die hälfte der teams weiterkommen bedenken bzw zumindest abfangen (hier ist gemeint dass es aktuell spezialcode für po2 turniere gibt bei denen immer die hälfte weiterkommt, es sollte aber auch _irgendwie_ für alle turniere funktionieren, ist nur out of scope für bpwstr)",Task,Low,To Do,backend -Timer: splash on end,"Original: - Timer groß werden lassen als splashscreen wenn er ausläuft",Story,Low,To Do,frontend beamer -Infra: bottle holders,"Original: - Flaschenhalter für die Techniktische",Task,Low,To Do,infra -Admin: timer UI cleanup,"Original: - timer end im admin frontend hübsch machen (aktuell hardcoded startwert)",Task,Low,To Do,frontend admin -Search: focus highlight,"Original: - turniere-match on focus suche markieren",Task,Low,To Do,frontend -UI: fullscreen spacing,"Original: - vollbildansicht anpassen, dass sie auch abstände oben hat (die navbar oben is ja weg)",Task,Low,To Do,frontend -Matches: out-of-order handling,"Original: - damit klarkommen wenn matches aus der reihe gespielt werden (ein match stoppen, anderes match starten, neue matches starten muss entsprechend auch noch funktionieren)",Story,High,To Do,backend frontend -Admin: tables + prompts,"Original: - tabellen im admin fe anzeigen, leute fragen beim ergebnis abgeben nach",Story,Medium,To Do,frontend admin -Rename: Live -> Läuft noch,"Original: - ""Live"" in ""Läuft noch"" umgenennen",Task,Low,To Do,frontend -Timer: unset function,"Original: - funktion timer unset",Task,Low,To Do,backend -Timer: count up mode,"Original: - alternativer timer der hochzählt, statt runter für viertelfinale etc.",Story,Low,To Do,frontend -Beamer: show stage,"Original: - auf fullscreen matches ansicht die stage anzeigen (8tel, 4tel, etc.)",Story,Low,To Do,frontend beamer -Ranking: tie-breaker logic,"Original: - direkten vergleich werten, wenn alles gleich ist sonst",Story,High,To Do,backend -Ranking: tie resolution,"Original: - bei gleichstand für stechen einen punkt vergeben (oder sonstwie, absprechen mit bpwstr)",Story,Medium,To Do,backend -Bug: playoff refresh broken,"Original: - bug: refresh war kaputt in viertelfinale, halbfinale, finale",Bug,High,To Do,frontend -Matches: set winner + end last match,"Original: - sieger setzen können; letztes spiel beenden können",Story,High,To Do,backend \ No newline at end of file +Summary,Description,Work Type,Priority,Status,Component,Component +Backend: advancing flag for team,"Original: - backend könnte ""advancing"" an ein team mit dranschreiben; das könnte das frontend anzeigen ✅",Story,Medium,To Do,backend, +Beamer: query param support,"Original: - alle funktionen der beamer ansichten müssen per query param gehen; beamer dann headless möglich (raspberry ohne maus/tastatur); noch besser: Beamer ansicht einfach /beamer und das backend entscheidet was geht",Story,High,To Do,frontend,beamer +Frontend: remember team,"Original: - feature im frontend für ""team merken"" damit man automatisch zur eigenen gruppe/aktuellstes game scrollt",Story,Medium,To Do,frontend, +Beamer: show round timer,"Original: - timer auf dem beamer anzeigen für aktuelle runde ✅",Story,Medium,To Do,beamer, +Beamer: filter current round,"Original: - filter für ""aktuelle runde"" für den beamer",Story,Medium,To Do,beamer, +Beamer: fullscreen mode,"Original: - beamer modus (vollbild ohne cursor) ✅",Task,Low,To Do,beamer, +Beamer: QR codes,"Original: - qr codes drucken für ergebnisausgabe und auf allen beamern anzeigen",Story,Medium,To Do,beamer,backend +Admin: auto refresh,"Original: - admin frontend automatisch aktualisieren",Story,Medium,To Do,frontend,admin +Admin: data age indicator,"Original: - admin frontend anzeigen wie ""alt"" die daten sind, also wann wurde die seite zuletzt aktualisiert",Story,Low,To Do,frontend,admin +Matches: next matches labeling,"Original: - nächste spiele sollten anzeigen wer da spielt (team a / team b) wenns direkt drunter ist und ansonsten ""gewinner achtelfinale 3""",Story,Medium,To Do,frontend, +Playoff: initial labeling,"Original: - erste playoff spiele sollten ""1. gruppe 15 vs 2. gruppe 16"" anzeigen",Story,Medium,To Do,backend,frontend +Admin: show tables,"Original: - admin frontend muss tische auch anzeigen",Story,Medium,To Do,frontend,admin +Tournament: group pairing logic,"Original: - WICHTIG UND EZ: gruppenphase in der gleichen gruppe sollten erst finale gegeneinander spielen (dazu nicht aus der nächsten gruppe sondern einmal advancing teams von vorne und einmal von hinten, oder offset von hälfte der weiterkommenden teams) ✅",Story,High,To Do,backend, +Matches: auto table assignment,"Original: - beim eintragen einer runde direkt den nächsten tisch anzeigen",Story,Medium,To Do,frontend, +Tournament: 3rd place match,"Original: - spiel um platz 3",Story,Low,To Do,backend, +Tournament: edgecase advancing >50%,"Original: - edgecase wenn mehr als die hälfte der teams weiterkommen bedenken bzw zumindest abfangen (hier ist gemeint dass es aktuell spezialcode für po2 turniere gibt bei denen immer die hälfte weiterkommt, es sollte aber auch _irgendwie_ für alle turniere funktionieren, ist nur out of scope für bpwstr)",Task,Low,To Do,backend, +Timer: splash on end,"Original: - Timer groß werden lassen als splashscreen wenn er ausläuft",Story,Low,To Do,frontend,beamer +Infra: bottle holders,"Original: - Flaschenhalter für die Techniktische",Task,Low,To Do,infra, +Admin: timer UI cleanup,"Original: - timer end im admin frontend hübsch machen (aktuell hardcoded startwert)",Task,Low,To Do,frontend,admin +Search: focus highlight,"Original: - turniere-match on focus suche markieren",Task,Low,To Do,frontend, +UI: fullscreen spacing,"Original: - vollbildansicht anpassen, dass sie auch abstände oben hat (die navbar oben is ja weg)",Task,Low,To Do,frontend, +Matches: out-of-order handling,"Original: - damit klarkommen wenn matches aus der reihe gespielt werden (ein match stoppen, anderes match starten, neue matches starten muss entsprechend auch noch funktionieren)",Story,High,To Do,backend,frontend +Admin: tables + prompts,"Original: - tabellen im admin fe anzeigen, leute fragen beim ergebnis abgeben nach",Story,Medium,To Do,frontend,admin +Rename: Live -> Läuft noch,"Original: - ""Live"" in ""Läuft noch"" umgenennen",Task,Low,To Do,frontend, +Timer: unset function,"Original: - funktion timer unset",Task,Low,To Do,backend, +Timer: count up mode,"Original: - alternativer timer der hochzählt, statt runter für viertelfinale etc.",Story,Low,To Do,frontend, +Beamer: show stage,"Original: - auf fullscreen matches ansicht die stage anzeigen (8tel, 4tel, etc.)",Story,Low,To Do,frontend,beamer +Ranking: tie-breaker logic,"Original: - direkten vergleich werten, wenn alles gleich ist sonst",Story,High,To Do,backend, +Ranking: tie resolution,"Original: - bei gleichstand für stechen einen punkt vergeben (oder sonstwie, absprechen mit bpwstr)",Story,Medium,To Do,backend, +Bug: playoff refresh broken,"Original: - bug: refresh war kaputt in viertelfinale, halbfinale, finale",Bug,High,To Do,frontend, +Matches: set winner + end last match,"Original: - sieger setzen können; letztes spiel beenden können",Story,High,To Do,backend, From fdec1deaeb785b667973d2b5dd98aed2cf1de1eb Mon Sep 17 00:00:00 2001 From: Malaber Date: Sun, 12 Apr 2026 10:43:39 +0200 Subject: [PATCH 05/10] more csv --- TODO.csv | 62 ++++++++++++++++++++++++++++---------------------------- 1 file changed, 31 insertions(+), 31 deletions(-) diff --git a/TODO.csv b/TODO.csv index a5ce995..29dbee1 100644 --- a/TODO.csv +++ b/TODO.csv @@ -1,32 +1,32 @@ Summary,Description,Work Type,Priority,Status,Component,Component -Backend: advancing flag for team,"Original: - backend könnte ""advancing"" an ein team mit dranschreiben; das könnte das frontend anzeigen ✅",Story,Medium,To Do,backend, -Beamer: query param support,"Original: - alle funktionen der beamer ansichten müssen per query param gehen; beamer dann headless möglich (raspberry ohne maus/tastatur); noch besser: Beamer ansicht einfach /beamer und das backend entscheidet was geht",Story,High,To Do,frontend,beamer -Frontend: remember team,"Original: - feature im frontend für ""team merken"" damit man automatisch zur eigenen gruppe/aktuellstes game scrollt",Story,Medium,To Do,frontend, -Beamer: show round timer,"Original: - timer auf dem beamer anzeigen für aktuelle runde ✅",Story,Medium,To Do,beamer, -Beamer: filter current round,"Original: - filter für ""aktuelle runde"" für den beamer",Story,Medium,To Do,beamer, -Beamer: fullscreen mode,"Original: - beamer modus (vollbild ohne cursor) ✅",Task,Low,To Do,beamer, -Beamer: QR codes,"Original: - qr codes drucken für ergebnisausgabe und auf allen beamern anzeigen",Story,Medium,To Do,beamer,backend -Admin: auto refresh,"Original: - admin frontend automatisch aktualisieren",Story,Medium,To Do,frontend,admin -Admin: data age indicator,"Original: - admin frontend anzeigen wie ""alt"" die daten sind, also wann wurde die seite zuletzt aktualisiert",Story,Low,To Do,frontend,admin -Matches: next matches labeling,"Original: - nächste spiele sollten anzeigen wer da spielt (team a / team b) wenns direkt drunter ist und ansonsten ""gewinner achtelfinale 3""",Story,Medium,To Do,frontend, -Playoff: initial labeling,"Original: - erste playoff spiele sollten ""1. gruppe 15 vs 2. gruppe 16"" anzeigen",Story,Medium,To Do,backend,frontend -Admin: show tables,"Original: - admin frontend muss tische auch anzeigen",Story,Medium,To Do,frontend,admin -Tournament: group pairing logic,"Original: - WICHTIG UND EZ: gruppenphase in der gleichen gruppe sollten erst finale gegeneinander spielen (dazu nicht aus der nächsten gruppe sondern einmal advancing teams von vorne und einmal von hinten, oder offset von hälfte der weiterkommenden teams) ✅",Story,High,To Do,backend, -Matches: auto table assignment,"Original: - beim eintragen einer runde direkt den nächsten tisch anzeigen",Story,Medium,To Do,frontend, -Tournament: 3rd place match,"Original: - spiel um platz 3",Story,Low,To Do,backend, -Tournament: edgecase advancing >50%,"Original: - edgecase wenn mehr als die hälfte der teams weiterkommen bedenken bzw zumindest abfangen (hier ist gemeint dass es aktuell spezialcode für po2 turniere gibt bei denen immer die hälfte weiterkommt, es sollte aber auch _irgendwie_ für alle turniere funktionieren, ist nur out of scope für bpwstr)",Task,Low,To Do,backend, -Timer: splash on end,"Original: - Timer groß werden lassen als splashscreen wenn er ausläuft",Story,Low,To Do,frontend,beamer -Infra: bottle holders,"Original: - Flaschenhalter für die Techniktische",Task,Low,To Do,infra, -Admin: timer UI cleanup,"Original: - timer end im admin frontend hübsch machen (aktuell hardcoded startwert)",Task,Low,To Do,frontend,admin -Search: focus highlight,"Original: - turniere-match on focus suche markieren",Task,Low,To Do,frontend, -UI: fullscreen spacing,"Original: - vollbildansicht anpassen, dass sie auch abstände oben hat (die navbar oben is ja weg)",Task,Low,To Do,frontend, -Matches: out-of-order handling,"Original: - damit klarkommen wenn matches aus der reihe gespielt werden (ein match stoppen, anderes match starten, neue matches starten muss entsprechend auch noch funktionieren)",Story,High,To Do,backend,frontend -Admin: tables + prompts,"Original: - tabellen im admin fe anzeigen, leute fragen beim ergebnis abgeben nach",Story,Medium,To Do,frontend,admin -Rename: Live -> Läuft noch,"Original: - ""Live"" in ""Läuft noch"" umgenennen",Task,Low,To Do,frontend, -Timer: unset function,"Original: - funktion timer unset",Task,Low,To Do,backend, -Timer: count up mode,"Original: - alternativer timer der hochzählt, statt runter für viertelfinale etc.",Story,Low,To Do,frontend, -Beamer: show stage,"Original: - auf fullscreen matches ansicht die stage anzeigen (8tel, 4tel, etc.)",Story,Low,To Do,frontend,beamer -Ranking: tie-breaker logic,"Original: - direkten vergleich werten, wenn alles gleich ist sonst",Story,High,To Do,backend, -Ranking: tie resolution,"Original: - bei gleichstand für stechen einen punkt vergeben (oder sonstwie, absprechen mit bpwstr)",Story,Medium,To Do,backend, -Bug: playoff refresh broken,"Original: - bug: refresh war kaputt in viertelfinale, halbfinale, finale",Bug,High,To Do,frontend, -Matches: set winner + end last match,"Original: - sieger setzen können; letztes spiel beenden können",Story,High,To Do,backend, +Backend: advancing flag for team,"Original - backend koennte advancing an ein team mit dranschreiben; das koennte das frontend anzeigen",Story,Medium,To Do,backend, +Beamer: query param support,"Original - alle funktionen der beamer ansichten muessen per query param gehen; beamer dann headless moeglich raspberry ohne maus tastatur; noch besser beamer ansicht einfach /beamer und das backend entscheidet was geht",Story,High,To Do,frontend,beamer +Frontend: remember team,"Original - feature im frontend fuer team merken damit man automatisch zur eigenen gruppe aktuellstes game scrollt",Story,Medium,To Do,frontend, +Beamer: show round timer,"Original - timer auf dem beamer anzeigen fuer aktuelle runde",Story,Medium,To Do,beamer, +Beamer: filter current round,"Original - filter fuer aktuelle runde fuer den beamer",Story,Medium,To Do,beamer, +Beamer: fullscreen mode,"Original - beamer modus vollbild ohne cursor",Task,Low,To Do,beamer, +Beamer: QR codes,"Original - qr codes drucken fuer ergebnisausgabe und auf allen beamern anzeigen",Story,Medium,To Do,beamer,backend +Admin: auto refresh,"Original - admin frontend automatisch aktualisieren",Story,Medium,To Do,frontend,admin +Admin: data age indicator,"Original - admin frontend anzeigen wie alt die daten sind also wann wurde die seite zuletzt aktualisiert",Story,Low,To Do,frontend,admin +Matches: next matches labeling,"Original - naechste spiele sollten anzeigen wer da spielt team a team b wenns direkt drunter ist und ansonsten gewinner achtelfinale 3",Story,Medium,To Do,frontend, +Playoff: initial labeling,"Original - erste playoff spiele sollten 1 gruppe 15 vs 2 gruppe 16 anzeigen",Story,Medium,To Do,backend,frontend +Admin: show tables,"Original - admin frontend muss tische auch anzeigen",Story,Medium,To Do,frontend,admin +Tournament: group pairing logic,"Original - gruppenphase in der gleichen gruppe sollten erst finale gegeneinander spielen dazu nicht aus der naechsten gruppe sondern einmal advancing teams von vorne und einmal von hinten oder offset von haelfte der weiterkommenden teams",Story,High,To Do,backend, +Matches: auto table assignment,"Original - beim eintragen einer runde direkt den naechsten tisch anzeigen",Story,Medium,To Do,frontend, +Tournament: 3rd place match,"Original - spiel um platz 3",Story,Low,To Do,backend, +Tournament: edgecase advancing gt50,"Original - edgecase wenn mehr als die haelfte der teams weiterkommen bedenken bzw zumindest abfangen aktuell spezialcode fuer po2 turniere sollte aber auch fuer alle turniere funktionieren",Task,Low,To Do,backend, +Timer: splash on end,"Original - timer gross werden lassen als splashscreen wenn er auslaeuft",Story,Low,To Do,frontend,beamer +Infra: bottle holders,"Original - flaschenhalter fuer die techniktische",Task,Low,To Do,infra, +Admin: timer UI cleanup,"Original - timer end im admin frontend huebsch machen aktuell hardcoded startwert",Task,Low,To Do,frontend,admin +Search: focus highlight,"Original - turniere match on focus suche markieren",Task,Low,To Do,frontend, +UI: fullscreen spacing,"Original - vollbildansicht anpassen dass sie auch abstaende oben hat navbar oben ist ja weg",Task,Low,To Do,frontend, +Matches: out of order handling,"Original - damit klarkommen wenn matches aus der reihe gespielt werden ein match stoppen anderes match starten neue matches starten muss entsprechend auch funktionieren",Story,High,To Do,backend,frontend +Admin: tables and prompts,"Original - tabellen im admin fe anzeigen leute fragen beim ergebnis abgeben nach",Story,Medium,To Do,frontend,admin +Rename: Live to Laeuft noch,"Original - Live in Laeuft noch umbenennen",Task,Low,To Do,frontend, +Timer: unset function,"Original - funktion timer unset",Task,Low,To Do,backend, +Timer: count up mode,"Original - alternativer timer der hochzaehlt statt runter fuer viertelfinale etc",Story,Low,To Do,frontend, +Beamer: show stage,"Original - auf fullscreen matches ansicht die stage anzeigen 8tel 4tel etc",Story,Low,To Do,frontend,beamer +Ranking: tie breaker logic,"Original - direkten vergleich werten wenn alles gleich ist sonst",Story,High,To Do,backend, +Ranking: tie resolution,"Original - bei gleichstand fuer stechen einen punkt vergeben oder sonstwie",Story,Medium,To Do,backend, +Bug: playoff refresh broken,"Original - bug refresh war kaputt in viertelfinale halbfinale finale",Bug,High,To Do,frontend, +Matches: set winner and end last match,"Original - sieger setzen koennen letztes spiel beenden koennen",Story,High,To Do,backend, From 789f7e7bcdb8848078786974d6e2c97ce5463a1f Mon Sep 17 00:00:00 2001 From: Malaber Date: Sun, 12 Apr 2026 10:49:04 +0200 Subject: [PATCH 06/10] Revert "more csv" This reverts commit fdec1deaeb785b667973d2b5dd98aed2cf1de1eb. --- TODO.csv | 62 ++++++++++++++++++++++++++++---------------------------- 1 file changed, 31 insertions(+), 31 deletions(-) diff --git a/TODO.csv b/TODO.csv index 29dbee1..a5ce995 100644 --- a/TODO.csv +++ b/TODO.csv @@ -1,32 +1,32 @@ Summary,Description,Work Type,Priority,Status,Component,Component -Backend: advancing flag for team,"Original - backend koennte advancing an ein team mit dranschreiben; das koennte das frontend anzeigen",Story,Medium,To Do,backend, -Beamer: query param support,"Original - alle funktionen der beamer ansichten muessen per query param gehen; beamer dann headless moeglich raspberry ohne maus tastatur; noch besser beamer ansicht einfach /beamer und das backend entscheidet was geht",Story,High,To Do,frontend,beamer -Frontend: remember team,"Original - feature im frontend fuer team merken damit man automatisch zur eigenen gruppe aktuellstes game scrollt",Story,Medium,To Do,frontend, -Beamer: show round timer,"Original - timer auf dem beamer anzeigen fuer aktuelle runde",Story,Medium,To Do,beamer, -Beamer: filter current round,"Original - filter fuer aktuelle runde fuer den beamer",Story,Medium,To Do,beamer, -Beamer: fullscreen mode,"Original - beamer modus vollbild ohne cursor",Task,Low,To Do,beamer, -Beamer: QR codes,"Original - qr codes drucken fuer ergebnisausgabe und auf allen beamern anzeigen",Story,Medium,To Do,beamer,backend -Admin: auto refresh,"Original - admin frontend automatisch aktualisieren",Story,Medium,To Do,frontend,admin -Admin: data age indicator,"Original - admin frontend anzeigen wie alt die daten sind also wann wurde die seite zuletzt aktualisiert",Story,Low,To Do,frontend,admin -Matches: next matches labeling,"Original - naechste spiele sollten anzeigen wer da spielt team a team b wenns direkt drunter ist und ansonsten gewinner achtelfinale 3",Story,Medium,To Do,frontend, -Playoff: initial labeling,"Original - erste playoff spiele sollten 1 gruppe 15 vs 2 gruppe 16 anzeigen",Story,Medium,To Do,backend,frontend -Admin: show tables,"Original - admin frontend muss tische auch anzeigen",Story,Medium,To Do,frontend,admin -Tournament: group pairing logic,"Original - gruppenphase in der gleichen gruppe sollten erst finale gegeneinander spielen dazu nicht aus der naechsten gruppe sondern einmal advancing teams von vorne und einmal von hinten oder offset von haelfte der weiterkommenden teams",Story,High,To Do,backend, -Matches: auto table assignment,"Original - beim eintragen einer runde direkt den naechsten tisch anzeigen",Story,Medium,To Do,frontend, -Tournament: 3rd place match,"Original - spiel um platz 3",Story,Low,To Do,backend, -Tournament: edgecase advancing gt50,"Original - edgecase wenn mehr als die haelfte der teams weiterkommen bedenken bzw zumindest abfangen aktuell spezialcode fuer po2 turniere sollte aber auch fuer alle turniere funktionieren",Task,Low,To Do,backend, -Timer: splash on end,"Original - timer gross werden lassen als splashscreen wenn er auslaeuft",Story,Low,To Do,frontend,beamer -Infra: bottle holders,"Original - flaschenhalter fuer die techniktische",Task,Low,To Do,infra, -Admin: timer UI cleanup,"Original - timer end im admin frontend huebsch machen aktuell hardcoded startwert",Task,Low,To Do,frontend,admin -Search: focus highlight,"Original - turniere match on focus suche markieren",Task,Low,To Do,frontend, -UI: fullscreen spacing,"Original - vollbildansicht anpassen dass sie auch abstaende oben hat navbar oben ist ja weg",Task,Low,To Do,frontend, -Matches: out of order handling,"Original - damit klarkommen wenn matches aus der reihe gespielt werden ein match stoppen anderes match starten neue matches starten muss entsprechend auch funktionieren",Story,High,To Do,backend,frontend -Admin: tables and prompts,"Original - tabellen im admin fe anzeigen leute fragen beim ergebnis abgeben nach",Story,Medium,To Do,frontend,admin -Rename: Live to Laeuft noch,"Original - Live in Laeuft noch umbenennen",Task,Low,To Do,frontend, -Timer: unset function,"Original - funktion timer unset",Task,Low,To Do,backend, -Timer: count up mode,"Original - alternativer timer der hochzaehlt statt runter fuer viertelfinale etc",Story,Low,To Do,frontend, -Beamer: show stage,"Original - auf fullscreen matches ansicht die stage anzeigen 8tel 4tel etc",Story,Low,To Do,frontend,beamer -Ranking: tie breaker logic,"Original - direkten vergleich werten wenn alles gleich ist sonst",Story,High,To Do,backend, -Ranking: tie resolution,"Original - bei gleichstand fuer stechen einen punkt vergeben oder sonstwie",Story,Medium,To Do,backend, -Bug: playoff refresh broken,"Original - bug refresh war kaputt in viertelfinale halbfinale finale",Bug,High,To Do,frontend, -Matches: set winner and end last match,"Original - sieger setzen koennen letztes spiel beenden koennen",Story,High,To Do,backend, +Backend: advancing flag for team,"Original: - backend könnte ""advancing"" an ein team mit dranschreiben; das könnte das frontend anzeigen ✅",Story,Medium,To Do,backend, +Beamer: query param support,"Original: - alle funktionen der beamer ansichten müssen per query param gehen; beamer dann headless möglich (raspberry ohne maus/tastatur); noch besser: Beamer ansicht einfach /beamer und das backend entscheidet was geht",Story,High,To Do,frontend,beamer +Frontend: remember team,"Original: - feature im frontend für ""team merken"" damit man automatisch zur eigenen gruppe/aktuellstes game scrollt",Story,Medium,To Do,frontend, +Beamer: show round timer,"Original: - timer auf dem beamer anzeigen für aktuelle runde ✅",Story,Medium,To Do,beamer, +Beamer: filter current round,"Original: - filter für ""aktuelle runde"" für den beamer",Story,Medium,To Do,beamer, +Beamer: fullscreen mode,"Original: - beamer modus (vollbild ohne cursor) ✅",Task,Low,To Do,beamer, +Beamer: QR codes,"Original: - qr codes drucken für ergebnisausgabe und auf allen beamern anzeigen",Story,Medium,To Do,beamer,backend +Admin: auto refresh,"Original: - admin frontend automatisch aktualisieren",Story,Medium,To Do,frontend,admin +Admin: data age indicator,"Original: - admin frontend anzeigen wie ""alt"" die daten sind, also wann wurde die seite zuletzt aktualisiert",Story,Low,To Do,frontend,admin +Matches: next matches labeling,"Original: - nächste spiele sollten anzeigen wer da spielt (team a / team b) wenns direkt drunter ist und ansonsten ""gewinner achtelfinale 3""",Story,Medium,To Do,frontend, +Playoff: initial labeling,"Original: - erste playoff spiele sollten ""1. gruppe 15 vs 2. gruppe 16"" anzeigen",Story,Medium,To Do,backend,frontend +Admin: show tables,"Original: - admin frontend muss tische auch anzeigen",Story,Medium,To Do,frontend,admin +Tournament: group pairing logic,"Original: - WICHTIG UND EZ: gruppenphase in der gleichen gruppe sollten erst finale gegeneinander spielen (dazu nicht aus der nächsten gruppe sondern einmal advancing teams von vorne und einmal von hinten, oder offset von hälfte der weiterkommenden teams) ✅",Story,High,To Do,backend, +Matches: auto table assignment,"Original: - beim eintragen einer runde direkt den nächsten tisch anzeigen",Story,Medium,To Do,frontend, +Tournament: 3rd place match,"Original: - spiel um platz 3",Story,Low,To Do,backend, +Tournament: edgecase advancing >50%,"Original: - edgecase wenn mehr als die hälfte der teams weiterkommen bedenken bzw zumindest abfangen (hier ist gemeint dass es aktuell spezialcode für po2 turniere gibt bei denen immer die hälfte weiterkommt, es sollte aber auch _irgendwie_ für alle turniere funktionieren, ist nur out of scope für bpwstr)",Task,Low,To Do,backend, +Timer: splash on end,"Original: - Timer groß werden lassen als splashscreen wenn er ausläuft",Story,Low,To Do,frontend,beamer +Infra: bottle holders,"Original: - Flaschenhalter für die Techniktische",Task,Low,To Do,infra, +Admin: timer UI cleanup,"Original: - timer end im admin frontend hübsch machen (aktuell hardcoded startwert)",Task,Low,To Do,frontend,admin +Search: focus highlight,"Original: - turniere-match on focus suche markieren",Task,Low,To Do,frontend, +UI: fullscreen spacing,"Original: - vollbildansicht anpassen, dass sie auch abstände oben hat (die navbar oben is ja weg)",Task,Low,To Do,frontend, +Matches: out-of-order handling,"Original: - damit klarkommen wenn matches aus der reihe gespielt werden (ein match stoppen, anderes match starten, neue matches starten muss entsprechend auch noch funktionieren)",Story,High,To Do,backend,frontend +Admin: tables + prompts,"Original: - tabellen im admin fe anzeigen, leute fragen beim ergebnis abgeben nach",Story,Medium,To Do,frontend,admin +Rename: Live -> Läuft noch,"Original: - ""Live"" in ""Läuft noch"" umgenennen",Task,Low,To Do,frontend, +Timer: unset function,"Original: - funktion timer unset",Task,Low,To Do,backend, +Timer: count up mode,"Original: - alternativer timer der hochzählt, statt runter für viertelfinale etc.",Story,Low,To Do,frontend, +Beamer: show stage,"Original: - auf fullscreen matches ansicht die stage anzeigen (8tel, 4tel, etc.)",Story,Low,To Do,frontend,beamer +Ranking: tie-breaker logic,"Original: - direkten vergleich werten, wenn alles gleich ist sonst",Story,High,To Do,backend, +Ranking: tie resolution,"Original: - bei gleichstand für stechen einen punkt vergeben (oder sonstwie, absprechen mit bpwstr)",Story,Medium,To Do,backend, +Bug: playoff refresh broken,"Original: - bug: refresh war kaputt in viertelfinale, halbfinale, finale",Bug,High,To Do,frontend, +Matches: set winner + end last match,"Original: - sieger setzen können; letztes spiel beenden können",Story,High,To Do,backend, From cc9c6052d620ad721ad898ef3646083868b93c57 Mon Sep 17 00:00:00 2001 From: Malaber Date: Sun, 12 Apr 2026 10:59:16 +0200 Subject: [PATCH 07/10] Jira import --- TODO.csv | 62 ++++---- jira_import.py | 424 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 455 insertions(+), 31 deletions(-) create mode 100644 jira_import.py diff --git a/TODO.csv b/TODO.csv index a5ce995..dd24297 100644 --- a/TODO.csv +++ b/TODO.csv @@ -1,32 +1,32 @@ Summary,Description,Work Type,Priority,Status,Component,Component -Backend: advancing flag for team,"Original: - backend könnte ""advancing"" an ein team mit dranschreiben; das könnte das frontend anzeigen ✅",Story,Medium,To Do,backend, -Beamer: query param support,"Original: - alle funktionen der beamer ansichten müssen per query param gehen; beamer dann headless möglich (raspberry ohne maus/tastatur); noch besser: Beamer ansicht einfach /beamer und das backend entscheidet was geht",Story,High,To Do,frontend,beamer -Frontend: remember team,"Original: - feature im frontend für ""team merken"" damit man automatisch zur eigenen gruppe/aktuellstes game scrollt",Story,Medium,To Do,frontend, -Beamer: show round timer,"Original: - timer auf dem beamer anzeigen für aktuelle runde ✅",Story,Medium,To Do,beamer, -Beamer: filter current round,"Original: - filter für ""aktuelle runde"" für den beamer",Story,Medium,To Do,beamer, -Beamer: fullscreen mode,"Original: - beamer modus (vollbild ohne cursor) ✅",Task,Low,To Do,beamer, -Beamer: QR codes,"Original: - qr codes drucken für ergebnisausgabe und auf allen beamern anzeigen",Story,Medium,To Do,beamer,backend -Admin: auto refresh,"Original: - admin frontend automatisch aktualisieren",Story,Medium,To Do,frontend,admin -Admin: data age indicator,"Original: - admin frontend anzeigen wie ""alt"" die daten sind, also wann wurde die seite zuletzt aktualisiert",Story,Low,To Do,frontend,admin -Matches: next matches labeling,"Original: - nächste spiele sollten anzeigen wer da spielt (team a / team b) wenns direkt drunter ist und ansonsten ""gewinner achtelfinale 3""",Story,Medium,To Do,frontend, -Playoff: initial labeling,"Original: - erste playoff spiele sollten ""1. gruppe 15 vs 2. gruppe 16"" anzeigen",Story,Medium,To Do,backend,frontend -Admin: show tables,"Original: - admin frontend muss tische auch anzeigen",Story,Medium,To Do,frontend,admin -Tournament: group pairing logic,"Original: - WICHTIG UND EZ: gruppenphase in der gleichen gruppe sollten erst finale gegeneinander spielen (dazu nicht aus der nächsten gruppe sondern einmal advancing teams von vorne und einmal von hinten, oder offset von hälfte der weiterkommenden teams) ✅",Story,High,To Do,backend, -Matches: auto table assignment,"Original: - beim eintragen einer runde direkt den nächsten tisch anzeigen",Story,Medium,To Do,frontend, -Tournament: 3rd place match,"Original: - spiel um platz 3",Story,Low,To Do,backend, -Tournament: edgecase advancing >50%,"Original: - edgecase wenn mehr als die hälfte der teams weiterkommen bedenken bzw zumindest abfangen (hier ist gemeint dass es aktuell spezialcode für po2 turniere gibt bei denen immer die hälfte weiterkommt, es sollte aber auch _irgendwie_ für alle turniere funktionieren, ist nur out of scope für bpwstr)",Task,Low,To Do,backend, -Timer: splash on end,"Original: - Timer groß werden lassen als splashscreen wenn er ausläuft",Story,Low,To Do,frontend,beamer -Infra: bottle holders,"Original: - Flaschenhalter für die Techniktische",Task,Low,To Do,infra, -Admin: timer UI cleanup,"Original: - timer end im admin frontend hübsch machen (aktuell hardcoded startwert)",Task,Low,To Do,frontend,admin -Search: focus highlight,"Original: - turniere-match on focus suche markieren",Task,Low,To Do,frontend, -UI: fullscreen spacing,"Original: - vollbildansicht anpassen, dass sie auch abstände oben hat (die navbar oben is ja weg)",Task,Low,To Do,frontend, -Matches: out-of-order handling,"Original: - damit klarkommen wenn matches aus der reihe gespielt werden (ein match stoppen, anderes match starten, neue matches starten muss entsprechend auch noch funktionieren)",Story,High,To Do,backend,frontend -Admin: tables + prompts,"Original: - tabellen im admin fe anzeigen, leute fragen beim ergebnis abgeben nach",Story,Medium,To Do,frontend,admin -Rename: Live -> Läuft noch,"Original: - ""Live"" in ""Läuft noch"" umgenennen",Task,Low,To Do,frontend, -Timer: unset function,"Original: - funktion timer unset",Task,Low,To Do,backend, -Timer: count up mode,"Original: - alternativer timer der hochzählt, statt runter für viertelfinale etc.",Story,Low,To Do,frontend, -Beamer: show stage,"Original: - auf fullscreen matches ansicht die stage anzeigen (8tel, 4tel, etc.)",Story,Low,To Do,frontend,beamer -Ranking: tie-breaker logic,"Original: - direkten vergleich werten, wenn alles gleich ist sonst",Story,High,To Do,backend, -Ranking: tie resolution,"Original: - bei gleichstand für stechen einen punkt vergeben (oder sonstwie, absprechen mit bpwstr)",Story,Medium,To Do,backend, -Bug: playoff refresh broken,"Original: - bug: refresh war kaputt in viertelfinale, halbfinale, finale",Bug,High,To Do,frontend, -Matches: set winner + end last match,"Original: - sieger setzen können; letztes spiel beenden können",Story,High,To Do,backend, +Backend: advancing flag for team,"backend könnte ""advancing"" an ein team mit dranschreiben; das könnte das frontend anzeigen ✅",Story,Medium,To Do,Backend, +Beamer: query param support,"alle funktionen der beamer ansichten müssen per query param gehen; beamer dann headless möglich (raspberry ohne maus/tastatur); noch besser: Beamer ansicht einfach /beamer und das backend entscheidet was geht",Story,High,To Do,Frontend,Beamer +Frontend: remember team,"feature im frontend für ""team merken"" damit man automatisch zur eigenen gruppe/aktuellstes game scrollt",Story,Medium,To Do,Frontend, +Beamer: show round timer,"timer auf dem beamer anzeigen für aktuelle runde ✅",Story,Medium,To Do,Beamer, +Beamer: filter current round,"filter für ""aktuelle runde"" für den beamer",Story,Medium,To Do,Beamer, +Beamer: fullscreen mode,"beamer modus (vollbild ohne cursor) ✅",Task,Low,To Do,Beamer, +Beamer: QR codes,"qr codes drucken für ergebnisausgabe und auf allen beamern anzeigen",Story,Medium,To Do,Beamer,Backend +Admin: auto refresh,"admin frontend automatisch aktualisieren",Story,Medium,To Do,Frontend,Admin +Admin: data age indicator,"admin frontend anzeigen wie ""alt"" die daten sind, also wann wurde die seite zuletzt aktualisiert",Story,Low,To Do,Frontend,Admin +Matches: next matches labeling,"nächste spiele sollten anzeigen wer da spielt (team a / team b) wenns direkt drunter ist und ansonsten ""gewinner achtelfinale 3""",Story,Medium,To Do,Frontend, +Playoff: initial labeling,"erste playoff spiele sollten ""1. gruppe 15 vs 2. gruppe 16"" anzeigen",Story,Medium,To Do,Backend,Frontend +Admin: show tables,"admin frontend muss tische auch anzeigen",Story,Medium,To Do,Frontend,Admin +Tournament: group pairing logic,"WICHTIG UND EZ: gruppenphase in der gleichen gruppe sollten erst finale gegeneinander spielen (dazu nicht aus der nächsten gruppe sondern einmal advancing teams von vorne und einmal von hinten, oder offset von hälfte der weiterkommenden teams) ✅",Story,High,To Do,Backend, +Matches: auto table assignment,"beim eintragen einer runde direkt den nächsten tisch anzeigen",Story,Medium,To Do,Frontend, +Tournament: 3rd place match,"spiel um platz 3",Story,Low,To Do,Backend, +Tournament: edgecase advancing >50%,"edgecase wenn mehr als die hälfte der teams weiterkommen bedenken bzw zumindest abfangen (hier ist gemeint dass es aktuell spezialcode für po2 turniere gibt bei denen immer die hälfte weiterkommt, es sollte aber auch _irgendwie_ für alle turniere funktionieren, ist nur out of scope für bpwstr)",Task,Low,To Do,Backend, +Timer: splash on end,"Timer groß werden lassen als splashscreen wenn er ausläuft",Story,Low,To Do,Frontend,Beamer +Infra: bottle holders,"Flaschenhalter für die Techniktische",Task,Low,To Do,infra, +Admin: timer UI cleanup,"timer end im admin frontend hübsch machen (aktuell hardcoded startwert)",Task,Low,To Do,Frontend,Admin +Search: focus highlight,"turniere-match on focus suche markieren",Task,Low,To Do,Frontend, +UI: fullscreen spacing,"vollbildansicht anpassen, dass sie auch abstände oben hat (die navbar oben is ja weg)",Task,Low,To Do,Frontend, +Matches: out-of-order handling,"damit klarkommen wenn matches aus der reihe gespielt werden (ein match stoppen, anderes match starten, neue matches starten muss entsprechend auch noch funktionieren)",Story,High,To Do,Backend,Frontend +Admin: tables + prompts,"tabellen im admin fe anzeigen, leute fragen beim ergebnis abgeben nach",Story,Medium,To Do,Frontend,Admin +Rename: Live -> Läuft noch,"""Live"" in ""Läuft noch"" umgenennen",Task,Low,To Do,Frontend, +Timer: unset function,"funktion timer unset",Task,Low,To Do,Backend, +Timer: count up mode,"alternativer timer der hochzählt, statt runter für viertelfinale etc.",Story,Low,To Do,Frontend, +Beamer: show stage,"auf fullscreen matches ansicht die stage anzeigen (8tel, 4tel, etc.)",Story,Low,To Do,Frontend,Beamer +Ranking: tie-breaker logic,"direkten vergleich werten, wenn alles gleich ist sonst",Story,High,To Do,Backend, +Ranking: tie resolution,"bei gleichstand für stechen einen punkt vergeben (oder sonstwie, absprechen mit bpwstr)",Story,Medium,To Do,Backend, +Bug: playoff refresh broken,"bug: refresh war kaputt in viertelfinale, halbfinale, finale",Bug,High,To Do,Frontend, +Matches: set winner + end last match,"sieger setzen können; letztes spiel beenden können",Story,High,To Do,Backend, diff --git a/jira_import.py b/jira_import.py new file mode 100644 index 0000000..ccb8faa --- /dev/null +++ b/jira_import.py @@ -0,0 +1,424 @@ +#!/usr/bin/env python3 +""" +Bulk-create Jira Cloud issues from a CSV file. + +CSV expected columns: +Summary,Description,Work Type,Priority,Status,Component,Component + +Example: +python jira_bulk_import.py \ + --site https://your-domain.atlassian.net \ + --email you@example.com \ + --api-token YOUR_TOKEN \ + --project TURN \ + --csv issues.csv \ + --create-missing-components +""" + +from __future__ import annotations + +import argparse +import csv +import json +import sys +import time +from dataclasses import dataclass +from typing import Any + +import requests + + +@dataclass +class CsvIssue: + summary: str + description: str + work_type: str + priority: str + status: str + components: list[str] + + +class JiraClient: + def __init__(self, site: str, email: str, api_token: str, timeout: int = 30) -> None: + self.site = site.rstrip("/") + self.timeout = timeout + self.session = requests.Session() + self.session.auth = (email, api_token) + self.session.headers.update( + { + "Accept": "application/json", + "Content-Type": "application/json", + } + ) + + def _url(self, path: str) -> str: + return f"{self.site}{path}" + + def get(self, path: str, **kwargs: Any) -> requests.Response: + resp = self.session.get(self._url(path), timeout=self.timeout, **kwargs) + self._raise_for_status(resp) + return resp + + def post(self, path: str, payload: dict[str, Any]) -> requests.Response: + resp = self.session.post( + self._url(path), + timeout=self.timeout, + data=json.dumps(payload), + ) + self._raise_for_status(resp) + return resp + + def _raise_for_status(self, resp: requests.Response) -> None: + if resp.ok: + return + + body = resp.text + try: + parsed = resp.json() + body = json.dumps(parsed, indent=2, ensure_ascii=False) + except Exception: + pass + + raise RuntimeError( + f"Jira API error {resp.status_code} for {resp.request.method} {resp.url}\n{body}" + ) + + def get_project_components(self, project_key: str) -> dict[str, dict[str, Any]]: + # GET /rest/api/3/project/{projectKeyOrId}/components + resp = self.get(f"/rest/api/3/project/{project_key}/components") + items = resp.json() + return {item["name"].strip().lower(): item for item in items} + + def create_component(self, project_key: str, component_name: str) -> dict[str, Any]: + payload = { + "name": component_name, + "project": project_key, + } + resp = self.post("/rest/api/3/component", payload) + return resp.json() + + def get_issue_types_for_project(self, project_key: str) -> dict[str, dict[str, Any]]: + # GET /rest/api/3/issue/createmeta/{projectIdOrKey}/issuetypes + resp = self.get(f"/rest/api/3/issue/createmeta/{project_key}/issuetypes") + data = resp.json() + + values = data.get("issueTypes") or data.get("values") or [] + result: dict[str, dict[str, Any]] = {} + for item in values: + name = item["name"].strip().lower() + result[name] = item + return result + + def get_create_fields_metadata(self, project_key: str, issue_type_id: str) -> dict[str, Any]: + # GET /rest/api/3/issue/createmeta/{projectIdOrKey}/issuetypes/{issueTypeId} + resp = self.get(f"/rest/api/3/issue/createmeta/{project_key}/issuetypes/{issue_type_id}") + data = resp.json() + return data.get("fields", {}) + + def bulk_create_issues(self, issue_updates: list[dict[str, Any]]) -> dict[str, Any]: + payload = {"issueUpdates": issue_updates} + resp = self.post("/rest/api/3/issue/bulk", payload) + return resp.json() + + +def parse_args() -> argparse.Namespace: + parser = argparse.ArgumentParser(description="Bulk import Jira issues from CSV") + parser.add_argument("--site", required=True, help="https://your-domain.atlassian.net") + parser.add_argument("--email", required=True, help="Jira account email") + parser.add_argument("--api-token", required=True, help="Jira API token") + parser.add_argument("--project", required=True, help="Jira project key, e.g. TURN") + parser.add_argument("--csv", required=True, help="Path to CSV file") + parser.add_argument( + "--create-missing-components", + action="store_true", + help="Create missing project components automatically", + ) + parser.add_argument( + "--dry-run", + action="store_true", + help="Print the payloads without sending them to Jira", + ) + return parser.parse_args() + + +def read_csv_issues(csv_path: str) -> list[CsvIssue]: + issues: list[CsvIssue] = [] + + with open(csv_path, "r", encoding="utf-8-sig", newline="") as f: + reader = csv.reader(f) + rows = list(reader) + + if not rows: + raise RuntimeError("CSV is empty") + + header = rows[0] + expected_prefix = ["Summary", "Description", "Work Type", "Priority", "Status", "Component"] + if len(header) < 6 or header[:6] != expected_prefix: + raise RuntimeError( + "Unexpected CSV header. Expected at least:\n" + "Summary,Description,Work Type,Priority,Status,Component,Component" + ) + + for idx, row in enumerate(rows[1:], start=2): + if not row or not any(cell.strip() for cell in row): + continue + + # Pad short rows + padded = row + [""] * max(0, 7 - len(row)) + + summary = padded[0].strip() + description = padded[1].strip() + work_type = padded[2].strip() + priority = padded[3].strip() + status = padded[4].strip() + component_1 = padded[5].strip() + component_2 = padded[6].strip() if len(padded) > 6 else "" + + if not summary: + print(f"Skipping row {idx}: empty Summary", file=sys.stderr) + continue + + components = [] + for comp in (component_1, component_2): + if comp and comp not in components: + components.append(comp) + + issues.append( + CsvIssue( + summary=summary, + description=description, + work_type=work_type, + priority=priority, + status=status, + components=components, + ) + ) + + return issues + + +def adf_paragraph(text: str) -> dict[str, Any]: + paragraphs = [] + for line in text.splitlines(): + if line.strip(): + paragraphs.append( + { + "type": "paragraph", + "content": [{"type": "text", "text": line}], + } + ) + else: + paragraphs.append({"type": "paragraph", "content": []}) + + if not paragraphs: + paragraphs = [{"type": "paragraph", "content": []}] + + return { + "type": "doc", + "version": 1, + "content": paragraphs, + } + + +def chunked[T](items: list[T], size: int) -> list[list[T]]: + return [items[i:i + size] for i in range(0, len(items), size)] + + +def normalize(s: str) -> str: + return s.strip().lower() + + +def ensure_components( + jira: JiraClient, + project_key: str, + issues: list[CsvIssue], + create_missing: bool, +) -> dict[str, dict[str, Any]]: + existing = jira.get_project_components(project_key) + + needed_names: list[str] = [] + for issue in issues: + for comp in issue.components: + key = normalize(comp) + if key and key not in existing and comp not in needed_names: + needed_names.append(comp) + + if needed_names and not create_missing: + missing = ", ".join(needed_names) + raise RuntimeError( + "These components do not exist in Jira:\n" + f"{missing}\n\n" + "Re-run with --create-missing-components to create them automatically." + ) + + for name in needed_names: + created = jira.create_component(project_key, name) + existing[normalize(created["name"])] = created + print(f"Created component: {created['name']}") + + return existing + + +def build_issue_payload( + issue: CsvIssue, + project_key: str, + issue_types_by_name: dict[str, dict[str, Any]], + create_fields_by_issue_type_id: dict[str, dict[str, Any]], + components_by_name: dict[str, dict[str, Any]], +) -> dict[str, Any]: + work_type_key = normalize(issue.work_type) + if work_type_key not in issue_types_by_name: + known = ", ".join(sorted(it["name"] for it in issue_types_by_name.values())) + raise RuntimeError( + f"Unknown Work Type '{issue.work_type}' for summary '{issue.summary}'. " + f"Known Jira issue types in project {project_key}: {known}" + ) + + issue_type = issue_types_by_name[work_type_key] + issue_type_id = issue_type["id"] + fields_meta = create_fields_by_issue_type_id[issue_type_id] + + fields: dict[str, Any] = { + "project": {"key": project_key}, + "summary": issue.summary, + "issuetype": {"id": issue_type_id}, + } + + if "description" in fields_meta: + fields["description"] = adf_paragraph(issue.description) + + if issue.priority and "priority" in fields_meta: + fields["priority"] = {"name": issue.priority} + + if issue.components and "components" in fields_meta: + comps = [] + for comp_name in issue.components: + key = normalize(comp_name) + component = components_by_name.get(key) + if not component: + raise RuntimeError( + f"Component '{comp_name}' not found for issue '{issue.summary}'" + ) + comps.append({"id": component["id"]}) + fields["components"] = comps + + # Intentionally not sending "status". + # Jira creation should start in the workflow default state unless you add + # transition logic after creation. + + return {"fields": fields} + + +def main() -> int: + args = parse_args() + + issues = read_csv_issues(args.csv) + if not issues: + print("No issues found in CSV.") + return 0 + + jira = JiraClient( + site=args.site, + email=args.email, + api_token=args.api_token, + ) + + print(f"Loaded {len(issues)} issues from CSV") + + issue_types_by_name = jira.get_issue_types_for_project(args.project) + if not issue_types_by_name: + raise RuntimeError( + f"No creatable issue types returned for project {args.project}. " + "Check permissions and project key." + ) + + needed_issue_type_ids = { + issue_types_by_name[normalize(issue.work_type)]["id"] + for issue in issues + if normalize(issue.work_type) in issue_types_by_name + } + + create_fields_by_issue_type_id: dict[str, dict[str, Any]] = {} + for issue_type_id in needed_issue_type_ids: + create_fields_by_issue_type_id[issue_type_id] = jira.get_create_fields_metadata( + args.project, + issue_type_id, + ) + + components_by_name = ensure_components( + jira=jira, + project_key=args.project, + issues=issues, + create_missing=args.create_missing_components, + ) + + payloads: list[dict[str, Any]] = [] + for issue in issues: + payloads.append( + build_issue_payload( + issue=issue, + project_key=args.project, + issue_types_by_name=issue_types_by_name, + create_fields_by_issue_type_id=create_fields_by_issue_type_id, + components_by_name=components_by_name, + ) + ) + + if args.dry_run: + print(json.dumps({"issueUpdates": payloads[:2]}, indent=2, ensure_ascii=False)) + print(f"\nDry run only. Total issues prepared: {len(payloads)}") + return 0 + + created_total = 0 + error_total = 0 + + for batch_no, batch in enumerate(chunked(payloads, 50), start=1): + print(f"Sending batch {batch_no} with {len(batch)} issues...") + result = jira.bulk_create_issues(batch) + + created = result.get("issues", []) or [] + errors = result.get("errors", []) or [] + + for item in created: + key = item.get("key", "") + issue_id = item.get("id", "") + print(f"Created: {key} (id={issue_id})") + + for item in errors: + failed = item.get("failedElementNumber") + element_errors = item.get("elementErrors", {}) + print( + f"ERROR in batch item index {failed}: " + f"{json.dumps(element_errors, ensure_ascii=False)}", + file=sys.stderr, + ) + + created_total += len(created) + error_total += len(errors) + + # Gentle pause between batches to avoid hammering the API. + time.sleep(0.5) + + print() + print(f"Done. Created: {created_total}, Errors: {error_total}") + + return 0 if error_total == 0 else 1 + + +if __name__ == "__main__": + try: + raise SystemExit(main()) + except KeyboardInterrupt: + print("\nInterrupted.", file=sys.stderr) + raise SystemExit(130) + except Exception as exc: + print(f"\nFATAL: {exc}", file=sys.stderr) + raise SystemExit(1) + +# python jira_bulk_import.py \ +# --site https://YOURDOMAIN.atlassian.net \ +# --email you@example.com \ +# --api-token YOUR_API_TOKEN \ +# --project TUR \ +# --csv TODO.csv \ +# --create-missing-components \ No newline at end of file From 780bc64adbadaf8c13f0ec1e1efb69edb0e0597e Mon Sep 17 00:00:00 2001 From: Malaber Date: Sun, 12 Apr 2026 13:39:21 +0200 Subject: [PATCH 08/10] Jira import --- jira_import.py => jira_bulk_import.py | 56 +++++++++++++-------------- 1 file changed, 27 insertions(+), 29 deletions(-) rename jira_import.py => jira_bulk_import.py (90%) diff --git a/jira_import.py b/jira_bulk_import.py similarity index 90% rename from jira_import.py rename to jira_bulk_import.py index ccb8faa..5dc8d55 100644 --- a/jira_import.py +++ b/jira_bulk_import.py @@ -13,6 +13,9 @@ python jira_bulk_import.py \ --project TURN \ --csv issues.csv \ --create-missing-components + +Optional: + --default-component General """ from __future__ import annotations @@ -84,7 +87,6 @@ class JiraClient: ) def get_project_components(self, project_key: str) -> dict[str, dict[str, Any]]: - # GET /rest/api/3/project/{projectKeyOrId}/components resp = self.get(f"/rest/api/3/project/{project_key}/components") items = resp.json() return {item["name"].strip().lower(): item for item in items} @@ -98,7 +100,6 @@ class JiraClient: return resp.json() def get_issue_types_for_project(self, project_key: str) -> dict[str, dict[str, Any]]: - # GET /rest/api/3/issue/createmeta/{projectIdOrKey}/issuetypes resp = self.get(f"/rest/api/3/issue/createmeta/{project_key}/issuetypes") data = resp.json() @@ -110,7 +111,6 @@ class JiraClient: return result def get_create_fields_metadata(self, project_key: str, issue_type_id: str) -> dict[str, Any]: - # GET /rest/api/3/issue/createmeta/{projectIdOrKey}/issuetypes/{issueTypeId} resp = self.get(f"/rest/api/3/issue/createmeta/{project_key}/issuetypes/{issue_type_id}") data = resp.json() return data.get("fields", {}) @@ -133,6 +133,11 @@ def parse_args() -> argparse.Namespace: action="store_true", help="Create missing project components automatically", ) + parser.add_argument( + "--default-component", + default="General", + help="Fallback Jira component to use when a CSV row has no component", + ) parser.add_argument( "--dry-run", action="store_true", @@ -163,7 +168,6 @@ def read_csv_issues(csv_path: str) -> list[CsvIssue]: if not row or not any(cell.strip() for cell in row): continue - # Pad short rows padded = row + [""] * max(0, 7 - len(row)) summary = padded[0].strip() @@ -178,8 +182,9 @@ def read_csv_issues(csv_path: str) -> list[CsvIssue]: print(f"Skipping row {idx}: empty Summary", file=sys.stderr) continue - components = [] + components: list[str] = [] for comp in (component_1, component_2): + comp = comp.strip() if comp and comp not in components: components.append(comp) @@ -233,12 +238,14 @@ def ensure_components( project_key: str, issues: list[CsvIssue], create_missing: bool, + default_component: str, ) -> dict[str, dict[str, Any]]: existing = jira.get_project_components(project_key) needed_names: list[str] = [] for issue in issues: - for comp in issue.components: + issue_components = issue.components or [default_component] + for comp in issue_components: key = normalize(comp) if key and key not in existing and comp not in needed_names: needed_names.append(comp) @@ -265,6 +272,7 @@ def build_issue_payload( issue_types_by_name: dict[str, dict[str, Any]], create_fields_by_issue_type_id: dict[str, dict[str, Any]], components_by_name: dict[str, dict[str, Any]], + default_component: str, ) -> dict[str, Any]: work_type_key = normalize(issue.work_type) if work_type_key not in issue_types_by_name: @@ -290,21 +298,18 @@ def build_issue_payload( if issue.priority and "priority" in fields_meta: fields["priority"] = {"name": issue.priority} - if issue.components and "components" in fields_meta: - comps = [] - for comp_name in issue.components: - key = normalize(comp_name) - component = components_by_name.get(key) - if not component: - raise RuntimeError( - f"Component '{comp_name}' not found for issue '{issue.summary}'" - ) - comps.append({"id": component["id"]}) - fields["components"] = comps + effective_components = issue.components or [default_component] - # Intentionally not sending "status". - # Jira creation should start in the workflow default state unless you add - # transition logic after creation. + comps = [] + for comp_name in effective_components: + key = normalize(comp_name) + component = components_by_name.get(key) + if not component: + raise RuntimeError( + f"Component '{comp_name}' not found for issue '{issue.summary}'" + ) + comps.append({"id": component["id"]}) + fields["components"] = comps return {"fields": fields} @@ -350,6 +355,7 @@ def main() -> int: project_key=args.project, issues=issues, create_missing=args.create_missing_components, + default_component=args.default_component, ) payloads: list[dict[str, Any]] = [] @@ -361,6 +367,7 @@ def main() -> int: issue_types_by_name=issue_types_by_name, create_fields_by_issue_type_id=create_fields_by_issue_type_id, components_by_name=components_by_name, + default_component=args.default_component, ) ) @@ -396,7 +403,6 @@ def main() -> int: created_total += len(created) error_total += len(errors) - # Gentle pause between batches to avoid hammering the API. time.sleep(0.5) print() @@ -414,11 +420,3 @@ if __name__ == "__main__": except Exception as exc: print(f"\nFATAL: {exc}", file=sys.stderr) raise SystemExit(1) - -# python jira_bulk_import.py \ -# --site https://YOURDOMAIN.atlassian.net \ -# --email you@example.com \ -# --api-token YOUR_API_TOKEN \ -# --project TUR \ -# --csv TODO.csv \ -# --create-missing-components \ No newline at end of file From 1981d4ecd8b9622d49996ed68936bf0eb598761d Mon Sep 17 00:00:00 2001 From: Malaber Date: Sun, 12 Apr 2026 13:44:05 +0200 Subject: [PATCH 09/10] Todo --- TODO.csv | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/TODO.csv b/TODO.csv index dd24297..dc5795b 100644 --- a/TODO.csv +++ b/TODO.csv @@ -15,7 +15,7 @@ Tournament: group pairing logic,"WICHTIG UND EZ: gruppenphase in der gleichen gr Matches: auto table assignment,"beim eintragen einer runde direkt den nächsten tisch anzeigen",Story,Medium,To Do,Frontend, Tournament: 3rd place match,"spiel um platz 3",Story,Low,To Do,Backend, Tournament: edgecase advancing >50%,"edgecase wenn mehr als die hälfte der teams weiterkommen bedenken bzw zumindest abfangen (hier ist gemeint dass es aktuell spezialcode für po2 turniere gibt bei denen immer die hälfte weiterkommt, es sollte aber auch _irgendwie_ für alle turniere funktionieren, ist nur out of scope für bpwstr)",Task,Low,To Do,Backend, -Timer: splash on end,"Timer groß werden lassen als splashscreen wenn er ausläuft",Story,Low,To Do,Frontend,Beamer +47: Timer: splash on end,"Timer groß werden lassen als splashscreen wenn er ausläuft",Story,Low,To Do,Frontend,Beamer Infra: bottle holders,"Flaschenhalter für die Techniktische",Task,Low,To Do,infra, Admin: timer UI cleanup,"timer end im admin frontend hübsch machen (aktuell hardcoded startwert)",Task,Low,To Do,Frontend,Admin Search: focus highlight,"turniere-match on focus suche markieren",Task,Low,To Do,Frontend, @@ -29,4 +29,4 @@ Beamer: show stage,"auf fullscreen matches ansicht die stage anzeigen (8tel, 4te Ranking: tie-breaker logic,"direkten vergleich werten, wenn alles gleich ist sonst",Story,High,To Do,Backend, Ranking: tie resolution,"bei gleichstand für stechen einen punkt vergeben (oder sonstwie, absprechen mit bpwstr)",Story,Medium,To Do,Backend, Bug: playoff refresh broken,"bug: refresh war kaputt in viertelfinale, halbfinale, finale",Bug,High,To Do,Frontend, -Matches: set winner + end last match,"sieger setzen können; letztes spiel beenden können",Story,High,To Do,Backend, +Matches: set winner + end last match,"sieger setzen können; letztes spiel beenden können",Story,High,To Do,Backend, \ No newline at end of file From 869e2aa50726cdc5e2ed2a2fadc13822eb854116 Mon Sep 17 00:00:00 2001 From: Malaber Date: Sun, 12 Apr 2026 13:44:13 +0200 Subject: [PATCH 10/10] Remove todo --- TODO.csv | 32 -------------------------------- 1 file changed, 32 deletions(-) delete mode 100644 TODO.csv diff --git a/TODO.csv b/TODO.csv deleted file mode 100644 index dc5795b..0000000 --- a/TODO.csv +++ /dev/null @@ -1,32 +0,0 @@ -Summary,Description,Work Type,Priority,Status,Component,Component -Backend: advancing flag for team,"backend könnte ""advancing"" an ein team mit dranschreiben; das könnte das frontend anzeigen ✅",Story,Medium,To Do,Backend, -Beamer: query param support,"alle funktionen der beamer ansichten müssen per query param gehen; beamer dann headless möglich (raspberry ohne maus/tastatur); noch besser: Beamer ansicht einfach /beamer und das backend entscheidet was geht",Story,High,To Do,Frontend,Beamer -Frontend: remember team,"feature im frontend für ""team merken"" damit man automatisch zur eigenen gruppe/aktuellstes game scrollt",Story,Medium,To Do,Frontend, -Beamer: show round timer,"timer auf dem beamer anzeigen für aktuelle runde ✅",Story,Medium,To Do,Beamer, -Beamer: filter current round,"filter für ""aktuelle runde"" für den beamer",Story,Medium,To Do,Beamer, -Beamer: fullscreen mode,"beamer modus (vollbild ohne cursor) ✅",Task,Low,To Do,Beamer, -Beamer: QR codes,"qr codes drucken für ergebnisausgabe und auf allen beamern anzeigen",Story,Medium,To Do,Beamer,Backend -Admin: auto refresh,"admin frontend automatisch aktualisieren",Story,Medium,To Do,Frontend,Admin -Admin: data age indicator,"admin frontend anzeigen wie ""alt"" die daten sind, also wann wurde die seite zuletzt aktualisiert",Story,Low,To Do,Frontend,Admin -Matches: next matches labeling,"nächste spiele sollten anzeigen wer da spielt (team a / team b) wenns direkt drunter ist und ansonsten ""gewinner achtelfinale 3""",Story,Medium,To Do,Frontend, -Playoff: initial labeling,"erste playoff spiele sollten ""1. gruppe 15 vs 2. gruppe 16"" anzeigen",Story,Medium,To Do,Backend,Frontend -Admin: show tables,"admin frontend muss tische auch anzeigen",Story,Medium,To Do,Frontend,Admin -Tournament: group pairing logic,"WICHTIG UND EZ: gruppenphase in der gleichen gruppe sollten erst finale gegeneinander spielen (dazu nicht aus der nächsten gruppe sondern einmal advancing teams von vorne und einmal von hinten, oder offset von hälfte der weiterkommenden teams) ✅",Story,High,To Do,Backend, -Matches: auto table assignment,"beim eintragen einer runde direkt den nächsten tisch anzeigen",Story,Medium,To Do,Frontend, -Tournament: 3rd place match,"spiel um platz 3",Story,Low,To Do,Backend, -Tournament: edgecase advancing >50%,"edgecase wenn mehr als die hälfte der teams weiterkommen bedenken bzw zumindest abfangen (hier ist gemeint dass es aktuell spezialcode für po2 turniere gibt bei denen immer die hälfte weiterkommt, es sollte aber auch _irgendwie_ für alle turniere funktionieren, ist nur out of scope für bpwstr)",Task,Low,To Do,Backend, -47: Timer: splash on end,"Timer groß werden lassen als splashscreen wenn er ausläuft",Story,Low,To Do,Frontend,Beamer -Infra: bottle holders,"Flaschenhalter für die Techniktische",Task,Low,To Do,infra, -Admin: timer UI cleanup,"timer end im admin frontend hübsch machen (aktuell hardcoded startwert)",Task,Low,To Do,Frontend,Admin -Search: focus highlight,"turniere-match on focus suche markieren",Task,Low,To Do,Frontend, -UI: fullscreen spacing,"vollbildansicht anpassen, dass sie auch abstände oben hat (die navbar oben is ja weg)",Task,Low,To Do,Frontend, -Matches: out-of-order handling,"damit klarkommen wenn matches aus der reihe gespielt werden (ein match stoppen, anderes match starten, neue matches starten muss entsprechend auch noch funktionieren)",Story,High,To Do,Backend,Frontend -Admin: tables + prompts,"tabellen im admin fe anzeigen, leute fragen beim ergebnis abgeben nach",Story,Medium,To Do,Frontend,Admin -Rename: Live -> Läuft noch,"""Live"" in ""Läuft noch"" umgenennen",Task,Low,To Do,Frontend, -Timer: unset function,"funktion timer unset",Task,Low,To Do,Backend, -Timer: count up mode,"alternativer timer der hochzählt, statt runter für viertelfinale etc.",Story,Low,To Do,Frontend, -Beamer: show stage,"auf fullscreen matches ansicht die stage anzeigen (8tel, 4tel, etc.)",Story,Low,To Do,Frontend,Beamer -Ranking: tie-breaker logic,"direkten vergleich werten, wenn alles gleich ist sonst",Story,High,To Do,Backend, -Ranking: tie resolution,"bei gleichstand für stechen einen punkt vergeben (oder sonstwie, absprechen mit bpwstr)",Story,Medium,To Do,Backend, -Bug: playoff refresh broken,"bug: refresh war kaputt in viertelfinale, halbfinale, finale",Bug,High,To Do,Frontend, -Matches: set winner + end last match,"sieger setzen können; letztes spiel beenden können",Story,High,To Do,Backend, \ No newline at end of file