200 lines
7.1 KiB
Markdown
200 lines
7.1 KiB
Markdown
# 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', '<bcrypt-hash>', '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
|