From 3e179391b0f67945fecd222edfa59fdee3a98b0e Mon Sep 17 00:00:00 2001 From: Nick Szaunig Date: Tue, 8 Sep 2026 22:35:32 +0200 Subject: [PATCH] fix: block assigning a colony to a queen who is no longer available assignColony() never checked the queen's own status, so a queen marked LOST/DECEASED/REPLACED/SOLD - exactly the statuses the queen-loss fix now treats as "not really available" and releases her from her old colony for - could still be assigned to a brand new colony, which makes no domain sense (you can't put a dead queen in a hive). Rejects with ConflictException up front, before even looking up the destination colony; correcting a mistaken status update first is the intended fix path. Co-Authored-By: Claude Sonnet 5 --- .../src/queens/queens.service.spec.ts | 17 ++++++++++++++++- ApiCore-Backend/src/queens/queens.service.ts | 6 ++++++ 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/ApiCore-Backend/src/queens/queens.service.spec.ts b/ApiCore-Backend/src/queens/queens.service.spec.ts index 357f633..62d84a5 100644 --- a/ApiCore-Backend/src/queens/queens.service.spec.ts +++ b/ApiCore-Backend/src/queens/queens.service.spec.ts @@ -1,4 +1,8 @@ -import { BadRequestException, NotFoundException } from '@nestjs/common'; +import { + BadRequestException, + ConflictException, + NotFoundException, +} from '@nestjs/common'; import { QueensService } from './queens.service'; import { PrismaService } from '../prisma/prisma.service'; import { AuditLogService } from '../audit/audit-log.service'; @@ -78,6 +82,17 @@ describe('QueensService', () => { ).rejects.toBeInstanceOf(NotFoundException); }); + it('assignColony rejects a queen who is no longer available', async () => { + prisma.queen.findUnique.mockResolvedValue({ + ...queen, + status: 'DECEASED', + }); + await expect( + service.assignColony('queen-1', { colonyId: 'colony-1' }, 'user-1'), + ).rejects.toBeInstanceOf(ConflictException); + expect(prisma.colony.findUnique).not.toHaveBeenCalled(); + }); + it('assignColony closes the previous queen history, sets currentQueenId, and opens a new history row', async () => { prisma.queen.findUnique.mockResolvedValue(queen); prisma.colony.findUnique.mockResolvedValue({ diff --git a/ApiCore-Backend/src/queens/queens.service.ts b/ApiCore-Backend/src/queens/queens.service.ts index 1fe5c07..fe811d1 100644 --- a/ApiCore-Backend/src/queens/queens.service.ts +++ b/ApiCore-Backend/src/queens/queens.service.ts @@ -1,5 +1,6 @@ import { BadRequestException, + ConflictException, Injectable, NotFoundException, } from '@nestjs/common'; @@ -154,6 +155,11 @@ export class QueensService { actingUserId: string, ): Promise { const queen = await this.findById(id); + if (QUEEN_NO_LONGER_AVAILABLE_STATUSES.includes(queen.status)) { + throw new ConflictException( + `Queen ${id} is not available for assignment (status: ${queen.status}) - correct her status first if this was a mistake`, + ); + } const colony = await this.prisma.colony.findUnique({ where: { id: dto.colonyId }, });