diff --git a/.claude/CLAUDE.md b/.claude/CLAUDE.md index b66a21c..0e23616 100644 --- a/.claude/CLAUDE.md +++ b/.claude/CLAUDE.md @@ -2,29 +2,29 @@ ## Entwicklungsumgebung (WICHTIG - IMMER ZUERST LESEN) -### Zwei-Rechner-Setup + Coolify +### Zwei-Rechner-Setup + Orca | Geraet | Rolle | Aufgaben | |--------|-------|----------| | **MacBook** | Entwicklung | Claude Terminal, Code-Entwicklung, Browser (Frontend-Tests) | | **Mac Mini** | Lokaler Server | Docker fuer lokale Dev/Tests (NICHT fuer Production!) | -| **Coolify** | Production | Automatisches Build + Deploy bei Push auf gitea | +| **Orca** | Production | Automatisches Build + Deploy bei Push auf gitea | -**WICHTIG:** Code wird direkt auf dem MacBook in diesem Repo bearbeitet. Production-Deployment laeuft automatisch ueber Coolify. +**WICHTIG:** Code wird direkt auf dem MacBook in diesem Repo bearbeitet. Production-Deployment laeuft automatisch ueber Orca. -### Entwicklungsworkflow (CI/CD — Coolify) +### Entwicklungsworkflow (CI/CD — Orca) ```bash # 1. Code auf MacBook bearbeiten (dieses Verzeichnis) # 2. Committen und zu BEIDEN Remotes pushen: -git push origin main && git push gitea main +git push origin main # 3. FERTIG! Push auf gitea triggert automatisch: # - Gitea Actions: Tests -# - Coolify: Build → Deploy +# - Orca: Build → Deploy ``` -**NIEMALS** manuell in Coolify auf "Redeploy" klicken — Gitea Actions triggert Coolify automatisch. +**NIEMALS** manuell in Orca auf "Redeploy" klicken — Gitea Actions triggert Orca automatisch. **IMMER auf `main` pushen** — sowohl origin als auch gitea. ### Post-Push Deploy-Monitoring (PFLICHT nach jedem Push auf gitea) @@ -39,7 +39,7 @@ git push origin main && git push gitea main ``` 3. Sobald ALLE Endpoints healthy sind, dem User im Chat melden: **"Deploy abgeschlossen! Du kannst jetzt testen."** -4. Falls nach 5 Minuten noch nicht healthy → Fehlermeldung mit Hinweis auf Coolify-Logs. +4. Falls nach 5 Minuten noch nicht healthy → Fehlermeldung mit Hinweis auf Orca-Logs. ### Lokale Entwicklung (Mac Mini — optional, nur Dev/Tests) @@ -80,8 +80,8 @@ networks: | Repo | Deployment | Trigger | |------|-----------|---------| -| **breakpilot-core** | Coolify (automatisch) | Push auf gitea main | -| **breakpilot-compliance** | Coolify (automatisch) | Push auf gitea main | +| **breakpilot-core** | Orca (automatisch) | Push auf gitea main | +| **breakpilot-compliance** | Orca (automatisch) | Push auf gitea main | | **breakpilot-lehrer** | Mac Mini (lokal) | Manuell docker compose | --- @@ -252,8 +252,8 @@ ssh macmini "/usr/local/bin/docker logs -f bp-core-control-pipeline" ### Deployment (CI/CD — Standardweg) ```bash -# Committen und pushen → Coolify deployt automatisch: -git push origin main && git push gitea main +# Committen und pushen → Orca deployt automatisch: +git push origin main ``` ### Lokale Docker-Befehle (Mac Mini — nur Dev/Tests) @@ -278,11 +278,11 @@ ssh macmini "/usr/local/bin/docker ps --filter name=bp-core" ```bash # Zu BEIDEN Remotes pushen (PFLICHT!): -git push origin main && git push gitea main +git push origin main # Remotes: -# origin: lokale Gitea (macmini:3003) -# gitea: gitea.meghsakha.com + + ``` --- diff --git a/.claude/rules/pre-push-checks.md b/.claude/rules/pre-push-checks.md index 7c39592..708a3d0 100644 --- a/.claude/rules/pre-push-checks.md +++ b/.claude/rules/pre-push-checks.md @@ -58,7 +58,7 @@ Blocks on: type errors, lint violations, **build failures**. |-------|-------|------| | Pre-push (local) | Claude runs | Lint + type check + unit tests + build | | CI (Gitea Actions) | Automatic on push | Same + integration tests + contract tests | -| Deploy (Coolify) | Automatic after CI | Docker build + health check | +| Deploy (Orca) | Automatic after CI | Docker build + health check | Local checks catch 90% of CI failures in seconds. CI is the safety net, not the first line of defense. diff --git a/.gitea/workflows/build-pitch-deck.yml b/.gitea/workflows/build-pitch-deck.yml index 8e91ad3..6d2144b 100644 --- a/.gitea/workflows/build-pitch-deck.yml +++ b/.gitea/workflows/build-pitch-deck.yml @@ -35,6 +35,7 @@ jobs: cd pitch-deck SHORT_SHA=$(git rev-parse --short HEAD) docker build \ + --build-arg GIT_SHA=${SHORT_SHA} \ -t registry.meghsakha.com/breakpilot/pitch-deck:latest \ -t registry.meghsakha.com/breakpilot/pitch-deck:${SHORT_SHA} \ . diff --git a/docs-src/architecture/environments.md b/docs-src/architecture/environments.md index b5bb4d8..aa4f5fa 100644 --- a/docs-src/architecture/environments.md +++ b/docs-src/architecture/environments.md @@ -7,10 +7,10 @@ BreakPilot verwendet zwei Umgebungen: ``` ┌─────────────────┐ ┌─────────────────┐ │ Development │───── git push ────▶│ Production │ -│ (Mac Mini) │ │ (Coolify) │ +│ (Mac Mini) │ │ (Orca) │ └─────────────────┘ └─────────────────┘ Lokale Automatisch - Entwicklung via Coolify + Entwicklung via Orca ``` ## Umgebungen @@ -32,21 +32,21 @@ BreakPilot verwendet zwei Umgebungen: ssh macmini "cd ~/Projekte/breakpilot-core && /usr/local/bin/docker compose up -d" ``` -### Production (Coolify) +### Production (Orca) **Zweck:** Live-System | Eigenschaft | Wert | |-------------|------| | Git Branch | `main` | -| Deployment | Coolify (automatisch bei Push auf gitea) | +| Deployment | Orca (automatisch bei Push auf gitea) | | Database | Externe PostgreSQL (TLS) | | Debug | Deaktiviert | **Deploy:** ```bash git push origin main && git push gitea main -# Coolify baut und deployt automatisch +# Orca baut und deployt automatisch ``` ## Docker Compose Architektur @@ -54,10 +54,10 @@ git push origin main && git push gitea main ``` docker-compose.yml ← Basis-Konfiguration (lokal, arm64) │ - └── docker-compose.coolify.yml ← Production Override (amd64) + └── docker-compose.orca.yml ← Production Override (amd64) ``` -Coolify verwendet automatisch beide Compose-Files fuer den Production-Build. +Orca verwendet automatisch beide Compose-Files fuer den Production-Build. ## Secrets Management diff --git a/docs-src/development/ci-cd-pipeline.md b/docs-src/development/ci-cd-pipeline.md index 68f7073..83b1668 100644 --- a/docs-src/development/ci-cd-pipeline.md +++ b/docs-src/development/ci-cd-pipeline.md @@ -6,8 +6,8 @@ Uebersicht ueber den Deployment-Prozess fuer BreakPilot. | Repo | Deployment | Trigger | Compose File | |------|-----------|---------|--------------| -| **breakpilot-core** | Coolify (automatisch) | Push auf `coolify` Branch | `docker-compose.coolify.yml` | -| **breakpilot-compliance** | Coolify (automatisch) | Push auf `main` Branch | `docker-compose.yml` + `docker-compose.coolify.yml` | +| **breakpilot-core** | Orca (automatisch) | Push auf `orca` Branch | `docker-compose.orca.yml` | +| **breakpilot-compliance** | Orca (automatisch) | Push auf `main` Branch | `docker-compose.yml` + `docker-compose.orca.yml` | | **breakpilot-lehrer** | Mac Mini (lokal) | Manuell `docker compose` | `docker-compose.yml` | ## Deployment-Architektur @@ -16,7 +16,7 @@ Uebersicht ueber den Deployment-Prozess fuer BreakPilot. ┌─────────────────────────────────────────────────────────────────┐ │ Entwickler-MacBook │ │ │ -│ breakpilot-core/ → git push gitea coolify │ +│ breakpilot-core/ → git push gitea orca │ │ breakpilot-compliance/ → git push gitea main │ │ breakpilot-lehrer/ → git push + ssh macmini docker ... │ │ │ @@ -26,11 +26,11 @@ Uebersicht ueber den Deployment-Prozess fuer BreakPilot. │ │ ▼ ▼ ┌───────────────────────────┐ ┌───────────────────────────┐ -│ Coolify (Production) │ │ Mac Mini (Lokal/Dev) │ +│ Orca (Production) │ │ Mac Mini (Lokal/Dev) │ │ │ │ │ │ Gitea Actions │ │ breakpilot-lehrer │ │ ├── Tests │ │ ├── studio-v2 │ -│ └── Coolify API Deploy │ │ ├── klausur-service │ +│ └── Orca API Deploy │ │ ├── klausur-service │ │ │ │ ├── backend-lehrer │ │ Core Services: │ │ └── voice-service │ │ ├── consent-service │ │ │ @@ -47,23 +47,23 @@ Uebersicht ueber den Deployment-Prozess fuer BreakPilot. └───────────────────────────┘ └───────────────────────────┘ ``` -## breakpilot-core → Coolify +## breakpilot-core → Orca ### Pipeline ```yaml -# .gitea/workflows/deploy-coolify.yml +# .gitea/workflows/deploy-orca.yml on: push: - branches: [coolify] + branches: [orca] jobs: deploy: runs-on: ubuntu-latest steps: - - name: Deploy via Coolify API - # Triggert Coolify Build + Deploy ueber API - # Secrets: COOLIFY_API_TOKEN, COOLIFY_RESOURCE_UUID, COOLIFY_BASE_URL + - name: Deploy via Orca API + # Triggert Orca Build + Deploy ueber API + # Secrets: ORCA_API_TOKEN, ORCA_RESOURCE_UUID, ORCA_BASE_URL ``` ### Workflow @@ -74,13 +74,13 @@ jobs: git push origin main && git push gitea main # 3. Fuer Production-Deploy: -git push gitea coolify +git push gitea orca # 4. Status pruefen: # https://gitea.meghsakha.com/Benjamin_Boenisch/breakpilot-core/actions ``` -### Coolify-deployed Services +### Orca-deployed Services | Service | Container | Beschreibung | |---------|-----------|--------------| @@ -91,7 +91,7 @@ git push gitea coolify | paddleocr-service | bp-core-paddleocr | OCR Engine (x86_64) | | health-aggregator | bp-core-health | Health-Check Aggregator | -## breakpilot-compliance → Coolify +## breakpilot-compliance → Orca ### Pipeline @@ -111,7 +111,7 @@ jobs: ### Workflow ```bash -# Committen und pushen → Coolify deployt automatisch: +# Committen und pushen → Orca deployt automatisch: git push origin main && git push gitea main # CI-Status pruefen: @@ -154,8 +154,8 @@ Workflows liegen in jedem Repo unter `.gitea/workflows/`: | Repo | Workflow | Branch | Aktion | |------|----------|--------|--------| -| breakpilot-core | `deploy-coolify.yml` | `coolify` | Coolify API Deploy | -| breakpilot-compliance | `ci.yaml` | `main` | Tests + Coolify Deploy | +| breakpilot-core | `deploy-orca.yml` | `orca` | Orca API Deploy | +| breakpilot-compliance | `ci.yaml` | `main` | Tests + Orca Deploy | ### Runner-Token erneuern @@ -181,7 +181,7 @@ ssh macmini "/usr/local/bin/docker logs -f bp-core-gitea-runner" ## Health Checks -### Production (Coolify) +### Production (Orca) ```bash # Core PaddleOCR @@ -229,14 +229,14 @@ ssh macmini "docker compose build --no-cache " ## Rollback -### Coolify +### Orca Ein Redeploy mit einem aelteren Commit kann durch Zuruecksetzen des Branches ausgeloest werden: ```bash # Branch auf vorherigen Commit zuruecksetzen und pushen git reset --hard -git push gitea coolify --force +git push gitea orca --force ``` ### Lokal (Mac Mini) diff --git a/docs-src/index.md b/docs-src/index.md index 4d627c2..8dd3e0e 100644 --- a/docs-src/index.md +++ b/docs-src/index.md @@ -16,8 +16,8 @@ BreakPilot besteht aus drei unabhaengigen Projekten: | Repo | Deployment | Trigger | |------|-----------|---------| -| **breakpilot-core** | Coolify (automatisch) | Push auf gitea main | -| **breakpilot-compliance** | Coolify (automatisch) | Push auf gitea main | +| **breakpilot-core** | Orca (automatisch) | Push auf gitea main | +| **breakpilot-compliance** | Orca (automatisch) | Push auf gitea main | | **breakpilot-lehrer** | Mac Mini (lokal) | Manuell docker compose | ## Core Services diff --git a/pitch-deck/Dockerfile b/pitch-deck/Dockerfile index 05b22e0..3c986ae 100644 --- a/pitch-deck/Dockerfile +++ b/pitch-deck/Dockerfile @@ -12,6 +12,10 @@ RUN npm install # Copy source code COPY . . +# Embed git commit hash into build +ARG GIT_SHA=dev +ENV GIT_SHA=$GIT_SHA + # Build the application RUN npm run build diff --git a/pitch-deck/app/api/financial-model/compute/route.ts b/pitch-deck/app/api/financial-model/compute/route.ts index 4008acf..32055b4 100644 --- a/pitch-deck/app/api/financial-model/compute/route.ts +++ b/pitch-deck/app/api/financial-model/compute/route.ts @@ -6,7 +6,7 @@ import { finanzplanToFMResults } from '@/lib/finanzplan/adapter' export async function POST(request: NextRequest) { try { const body = await request.json() - const { scenarioId, source } = body + const { scenarioId, source, force } = body // If source=finanzplan, use the Finanzplan engine instead if (source === 'finanzplan') { @@ -28,8 +28,8 @@ export async function POST(request: NextRequest) { const client = await pool.connect() try { - // Fast path: return cached results if they exist (avoid expensive recompute + 60 inserts) - const cached = await client.query( + // Fast path: return cached results if they exist (skip when force=true) + const cached = force ? { rows: [] } : await client.query( 'SELECT * FROM pitch_fm_results WHERE scenario_id = $1 ORDER BY month', [scenarioId] ) diff --git a/pitch-deck/app/api/finanzplan/[sheetName]/route.ts b/pitch-deck/app/api/finanzplan/[sheetName]/route.ts index acf46c8..6a32155 100644 --- a/pitch-deck/app/api/finanzplan/[sheetName]/route.ts +++ b/pitch-deck/app/api/finanzplan/[sheetName]/route.ts @@ -39,7 +39,9 @@ export async function GET( query += ' ORDER BY sort_order' const { rows } = await pool.query(query, params) - return NextResponse.json({ sheet: sheetName, rows }) + return NextResponse.json({ sheet: sheetName, rows }, { + headers: { 'Cache-Control': 'no-store' }, + }) } catch (error) { return NextResponse.json({ error: String(error) }, { status: 500 }) } diff --git a/pitch-deck/app/api/finanzplan/route.ts b/pitch-deck/app/api/finanzplan/route.ts index 6788e9f..953e6c7 100644 --- a/pitch-deck/app/api/finanzplan/route.ts +++ b/pitch-deck/app/api/finanzplan/route.ts @@ -25,6 +25,8 @@ export async function GET() { sheets, scenarios: scenarios.rows, months: { start: '2026-01', end: '2030-12', count: 60, founding: '2026-08' }, + }, { + headers: { 'Cache-Control': 'no-store' }, }) } catch (error) { return NextResponse.json({ error: String(error) }, { status: 500 }) diff --git a/pitch-deck/app/pitch-admin/(authed)/financial-model/[scenarioId]/page.tsx b/pitch-deck/app/pitch-admin/(authed)/financial-model/[scenarioId]/page.tsx index b471286..264a493 100644 --- a/pitch-deck/app/pitch-admin/(authed)/financial-model/[scenarioId]/page.tsx +++ b/pitch-deck/app/pitch-admin/(authed)/financial-model/[scenarioId]/page.tsx @@ -3,7 +3,7 @@ import { useEffect, useState } from 'react' import { useParams } from 'next/navigation' import Link from 'next/link' -import { ArrowLeft, Save } from 'lucide-react' +import { ArrowLeft, RefreshCw, Save } from 'lucide-react' interface Assumption { id: string @@ -36,6 +36,7 @@ export default function EditScenarioPage() { const [loading, setLoading] = useState(true) const [edits, setEdits] = useState>({}) const [savingId, setSavingId] = useState(null) + const [recomputing, setRecomputing] = useState(false) const [toast, setToast] = useState(null) function flashToast(msg: string) { @@ -56,6 +57,17 @@ export default function EditScenarioPage() { useEffect(() => { if (scenarioId) load() }, [scenarioId]) + async function forceRecompute() { + setRecomputing(true) + const res = await fetch('/api/financial-model/compute', { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ scenarioId, force: true }), + }) + setRecomputing(false) + flashToast(res.ok ? 'Recomputed successfully' : 'Recompute failed') + } + function setEdit(id: string, val: string) { setEdits(prev => ({ ...prev, [id]: val })) } @@ -108,17 +120,28 @@ export default function EditScenarioPage() { Back to scenarios -
-
-
-

{scenario.name}

- {scenario.is_default && ( - - Default - - )} +
+
+
+
+

{scenario.name}

+ {scenario.is_default && ( + + Default + + )} +
+ {scenario.description &&

{scenario.description}

}
- {scenario.description &&

{scenario.description}

} +
diff --git a/pitch-deck/components/pitch-admin/AdminShell.tsx b/pitch-deck/components/pitch-admin/AdminShell.tsx index 7fa0eb1..fbe9f9d 100644 --- a/pitch-deck/components/pitch-admin/AdminShell.tsx +++ b/pitch-deck/components/pitch-admin/AdminShell.tsx @@ -92,6 +92,11 @@ export default function AdminShell({ admin, children }: AdminShellProps) {
{admin.name}
{admin.email}
+
+ + {process.env.NEXT_PUBLIC_GIT_SHA ?? 'dev'} + +