Files
RAPPORT-HOST/server/index.js
T
karim 13173dddc5 refactor: RAPPORT-HOST ist jetzt reines Backend
Das Frontend (Marketing + Login/Konto) ist in RAPPORT-WEBSITE umgezogen
(Hugo + Vanilla-JS). RAPPORT-HOST liefert dessen gebautes public/ statisch
aus und stellt /api bereit.

- server/index.js: serviert RAPPORT-WEBSITE/public + /api (eine Origin)
- server/env.js: websitePublicDir (WEBSITE_PUBLIC_DIR, Default Schwester-Repo);
  PUBLIC_BASE_URL Default auf einheitliche Origin :8787
- billing.js: Checkout-Redirects auf /konto/ bzw. /hosting-preise/
- entfernt: src/ (React), marketing/ (Hugo-Kopie), index.html, vite.config.js
- package.json: nur noch server/migrate/build:website-Scripts

E2E verifiziert: /, /hosting/, /login/, /konto/, /js + Font = 200;
register→checkout(mock)→Instanz; Redirect → /konto/?provisioned=1.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-05-30 16:41:09 +02:00

54 lines
2.5 KiB
JavaScript

// RAPPORT-HOST Backend-Entry.
import express from "express";
import path from "node:path";
import { fileURLToPath } from "node:url";
import { env } from "./env.js";
import { authRouter } from "./routes/auth.js";
import { billingRouter } from "./routes/billing.js";
import { accountRouter } from "./routes/account.js";
const __dirname = path.dirname(fileURLToPath(import.meta.url));
const app = express();
// WICHTIG: Der Stripe-Webhook braucht den ROHEN Body für die Signaturprüfung.
// express.raw greift nur für diese Route und setzt req._body, sodass das danach
// registrierte express.json() den Webhook-Body NICHT erneut parst.
app.use("/api/billing/webhook", express.raw({ type: "application/json" }));
app.use(express.json());
app.get("/api/health", (_req, res) => res.json({ ok: true, service: "rapport-host" }));
app.use("/api/auth", authRouter);
app.use("/api/billing", billingRouter);
app.use("/api/account", accountRouter);
// ── Statische Auslieferung der RAPPORT-WEBSITE (Hugo-Build) ──────────────────
// Die komplette Frontend-Oberfläche (Marketing + Hosting + Login/Konto als
// Vanilla-JS-Seiten) kommt aus dem AGPL-Repo RAPPORT-WEBSITE. Dieses Backend
// liefert dessen gebautes public/ aus und stellt darunter /api bereit.
// Saubere Trennung: die Website enthält keinen Backend-Code, nur fetch('/api').
// Pfad per WEBSITE_PUBLIC_DIR überschreibbar (Default: Schwester-Repo).
const websitePublic = env.websitePublicDir;
app.use(express.static(websitePublic));
app.get("*", (req, res, next) => {
if (req.path.startsWith("/api/")) return next();
// Hugo erzeugt pro Seite eine eigene index.html → Clean-URLs funktionieren
// direkt über express.static. Unbekannte Pfade → 404-Seite.
res.status(404).sendFile(path.join(websitePublic, "404.html"), (err) => err && next());
});
// Express-Fehlerhandler: fängt synchron geworfene Fehler aus Routen → 500
// statt stiller Empty-Reply.
app.use((err, _req, res, _next) => {
console.error("Unbehandelter Routen-Fehler:", err);
if (!res.headersSent) res.status(500).json({ error: "Interner Fehler." });
});
// Letzte Verteidigungslinie: ein einzelner async-Fehler darf den Prozess nicht
// killen (im Dev-Test sonst "connection refused" für alle Folge-Requests).
process.on("unhandledRejection", (reason) => console.error("unhandledRejection:", reason));
app.listen(env.port, () => {
console.log(`RAPPORT-HOST API läuft auf :${env.port} (Base: ${env.publicBaseUrl})`);
});