diff --git a/README.md b/README.md index b58770d..53022ea 100644 --- a/README.md +++ b/README.md @@ -12,12 +12,13 @@ for the full architecture and phased roadmap. sharing, chat, local/cloud sync). See [backend/README.md](backend/README.md) for setup. Also serves the web client (see below) directly, so it's the single entry point for the web experience. +- `client/app/` — the Flutter client (single codebase; **web** target + enabled, mobile/desktop can be added later). Login (guest / local Teamer / + invite redemption), role-aware home, guest Workshop-Wahl, file list, + read-only chat. See [client/app/README.md](client/app/README.md). - `client/web/` — minimal dependency-free HTML/CSS/JS placeholder web - client (guest join, Wahl submission, file list, chat) exercising the real - API, served by the backend at `/`. Will be replaced by the Flutter web - build once Flutter is available. -- `client/` (mobile/desktop) — planned Flutter app, not yet scaffolded - (Flutter is not installed in this environment). + client, served by the backend at `/`. Superseded by the Flutter web build; + kept for now as a zero-dependency fallback. ## Status @@ -50,12 +51,24 @@ cloud server's `/sync/ingest` + `/sync/export` endpoints (shared-secret authenticated, not user auth). No conflict resolution needed by design - the local server is the sole source of truth while an event is live. -The backend now also serves the web client directly (static files from -`client/web/`, API under `/api`), so the same process is the single entry -point for the web experience. +Since then: local (non-Authentik) Gemeinde Teamer accounts + invites +(`teamer/`, `auth/team-login`), Gemeinde CRUD (`gemeinde/`), Gemeinde +Verantwortliche self-registration with LT approval (`onboarding/`), JIT +`User` provisioning on first Authentik login, LEITUNGSTEAM derived from the +Authentik `groups` claim, and an email module (`mail/`, log-only by default, +SMTP opt-in) that sends personal Teamer invites. First Prisma migration is +in (`backend/prisma/migrations/`); the backend has been run end to end +against a local PostgreSQL 16. `npm test` covers the assignment algorithm +and the new auth/onboarding services (56 tests). -Backend builds and boots cleanly (`npm run build`, `node dist/main.js`) but -requires a real PostgreSQL database, Authentik instance, and Nextcloud/S3 -credentials (see `backend/.env.example`) to run end to end. Remaining: the -Flutter clients (mobile/desktop; web has an interim plain-HTML client). +Phase 7 (Flutter client) started: `client/app/` is a single Flutter +codebase with the **web** target enabled — login (guest / local Teamer / +invite redemption), role-aware home, guest Workshop-Wahl, file list, +read-only chat. `flutter build web` and `flutter test` pass. Mobile/desktop +targets, the Authentik Authorization-Code flow, WebSocket chat send, and LT +admin screens are still to come. + +The backend also serves the interim `client/web/` placeholder at `/` (API +under `/api`). Running end to end still needs a real Authentik instance and +Nextcloud/S3 credentials (see `backend/.env.example`). diff --git a/plan-kcAppMultiTenantPlatform.prompt.md b/plan-kcAppMultiTenantPlatform.prompt.md index 11c1f5e..9675fdd 100644 --- a/plan-kcAppMultiTenantPlatform.prompt.md +++ b/plan-kcAppMultiTenantPlatform.prompt.md @@ -2,7 +2,7 @@ Neuentwicklung, die das WordPress-Plugin **Workshop-Wahlen** (Wahlen/Workshops/Teilnehmer/Zuteilungslogik) ablöst und um Rollen-/Rechteverwaltung via Authentik, gestaffelte Dateifreigabe, mehrstufigen Chat und eine Hybrid-Server-Architektur (online + lokal mit Sync) erweitert. Backend: **NestJS 10 + PostgreSQL + Prisma 5**. Client: **Flutter** (eine Codebase für Mobile, Web, Desktop) — bis Flutter verfügbar ist, liefert das Backend selbst einen minimalen Platzhalter-Web-Client aus. -> Status (Stand dieser Session): **Alle geplanten Backend-Phasen (0–6) sind implementiert und verifiziert** (Typecheck, Build, Boot-Test). Offen ist ausschließlich der Flutter-Client (Mobile/Desktop), da Flutter in dieser Umgebung nicht installiert ist. +> Status: **Backend-Phasen 0–6 komplett** plus lokale Teamer-Accounts/Invites, Gemeinde-CRUD, Verantwortlichen-Selbstregistrierung (`onboarding/`), Authentik-JIT + LT-aus-`groups`, `mail/`-Modul. Erste Prisma-Migration vorhanden, Backend lief Ende-zu-Ende gegen lokales PostgreSQL 16 (`npm test`: 56). **Phase 7 (Flutter) begonnen**: `client/app/` — eine Codebase, Web-Target aktiv, Login/Home/Wahl/Dateien/Chat(read-only); `flutter build web` + `flutter test` grün. Offen: Mobile/Desktop-Targets, Authentik-Auth-Code-Flow im Client, WS-Chat-Senden, LT-Admin-Screens, Push, echte Authentik/Nextcloud-Infra. --- @@ -37,7 +37,7 @@ Vollständiges Schema: [backend/prisma/schema.prisma](backend/prisma/schema.pris | Bereich | Entscheidung | Begründung | |---|---|---| | Backend | NestJS 10 + PostgreSQL + Prisma 5 | bestätigt vom Nutzer; Nest 10 statt CLI-Default (siehe unten) | -| Client | Flutter, eine Codebase Mobile/Web/Desktop | vom Nutzer delegiert; noch nicht scaffoldbar (Flutter fehlt lokal) | +| Client | Flutter, eine Codebase Mobile/Web/Desktop — `client/app/`, aktuell nur Web-Target aktiviert | vom Nutzer delegiert; Flutter-SDK lokal via Homebrew installiert (nur Web-Toolchain, Android/iOS wegen Speicher weggelassen); `lib/` ist plattformneutral, weitere Targets per `flutter create --platforms=…` nachrüstbar | | Web-Interimslösung | Backend liefert `client/web/` (reines HTML/CSS/JS, kein Build-Schritt) über `ServeStaticModule` aus; REST-API liegt unter `/api/*` | Nutzerwunsch: "Server soll auch Web-Client bereitstellen"; vermeidet Kollision zwischen API-Routen und statischen Dateien | | Auth (Team) | Authentik als OIDC Resource Server (JWKS-Verifikation), kein lokaler Autorisierungscode-Flow im Backend | Clients machen Authorization Code + PKCE direkt gegen Authentik; Backend validiert nur Access Token + löst lokale `Membership` auf | | Auth (Guest) | Rein lokale JWTs (`GUEST_JWT_SECRET`), kein Authentik | explizite Nutzervorgabe: Konfi-Accounts sind nie in Authentik | @@ -97,7 +97,7 @@ Details, Setup-Anleitung und `.env`-Variablen: [backend/README.md](backend/READM 4. **Dateifreigabe** – Storage-Abstraktion, Sichtbarkeitsstufen. ✅ 5. **Kommunikation** – Chat (Gruppen/DM/LT/Broadcast), WebSocket. ✅ (Push-Integration noch offen) 6. **Hybrid Lokal/Cloud-Server & Sync** – Replikationslog, Scheduler, Shared-Secret-Auth. ✅ -7. **Flutter-Clients** – gemeinsame Codebase; Screens: Invite/Login, rollenspezifisches Dashboard, Wahl-Formular/Ergebnis, Dateien, Chat, Admin/Nutzerverwaltung. ❌ **offen** (Flutter nicht installiert); Web-Interimslösung siehe Abschnitt 3. +7. **Flutter-Clients** – gemeinsame Codebase (`client/app/`, Web-Target). ✅ Grundgerüst: Login (Guest / lokaler Teamer / Invite-Redemption, Token in `shared_preferences`, `GET /auth/me` für rollenabhängige Startseite), Guest-Wahl-Formular (`/wahl/guest/overview` → geordnete Wunsch-Auswahl → Absenden), Datei-Liste, Chat (nur lesen). 🔜 Mobile/Desktop-Targets, Authentik-Auth-Code-Flow, Wahl-**Ergebnis**-Ansicht, WS-Chat-Senden, LT-/Verantwortlichen-Admin-Screens (KC/Gemeinde/Teamer/Onboarding-Freigaben). --- @@ -112,6 +112,8 @@ Details, Setup-Anleitung und `.env`-Variablen: [backend/README.md](backend/READM 1. Nach jeder Phase: `npx tsc -p tsconfig.build.json --noEmit`, `npx nest build`, sowie ein kurzer Boot-Test (`node dist/main.js`) zur Prüfung, dass der DI-Graph auflöst und alle Routen korrekt gemappt werden (ohne Live-DB/Authentik/Nextcloud). 2. Sync-Modul: manuell verifiziert, dass `SyncSecretGuard` Requests ohne `x-sync-secret` mit 403 ablehnt und mit korrektem Secret durchlässt (DB-Fehler in der Sandbox ist erwartet, da kein Postgres läuft). 3. Web-Client: `GET /` liefert die statische Seite (200), `GET /api/kc` trifft die echte, geschützte API (401 ohne Token). +3a. Gegen lokales **PostgreSQL 16** (Homebrew): `prisma migrate dev --name init` erzeugt/appliziert die erste Migration; Guest-Flow Ende-zu-Ende geprüft (`/auth/guest` → `/auth/me` → `/wahl/guest/overview` → `POST …/teilnehmer` → Re-Fetch zeigt `meinePrioritaeten`). Seed: `prisma/seed-dev.js`. +3b. Flutter-Client (`client/app/`): `flutter analyze` sauber, `flutter build web --release` erfolgreich, `flutter test` grün (Login-Screen-Smoke-Test); CORS-Preflight vom Browser-Origin ok. 4. Jest-Unit-Tests (Prisma/Sync/Mail gemockt, `npm test` grün, 56 Tests): - `src/wahl/zuteilung.service.spec.ts`: Force-Vorrang, Wunschrunden-Fallback bei voller Kapazität, Unzugeteilt-Fall, Konsolidierung unterbesetzter Workshops, Sync-Capture-Anzahl. - `src/auth/team-auth.service.spec.ts`: Invite-Redemption (unbekannt/widerrufen/abgelaufen/aufgebraucht, Gruppen-Link ohne E-Mail, E-Mail-Mismatch, Dublette) + Passwort-Login. @@ -124,8 +126,8 @@ Details, Setup-Anleitung und `.env`-Variablen: [backend/README.md](backend/READM ## 8. Nächste Schritte -1. Sobald Flutter verfügbar ist: Client-Grundgerüst aufsetzen (Mobile + Web + Desktop, eine Codebase), beginnend mit Invite/Login-Flow gegen die bestehende API. -2. Authentik-Provider so konfigurieren, dass das Access-Token den `groups`-Claim trägt (Scope „groups"), und die LT-Gruppe auf `AUTHENTIK_LEITUNGSTEAM_GROUP` abstimmen — sonst greift der LT-Abgleich nicht. (Reine Ops-/Config-Aufgabe, Code ist fertig.) -3. SMTP konfigurieren (`MAIL_PROVIDER=smtp` + `SMTP_*`/`MAIL_FROM`/`APP_BASE_URL`) und die Invite-Mail-Templates finalisieren (aktuell nur Plain-Text); optional Onboarding-Benachrichtigungen an LT. +1. Flutter-Client ausbauen: Authentik-Authorization-Code-Flow (LT/Verantwortliche), Wahl-Ergebnis-Ansicht, LT-/Verantwortlichen-Admin-Screens (KC/Gemeinde/Teamer anlegen, Onboarding-Anfragen freigeben), WS-Chat-Senden, dann Mobile/Desktop-Targets aktivieren. +2. Authentik-Provider so konfigurieren, dass das Access-Token den `groups`-Claim trägt (Scope „groups"), LT-Gruppe = `AUTHENTIK_LEITUNGSTEAM_GROUP`. (Ops/Config, Code ist fertig.) +3. SMTP konfigurieren (`MAIL_PROVIDER=smtp` + `SMTP_*`/`MAIL_FROM`/`APP_BASE_URL`) und Invite-Mail-Templates finalisieren (aktuell Plain-Text); optional Onboarding-Benachrichtigungen an LT. 4. Push-Benachrichtigungen (FCM/APNs) für Chat/Ankündigungen. -5. Echte Infrastruktur (Postgres, Authentik, Nextcloud/S3) aufsetzen, erste Prisma-Migration erzeugen (`prisma migrate dev`, bisher nur `schema.prisma`) und die in Abschnitt 7 offenen Verifikationsschritte durchführen. +5. Echte Authentik- + Nextcloud/S3-Infra anbinden und die in Abschnitt 7 offenen E2E-Verifikationsschritte durchführen (lokales Postgres + Migration sind erledigt).