"""Pusht Meilensteinplan 12 Monate als Confluence-Seite 27."""
import urllib.request, json, ssl, urllib.parse
from pathlib import Path
secrets = {}
with open("project-audit/.secrets", "r", encoding="utf-8-sig") as f:
for line in f:
if "=" in line and not line.startswith("#"):
k, v = line.strip().split("=", 1)
secrets[k.strip()] = v.strip()
TOKEN = secrets.get("CONFLUENCE_TOKEN", "")
BASE = "https://arija-confluence.jaas.service.deutschebahn.com/rest/api"
SPACE = "BES"
PARENT = "581013135"
TITLE = "27. Meilensteinplan 12 Monate (Jun 2026 - Mai 2027)"
ctx = ssl.create_default_context()
ctx.check_hostname = False
ctx.verify_mode = ssl.CERT_NONE
html = """
Meilensteinplan pathOS — 12 Monate
Stand: 2026-05-12 | Status: ENTWURF
Vision: pathOS als Kernplattform eines integrierten InfraGO-Bestellportals
Prioritäten: Stabilität → Regulatorik → Kunden-Features
Kapazität: ~400 Issues/Monat (alle Teams), ~35 Personen
4 Phasen, 13 Meilensteine: Stabilisieren → Normalbetrieb + Regulatorik → Skalieren + Reorg → Integrieren + Vision
Grafische Übersicht: Timeline
| Meilenstein |
Jun |
Jul |
Aug |
Sep |
Okt |
Nov |
Dez |
Jan |
Feb |
Mär |
Apr |
Mai |
"""
html += """
| Phase 1: STABILISIEREN |
| M1: Spring Boot 4 ⚠ |
★ |
| | | | | | | | | | |
| M2: Bug-Rate <25% |
|
★ |
| | | | | | | | | |
| M3: Führungswechsel |
|
★ |
| | | | | | | | | |
"""
html += """
| Phase 2: NORMALBETRIEB + REGULATORIK |
| M4: SL Silber Plus ⚠ |
| |
★ |
| | | | | | | | |
| M5: Abrechnung TTT |
| |
|
|
★ |
| | | | | | |
| M6: NAÄ produktiv |
| |
|
★ |
| | | | | | | |
| M7: OpsDev formiert |
| |
|
★ |
| | | | | | | |
"""
html += """
| Phase 3: SKALIEREN + REORG |
| M8: FplJ 28 ⚠ |
| | | |
|
|
★ |
| | | | |
| M9: Rechnungsbeginn TTT ⚠ |
| | | | | | |
★ |
| | | |
| M10: Reorg abgeschlossen |
| | | | |
|
|
★ |
| | | |
"""
html += """
| Phase 4: INTEGRIEREN + VISION |
| M11: TrassenOrder-Integr. |
| | | | | | | |
★ |
| | |
| M12: Plattform-Vision |
| | | | | | | |
|
★ |
| |
| M13: Kundenzufriedenheit |
| | | | | | | | |
|
|
★ |
Legende: ★ = Deadline | ⚠ = Harte externe Deadline |
MUSS
HOCH
Feature
Strategie
Reorg
"""
html += """
Phase 1: STABILISIEREN (Jun – Jul 2026)
Ziel
Technische Schulden abbauen, Hypercare beenden, Führungswechsel vorbereiten
M1: Spring Boot 4 abgeschlossen (30. Jun 2026) ⚠
| Was | Wer | Status |
| SV, AV, IFP auf Spring Boot 4 | CIB (Saurav, Hans-Henning) | 🔄 In Arbeit |
| CI, AV-Trasse auf Spring Boot 4 | Zero (O2CZERO-7043) | 🔄 In Arbeit |
| Alle Services auf Java 21 | Alle | Teilweise |
| Regressionstests nach Upgrade | QA + Teams | Offen |
Risiko: EOL 3.5 ist Juni 2026 — kein Security-Support mehr danach. MUSS-Termin.
M2: Bug-Rate Portal unter 25% (31. Jul 2026)
| Was | Wer | Status |
| Entkopplung Zuglaufpunkte/Zugcharakteristik (Hauptursache) | 404 | Offen |
| Fehlermeldungen-Konzept umsetzen | 404 | Offen |
| E2E-Tests (Playwright) für Top-10-Flows | 404 | Offen |
| Testumgebung mit TPN dauerhaft verfügbar | 404 + OPs | Offen |
M3: Führungswechsel + Hypercare-Ende (Jul 2026)
| Was | Wer | Status |
| Neue Führung eingesetzt | Management | Offen |
| Hypercare-Kriterien definiert und erfüllt | PO + BO | Offen |
| Übergang zu Normalbetrieb dokumentiert | Alle | Offen |
| Support-Prozesse definiert (Eskalation, SLAs) | BSSUPPORT + OPs | Offen |
"""
html += """
Phase 2: NORMALBETRIEB + REGULATORIK (Aug – Nov 2026)
Ziel
Vertragliche Pflichten erfüllen, Abrechnung stabilisieren, Team-Reorg starten
M4: Service Level Silber Plus (31. Aug 2026) ⚠
| Was | Wer | Status |
| Netcool-Anbindung produktiv | OPs | 🔄 In Arbeit |
| Monitoring-Konzept abgeschlossen | OPs + Zero | 🔄 In Arbeit |
| Disaster-Recovery-Test 3 bestanden | OPs | 🔄 Validierung |
| Deployment-Automatisierung (Smoketests) | OPs/DevOps | 🔄 In Arbeit |
| Secret-Rotation implementiert | OPs | Offen |
| Kubernetes-Namespaces umgestellt | OPs | 🔄 In Arbeit |
Risiko: Vertragsverletzung bei Versäumnis. Keine Verhandlungsmasse.
M5: Abrechnung TTT produktionsreif (31. Okt 2026)
| Was | Wer | Status |
| 20h-Zug Abrechnung (TTTSOL-2149) entblockt | CIB | ❌ Blocked |
| Zugtrasse mit Umleitung ohne VT-Wechsel (TTTSOL-2147) | CIB | Offen |
| Abrechnung fremde Infrastruktur (TTTSOL-2148) | CIB | Offen |
| Neue Zugnummer Umleitungsfall (TTTSOL-2035) | CIB | 🔄 In Arbeit |
| VDV-Erweiterung für AC Trasse (strategisch) | CIB + Zero | Offen |
| Alle 41 Abrechnungs-Tickets priorisiert | CIB PO | Offen |
Rechnungsbeginn TTT ist Januar 2027. Bis Oktober müssen kritische Fälle gelöst sein. Nov/Dez = Buffer für Regressionstests.
M6: NAÄ implizite Annahme produktiv (30. Sep 2026)
| Was | Wer | Status |
| O2CCIB-6931 assigned und implementiert | CIB | ⚠ Geschoben |
| Prozess-Design mit Fachbereich abgestimmt | CIB BA | Offen |
| E2E-Test NAÄ-Szenario | CIB + 404 | Offen |
M7: Team-Reorg Phase 1 — OpsDev formiert (30. Sep 2026)
| Was | Wer | Status |
| OpsDev-Team definiert (~6 Personen) | Management + Leads | Offen |
| OpsDev-Lead benannt | Management | Offen |
| Jan Lubenow Wissenstransfer (50% abgeschlossen) | DevOps | ⚠ Kritisch |
| Bug-Triage-Prozess definiert | OpsDev-Lead | Offen |
| OPs-Rotation beendet (feste Zuordnung) | Management | Offen |
"""
html += """
Phase 3: SKALIEREN + REORG (Dez 2026 – Feb 2027)
Ziel
Fahrplanwechsel absichern, Team-Umstellung abschließen, Plattform-Denken etablieren
M8: Fahrplanwechsel FplJ 28 (Dez 2026) ⚠
| Was | Wer | Status |
| GelV-Erweiterungen (TTT-Meilenstein) | CIB + Zero | Offen |
| OTN-Vergabe Fpl 2027 (TTTSOL-1683) | CIB | 🔄 In Arbeit |
| ujBau Funktionalität | Alle | 🔄 In Arbeit |
| FplJ-28-spezifische Validierungen getestet | QA | Offen |
| Daten-Partitionierung (Performance) | CIB/Zero | Offen |
Risiko: Fahrplanwechsel ist harter externer Termin. Kein Verschieben möglich.
M9: Rechnungsbeginn TTT (Jan 2027) ⚠
| Was | Wer | Status |
| Alle kritischen Abrechnungsfälle gelöst (aus M5) | CIB | Abhängig von M5 |
| Rechnungslauf erfolgreich getestet (Staging) | CIB + QA | Offen |
| Monitoring für Abrechnungsfehler aktiv | OPs/OpsDev | Offen |
| Fallback-Prozess bei Abrechnungsfehlern definiert | CIB + BO | Offen |
M10: Team-Reorg abgeschlossen (31. Jan 2027)
| Was | Wer | Status |
| 2 fachliche Teams formiert ("Bestellen" + "Verarbeiten") | Management | Offen |
| Service-Ownership klar zugeordnet | Team-Leads | Offen |
| PO-Struktur definiert | Management | Offen |
| Wissenstransfer abgeschlossen | Alle | Offen |
| Erste Sprints in neuer Struktur erfolgreich | Teams | Offen |
| Metriken definiert (Bug-Rate, Durchlaufzeit, Deploy-Freq.) | BO + Leads | Offen |
Reorg NACH Fahrplanwechsel abschließen — nicht während des kritischen Zeitraums umbauen.
"""
html += """
Phase 4: INTEGRIEREN + VISION (Feb – Mai 2027)
Ziel
TrassenOrder-Learnings integrieren, Plattform-Architektur vorbereiten, Kundenzufriedenheit steigern
M11: TrassenOrder-Integration definiert (28. Feb 2027)
| Was | Wer | Status |
| TrassenOrder Livegang evaluiert (Q4 2026) | TraPo + BO | Offen |
| Abgrenzung pathOS/TrassenOrder dokumentiert | POs + Architektur | Offen |
| API-Vertrag zwischen pathOS und TrassenOrder | CIB/Zero + TraPo | Offen |
| Entscheidung: GelV bei pathOS oder TraPo? | BO + Management | Offen |
| Übernahme-Szenario TraPo → pathOS-Team bewertet | Management | Offen |
M12: Plattform-Architektur-Vision (31. März 2027)
| Was | Wer | Status |
| Architektur-Vision "Integriertes Bestellportal" dokumentiert | Architektur + BO | Offen |
| Kernkomponenten als integrierbare Module identifiziert | Architektur | Offen |
| Schnittstellen-Strategie (API-First) definiert | Architektur + Teams | Offen |
| Roadmap für Anlage + Nebenleistungen (nächste 12M) | BO + POs | Offen |
| TPN-Ablösung Zeitplan konkretisiert | POs + Kunden | Offen |
M13: Kundenzufriedenheit messbar verbessert (Mai 2027)
| Was | Wer | Status |
| Bug-Rate Portal unter 15% (von 33%) | Team "Bestellen" | Offen |
| Vorprüfung Portal produktiv | CIB + 404 | Offen |
| Expertenmodus verfügbar | 404 | Offen |
| Übersichtsseite Vorgänge live | 404 | Offen |
| Kundenfeedback-Loop etabliert | PO + UX | Offen |
| NPS oder CSAT Baseline gemessen | PO + BO | Offen |
"""
html += """
Kritischer Pfad & Abhängigkeiten
| Pfad | Abhängigkeit | Konsequenz bei Verzögerung |
| M1 → M4 | Spring Boot 4 muss fertig sein für SL Silber+ (Security-Compliance) | Vertragsverletzung |
| M5 → M9 | Abrechnung muss bis Okt stehen für Rechnungsbeginn Jan | Falsche Rechnungen an Kunden |
| M3 → M7 → M10 | Führungswechsel ermöglicht Reorg, Reorg nach FplJ abschließen | Produktivitätsverlust |
| M8 (extern) | Fahrplanwechsel ist Fixpunkt — alles andere drumherum planen | Fahrplan gefährdet |
Risiko-Matrix
| Risiko | Wahrscheinlichkeit | Impact | Mitigation |
| Abrechnung bleibt blocked (20h-Zug) | HOCH | KRITISCH | Eskalation an TTT-Programm, Workaround |
| Bug-Rate 404 steigt weiter | HOCH | HOCH | Entkopplung Zuglaufpunkte priorisieren |
| SL Silber+ Deadline gerissen | Mittel | HOCH | Früh mit UKA abstimmen, Teilabnahme? |
| Reorg destabilisiert Teams | Mittel | HOCH | Sukzessiv, nicht Big Bang. Nach FplJ. |
| Jan Lubenow fällt aus (SPOF) | Niedrig | KRITISCH | Wissenstransfer ab sofort priorisieren |
| TrassenOrder scheitert/pivotiert | Mittel | MITTEL | pathOS bleibt autark, GelV intern weiter |
| Spring Boot 4 nicht rechtzeitig | Niedrig | KRITISCH | Fokus, keine Ablenkung |
Reorg-Zeitplan (sukzessiv)
| Zeitraum | Schritt | Risiko |
| Jul 2026 | Führungswechsel, Vision kommunizieren | Niedrig |
| Aug-Sep 2026 | OpsDev-Team formieren (aus OPs + DevOps-Teilen) | Mittel |
| Okt 2026 | OPs-Rotation beenden, feste Zuordnung | Niedrig |
| Nov 2026 | Fachliche Teams vorbereiten (Service-Mapping, Wissenstransfer) | Mittel |
| Jan 2027 | Umstellung auf 2 fachliche Teams ("Bestellen" + "Verarbeiten") | Hoch |
| Feb 2027 | Erste Sprints in neuer Struktur, Nachjustierung | Mittel |
| März 2027 | TrassenOrder-Team-Integration bewerten | Mittel |
Metriken zur Erfolgsmessung
| Metrik | Baseline (Mai 2026) | Ziel Sep 2026 | Ziel Jan 2027 | Ziel Mai 2027 |
| Bug-Rate Portal | 33% | 25% | 20% | <15% |
| Bug-Rate Gesamt | 20% | 18% | 15% | <12% |
| Deployment-Frequenz | ? (messen!) | 1x/Woche | 2x/Woche | Täglich möglich |
| Mean Time to Recovery | ? (messen!) | <4h | <2h | <1h |
| Offene Highest-Tickets | 8+ | <5 | <3 | 0 |
| SPOF-Index (>30%) | 2 (Jan, Steven) | 1 | 0 | 0 |
| Kundenzufriedenheit | Nicht gemessen | Baseline | +10 Pkt | +20 Pkt |
Offene Entscheidungen
| # | Entscheidung | Deadline | Wer |
| 1 | Wer wird neue Führung? | Jun 2026 | Management |
| 2 | OpsDev-Lead: Intern oder extern? | Jul 2026 | Management |
| 3 | SV-Monolith: Aufteilen oder einem Team zuordnen? | Okt 2026 | Architektur + BO |
| 4 | PO-Struktur: 1 pro Team oder übergreifend? | Nov 2026 | BO |
| 5 | TrassenOrder: Eigenes Team oder Integration? | Feb 2027 | BO + Management |
| 6 | GelV-Ownership: pathOS oder TraPo? | Feb 2027 | BO |
| 7 | Nächste Domäne nach Trasse (Anlage? Nebenleistungen?) | März 2027 | BO + Strategie |
Erstellt im Rahmen des pathOS Portfolio-Audits. Kontakt: Andre Knie
"""
# Push to Confluence
def api_request(url, method="GET", data=None):
req = urllib.request.Request(url, method=method)
req.add_header("Authorization", f"Bearer {TOKEN}")
req.add_header("Content-Type", "application/json")
if data:
req.data = json.dumps(data).encode("utf-8")
return json.loads(urllib.request.urlopen(req, context=ctx, timeout=30).read().decode("utf-8"))
# Check if page exists
search_url = f"{BASE}/content?spaceKey={SPACE}&title={urllib.parse.quote(TITLE)}&type=page"
req = urllib.request.Request(search_url)
req.add_header("Authorization", f"Bearer {TOKEN}")
resp = urllib.request.urlopen(req, context=ctx, timeout=30)
search_data = json.loads(resp.read().decode("utf-8"))
if search_data.get("results"):
# Update existing page
page_id = search_data["results"][0]["id"]
ver_url = f"{BASE}/content/{page_id}?expand=version"
req2 = urllib.request.Request(ver_url)
req2.add_header("Authorization", f"Bearer {TOKEN}")
ver_data = json.loads(urllib.request.urlopen(req2, context=ctx, timeout=30).read().decode("utf-8"))
version = ver_data["version"]["number"] + 1
body = json.dumps({
"version": {"number": version},
"title": TITLE,
"type": "page",
"body": {"storage": {"value": html, "representation": "storage"}}
}).encode("utf-8")
req3 = urllib.request.Request(f"{BASE}/content/{page_id}", method="PUT", data=body)
req3.add_header("Authorization", f"Bearer {TOKEN}")
req3.add_header("Content-Type", "application/json")
result = json.loads(urllib.request.urlopen(req3, context=ctx, timeout=30).read().decode("utf-8"))
print(f"Aktualisiert: https://arija-confluence.jaas.service.deutschebahn.com/pages/viewpage.action?pageId={result['id']}")
else:
# Create new page
body = json.dumps({
"type": "page",
"title": TITLE,
"space": {"key": SPACE},
"ancestors": [{"id": PARENT}],
"body": {"storage": {"value": html, "representation": "storage"}}
}).encode("utf-8")
req3 = urllib.request.Request(f"{BASE}/content", method="POST", data=body)
req3.add_header("Authorization", f"Bearer {TOKEN}")
req3.add_header("Content-Type", "application/json")
result = json.loads(urllib.request.urlopen(req3, context=ctx, timeout=30).read().decode("utf-8"))
print(f"Erstellt: https://arija-confluence.jaas.service.deutschebahn.com/pages/viewpage.action?pageId={result['id']}")