Initial commit: FL-Akademie LMS mit Docker, Admin, Portal und Dokumentation.
Made-with: Cursor
This commit is contained in:
108
docs/HANDBUCH.md
Normal file
108
docs/HANDBUCH.md
Normal 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
125
docs/PLAN.md
Normal 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`**.
|
||||
Reference in New Issue
Block a user