- Veterinary medicine catalogue, lots and append-only movement ledger
(rest always computed; corrections as counter-bookings; inactive
medicines take no new stock; unit must match on lot moves).
- Documents of medicine lots, authority notices and restrictions need the
domain right on top of documents:* (403 before any lookup).
- Label particulars: pure checkLabel with six mandatory gaps and four
warnings, AFM font metrics, Berlin-day dates, geometric reading order
for split addresses, new master-data fields with row-locked updates.
- Herd events ColonyCreated, ColonyMoved, ApiaryChanged and
TskReferenceDayReached (ids only, never forwarded to webhooks); CSV
import emits ColonyCreated with audit.
- ARCHITECTURE.md §12 Compliance (T6), Annahmen 59–70.
Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
Backend
- Backup covers every Prisma model (bundle v3); a guard test fails for any
new model that is neither backed up nor explicitly excluded. Unsealed
bundles may only add rows to 27 legacy master/field tables and never
overwrite; counters, ledgers, settings, roles etc. need a sealed file.
Shared import limit BACKUP_MAX_IMPORT_BYTES (default 50 MB, max 256 MB)
with warnings in log and UI; replaced document files are removed after
commit.
- Post-commit side effects (automation, calendar sync, webhooks) run via
runAfterCommit and never turn a committed write into a 500, so retries
with the same Idempotency-Key no longer create duplicates.
- Calendar outbox is multi-replica safe: per-entry claims with stale
takeover, revision-based settle, new Graph event only on 404/410,
transactionId on create, 30 s Graph timeout, URL-encoded ids, GUID
validation for groupId, "run now" in background and resets FAILED.
- Automation tasks are deduplicated under a row lock on the rule.
- Update DTOs follow one null rule: omitted = unchanged, null clears a
nullable field, null on a required field is a 400.
- Varroa mites/day is recomputed on correction; withdrawal status is
checked against the harvest date (?at=), bounded colonyIds; inspection
create is audited; updates re-enqueue calendar entries.
- Dashboard, statistics and apiary/colony guards treat WEAK, CONSPICUOUS
and QUEENLESS colonies as living.
- Prisma errors and body-parser errors are logged without query values or
request bodies.
- Migration 20261012100000_calendar_sync_claims; schema index name aligned
with the existing database object.
Frontend
- Sticky save bar sticks again (no scroll container ancestors, card uses
overflow-clip), safe-area insets, scroll-padding, FAB hidden on forms,
sticky desktop sidebar.
- Inspections record yes / no / not checked instead of silent defaults.
- All living colonies are selectable; shared RecordSelect, EnumSelect,
ChoiceGroup and TriStateField replace per-page copies; selects show
names instead of ids; labels point at real controls.
- Emptied optional fields are sent as null (emptyToNull) so every field
can be cleared; dates default to the local day and are sent via
toApiDate.
- Harvest withdrawal warning uses the harvest date; backup page warns when
a backup outgrows the import limit and lists skipped tables.
Build and docs
- Docker builds fail unless lint, typecheck and unit tests pass.
- ARCHITECTURE.md updated (assumptions 9-12, 19-21, section 8) and spec
docs/superpowers/specs/2026-10-12-plattform-rueckgrat-und-fahrplan-design.md
for the backbone (api/worker/job roles, domain event outbox) and the
feature roadmap T3-T7.
Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
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.