MBO-Tech-IT-Webseite/docs/superpowers/specs/2026-05-12-module-supabase-...

7.1 KiB

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

npm install nodemailer @types/nodemailer
npm install bcryptjs @types/bcryptjs
# @supabase/supabase-js + @supabase/ssr bereits vorhanden

Schritt 6: Env-Variablen ergänzen

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:

INSERT INTO admin_users (email, password_hash, name)
VALUES ('jonny@mbo-tech-it.de', '<bcrypt-hash>', 'Admin');

Schritt 8: Queue-Worker (instrumentation.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