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_usersTabelle (für Admin-Auth, Tabellenname abweichend von Template:admin_usersstattbenutzer)email_queueTabelle (Modul 01)anfragenTabelle (Modul 06-Kunden)
Schritt 2: Supabase-Typen ergänzen (lib/supabase.ts)
CMS-Tabellentypen hinzufügen:
hero_content,hero_badgesueber_uns_content,ueber_uns_statsgalerie_bilderkontakt_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, badgesapp/api/admin/hero/badges/[id]/route.ts(Ordner umbenennen:id/→[id]/)app/api/admin/galerie/route.ts+ sortapp/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.tsxapp/admin/galerie/page.tsxapp/admin/ueber-uns/page.tsxapp/admin/kontakt/page.tsxapp/admin/passwort/page.tsx
Komponenten:
components/GalerieAnzeige.tsxcomponents/admin/HeroVerwaltung.tsxcomponents/admin/GalerieVerwaltung.tsxcomponents/admin/UeberUnsVerwaltung.tsxcomponents/admin/KontaktVerwaltung.tsxcomponents/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-bildersite-assetsueber-uns-bildergalerie-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 definiertto_addr,text,attempts,max_attempts,last_error. Der tatsächliche Code (lib/email-queue.ts+lib/supabase.ts) verwendetmail_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_usersstattbenutzer: Tabelle heißtadmin_users, Spalten:id, email, name, password_hash, aktiv, created_at. -
KPI-Dashboard ohne
anfragen_positionen:app/api/admin/statistik/route.tsist bereits ans Projekt angepasst und fragt nuranfragenab (keineanfragen_positionenwie im generischen Template). -
lib/supabase.tsnutztSUPABASE_URL(nichtNEXT_PUBLIC_SUPABASE_URL) für den Service Client — korrekt so. -
CMS-API-Routen: Sollen
SUPABASE_INTERNAL_URLfü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