diff --git a/docs/superpowers/specs/2026-05-12-module-supabase-integration-design.md b/docs/superpowers/specs/2026-05-12-module-supabase-integration-design.md new file mode 100644 index 0000000..d7d0dd4 --- /dev/null +++ b/docs/superpowers/specs/2026-05-12-module-supabase-integration-design.md @@ -0,0 +1,199 @@ +# Design: Modul-Integration & Supabase-Anbindung + +**Datum:** 2026-05-12 +**Projekt:** MBO-Tech-IT Website (Next.js 15) +**Supabase:** Self-hosted, Docker VM unter `supabase.mbo-tech-it.de` + +--- + +## Ausgangssituation + +Die Module 01 (E-Mail), 02 (Admin-Auth), 03 (Analytics), 06-Kunden-Portal und 07-KPI-Dashboard haben ihre Code-Dateien bereits im Projekt. Modul 06-Website-CMS fehlt noch vollständig. Supabase läuft im Docker-Container, aber DB-Migrationen, Storage Buckets und Auth-Konfiguration fehlen noch. Die Supabase-Keys sind bereits in `.env.local` eingetragen. + +--- + +## Ziel + +Alle 6 Module vollständig einbinden: Datenbank-Tabellen anlegen, CMS-Code integrieren, öffentliche Website-Sektionen (Hero, Über uns, Galerie, Kontakt) aus der Datenbank laden, Storage Buckets und Auth konfigurieren. + +--- + +## Architektur + +``` +mbo-tech-it.de (Next.js 15 App Router) +│ +├── Öffentliche Seiten ← Hero, Über uns, Galerie, Kontakt aus Supabase DB +├── /admin/* ← CMS + Analytics + Statistik (HMAC-Auth) +└── /kunden/* ← Kunden-Portal (Supabase Auth) + +supabase.mbo-tech-it.de (Docker VM) +├── 13 DB-Tabellen +├── 4 Public Storage Buckets +└── Supabase Auth (Kunden-Portal) +``` + +--- + +## Umsetzungsplan (Option A — Modul für Modul) + +### Schritt 1: DB-Migrationen + +Alle SQL-Dateien nacheinander im Supabase SQL-Editor ausführen: + +| Migration | Erstellt | +|---|---| +| `modules/02-admin-auth/migrations/MIGRATIONS_AUDIT_LOGS.sql` | `admin_audit_logs` | +| `modules/02-admin-auth/migrations/MIGRATIONS_TOKEN_BLACKLIST.sql` | `admin_session_blacklist`, `action_token_blacklist` | +| `modules/03-analytics/migrations/MIGRATIONS_PAGE_VIEWS.sql` | `page_views` | +| `modules/03-analytics/migrations/MIGRATIONS_PHONE_CLICKS.sql` | `phone_clicks` | +| `modules/06-website-cms/migrations/MIGRATIONS_WEBSITE_CMS.sql` | 8 CMS-Tabellen | + +Zusätzlich manuell: +- `admin_users` Tabelle (für Admin-Auth, Tabellenname abweichend von Template: `admin_users` statt `benutzer`) +- `email_queue` Tabelle (Modul 01) +- `anfragen` Tabelle (Modul 06-Kunden) + +### Schritt 2: Supabase-Typen ergänzen (`lib/supabase.ts`) + +CMS-Tabellentypen hinzufügen: +- `hero_content`, `hero_badges` +- `ueber_uns_content`, `ueber_uns_stats` +- `galerie_bilder` +- `kontakt_info`, `kontakt_oeffnungszeiten`, `kontakt_social` + +### Schritt 3: Modul 06-Website-CMS Code integrieren + +**Neue Dateien kopieren** aus `modules/06-website-cms/files/`: + +API-Routen: +- `app/api/admin/hero/route.ts` + bild, logo, favicon, badges +- `app/api/admin/hero/badges/[id]/route.ts` (Ordner umbenennen: `id/` → `[id]/`) +- `app/api/admin/galerie/route.ts` + sort +- `app/api/admin/ueber-uns/route.ts` + upload, stats, stats/[id] +- `app/api/admin/kontakt/route.ts` + oeffnungszeiten/[id], social/[id] +- `app/api/admin/passwort/route.ts` + +Admin-Seiten: +- `app/admin/hero/page.tsx` +- `app/admin/galerie/page.tsx` +- `app/admin/ueber-uns/page.tsx` +- `app/admin/kontakt/page.tsx` +- `app/admin/passwort/page.tsx` + +Komponenten: +- `components/GalerieAnzeige.tsx` +- `components/admin/HeroVerwaltung.tsx` +- `components/admin/GalerieVerwaltung.tsx` +- `components/admin/UeberUnsVerwaltung.tsx` +- `components/admin/KontaktVerwaltung.tsx` +- `components/admin/PasswortAendern.tsx` + +**Hinweis:** `SUPABASE_INTERNAL_URL` muss in den CMS-API-Routen für Docker-internen Zugriff verwendet werden. + +### Schritt 4: Öffentliche Seiten dynamisieren + +**`app/page.tsx`** wird zu einer async Server Component, die alle CMS-Daten lädt und als Props weitergibt. + +**Komponenten erhalten Props statt hardcodierter Werte:** + +| Komponente | Datenquelle | +|---|---| +| `components/Hero.tsx` | `hero_content` + `hero_badges` aus Supabase | +| `components/About.tsx` | `ueber_uns_content` + `ueber_uns_stats` | +| `components/Contact.tsx` | `kontakt_info` + `kontakt_oeffnungszeiten` + `kontakt_social` | +| `components/GalerieAnzeige.tsx` | `galerie_bilder` (neue Komponente) | + +**Fallback-Strategie:** Jede Sektion nutzt `try/catch`. Bei DB-Fehler greift ein hardcodierter Fallback, die Seite bleibt immer aufrufbar. + +**`app/layout.tsx`:** `PageTracker` von Analytics einbinden. + +**`components/admin/AdminNav.tsx`:** Links zu `/admin/hero`, `/admin/ueber-uns`, `/admin/galerie`, `/admin/kontakt`, `/admin/passwort` ergänzen. + +### Schritt 5: npm-Pakete prüfen + +```bash +npm install nodemailer @types/nodemailer +npm install bcryptjs @types/bcryptjs +# @supabase/supabase-js + @supabase/ssr bereits vorhanden +``` + +### Schritt 6: Env-Variablen ergänzen + +```env +SUPABASE_INTERNAL_URL=http://supabase-kong:8000 +# SMTP-Felder ausfüllen (SMTP_HOST, SMTP_USER, SMTP_PASS) +``` + +### Schritt 7: Infrastructure (manuell im Supabase-Dashboard) + +**Storage Buckets anlegen (alle Public):** +- `hero-bilder` +- `site-assets` +- `ueber-uns-bilder` +- `galerie-bilder` + +**Auth konfigurieren:** +- Site URL: `https://mbo-tech-it.de` +- Redirect URL: `https://mbo-tech-it.de/auth/callback` +- E-Mail-Bestätigung aktivieren + +**Ersten Admin-User anlegen:** +```sql +INSERT INTO admin_users (email, password_hash, name) +VALUES ('jonny@mbo-tech-it.de', '', 'Admin'); +``` + +### Schritt 8: Queue-Worker (instrumentation.ts) + +```ts +import { startEmailQueueWorker } from "@/lib/email-queue"; +export async function register() { + if (process.env.NEXT_RUNTIME === "nodejs") startEmailQueueWorker(); +} +``` + +--- + +## Datenbank-Schema (13 Tabellen) + +| Tabelle | Modul | Typ | +|---|---|---| +| `email_queue` | 01 | Queue | +| `admin_users` | 02 | Singleton-Liste | +| `admin_audit_logs` | 02 | Protokoll | +| `admin_session_blacklist` | 02 | Blacklist | +| `action_token_blacklist` | 02 | Blacklist | +| `page_views` | 03 | Tracking | +| `phone_clicks` | 03 | Tracking | +| `anfragen` | 06-Kunden | CRUD | +| `hero_content` | 06-CMS | Singleton | +| `hero_badges` | 06-CMS | Liste | +| `ueber_uns_content` | 06-CMS | Singleton | +| `ueber_uns_stats` | 06-CMS | Liste | +| `galerie_bilder` | 06-CMS | Liste | +| `kontakt_info` | 06-CMS | Singleton | +| `kontakt_oeffnungszeiten` | 06-CMS | Liste | +| `kontakt_social` | 06-CMS | Liste | + +--- + +## Wichtige Abweichungen von den Modul-Templates + +- **`email_queue` — andere Spaltennamen:** Das Modul-Template definiert `to_addr`, `text`, `attempts`, `max_attempts`, `last_error`. Der tatsächliche Code (`lib/email-queue.ts` + `lib/supabase.ts`) verwendet `mail_from`, `mail_to`, `reply_to`, `body_text`, `retry_count`, `error_last`. Die DB-Migration muss die Spaltennamen aus dem Code verwenden, **nicht** aus dem Template. + +- **`admin_users` statt `benutzer`:** Tabelle heißt `admin_users`, Spalten: `id, email, name, password_hash, aktiv, created_at`. + +- **KPI-Dashboard ohne `anfragen_positionen`:** `app/api/admin/statistik/route.ts` ist bereits ans Projekt angepasst und fragt nur `anfragen` ab (keine `anfragen_positionen` wie im generischen Template). + +- **`lib/supabase.ts` nutzt `SUPABASE_URL`** (nicht `NEXT_PUBLIC_SUPABASE_URL`) für den Service Client — korrekt so. + +- **CMS-API-Routen:** Sollen `SUPABASE_INTERNAL_URL` für Docker-internen Zugriff verwenden. + +--- + +## Nicht im Scope + +- Docker-Compose-Konfiguration für Supabase (läuft bereits) +- Modul 04 (Reservierungssystem) — nicht vorhanden; KPI-Dashboard und Kunden-Portal sind bereits ohne es angepasst +- CI/CD-Pipeline