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:
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;
|
||||
@@ -93,6 +93,7 @@ model User {
|
||||
inspections Inspection[]
|
||||
varroaMeasurements VarroaMeasurement[]
|
||||
swarmControlChecks SwarmControlCheck[]
|
||||
winterChecks WinterCheck[]
|
||||
treatments Treatment[]
|
||||
feedings Feeding[]
|
||||
harvests Harvest[]
|
||||
@@ -270,6 +271,7 @@ model Colony {
|
||||
inspections Inspection[]
|
||||
varroaMeasurements VarroaMeasurement[]
|
||||
swarmControlChecks SwarmControlCheck[]
|
||||
winterChecks WinterCheck[]
|
||||
treatments Treatment[]
|
||||
feedings Feeding[]
|
||||
harvests HarvestColony[]
|
||||
@@ -595,6 +597,54 @@ model SwarmControlCheck {
|
||||
@@index([colonyId, date])
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Ein- und Auswinterung, Winterverluste
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
enum WinterCheckSeason {
|
||||
AUTUMN // Einwinterung
|
||||
SPRING // Auswinterung
|
||||
}
|
||||
|
||||
enum WinterOutcome {
|
||||
SURVIVED
|
||||
WEAK
|
||||
LOST
|
||||
}
|
||||
|
||||
// Verlustkategorien des COLOSS-Monitorings: totes/leeres Volk, unloesbares
|
||||
// Koeniginnenproblem, Naturereignis. Bewusst keine Diagnose (Varroa, Virus
|
||||
// ...): die gehoert, wenn ueberhaupt bekannt, in die Notiz.
|
||||
enum ColonyLossCause {
|
||||
DEAD_OR_EMPTY
|
||||
QUEEN_PROBLEM
|
||||
NATURAL_DISASTER
|
||||
}
|
||||
|
||||
// Eine Einwinterung und eine Auswinterung je Volk und Winter. winterYear ist
|
||||
// das Jahr, in dem der Winter beginnt (Winter 2026/27 = 2026).
|
||||
model WinterCheck {
|
||||
id String @id @default(cuid())
|
||||
colonyId String
|
||||
colony Colony @relation(fields: [colonyId], references: [id])
|
||||
userId String
|
||||
user User @relation(fields: [userId], references: [id])
|
||||
winterYear Int
|
||||
season WinterCheckSeason
|
||||
date DateTime
|
||||
occupiedSeams Int?
|
||||
feedStockKg Float?
|
||||
queenPresent Boolean?
|
||||
outcome WinterOutcome?
|
||||
lossCause ColonyLossCause?
|
||||
notes String?
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
@@unique([colonyId, winterYear, season])
|
||||
@@index([winterYear])
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Behandlung / Tierarzneimittel (Abschnitt 4.11)
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
Reference in new issue
Block a user