Backend business-rule guards (inactive apiary blocking colony
create/move, active colonies blocking apiary deactivation, negative
quantity on IN/OUT stock movements, unavailable queen blocking colony
assignment, inactive colony blocking split/merge/move) threw English,
UUID-laden exception text that the frontend either discarded in favor
of a generic message or - in colony-actions.tsx's move/split/merge/
assign-queen dialogs - didn't handle at all, so the guard fired with
zero visible feedback. Translated the messages to plain German and
wired the affected mutations to display them, so a beekeeper sees the
actual reason a save was rejected instead of silence or "failed".
Co-Authored-By: Claude Sonnet 5 <[email protected]>
Colony.apiaryId is a plain FK, never checked against the apiary's own
status. Without a guard, deactivating an apiary silently orphaned any
colonies still living there: they kept showing as ACTIVE, but their
apiary had disappeared from every "active apiaries" list, dashboard
count, and colony-creation picker - a confusing half-state with no
warning at all.
ApiariesService.deactivate() now throws ConflictException when active
colonies remain, so the beekeeper has to move or dissolve them first -
matching the same assertActive-style guard pattern already used
elsewhere (colonies, e.g. move()/merge()/split()).
Co-Authored-By: Claude Sonnet 5 <[email protected]>
Da fachliche Objekte nie hart geloescht werden (nur status +
deactivatedAt), fehlte bisher ein Weg, ein versehentlich aufgeloestes
Volk oder deaktivierten Bienenstand wieder zu aktivieren. Neue
POST :id/reactivate-Endpunkte setzen status zurueck auf ACTIVE und
loeschen deactivatedAt; ConflictException wenn bereits aktiv.
SearchModule mit GET /search?q= über Bienenstände, Völker,
Königinnen, Aufgaben und Honigchargen. Kombinierbare Filter
(Status, Standort, Bienenstand) in den bestehenden List-Endpunkten.