linusandClaude Sonnet 5 dbaafabcf4 feat(backend): self-registration for Gemeinde Verantwortliche
New onboarding/ module. A prospective Verantwortliche/r signs in with their
Konfi-Castle-ID (Authentik), looks up a KC by invite code, picks an existing
Gemeinde, and registers:

- GET  /api/onboarding/kc/:inviteCode  -> KC name + its Gemeinden (public;
  the invite code is the shared secret)
- POST /api/onboarding/verantwortliche -> verifies the raw Authentik bearer
  token's claims (no local Membership required yet via new
  TokenVerificationService.verifyAuthentikClaims), JIT-provisions the local
  User, and creates a Membership with status PENDING. Idempotent per
  (user, kc, gemeinde).
- GET  /api/onboarding/requests?kcId=            (LT) list pending
- POST /api/onboarding/requests/:id/approve|reject (LT) approve flips to
  ACTIVE, reject deletes.

Schema: Membership gains status (enum MembershipStatus { ACTIVE, PENDING },
default ACTIVE). AuthentikStrategy / TokenVerificationService / TeamAuthService
now load only ACTIVE memberships, so a pending request grants nothing until
approved. Membership create/update/delete flow through the sync log.

Tests: onboarding.service.spec.ts (14 cases); npm test green at 46.
Docs (plan + backend README) updated.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-10 08:01:19 +02:00
2026-09-09 08:30:18 +00:00

KC-APP

Multi-tenant event, election and communication platform for Konfi-Castle events (KCs), replacing the WordPress plugin "Workshop-Wahlen". See plan-kcAppMultiTenantPlatform.prompt.md for the full architecture and phased roadmap.

Structure

  • backend/ — NestJS API (Prisma/PostgreSQL, Authentik OIDC as resource server, guest/Konfi local accounts, roles/permissions foundation, file sharing, chat, local/cloud sync). See 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/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).

Status

Phase 0/1 foundation implemented: monorepo skeleton, Prisma data model (Kc, Gemeinde, User, Membership, GuestAccount, Wahl/Workshop/Teilnehmer/Zuteilung, File, Chat), Authentik JWT resource-server strategy, guest invite-code login, Role-based guard scoped per KC.

Phase 2 (Workshop-Wahl engine) implemented: Wahl/Workshop administration, guest Teilnehmer submission, Force-Zuteilung overrides, and the assignment algorithm ported from the WP plugin's kc_run_zuteilung (force-assignments → wish rounds 1-3 → random fill → consolidation of underfilled workshops), plus CSV export.

Phase 3 (Dateifreigabe) implemented: Leitungsteam-only upload tagged with a visibility tier (alle / alle außer Konfis / nur LT), list/download for Authentik or guest callers filtered by their allowed tiers, storage behind a provider abstraction defaulting to Nextcloud/WebDAV (S3-compatible storage as an alternative via STORAGE_PROVIDER=s3).

Phase 5 (Kommunikation) implemented: Gemeinde-Gruppenchat, 1:1-DMs, LT- kanalübergreifende Kanäle, Broadcast (read-only für Konfis); channel/history via REST, real-time send/receive via a raw WebSocket gateway authenticated with the same Authentik/guest tokens as the REST API.

Phase 6 (Hybrid Lokal/Cloud-Server & Sync) implemented: an append-only replication log (SyncLogEntry) captured by every feature service after its writes; the local (on-site) server periodically pushes/pulls against the 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.

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

S
Description
No description provided
Readme GPL-3.0
585 KiB
Languages
Dart 78.3%
JavaScript 9.9%
HTML 7.5%
CSS 4.3%