feat: Wahl-Phasen, Verantwortliche-Invites, Auth fixes, GRUPPE chat #1
@@ -0,0 +1,7 @@
|
|||||||
|
import { IsBoolean, IsOptional } from 'class-validator';
|
||||||
|
|
||||||
|
export class UpdateWahlDto {
|
||||||
|
@IsOptional()
|
||||||
|
@IsBoolean()
|
||||||
|
isOpen?: boolean;
|
||||||
|
}
|
||||||
@@ -3,6 +3,7 @@ import {
|
|||||||
Controller,
|
Controller,
|
||||||
Get,
|
Get,
|
||||||
Param,
|
Param,
|
||||||
|
Patch,
|
||||||
Post,
|
Post,
|
||||||
Query,
|
Query,
|
||||||
Req,
|
Req,
|
||||||
@@ -14,6 +15,7 @@ import { Response } from 'express';
|
|||||||
import { WahlService } from './wahl.service';
|
import { WahlService } from './wahl.service';
|
||||||
import { ZuteilungService } from './zuteilung.service';
|
import { ZuteilungService } from './zuteilung.service';
|
||||||
import { CreateWahlDto } from './dto/create-wahl.dto';
|
import { CreateWahlDto } from './dto/create-wahl.dto';
|
||||||
|
import { UpdateWahlDto } from './dto/update-wahl.dto';
|
||||||
import { CreateWorkshopDto } from './dto/create-workshop.dto';
|
import { CreateWorkshopDto } from './dto/create-workshop.dto';
|
||||||
import { SubmitTeilnehmerDto } from './dto/submit-teilnehmer.dto';
|
import { SubmitTeilnehmerDto } from './dto/submit-teilnehmer.dto';
|
||||||
import { CreateForceZuteilungDto } from './dto/create-force-zuteilung.dto';
|
import { CreateForceZuteilungDto } from './dto/create-force-zuteilung.dto';
|
||||||
@@ -45,6 +47,20 @@ export class WahlController {
|
|||||||
return this.wahl.listWahlen(kcId);
|
return this.wahl.listWahlen(kcId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Patch(':wahlId')
|
||||||
|
@UseGuards(AuthGuard(['authentik', 'team']), RolesGuard)
|
||||||
|
@Roles(Role.LEITUNGSTEAM)
|
||||||
|
updateWahl(@Param('wahlId') wahlId: string, @Body() dto: UpdateWahlDto) {
|
||||||
|
return this.wahl.updateWahl(wahlId, { isOpen: dto.isOpen });
|
||||||
|
}
|
||||||
|
|
||||||
|
@Get(':wahlId/teilnehmer')
|
||||||
|
@UseGuards(AuthGuard(['authentik', 'team']), RolesGuard)
|
||||||
|
@Roles(Role.LEITUNGSTEAM)
|
||||||
|
listTeilnehmer(@Param('wahlId') wahlId: string) {
|
||||||
|
return this.wahl.listTeilnehmer(wahlId);
|
||||||
|
}
|
||||||
|
|
||||||
@Post(':wahlId/workshops')
|
@Post(':wahlId/workshops')
|
||||||
@UseGuards(AuthGuard(['authentik', 'team']), RolesGuard)
|
@UseGuards(AuthGuard(['authentik', 'team']), RolesGuard)
|
||||||
@Roles(Role.LEITUNGSTEAM)
|
@Roles(Role.LEITUNGSTEAM)
|
||||||
|
|||||||
@@ -22,6 +22,33 @@ export class WahlService {
|
|||||||
return this.prisma.wahl.findMany({ where: { kcId } });
|
return this.prisma.wahl.findMany({ where: { kcId } });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async updateWahl(wahlId: string, data: { isOpen?: boolean }) {
|
||||||
|
await this.getWahlOrThrow(wahlId);
|
||||||
|
const wahl = await this.prisma.wahl.update({ where: { id: wahlId }, data });
|
||||||
|
await this.sync.capture('Wahl', SyncOperation.UPDATE, wahl.id, wahl);
|
||||||
|
return wahl;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// LT view of who took part in a Wahl, with their priorities and any
|
||||||
|
/// existing Force-Zuteilung.
|
||||||
|
async listTeilnehmer(wahlId: string) {
|
||||||
|
await this.getWahlOrThrow(wahlId);
|
||||||
|
const rows = await this.prisma.teilnehmer.findMany({
|
||||||
|
where: { wahlId },
|
||||||
|
orderBy: { guestAccount: { lastName: 'asc' } },
|
||||||
|
include: {
|
||||||
|
guestAccount: { select: { firstName: true, lastName: true } },
|
||||||
|
forceZuteilung: { select: { workshopId: true } },
|
||||||
|
},
|
||||||
|
});
|
||||||
|
return rows.map((t) => ({
|
||||||
|
id: t.id,
|
||||||
|
name: `${t.guestAccount.firstName} ${t.guestAccount.lastName}`.trim(),
|
||||||
|
prioritaeten: (t.prioritaeten as string[] | null) ?? [],
|
||||||
|
forcedWorkshopId: t.forceZuteilung?.workshopId ?? null,
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
/// Guest-facing view: open Wahlen for the guest's KC, each with its
|
/// Guest-facing view: open Wahlen for the guest's KC, each with its
|
||||||
/// workshops and the guest's own current priorities (null if not submitted).
|
/// workshops and the guest's own current priorities (null if not submitted).
|
||||||
async guestOverview(kcId: string, guestAccountId: string) {
|
async guestOverview(kcId: string, guestAccountId: string) {
|
||||||
|
|||||||
Reference in New Issue
Block a user