feat(backend): Koeniginnen-Modul (Modul 4)
QueensModule: CRUD + assign-colony + history, entsprechend Lastenheft §4.5 (Koeniginnenverwaltung). assign-colony schliesst die offene QueenColonyHistory der bisherigen Koenigin am Zielvolk (falls vorhanden) sowie eine evtl. noch offene History dieser Koenigin an einem anderen Volk, bevor Colony.currentQueenId gesetzt und ein neuer History-Eintrag angelegt wird - damit bleibt jeder Koeniginnenwechsel nachvollziehbar, wie gefordert. Rollen wie bei Apiaries/Colonies: Lesen offen, Schreiben auf ADMIN/BEEKEEPER beschraenkt. 5 Unit-Tests + 2 e2e-Tests, Lint, Typecheck und Build gruen.
This commit is contained in:
1 parent
6e328cdacb
commit
b18d61640d
10 files changed
+486
-1
No files matched your search
@@ -0,0 +1,122 @@
|
||||
import { Injectable, NotFoundException } from '@nestjs/common';
|
||||
import { PrismaService } from '../prisma/prisma.service';
|
||||
import { AuditLogService } from '../audit/audit-log.service';
|
||||
import { Queen } from '../../generated/prisma';
|
||||
import { CreateQueenDto } from './dto/create-queen.dto';
|
||||
import { UpdateQueenDto } from './dto/update-queen.dto';
|
||||
import { AssignColonyDto } from './dto/assign-colony.dto';
|
||||
|
||||
@Injectable()
|
||||
export class QueensService {
|
||||
constructor(
|
||||
private readonly prisma: PrismaService,
|
||||
private readonly auditLog: AuditLogService,
|
||||
) {}
|
||||
|
||||
async findAll(): Promise<Queen[]> {
|
||||
return this.prisma.queen.findMany({ orderBy: { code: 'asc' } });
|
||||
}
|
||||
|
||||
async findById(id: string): Promise<Queen> {
|
||||
const queen = await this.prisma.queen.findUnique({ where: { id } });
|
||||
if (!queen) {
|
||||
throw new NotFoundException('Queen not found');
|
||||
}
|
||||
return queen;
|
||||
}
|
||||
|
||||
async create(dto: CreateQueenDto, actingUserId: string): Promise<Queen> {
|
||||
const queen = await this.prisma.queen.create({ data: { ...dto } });
|
||||
await this.auditLog.record({
|
||||
entityType: 'Queen',
|
||||
entityId: queen.id,
|
||||
action: 'CREATE',
|
||||
userId: actingUserId,
|
||||
afterData: queen,
|
||||
});
|
||||
return queen;
|
||||
}
|
||||
|
||||
async update(
|
||||
id: string,
|
||||
dto: UpdateQueenDto,
|
||||
actingUserId: string,
|
||||
): Promise<Queen> {
|
||||
const before = await this.findById(id);
|
||||
const queen = await this.prisma.queen.update({
|
||||
where: { id },
|
||||
data: { ...dto },
|
||||
});
|
||||
await this.auditLog.record({
|
||||
entityType: 'Queen',
|
||||
entityId: id,
|
||||
action: 'UPDATE',
|
||||
userId: actingUserId,
|
||||
beforeData: before,
|
||||
afterData: queen,
|
||||
});
|
||||
return queen;
|
||||
}
|
||||
|
||||
async assignColony(
|
||||
id: string,
|
||||
dto: AssignColonyDto,
|
||||
actingUserId: string,
|
||||
): Promise<Queen> {
|
||||
const queen = await this.findById(id);
|
||||
const colony = await this.prisma.colony.findUnique({
|
||||
where: { id: dto.colonyId },
|
||||
});
|
||||
if (!colony) {
|
||||
throw new NotFoundException('Colony not found');
|
||||
}
|
||||
|
||||
await this.prisma.$transaction(async (tx) => {
|
||||
if (colony.currentQueenId && colony.currentQueenId !== queen.id) {
|
||||
await tx.queenColonyHistory.updateMany({
|
||||
where: {
|
||||
queenId: colony.currentQueenId,
|
||||
colonyId: colony.id,
|
||||
endDate: null,
|
||||
},
|
||||
data: { endDate: new Date() },
|
||||
});
|
||||
}
|
||||
await tx.queenColonyHistory.updateMany({
|
||||
where: { queenId: queen.id, endDate: null },
|
||||
data: { endDate: new Date() },
|
||||
});
|
||||
await tx.colony.update({
|
||||
where: { id: colony.id },
|
||||
data: { currentQueenId: queen.id },
|
||||
});
|
||||
await tx.queenColonyHistory.create({
|
||||
data: {
|
||||
queenId: queen.id,
|
||||
colonyId: colony.id,
|
||||
startDate: new Date(),
|
||||
notes: dto.notes,
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
await this.auditLog.record({
|
||||
entityType: 'Queen',
|
||||
entityId: queen.id,
|
||||
action: 'UPDATE',
|
||||
userId: actingUserId,
|
||||
beforeData: queen,
|
||||
afterData: { ...queen, assignedColonyId: colony.id },
|
||||
});
|
||||
|
||||
return this.findById(id);
|
||||
}
|
||||
|
||||
async getHistory(id: string) {
|
||||
await this.findById(id);
|
||||
return this.prisma.queenColonyHistory.findMany({
|
||||
where: { queenId: id },
|
||||
orderBy: { startDate: 'desc' },
|
||||
});
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user