feat(chat): free-form GRUPPE channels with mutable participants
- 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
This commit is contained in:
@@ -50,7 +50,7 @@ export class PushService {
|
||||
try {
|
||||
const channel = await this.prisma.chatChannel.findUnique({
|
||||
where: { id: channelId },
|
||||
include: { participants: { select: { userId: true } } },
|
||||
include: { participants: { select: { userId: true, guestAccountId: true } } },
|
||||
});
|
||||
if (!channel) return;
|
||||
|
||||
@@ -90,10 +90,22 @@ export class PushService {
|
||||
kcId: string;
|
||||
type: ChatChannelType;
|
||||
gemeindeId: string | null;
|
||||
participants: { userId: string }[];
|
||||
participants: { userId: string | null; guestAccountId: string | null }[];
|
||||
}): Promise<{ userIds: string[]; guestIds: string[] }> {
|
||||
if (channel.type === ChatChannelType.DIREKT) {
|
||||
return { userIds: channel.participants.map((p) => p.userId), guestIds: [] };
|
||||
return {
|
||||
userIds: channel.participants.map((p) => p.userId).filter((id): id is string => !!id),
|
||||
guestIds: [],
|
||||
};
|
||||
}
|
||||
|
||||
if (channel.type === ChatChannelType.GRUPPE) {
|
||||
return {
|
||||
userIds: channel.participants.map((p) => p.userId).filter((id): id is string => !!id),
|
||||
guestIds: channel.participants
|
||||
.map((p) => p.guestAccountId)
|
||||
.filter((id): id is string => !!id),
|
||||
};
|
||||
}
|
||||
|
||||
const ltUsers = await this.prisma.user.findMany({
|
||||
|
||||
Reference in New Issue
Block a user