GET /admin/export/accounts.csv — eine Zeile pro Kunde (Profil + aktuelles
Abo + Plan-Preis + Instanzen). Semikolon-getrennt, UTF-8 BOM (Excel-CH),
Content-Disposition mit Datum. Nur mit Admin-Token (401 sonst).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Die Edits im Admin-Commit (6a23933) hatten nicht gegriffen — register/login
gaben is_admin nicht zurück (war undefined). Jetzt: returning …, is_admin +
ensureAdminFlag bei beiden. E2E verifiziert: Admin-Promotion=true, Kunde→403,
Stats korrekt (2 Kunden/MRR 49).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
studio-adapter ruft jetzt den neuen service_role-RPC (APP 0011): Auth-User
anlegen (oder bei 422 bestehenden holen) → create_studio_for_user → Instanz-URL.
MOCK-Modus bleibt für lokalen Test ohne Rapport-Stack.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Ursache des ungestylten Hosting-Frontends war ein veraltetes public/:
der Build überschrieb fingerprinted CSS nicht, sodass die neuen .hosting-*
Klassen nie ausgeliefert wurden. Clean-Build verhindert das. (Auch doppelte
build:website-Zeile entfernt.)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
git rm im vorigen Commit brach am fehlenden marketing/ ab, daher waren die
React-Dateien noch im Repo. RAPPORT-HOST ist jetzt wirklich reines Backend.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Echte Design-Tokens aus dem openbureau-Stylesheet übernommen:
- weißer Grund (#fff), warme Off-Whites (#fafafa/#fff8f0)
- near-black Text (#1a1a1a), warmes Braun als Akzent (#b07848)
- System-Font-Stack (-apple-system…) + SF Mono, Brand Krungthep
- Hero-CTA in Akzent-Braun, dunkle Sekundär-Buttons
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- env.js: '…CHANGE-ME'-Platzhalter aus .env.example zählen als NICHT gesetzt.
Vorher galt sk_test_CHANGE-ME als echter Stripe-Key → echter API-Call mit
ungültigem Key → 401 → unhandledRejection → Server-Crash.
- billing.js: /checkout in try/catch → 502 statt Empty-Reply/Crash.
- index.js: globaler Express-Error-Handler + unhandledRejection-Guard, damit
ein einzelner async-Fehler nie den ganzen Prozess killt.
E2E verifiziert (Mock): register→checkout→instance, idempotent (1 sub/1 inst),
401 bei falschem PW, Server lebt nach allen Requests.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>