- ChatChannelType.GRUPPE: created by Leitungsteam (any KC) or a Gemeinde
Verantwortliche/r (own KC), mixing team users and guests/Konfis as
explicit ChatParticipant rows (unlike GEMEINDE_GRUPPE, membership is
not derived from Gemeinde)
- POST /chat/:kcId/gruppen to create, GET participant-candidates, and
POST/DELETE /chat/gruppen/:channelId/participants to manage membership
(creator, LT, or Verantwortliche/r of that KC)
- ChatGateway broadcasts chat:participants-changed on membership change
- PushService updated for nullable ChatParticipant.userId + new
guestAccountId column
- SyncService now replicates ChatParticipant
- Prisma migration + 14 new unit tests (75/75 passing), tsc clean
- CI: add .gitea/workflows/cybedefend-scan.yml + .cybedefend project config