feat: Ein-/Auswinterung und Winterverluste je Volk

- WinterCheck per colony, winter and season (autumn/spring), every field
  editable; loss causes limited to the COLOSS monitoring categories.
- Summary per winter and apiary: loss rate lost/wintered, marked
  provisional while colonies are not yet checked in spring - an unchecked
  colony never counts as survived.
- A loss marks the colony deceased only on explicit request, in the same
  transaction and audited.
- Permissions winter-checks:read/create/update granted by migration to
  beekeeper and staff roles; winter checks included in backups.
- Page "Überwinterung": next action first, one button per row until the
  colony is wintered, German number format.

Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
This commit is contained in:
Nick SzaunigandClaude Opus 5.5 committed 2026-09-28 17:32:03 +02:00
1 parent 0d23963f07
commit fac66882fa
26 files changed
+2020 -2

No files matched your search

@@ -0,0 +1,60 @@
-- CreateEnum
CREATE TYPE "WinterCheckSeason" AS ENUM ('AUTUMN', 'SPRING');
-- CreateEnum
CREATE TYPE "WinterOutcome" AS ENUM ('SURVIVED', 'WEAK', 'LOST');
-- CreateEnum
CREATE TYPE "ColonyLossCause" AS ENUM ('DEAD_OR_EMPTY', 'QUEEN_PROBLEM', 'NATURAL_DISASTER');
-- CreateTable
CREATE TABLE "WinterCheck" (
"id" TEXT NOT NULL,
"colonyId" TEXT NOT NULL,
"userId" TEXT NOT NULL,
"winterYear" INTEGER NOT NULL,
"season" "WinterCheckSeason" NOT NULL,
"date" TIMESTAMP(3) NOT NULL,
"occupiedSeams" INTEGER,
"feedStockKg" DOUBLE PRECISION,
"queenPresent" BOOLEAN,
"outcome" "WinterOutcome",
"lossCause" "ColonyLossCause",
"notes" TEXT,
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" TIMESTAMP(3) NOT NULL,
CONSTRAINT "WinterCheck_pkey" PRIMARY KEY ("id")
);
-- CreateIndex
CREATE INDEX "WinterCheck_winterYear_idx" ON "WinterCheck"("winterYear");
-- CreateIndex
CREATE UNIQUE INDEX "WinterCheck_colonyId_winterYear_season_key" ON "WinterCheck"("colonyId", "winterYear", "season");
-- AddForeignKey
ALTER TABLE "WinterCheck" ADD CONSTRAINT "WinterCheck_colonyId_fkey" FOREIGN KEY ("colonyId") REFERENCES "Colony"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "WinterCheck" ADD CONSTRAINT "WinterCheck_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
-- Permissions: the boot-time catalog sync only grants new permissions to
-- system roles (ADMIN). Winter checks are everyday beekeeping records, so the
-- other roles get the same access they have to inspections.
INSERT INTO "Permission" (id, key, resource, action, "labelDe", "groupDe", "sortOrder")
VALUES
(gen_random_uuid()::text, 'winter-checks:read', 'winter-checks', 'read', 'Ansehen', 'Überwinterung', 850),
(gen_random_uuid()::text, 'winter-checks:create', 'winter-checks', 'create', 'Anlegen', 'Überwinterung', 851),
(gen_random_uuid()::text, 'winter-checks:update', 'winter-checks', 'update', 'Bearbeiten', 'Überwinterung', 852)
ON CONFLICT (key) DO NOTHING;
INSERT INTO "RolePermission" ("roleId", "permissionId", "grantedAt")
SELECT r.id, p.id, now()
FROM "Role" r, "Permission" p
WHERE p.resource = 'winter-checks'
AND (
r.key IN ('ADMIN', 'BEEKEEPER', 'STAFF')
OR (r.key IN ('READONLY', 'API_CLIENT') AND p.action = 'read')
)
ON CONFLICT DO NOTHING;