feat: hive setup data model and API (Beute L1)
Backend Image / build-and-push (push) Successful in 5m5s
Frontend Image / build-and-push (push) Successful in 11m2s

Each colony can now hold its hive setup (Ist-Zustand) as validated
JSON with an append-only change log:

- catalog: hive systems and part types with dimensions, placement
  rules and state fields; Liebig-Zander 10 seeded with fixed ids
  (owner's equipment incl. Bausperre, Futterzarge, Nassenheider)
- pure domain module (operations, validator, derived facts) with
  shared JSON fixtures the frontend runs too
- API: catalog (hive-systems:manage), setup create/change/history/
  state at a day (colonies:read/update), 409 HIVE_CONFLICT with the
  current state, idempotent writes, HiveChanged event
- inspections can carry hive ops saved in the same transaction
- backup export/import of the new tables (backup wins per colony)
- docs: ARCHITECTURE section 13, Annahmen 95-100

Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
This commit is contained in:
Nick SzaunigandClaude Opus 5.5 committed 2026-10-15 21:23:23 +02:00
1 parent 8982d0796a
commit b48fb157c8
141 files changed
+15211 -17

No files matched your search

+102 -1
View File
@@ -104,6 +104,7 @@ model User {
refreshTokens RefreshToken[]
inspections Inspection[]
hiveChanges HiveChange[]
varroaMeasurements VarroaMeasurement[]
swarmControlChecks SwarmControlCheck[]
winterChecks WinterCheck[]
@@ -331,6 +332,7 @@ model Colony {
harvests HarvestColony[]
queenEvaluations QueenEvaluation[]
suggestions Suggestion[]
hiveSetup HiveSetup?
@@index([apiaryId])
@@index([status])
@@ -501,7 +503,8 @@ model Inspection {
notes String?
createdAt DateTime @default(now())
tasks Task[]
tasks Task[]
hiveChange HiveChange?
@@index([colonyId, date])
}
@@ -2182,3 +2185,101 @@ model ComplianceAcknowledgement {
@@index([itemKey, subjectId])
}
// ---------------------------------------------------------------------------
// Beute in 3D: Beutensysteme, Teile-Arten, Aufbau je Volk (Spec 2026-10-15)
// ---------------------------------------------------------------------------
model HiveSystem {
id String @id @default(cuid())
name String @unique
frameWidthMm Int // Oberträger
frameHeightMm Int
footprintLMm Int
footprintWMm Int
template Json // Aufbau-JSON ohne Ids, Schema 5.2
active Boolean @default(true)
partTypes HivePartType[]
setups HiveSetup[]
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}
model HivePartType {
id String @id @default(cuid())
systemId String
system HiveSystem @relation(fields: [systemId], references: [id])
kind HivePartKind
name String
articleRef String? // z. B. Holtermann-Art.-Nr.
lengthMm Int
widthMm Int
heightMm Int
boxDepth HiveBoxDepth?
frameSlots Int? // nur BOX
stateSchema Json // Abschnitt 4.2
active Boolean @default(true)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
@@unique([systemId, name])
}
model HiveSetup {
colonyId String @id
colony Colony @relation(fields: [colonyId], references: [id])
systemId String
system HiveSystem @relation(fields: [systemId], references: [id])
version Int @default(1)
state Json // Abschnitt 5.2, immer vollständig
updatedAt DateTime @updatedAt
changes HiveChange[]
}
model HiveChange {
id String @id @default(cuid())
colonyId String
setup HiveSetup @relation(fields: [colonyId], references: [colonyId])
version Int // Version nach der Änderung
occurredOn DateTime // fachlicher Tag (Durchsicht oder Eingabe)
source HiveChangeSource
inspectionId String? @unique
inspection Inspection? @relation(fields: [inspectionId], references: [id])
userId String
user User @relation(fields: [userId], references: [id])
ops Json // angewandte Operationen, Abschnitt 6
stateAfter Json
note String?
createdAt DateTime @default(now())
@@unique([colonyId, version])
@@index([colonyId, occurredOn])
}
enum HivePartKind {
FLOOR
BOX
DIVIDER_BOARD
QUEEN_EXCLUDER
FEEDER
COVER_SHEET
PROPOLIS_SCREEN
INNER_LID
INSULATION
ROOF
FLOOR_INSERT
EVAPORATOR
}
enum HiveBoxDepth {
FULL
SHALLOW
}
enum HiveChangeSource {
INIT
CARD
EDITOR
INSPECTION
AI_SUGGESTION
}