Initial commit: FL-Akademie LMS mit Docker, Admin, Portal und Dokumentation.

Made-with: Cursor
This commit is contained in:
lo
2026-04-13 23:17:07 +02:00
commit d3367f0046
66 changed files with 3641 additions and 0 deletions

108
docs/HANDBUCH.md Normal file
View File

@@ -0,0 +1,108 @@
# Handbuch FL-Akademie LMS
Technische und organisatorische Dokumentation des **implementierten Stands**. Ergänzt [PLAN.md](PLAN.md) (Vision & Roadmap).
---
## 1. Rollen (NextAuth + Prisma)
| Rolle (`Role`) | Zweck |
|----------------|--------|
| `LEARNER` | Standard-Lernende |
| `INSTRUCTOR` | vorbereitet für spätere Dozenten-Features |
| `ADMIN` | voller Zugriff auf `/admin` |
Die Rolle liegt im **JWT** und wird über `middleware.ts` für `/admin` geprüft. `/portal` ist für **alle angemeldeten** Nutzer.
---
## 2. Öffentliche Website
- **Startseite `/`:** Inhalte (Hero, CTAs, Vorteils-Kacheln) kommen aus der Tabelle **`LandingPage`** (`id = "default"`, Feld `content` als JSON). Fallback-Logik in `lib/landing.ts`, wenn keine oder ungültige Daten vorliegen.
- **Kurse:** Veröffentlichte Kurse (`published = true`), Einschreibung über API nur bei **Preis 0** (kostenpflichtige Kurse: Hinweis in UI, Zahlung noch nicht angebunden).
---
## 3. Mitgliederbereich (`/portal`)
- **Übersicht:** Eingeschriebene Kurse, Fortschrittsbalken (abgeschlossene vs. gesamte veröffentlichte Lektionen), Links zum Lernen, zum Kurrikulum, zum Zertifikat (falls vorhanden).
- **Kurs wiederholen:** Link startet wieder bei der ersten Lektion; optional **„Fortschritt zurücksetzen“** (löscht `LessonProgress` und ggf. `Certificate` für diesen Kurs).
- **Konto `/portal/account`:** Passwort ändern (`POST /api/portal/password` aktuelles Passwort prüfen, neues hashen mit bcrypt).
- **Zertifikate `/portal/certificates`:** Liste ausgestellter Urkunden mit Link zur öffentlichen Ansicht.
---
## 4. Administration (`/admin`)
Nur mit Rolle **`ADMIN`** erreichbar (sonst Redirect nach `/portal`).
| Route | Funktion |
|-------|----------|
| `/admin` | Übersicht mit Verweisen |
| `/admin/courses` | Alle Kurse (inkl. Entwürfe), Link „Neuer Kurs“ |
| `/admin/courses/new` | Neuanlage: Titel, Slug, Beschreibung, Autor-Name, Preis (EUR), Abo-Intervall, Veröffentlicht |
| `/admin/courses/[id]/edit` | Stammdaten bearbeiten; **Module** und **Lektionen** hinzufügen (Lektion: optionaler Slug, HTML-Inhalt) |
| `/admin/users` | Nutzerliste (ohne Passwort): E-Mail, Name, Rolle, Anzahl Einschreibungen & Zertifikate |
| `/admin/landing` | Startseiten-Texte und bis zu 6 Vorteils-Kacheln; **Speichern wirkt sofort** auf `/` |
---
## 5. Zertifikate (Certificate of completion)
- **Ausstellung:** Sobald ein Nutzer **alle veröffentlichten Lektionen** eines Kurses als abgeschlossen markiert hat, legt `lib/certificates.ts` (`syncCertificateForCourse`) einen **`Certificate`**-Datensatz mit eindeutigem **`code`** an (Format z.B. `FA-…`).
- **Widerruf:** Entfernen einzelner Lektions-Abschlüsse oder „Fortschritt zurücksetzen“ löscht das Zertifikat wieder, sobald der Kurs nicht mehr vollständig ist.
- **Öffentliche Seite:** `/zertifikat/[code]` Name, Kurstitel, Datum, Verifikationscode; Drucklayout blendet Kopf-/Fußzeile aus (`@media print` in `app/globals.css`).
Auslöser nach Abschluss: `POST /api/progress` ruft `syncCertificateForCourse` auf.
---
## 6. Datenmodell (Prisma)
Wesentliche Modelle:
- `User`, `Course`, `CourseModule`, `Lesson`, `Enrollment`, `LessonProgress`
- `Category`, `CourseCategory` (Seed / spätere Filter)
- **`LandingPage`** eine Zeile `default` für Startseiten-JSON
- **`Certificate`** `@@unique([userId, courseId])`, `code` global eindeutig
Migrationen unter `prisma/migrations/`.
---
## 7. Docker Compose
| Service | Beschreibung |
|---------|----------------|
| `db` | `postgres:16-alpine`, Volume `postgres_data` |
| `web` | Build aus `Dockerfile`, Entrypoint `scripts/docker-entrypoint.sh` |
Umgebungsvariablen im Compose u.a. `NEXT_TELEMETRY_DISABLED=1`.
**Befehle:**
```bash
docker compose up --build -d # im Hintergrund
docker compose logs -f web # Logs
docker compose down # stoppen
```
---
## 8. Sicherheitshinweise (Produktion)
- `NEXTAUTH_SECRET` und `NEXTAUTH_URL` korrekt setzen.
- Credentials-Login ist für Dev/MVP gedacht für Produktion OAuth oder stärkere Passwortrichtlinien erwägen.
- Admin-Oberfläche nicht ohne Absicherung (TLS, Netzwerk) exponieren.
---
## 9. Git-Remote
Standard-Remote nach Klon/Push:
```text
https://git.loepperts.com/loepperts/FL-Akademie.git
```
Branch: `main` (empfohlen).

125
docs/PLAN.md Normal file
View File

@@ -0,0 +1,125 @@
# Motorrad-Akademie LMS Ersatz für Tutor LMS
Dieses Dokument ist die **Produkt- und Architekturgrundlage** für eine private, zielorientierte Lernplattform. Sie ersetzt schrittweise [Tutor LMS](https://tutorlms.com/) auf [akademie.fahrlaessig.com](https://akademie.fahrlaessig.com/).
---
## 1. Zielbild
- **Eigentümerschaft:** Code und Daten bei euch, keine Plugin-Lizenzkosten für das LMS-Kernstück.
- **Bedienung:** Reduzierte Admin-Oberfläche auf echte Workflows (Kurs anlegen, Lektionen, Zugang, Zahlung).
- **Kontinuität:** URLs, Kurslogik und Look sollen zur bestehenden Akademie passen (Migration/Redirects später).
- **Skalierung:** Produktionsfähige Basis (API, DB, Jobs), ohne WordPress als Laufzeit für den Lernbereich.
---
## 2. Ist-Analyse Akademie (öffentlich)
| Bereich | Anforderung |
|--------|-------------|
| Kurse | Karten mit Titel, Autor, Kategorien (kostenlos, Module, Übung der Woche). |
| Kurrikulum | `/kurse/.../lektionen/...` Module/Themen und Lektionen. |
| Zugang | Einschreiben vs. „Mit dem Lernen beginnen“. |
| Monetarisierung | Abo-Preise, Warenkorb/Demo, kostenpflichtig vs. kostenlos. |
| Vertrauen | Bewertungen, Dozentenprofile. |
| Marketing | Startseite, Roadmap, Blog/Shop teils außerhalb LMS. |
---
## 3. Tutor-LMS-Feature-Parität (phasenweise)
### Phase A MVP (Betrieb Akademie)
- Nutzer: Registrierung, Login, Passwort, Rollen (Lernender, Admin).
- Kurse: Slug, Titel, Beschreibung, Thumbnail, Kategorien, veröffentlicht.
- Kurrikulum: Kurs → Modul → Lektion (Reihenfolge), Rich-Text-Inhalt.
- Einschreibung + Fortschritt (Lektion abgeschlossen).
- Zahlungen: vorbereitet (Stripe o. Ä.); **Dev:** kostenlose Einschreibung + Preisfelder in DB.
- Öffentliche Kursliste + Kurssicht + Lektionsplayer-Layout.
### Phase B später
- Quizze, Aufgaben, Zertifikate, Prerequisites, Content Drip, Gradebook, erweiterte Analytics, Bundles, Live-Sessions, KI-Inhalte nur bei konkretem Bedarf.
---
## 4. Technische Architektur (Umsetzung in diesem Repo)
| Komponente | Wahl |
|------------|------|
| App | Next.js (App Router), TypeScript |
| Datenbank | PostgreSQL 16 |
| ORM | Prisma |
| Auth | NextAuth.js (Credentials, erweiterbar auf OAuth) |
| Deployment lokal | Docker Compose (`web` + `db`) |
Verzeichnisüberblick:
- `app/` Routen: Marketing (`/`), Kurse, Lektionen, Login, **Mitgliederbereich `/portal`**, **Admin `/admin`**, öffentliche Zertifikatsseite `/zertifikat/[code]`, API (`/api/...`).
- `components/` UI-Bausteine (Header, Kurskarten, Formulare).
- `lib/` Prisma-Client, Auth, Landing-Content, Zertifikate, Fortschritt, Slugs.
- `prisma/schema.prisma` Datenmodell inkl. `LandingPage`, `Certificate`.
- `prisma/seed.ts` Demo-Daten + Standard-Landing.
- `docker-compose.yml` Postgres (Hostport **5433**) + Web.
- `Dockerfile` + `scripts/docker-entrypoint.sh` Migration, Seed, `next dev`.
- `README.md` Einstieg & Schnellstart.
- `docs/HANDBUCH.md` **implementierter Stand** (Admin, Portal, Zertifikate, Docker).
---
## 5. Migration (später, produktiv)
- Export aus WordPress/Tutor → Import-Skripte ins Zielschema.
- Nutzer: Einladung/Passwort-Reset statt unsicherer Passwort-Übernahme.
- SEO: 301 von alten `/kurse/`-URLs.
- Zahlungen: Abgleich mit Payment-Provider (Kunden-IDs).
---
## 6. Sicherheit (Produktion)
- TLS, Security-Header (CSP iterativ), Rate-Limits auf Login.
- OWASP-Basics, keine Secrets im Image, regelmäßige Updates.
- RBAC für Admin/Dozent/Support.
---
## 7. Monitoring (sekundär, aber vorgesehen)
- Strukturierte Logs, Metriken (Latenz, 5xx, Jobs), Alerts bei Zahlungs-Webhooks.
- Healthchecks für App, DB, Queue.
---
## 8. Ausführung Entwicklung mit Docker Compose
Voraussetzung: Docker und Docker Compose installiert.
```bash
cd /home/lo/Dokumente/real-akademie-replacement
docker compose up --build
```
- App: **http://localhost:3000**
- Demo-Login (Seed): `admin@akademie.local` / `devpassword`
Lernender: `lernender@akademie.local` / `devpassword`
Umgebungsvariablen siehe `.env.example`. Für reine lokale Entwicklung ohne Docker: Node 20+, `npm install`, Postgres starten, `DATABASE_URL` setzen, `npx prisma generate`, `npx prisma migrate dev`, `npm run dev`.
**Hinweis Next.js:** Unter demselben dynamischen Pfadsegment (z.B. `/kurse/[slug]/…`) müssen die Parameternamen in allen verschachtelten Routen übereinstimmen (hier durchgängig `slug` für den Kurs).
---
## 9. Roadmap dieses Repos
1. ~~MVP-UI und Datenmodell~~; ~~Admin-UI (Kurse, Nutzer, Landing Page)~~; ~~Portal mit Passwort & Zertifikat~~ umgesetzt (siehe `docs/HANDBUCH.md`).
2. Stripe/Webhooks + echte Abos.
3. Migrationstools von Tutor-Export (Inhalte, Nutzer, Zahlungen).
4. Phase-B-Features nach Priorität (Quizze, Drip, …).
---
## 10. Repository
- **Git:** `https://git.loepperts.com/loepperts/FL-Akademie.git`
- Einstieg für neue Entwickler: zuerst **`README.md`**, dann **`docs/HANDBUCH.md`** und dieses **`docs/PLAN.md`**.