# 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).