Migrate all repos into monorepo context folders
Bahn: aisupport, Analyse-O2C-C2S, awesome-bahn-mcp-servers, beam-mcp,
Confluence_Bot, db-planet-mcp-server, O2C-Harness, project-audit,
Projekt-KIQ-HP, teamlandkarte-mcp
Dhive: Jury-Voting
Privat: CV, NoteGraph (NOTE: NoteGraph needs complete redo after consolidation)
Shared: AI-Orchestrator, OrgMyLife, power_skills_and_more
Shared/references: symphony (read-only)
Bahn repos remain available as independent remotes - this monorepo
pulls them in via subtree, the originals are untouched.
This commit is contained in:
@@ -0,0 +1,128 @@
|
||||
"""Pusht Team-Uebersicht inkl. TrassenOrder als Confluence-Seite."""
|
||||
import urllib.request, json, ssl, urllib.parse
|
||||
|
||||
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 = "26. Teams inkl. TrassenOrder"
|
||||
ctx = ssl.create_default_context()
|
||||
ctx.check_hostname = False
|
||||
ctx.verify_mode = ssl.CERT_NONE
|
||||
|
||||
html = """<h2>Team-Landschaft pathOS + TrassenOrder</h2>
|
||||
<p><strong>Stand:</strong> 2026-04-30 | Kontext: Reorganisations-Planung</p>
|
||||
|
||||
<ac:structured-macro ac:name="info"><ac:rich-text-body>
|
||||
<p><strong>TrassenOrder (TraPo)</strong> ist ein Testballon, um zu pruefen ob eine andere Herangehensweise (entkoppelt, UX-first, klein) schneller, besser und sicherer funktioniert als der pathOS-Ansatz (Microservice-Monolith, 167 Repos, 35+ Personen).</p>
|
||||
</ac:rich-text-body></ac:structured-macro>
|
||||
|
||||
<h3>Aktuelle Team-Landschaft</h3>
|
||||
<table>
|
||||
<tr><th>Team</th><th>Personen</th><th>Fokus</th><th>Services</th><th>Deployment</th><th>Besonderheit</th></tr>
|
||||
<tr><td><strong>Team 404</strong></td><td>~10</td><td>Portal UI + Middleware</td><td>2 (68K LoC)</td><td>pathOS Release-Zug</td><td>33% Bug-Rate, kundenseitig</td></tr>
|
||||
<tr><td><strong>Team CIB</strong></td><td>~13</td><td>Prozesse, Camunda, Backend</td><td>~15 (122K LoC)</td><td>pathOS Release-Zug</td><td>SV-Monolith, Abrechnung</td></tr>
|
||||
<tr><td><strong>Team Zero</strong></td><td>~9</td><td>TAF/TAP Schnittstellen</td><td>~9 (38K LoC)</td><td>pathOS Release-Zug</td><td>Beste Qualitaet, OPs-Rotation</td></tr>
|
||||
<tr><td><strong>OPs Squad</strong></td><td>2 fest + rot.</td><td>Betrieb, Infrastruktur</td><td>Infra-Repos</td><td>pathOS Release-Zug</td><td>Seit PI 39 (ex-STeam)</td></tr>
|
||||
<tr><td><strong>DevOps</strong></td><td>~7</td><td>CI/CD, Tooling, Pipelines</td><td>Pipelines, Helm</td><td>pathOS Release-Zug</td><td>Jan Lubenow = 39% SPOF</td></tr>
|
||||
<tr style="background:#dae8fc;"><td><strong>TrassenOrder (TraPo)</strong></td><td>~5 (klein)</td><td>GelV-Portal (UX-first)</td><td>1 (neu)</td><td><strong>Unabhaengig!</strong></td><td>Testballon, Discovery-Phase</td></tr>
|
||||
</table>
|
||||
|
||||
<h3>TrassenOrder vs. pathOS — Vergleich der Ansaetze</h3>
|
||||
<table>
|
||||
<tr><th>Dimension</th><th>pathOS (aktuell)</th><th>TrassenOrder (Testballon)</th></tr>
|
||||
<tr><td><strong>Architektur</strong></td><td>Microservice-Monolith (synchrone Releases, 167 Repos)</td><td>Externes System, eigene Schnittstellen, unabhaengig deploybar</td></tr>
|
||||
<tr><td><strong>Teamgroesse</strong></td><td>~35+ Personen, 5 Teams</td><td>~5 Personen, 1 Team</td></tr>
|
||||
<tr><td><strong>Zielgruppe</strong></td><td>Alle EVUs (Experten + Anfaenger)</td><td>Kleine EVUs, Ein-Mann-Betriebe ("WhatsApp-Nutzer")</td></tr>
|
||||
<tr><td><strong>UX-Ansatz</strong></td><td>240+ Formularfelder, Experten-Tool</td><td>3 Angaben fuer eine Bestellung, radikal vereinfacht</td></tr>
|
||||
<tr><td><strong>Deployment</strong></td><td>Release-Zug (alle Services zusammen)</td><td>Unabhaengig, eigener Rhythmus</td></tr>
|
||||
<tr><td><strong>Abhaengigkeiten</strong></td><td>Hoch (Kafka, Camunda, 15+ Services)</td><td>Minimal (nur API-Schnittstellen zu Primaerquellen)</td></tr>
|
||||
<tr><td><strong>Geschwindigkeit</strong></td><td>PI-getaktet (10 Wochen)</td><td>Kontinuierlich, Feature-basiert</td></tr>
|
||||
<tr><td><strong>Scope</strong></td><td>Netzfahrplan + GelV + ujBau + Abrechnung</td><td>Nur GelV (Gelegenheitsverkehr)</td></tr>
|
||||
<tr><td><strong>Phase</strong></td><td>Produktiv seit Dez 2025</td><td>Discovery seit Jan 2026, Livegang Q4 2026</td></tr>
|
||||
</table>
|
||||
|
||||
<h3>Was testet der Testballon?</h3>
|
||||
<ac:structured-macro ac:name="panel"><ac:parameter ac:name="title">Hypothesen</ac:parameter><ac:rich-text-body>
|
||||
<ol>
|
||||
<li><strong>Schneller:</strong> Kann ein kleines, entkoppeltes Team schneller liefern als ein grosses im Release-Zug?</li>
|
||||
<li><strong>Besser:</strong> Fuehrt UX-first + radikale Vereinfachung zu besserer Nutzerzufriedenheit?</li>
|
||||
<li><strong>Sicherer:</strong> Reduziert Entkopplung das Risiko (kein Dominoeffekt bei Fehlern)?</li>
|
||||
</ol>
|
||||
<p><strong>Wenn der Testballon erfolgreich ist:</strong> Das Modell koennte auf weitere Bereiche uebertragen werden (Netzfahrplan, ujBau). Langfristig koennte TrassenOrder das pathOS-Portal <strong>abloesen</strong>.</p>
|
||||
</ac:rich-text-body></ac:structured-macro>
|
||||
|
||||
<h3>Schnittstellen zwischen pathOS und TrassenOrder</h3>
|
||||
<table>
|
||||
<tr><th>Schnittstelle</th><th>Richtung</th><th>Zweck</th></tr>
|
||||
<tr><td>Trassenanmeldung API</td><td>TraPo → pathOS</td><td>Bestellung absetzen</td></tr>
|
||||
<tr><td>Stammdaten API</td><td>TraPo ← Primaerquelle</td><td>Direkt, NICHT ueber pathOS</td></tr>
|
||||
<tr><td>Angebots-Rueckmeldung</td><td>pathOS → TraPo</td><td>Ergebnis der Konstruktion</td></tr>
|
||||
<tr><td>Trassenfinder</td><td>TraPo ← BVU</td><td>Routing, Validierung (Fernziel)</td></tr>
|
||||
</table>
|
||||
<p><strong>Architekturentscheidung:</strong> TrassenOrder greift auf Primaerquellen direkt zu — nicht ueber eine pathOS-Zwischenschicht. Das vermeidet Abhaengigkeiten vom pathOS Release-Zug.</p>
|
||||
|
||||
<h3>Implikationen fuer Team-Reorganisation</h3>
|
||||
<table>
|
||||
<tr><th>Szenario</th><th>Auswirkung auf pathOS-Teams</th></tr>
|
||||
<tr><td><strong>TraPo erfolgreich → GelV wandert zu TraPo</strong></td><td>pathOS kann sich auf Netzfahrplan + ujBau + Abrechnung konzentrieren. Vereinfacht den fachlichen Schnitt erheblich. Click&Ride (ADR-72) wird obsolet.</td></tr>
|
||||
<tr><td><strong>TraPo erfolgreich → Modell wird uebertragen</strong></td><td>Weitere kleine Teams fuer spezifische Domaenen. pathOS wird zum API-Backend-Layer. Portal-Team (404) wird langfristig obsolet.</td></tr>
|
||||
<tr><td><strong>TraPo scheitert → GelV bleibt bei pathOS</strong></td><td>Keine Aenderung. Click&Ride Anbindung (ADR-72) wird weiter von CIB gebaut.</td></tr>
|
||||
</table>
|
||||
|
||||
<h3>Offene Fragen</h3>
|
||||
<ul>
|
||||
<li>Wann ist der Testballon "erfolgreich"? Welche Metriken? (Time-to-Market, Nutzerzufriedenheit, Bug-Rate?)</li>
|
||||
<li>Wie wird die Schnittstelle zwischen TraPo und pathOS-Backend definiert und versioniert?</li>
|
||||
<li>Wer pflegt die Schnittstelle langfristig? (API-Vertrag)</li>
|
||||
<li>Kann das TraPo-Modell auf Netzfahrplan skaliert werden? (Komplexitaet ist dort 10x hoeher)</li>
|
||||
<li>Was passiert mit Team 404 wenn TrassenOrder das Portal langfristig abloest?</li>
|
||||
</ul>
|
||||
|
||||
<h3>Team-Kennzahlen (Vergleich)</h3>
|
||||
<table>
|
||||
<tr><th>Metrik</th><th>pathOS gesamt</th><th>TrassenOrder</th><th>Faktor</th></tr>
|
||||
<tr><td>Personen</td><td>~35</td><td>~5</td><td>7x</td></tr>
|
||||
<tr><td>Services</td><td>~40 aktiv</td><td>1</td><td>40x</td></tr>
|
||||
<tr><td>Lines of Code</td><td>~260K</td><td>~0 (Discovery)</td><td>—</td></tr>
|
||||
<tr><td>Jira-Projekte</td><td>6 (O2C*, TTTI)</td><td>1 (TRAPO)</td><td>6x</td></tr>
|
||||
<tr><td>Release-Frequenz</td><td>~2x/Monat (KTU)</td><td>Kontinuierlich (Ziel)</td><td>—</td></tr>
|
||||
<tr><td>Bug-Rate</td><td>20-33%</td><td>0% (noch kein Code)</td><td>—</td></tr>
|
||||
<tr><td>Deployment-Abhaengigkeiten</td><td>Hoch (17+ Umgebungen)</td><td>Keine</td><td>—</td></tr>
|
||||
</table>
|
||||
"""
|
||||
|
||||
# Push
|
||||
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"):
|
||||
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:
|
||||
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']}")
|
||||
Reference in New Issue
Block a user