From 6b6f49e8203e942c893747e59e0a9a589cd70f73 Mon Sep 17 00:00:00 2001 From: marcus hinz Date: Sat, 20 Jun 2026 12:15:26 +0200 Subject: [PATCH] clean / centralize --- global/CLAUDE.md | 1 + global/bin/git-sync | 78 +++ global/commands/git-sync.md | 24 + global/settings.json | 21 + limbach/.$integration-server.drawio.bkp | 362 +++++++++++++ limbach/.$integration-server_sngle.drawio.bkp | 181 +++++++ limbach/.claude/settings.json | 11 +- limbach/integration-server.drawio | 474 ++++++++++++++++++ limbach/integration-server_sngle.drawio | 181 +++++++ limbach/memory/keine-rhetorischen-fragen.md | 14 + robotunits/.claude/settings.json | 13 +- robotunits/.claude/settings.local.json | 10 +- wittgenstein/.claude/settings.json | 14 +- wittgenstein/.claude/settings.local.json | 8 +- wuerth-plato/.claude/settings.json | 5 + wuerth-plato/.claude/settings.local.json | 38 ++ wuerth-plato/CLAUDE.md | 7 + wuerth-plato/memory/feedback_ort_zuerst.md | 19 + wuerth-plato/memory/project_prod_ist_stand.md | 35 ++ 19 files changed, 1469 insertions(+), 27 deletions(-) create mode 100755 global/bin/git-sync create mode 100644 global/commands/git-sync.md create mode 100644 global/settings.json create mode 100644 limbach/.$integration-server.drawio.bkp create mode 100644 limbach/.$integration-server_sngle.drawio.bkp create mode 100644 limbach/integration-server.drawio create mode 100644 limbach/integration-server_sngle.drawio create mode 100644 limbach/memory/keine-rhetorischen-fragen.md create mode 100644 wuerth-plato/.claude/settings.local.json create mode 100644 wuerth-plato/CLAUDE.md create mode 100644 wuerth-plato/memory/feedback_ort_zuerst.md create mode 100644 wuerth-plato/memory/project_prod_ist_stand.md diff --git a/global/CLAUDE.md b/global/CLAUDE.md index 6c930a5..d611ea6 100644 --- a/global/CLAUDE.md +++ b/global/CLAUDE.md @@ -3,6 +3,7 @@ - Sachlicher Ton, normales ruhiges Deutsch. Kein Motivieren, Loben oder Bedauern, keine Werbe-/Selbst-Slogans. - So knapp wie möglich: nur Fakten, keine Füllabsätze, keine Wiederholung meiner Aussagen, keine Annahmen über den Kontext. - Nur handeln, wenn ich es ausdrücklich sage. Sonst nur antworten/erklären. +- Eine konkrete Frage NUR beantworten — exakt das Gefragte, nicht mehr. Ja/Nein-Frage = Ja/Nein. Kein Entwerfen, keine Optionen, keine Lösung, kein Vorschlag, keine ungefragte Recherche/Investigation — auch nicht, wenn etwas falsch, gefährlich oder verbesserungswürdig aussieht. Ein auffälliger Punkt wird höchstens in einem Halbsatz benannt, nicht ausgearbeitet. - Keine Vorschläge für weiteres Vorgehen oder was man sonst noch machen könnte. - Positiv formulieren: beschreiben, was der Code tut / was getan wurde — nicht, was man nicht tut. Negationsketten vermeiden. - Bei Unsicherheit „weiß ich nicht" / „unklar" sagen, statt mit generischem Text aufzufüllen. diff --git a/global/bin/git-sync b/global/bin/git-sync new file mode 100755 index 0000000..f53c051 --- /dev/null +++ b/global/bin/git-sync @@ -0,0 +1,78 @@ +#!/usr/bin/env bash +# git-sync — add/commit/pull --rebase/push a single repo. +# Safe: rebases onto remote, never merges, never force-pushes; conflicts are +# reported (rebase aborted), not auto-resolved. +# Usage: git-sync [commit-message] +# Invoked by the /git-sync slash command, once per configured project repo. +set -uo pipefail + +dir=${1:?usage: git-sync [message]} +msg=${2:-} + +# expand leading ~ (not expanded inside variables) so $HOME-based paths work +case "$dir" in + "~") dir="$HOME" ;; + "~/"*) dir="$HOME/${dir#"~/"}" ;; +esac + +ok() { printf '\033[1;32m✓ %s\033[0m\n' "$*"; } # green +note() { printf '\033[1;36m· %s\033[0m\n' "$*"; } # cyan +warn() { printf '\033[1;33m⚠ %s\033[0m\n' "$*"; } # yellow + +g() { git -C "$dir" "$@"; } +label=$(basename "$dir") + +if ! g rev-parse --is-inside-work-tree >/dev/null 2>&1; then + warn "$label: kein Git-Repo — übersprungen." + exit 0 +fi +branch=$(g rev-parse --abbrev-ref HEAD) + +# --- commit working-tree changes ------------------------------------------- +if [[ -n "$(g status --porcelain)" ]]; then + g add -A + [[ -z "$msg" ]] && msg="git-sync: $(date '+%Y-%m-%d %H:%M')" + if g commit --quiet -m "$msg"; then + note "$label: committed — $msg" + else + warn "$label: commit fehlgeschlagen." + exit 0 + fi +else + note "$label: keine Änderungen." +fi + +# --- pull --rebase, then push (no force, no merge) ------------------------- +if ! g remote get-url origin >/dev/null 2>&1; then + note "$label: kein origin-Remote — push übersprungen." + exit 0 +fi + +if g rev-parse --abbrev-ref --symbolic-full-name '@{u}' >/dev/null 2>&1; then + # integrate remote first: rebase keeps history linear, no merge commits + g fetch --quiet 2>/dev/null || true + behind=$(g rev-list --count 'HEAD..@{u}' 2>/dev/null || echo 0) + if [[ "$behind" -gt 0 ]]; then + if g pull --rebase --quiet 2>/dev/null; then + note "$label: $behind Commit(s) per Rebase integriert." + else + g rebase --abort >/dev/null 2>&1 || true + warn "$label: Pull/Rebase-Konflikt — bitte manuell lösen. Push übersprungen." + exit 0 + fi + fi + ahead=$(g rev-list --count '@{u}..HEAD' 2>/dev/null || echo 0) + if [[ "$ahead" -eq 0 ]]; then + note "$label: nichts zu pushen." + elif g push --quiet 2>/dev/null; then + ok "$label: $ahead Commit(s) gepusht ($branch)." + else + warn "$label: push abgelehnt — Remote voraus. Manuell prüfen." + fi +else + if g push --quiet -u origin "$branch" 2>/dev/null; then + ok "$label: Upstream gesetzt und gepusht ($branch)." + else + warn "$label: kein Upstream, push fehlgeschlagen — einmal manuell pushen." + fi +fi diff --git a/global/commands/git-sync.md b/global/commands/git-sync.md new file mode 100644 index 0000000..7ba65ad --- /dev/null +++ b/global/commands/git-sync.md @@ -0,0 +1,24 @@ +--- +description: Commit + Push aller persistent konfigurierten Projekt-Repos +--- + +Du committest und pushst die persistent hinterlegten Projekt-Verzeichnisse +(`permissions.additionalDirectories` aus den Settings) — nicht das CWD. + +1. Verzeichnisse sammeln (Projekt-, lokale, User-Settings, dedupliziert): + ```bash + for f in .claude/settings.json .claude/settings.local.json "$HOME/.claude/settings.json"; do + [ -f "$f" ] && jq -r '.permissions.additionalDirectories[]?' "$f" 2>/dev/null + done | sort -u | sed "s|^~/|$HOME/|" + ``` +2. Für jedes Verzeichnis, das ein Git-Repo ist: aus `git -C status` und + `git -C diff --staged --stat` plus `git -C diff --stat` eine knappe, + sachliche einzeilige Commit-Message auf Deutsch erzeugen (beschreibt, was geändert wurde). +3. Pro Verzeichnis aufrufen: + ```bash + "$HOME/claude-projects/global/bin/git-sync" "" "" + ``` +4. Ergebnisse pro Repo zusammenfassen: committed / gepusht / nichts zu tun / abgelehnt. + +Verändere nichts außerhalb dieser Verzeichnisse. Kein force, kein merge — das Skript +ist darauf ausgelegt und meldet Konflikte nur, statt sie aufzulösen. diff --git a/global/settings.json b/global/settings.json new file mode 100644 index 0000000..3ae6802 --- /dev/null +++ b/global/settings.json @@ -0,0 +1,21 @@ +{ + "enabledPlugins": { + "frontend-design@claude-plugins-official": true + }, + "promptSuggestionEnabled": false, + "awaySummaryEnabled": false, + "theme": "dark", + "permissions": { + "allow": [ + "Bash(git add:*)", + "Bash(git commit:*)", + "Bash(git push:*)", + "Bash(git pull:*)", + "Bash(git status:*)", + "Bash(git diff:*)", + "Bash(git -C:*)", + "Bash(git mv:*)", + "Bash(git check-ignore:*)" + ] + } +} diff --git a/limbach/.$integration-server.drawio.bkp b/limbach/.$integration-server.drawio.bkp new file mode 100644 index 0000000..2b7bfd6 --- /dev/null +++ b/limbach/.$integration-server.drawio.bkp @@ -0,0 +1,362 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/limbach/.$integration-server_sngle.drawio.bkp b/limbach/.$integration-server_sngle.drawio.bkp new file mode 100644 index 0000000..c83d7c5 --- /dev/null +++ b/limbach/.$integration-server_sngle.drawio.bkp @@ -0,0 +1,181 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/limbach/.claude/settings.json b/limbach/.claude/settings.json index 795170a..7e41934 100644 --- a/limbach/.claude/settings.json +++ b/limbach/.claude/settings.json @@ -1,3 +1,12 @@ { - "autoMemoryDirectory": "~/claude-projects/limbach/memory" + "autoMemoryDirectory": "~/claude-projects/limbach/memory", + "permissions": { + "allow": [ + "Edit(~/projects/limbach/**)", + "Edit(~/claude-projects/limbach/**)" + ], + "additionalDirectories": [ + "~/projects/limbach" + ] + } } diff --git a/limbach/integration-server.drawio b/limbach/integration-server.drawio new file mode 100644 index 0000000..7924336 --- /dev/null +++ b/limbach/integration-server.drawio @@ -0,0 +1,474 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/limbach/integration-server_sngle.drawio b/limbach/integration-server_sngle.drawio new file mode 100644 index 0000000..cd502a8 --- /dev/null +++ b/limbach/integration-server_sngle.drawio @@ -0,0 +1,181 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/limbach/memory/keine-rhetorischen-fragen.md b/limbach/memory/keine-rhetorischen-fragen.md new file mode 100644 index 0000000..cfeea4a --- /dev/null +++ b/limbach/memory/keine-rhetorischen-fragen.md @@ -0,0 +1,14 @@ +--- +name: keine-rhetorischen-fragen +description: Niemals rhetorische Fragen verwenden — strikt verboten +metadata: + node_type: memory + type: feedback + originSessionId: d35a0bd9-ab2f-4a8e-975e-6bd133983fa8 +--- + +Niemals rhetorische Fragen verwenden. Striktes Verbot, ausnahmslos. + +**Why:** Der Nutzer empfindet rhetorische Fragen als störend und hat das ausdrücklich und nachdrücklich untersagt. + +**How to apply:** Aussagen statt Fragen formulieren. Keine Fragen zur Auflockerung, Überleitung oder als Stilmittel. Echte Rückfragen nur, wenn eine Antwort tatsächlich gebraucht wird. Verwandt mit [[verbotene-woerter]]. diff --git a/robotunits/.claude/settings.json b/robotunits/.claude/settings.json index 1c38087..4d405ea 100644 --- a/robotunits/.claude/settings.json +++ b/robotunits/.claude/settings.json @@ -1,3 +1,14 @@ { - "autoMemoryDirectory": "~/claude-projects/robotunits/memory" + "autoMemoryDirectory": "~/claude-projects/robotunits/memory", + "permissions": { + "allow": [ + "Edit(~/projects/geko-core/**)", + "Edit(~/projects/adesso-cpq/**)", + "Edit(~/claude-projects/robotunits/**)" + ], + "additionalDirectories": [ + "~/projects/geko-core", + "~/projects/adesso-cpq" + ] + } } diff --git a/robotunits/.claude/settings.local.json b/robotunits/.claude/settings.local.json index 0a68b8b..8b311a3 100644 --- a/robotunits/.claude/settings.local.json +++ b/robotunits/.claude/settings.local.json @@ -1,13 +1,5 @@ { "permissions": { - "allow": [ - "Bash(xargs -I {} find {} -type f \\\\\\( -name \"*.ts\" -o -name \"*.tsx\" -o -name \"*.js\" -o -name \"*.vue\" \\\\\\))", - "Bash(xargs cat)", - "Bash(xargs ls -la)", - "Bash(xargs -I {} sh -c 'echo \"=== {} ===\" && cat {}')", - "Bash(xargs -I {} bash -c 'echo \"=== {} ===\" && cat {}')", - "Bash(xargs ls -lh)", - "Bash(PATH=/home/marcuh/git/adesso-cpq/packages/blast/node_modules/.bin:__TRACKED_VAR__ tsup)" - ] + "allow": [] } } diff --git a/wittgenstein/.claude/settings.json b/wittgenstein/.claude/settings.json index 3ba0111..7a8880b 100644 --- a/wittgenstein/.claude/settings.json +++ b/wittgenstein/.claude/settings.json @@ -1,15 +1,11 @@ { "permissions": { "allow": [ - "Edit(/Users/marcush/projects/wittgenstein/**)", - "Edit(/Users/marcush/claude-projects/**)", - "Bash(git add:*)", - "Bash(git commit:*)", - "Bash(git push:*)", - "Bash(git pull:*)", - "Bash(git status:*)", - "Bash(git diff:*)", - "Bash(git -C:*)" + "Edit(~/projects/wittgenstein/**)", + "Edit(~/claude-projects/wittgenstein/**)" + ], + "additionalDirectories": [ + "~/projects/wittgenstein" ] }, "autoMemoryDirectory": "~/claude-projects/wittgenstein/memory" diff --git a/wittgenstein/.claude/settings.local.json b/wittgenstein/.claude/settings.local.json index 73a400e..8b311a3 100644 --- a/wittgenstein/.claude/settings.local.json +++ b/wittgenstein/.claude/settings.local.json @@ -1,11 +1,5 @@ { "permissions": { - "allow": [ - "mcp__outline__list_collections", - "mcp__outline__update_document", - "mcp__outline__create_document", - "mcp__outline__list_documents", - "mcp__outline__move_document" - ] + "allow": [] } } diff --git a/wuerth-plato/.claude/settings.json b/wuerth-plato/.claude/settings.json index f0db78a..e7b68f0 100644 --- a/wuerth-plato/.claude/settings.json +++ b/wuerth-plato/.claude/settings.json @@ -1,6 +1,11 @@ { "autoMemoryDirectory": "~/claude-projects/wuerth-plato/memory", "permissions": { + "allow": [ + "Edit(~/projects/fahrzeugeinrichtung-plato-backend/**)", + "Edit(~/projects/fahrzeugeinrichtung-plato-gitops/**)", + "Edit(~/claude-projects/wuerth-plato/**)" + ], "additionalDirectories": [ "~/projects/fahrzeugeinrichtung-plato-backend", "~/projects/fahrzeugeinrichtung-plato-gitops" diff --git a/wuerth-plato/.claude/settings.local.json b/wuerth-plato/.claude/settings.local.json new file mode 100644 index 0000000..8f33470 --- /dev/null +++ b/wuerth-plato/.claude/settings.local.json @@ -0,0 +1,38 @@ +{ + "permissions": { + "allow": [ + "Bash(npx nx *)", + "Bash(lsof -ti:3000)", + "Bash(xargs -r kill)", + "Bash(tee /tmp/plato-be.log)", + "Bash(python3 -)", + "Bash(npx tsc *)", + "Skill(code-review)", + "Bash(podman:*)", + "Bash(oc get:*)", + "Bash(oc describe:*)", + "Bash(oc status:*)", + "Bash(oc logs:*)", + "Bash(oc top:*)", + "Bash(oc project:*)", + "Bash(oc projects:*)", + "Bash(oc whoami:*)", + "Bash(oc version:*)", + "Bash(oc api-resources:*)", + "Bash(oc explain:*)" + ], + "ask": [ + "Bash(podman system reset:*)", + "Bash(podman system prune:*)", + "Bash(podman volume rm:*)", + "Bash(podman volume prune:*)", + "Bash(podman machine rm:*)", + "Bash(podman machine reset:*)" + ], + "deny": [ + "Bash(oc adm:*)", + "Bash(oc delete project:*)", + "Bash(oc delete namespace:*)" + ] + } +} diff --git a/wuerth-plato/CLAUDE.md b/wuerth-plato/CLAUDE.md new file mode 100644 index 0000000..f23051a --- /dev/null +++ b/wuerth-plato/CLAUDE.md @@ -0,0 +1,7 @@ +# CLAUDE.md + +This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. + +1. Dieses Modul ist Teil eines MonoRepos, das verschiedene — überwiegend Development- — Projekte bündelt. +2. Die eigentlichen Source- oder Ressource-Repos sind in der `settings.json` hinterlegt. +3. SAP-Zugriff (Basic Auth, Endpoint, Env→Secret/Overlay-Mapping): siehe `memory/sap-config.md`. diff --git a/wuerth-plato/memory/feedback_ort_zuerst.md b/wuerth-plato/memory/feedback_ort_zuerst.md new file mode 100644 index 0000000..57e108a --- /dev/null +++ b/wuerth-plato/memory/feedback_ort_zuerst.md @@ -0,0 +1,19 @@ +--- +name: feedback_ort_zuerst +description: "Bei \"wo mache ich X?\"-Fragen sofort die konkrete UI-Stelle nennen, nicht durch Menüs jagen" +metadata: + node_type: memory + type: feedback + originSessionId: 03691a44-b7eb-4d9d-9e7c-5d5aae84e110 +--- + +Marcus fragt bei UI/Tooling oft konkret "WO geht das?". Dann will er **die eine konkrete Stelle**, nicht eine Schritt-für-Schritt-Tour durch das Tool oder Vorbedingungen vorweg. + +**Why:** Lange Navigationsanleitungen ("erst Actions, dann Run, dann Banner...") bei einer simplen Ortsfrage haben ihn massiv genervt ("RED DEUTSCH", "durch das komplette GitHub gejagt"). Kostet Zeit und Nerven. + +**How to apply:** +- Ortsfrage → direkt der Ziel-Ort + der Knopf, in einem Satz. Z. B. "PR → Files changed → Review changes → Approve". +- Relevante Einschränkung in einem Halbsatz dazu (z. B. "eigenen PR kann man nicht approven"), aber nicht als Vorrede davorstellen. +- Keine "erst dies, dann das"-Ketten, wenn eine Stelle reicht. + +**Zweiter Fehler im selben Vorgang:** Ich behauptete früh "Review Required ist fürs Deployen ignorierbar". Falsch — der witglobal `deploy-branch`-Workflow prüft `reviewDecision` und bricht mit `REVIEW_REQUIRED` ab, solange der PR nicht approved ist. Lehre: bei Aussagen über fremde Workflows erst den reusable workflow lesen, nicht aus dem Muster raten. Siehe [[feedback_evidence_first]]. diff --git a/wuerth-plato/memory/project_prod_ist_stand.md b/wuerth-plato/memory/project_prod_ist_stand.md new file mode 100644 index 0000000..c08cdc7 --- /dev/null +++ b/wuerth-plato/memory/project_prod_ist_stand.md @@ -0,0 +1,35 @@ +--- +name: project_prod_ist_stand +description: Prod (ocp-01 / 1401-plato-production) — Secrets (inkl. SAP) erledigt+aktiviert; einziger Blocker noch das to_be_replaced Image-Tag +metadata: + node_type: memory + type: project + originSessionId: 03691a44-b7eb-4d9d-9e7c-5d5aae84e110 +--- + +Stand 2026-06-19, verifiziert direkt am Prod-Cluster (`api.ocp-01.wgn.wuerth.com`, Projekt `1401-plato-production`). + +**Stand 2026-06-19 abends: Prod ist LIVE und voll erreichbar** — backend `0.38.4` 1/1 Running auf ocp-01, alle 3 Secrets (customer/postgres/sap) gemountet, ghcr-Pull funktioniert. Öffentliche URL **https://plato.witglobal.net** (Test: https://plato-test.witglobal.net auf ocp-dev01), zusätzlich zur alten fahrzeugeinrichtung-Route. OIDC-Login funktioniert. + +**Custom-Routes + OIDC:** Routes als `route-public.yaml` je Overlay im gitops-Repo (commit `11ba61c`), edge/Redirect, host `plato.witglobal.net` bzw. `plato-test.witglobal.net` → backend-service:3000. Redirect-URI baut die App aus `req.headers.host` + fixem Pfad `/oauth/callback` (oidc.controller.ts `computeRedirectUri`). Beim IdP (PingFederate, strict byte-match, kein Trailing-Slash) **pro client_id** registriert: `https://plato.witglobal.net/oauth/callback` an `KONZ-PlaTo-Customer-PROD`, `https://plato-test.witglobal.net/oauth/callback` an `KONZ-PlaTo-Customer-DEV`. Kein Post-Logout-Redirect nötig. + +PR `development → main` gemergt — `main` spiegelt den Prod-Stand. Go-live abgeschlossen. + +Reihenfolge der Blocker, die fielen: (1) Secrets gesealt+aktiviert; (2) Dockerfile-Build-Bruch `crm.sqlite` raus → Image 0.38.4; (3) PR-Review REVIEW_REQUIRED approved; (4) **Namespace-Quota voll** (totes Frontend-Orphan-Deployment fraß 1 CPU/4Gi) → Frontend-Deployment/Service/Route gelöscht (war alter Split-Ansatz, Backend serviert FE-Assets selbst) → `oc rollout restart` → Pod startet. + +**Quota-Warnung für später:** `default-resource-quotas` = 3 CPU / 12Gi hart. backend(1)+postgres(1) = 2, lässt nur 1 Slot Surge. Sobald ein zweiter Workload dazukommt (oder Rolling Update mit maxSurge), reicht es nicht → Quota anheben (Plattform) oder maxSurge=0. + +**Historischer Ausgangsbefund (vor heute):** + +1. **Image-Tag nie ersetzt** (offen). backend-/frontend-Pods ziehen wörtlich `…/backend:to_be_replaced` → ImagePullBackOff (Deployment 198d, 0/1). Der `.deploy to production`-Workflow (PR `development→main`, Kommentar `.deploy to production`) ist **nie gelaufen**. Das ist der gewählte Weg A, um es zu lösen — bringt echten Tag + klärt zugleich den offenen ghcr-Pull-Recht-Punkt auf Prod. + +2. **Secrets — ERLEDIGT.** Alle drei SealedSecrets gegen ocp-01 gesealt, Entsiegelung auf Prod verifiziert (Synced=True), in `production/kustomization.yaml` aktiviert + in `backend.yaml` per `envFrom` referenziert: + - `plato-customer-secrets`, `plato-postgres-secrets` (commit `1ba047e`) + - `plato-sap-secrets` (commit `4601ea7`): SAP MUSS auf Prod (zentral). Werte = dieselben wie dev; dev-Klartext vom dev-Cluster gelesen, gegen ocp-01 neu gesealt. `SAP_URL` = dev-Endpoint `odatang9.wgn.wuerth.com/...` (User-Ansage „dieselben Werte"). Sealing-Rezept: `kubeseal --fetch-cert` geht auf Prod per Default-Pfad; dev-Secret per `oc --context= get secret -o json` → jq auf prod-ns umschreiben → `kubeseal --cert`. + - Beide gitops-Commits noch nicht gepusht (ahead 2; Push macht Marcus). Inhaltliche Werte-Korrektheit (richtige Prod-Creds?) erst sichtbar, wenn Backend hochkommt. + +**Sauber/fertig auf Prod:** Namespace-Label `argocd.argoproj.io/managed-by=issp-gitops-developers` gesetzt, ArgoCD-App existiert und syncht. Plattformseite steht. + +**Noch offen / nicht testbar:** ghcr-Pull-Berechtigung auf Prod (Pull via `default-dockercfg`, kein explizites `imagePullSecrets`) — scheitert aktuell am nicht-existenten Tag, nicht erkennbar an Auth. Zeigt sich erst mit echtem Tag. Außerdem: SAP-Secret fehlt für Prod komplett (dev hat `plato-sap-secrets.sealed.yaml`, prod nicht; `production/backend.yaml` referenziert SAP auch nicht). + +Deploy-Mechanik siehe PDF `ressources/GitHub CICD to OpenShift.pdf`: Image nur auf `development` gebaut + wiederverwendet, Prod via PR-Kommentar `.deploy to production`, Prod-ArgoCD vermutlich `autoSync: false` → manueller Sync. Dev-Cluster = ocp-dev01 läuft sauber (backend 0.38.1).