- 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]>
10 KiB
10 KiB
Prüfung & Verbesserung ApiCore / Wabenhain – Arbeitsstand September 2026
Branch in ApiCore: improve/integrity-sync-audhd (nicht gemergt, nicht gepusht).
Wabenhain: Commits direkt auf main (nicht gepusht).
Verifikationsstufen: CR = durch Codeprüfung beurteilt, AT = automatisiert getestet, MP = manuell im Browser geprüft (Desktop 1366 px + Mobil 390 px), NV = nicht verifiziert.
Prüfmatrix
| Funktion | Erwartetes Verhalten | Befund (vorher) | Prio | Umsetzung | Status |
|---|---|---|---|---|---|
| Abfüllung bucht Honigmenge | Menge nie doppelt/zu viel abgebucht | Menge außerhalb der Transaktion gelesen, Absolutwert geschrieben → parallele Abfüllungen überbuchen, Abzug geht verloren | Kritisch | Bedingtes UPDATE … WHERE amount >= x in Transaktion; Korrektur/Löschen per Increment |
AT |
| Lagerentnahme | Kein negativer Bestand | Ausgang ohne Bestandsprüfung | Hoch | Bedingtes Decrement, 400 bei Unterdeckung | AT |
| Völker umsetzen/teilen/vereinigen | Lebende Völker bearbeitbar | Nur Status ACTIVE erlaubt – schwache/weisellose Völker gesperrt (Vereinigung weiselloser Völker unmöglich) |
Hoch | Nur Endzustände (aufgelöst, verkauft, tot, vereinigt) sperren; Selbst-Vereinigung + doppeltes Auflösen abgelehnt | AT |
| Königin umweiseln | Wechsel A → B möglich, Historie korrekt | Altes Volk behielt currentQueenId → Unique-Konflikt; Zuweisung an aufgelöste Völker möglich |
Hoch | Altes Volk gibt Königin frei (→ weisellos), weiselloses Volk mit Königin → aktiv | AT |
| Aufgabe erledigen | Idempotent, Status/Zeit konsistent | Doppelklick verschob completedAt, Webhook doppelt; Wiedereröffnen behielt completedAt |
Mittel | Zweites Erledigen = No-op; completedAt folgt Status |
AT |
| Wiederkehrende Aufgaben | Fällige Aufgabe mit Termin | Erzeugte Aufgaben ohne Fälligkeit; verpasste Wochen einzeln nachgeholt | Mittel | Fälligkeit = Termin; verpasste Termine ergeben EINE Erinnerung | AT |
| Automatisierungen | Eine offene Aufgabe je Regel und Objekt | Jede Auslösung (z. B. jede Entnahme unter Mindestbestand) erzeugte neue Aufgabe + Warnung | Hoch | Kennzeichnung sourceAutomationTrigger, Duplikatsperre; optional config.dueInDays |
AT |
| Varroa-Schwelle | Vergleich nur in gleicher Einheit | Probenzählwerte (Puderzucker/Auswaschen) und Brettzählung ohne Zeitraum gegen „Milben/Tag“ verglichen | Hoch | Nur natürlicher Milbenfall mit Tagesrate | AT |
| Offline-Warteschlange | Wiederholung erzeugt keine Duplikate | Verlorene Antwort → erneutes Senden → doppelte Durchsicht/Ernte + Automatik-Aufgabe | Hoch | Idempotency-Key (Opt-in je Endpunkt), Schlüssel im Queue-Eintrag |
AT |
| Start mehrerer Replikas | Beide Pods starten | Berechtigungs-Sync auf leerer DB: Unique-Fehler, Pod-Absturz | Mittel | createMany … skipDuplicates |
AT |
| Eingabeplausibilität | Serverseitige Grenzen | Skalen 1–5 nur im UI; doppelte Völker in Ernte → 500; Netto > Brutto möglich | Mittel | DTO-Grenzen, ArrayUnique, Gewichtsprüfung |
AT |
| Wabenhain: Ernte-Beschreibung | Keine internen Daten öffentlich | Interne ApiCore-Ernte-Notizen in Shoptext kopiert | Hoch (Sicherheit) | Notizen nicht mehr übernommen | AT |
| Wabenhain: Entwürfe | Admin-Korrekturen bleiben | Jeder Sync überschrieb unveröffentlichte Entwürfe | Hoch | Im Admin bearbeitete Entwürfe (Audit-Log) geschützt, gemeldet | CR |
| Wabenhain: Abruf | Kein Hängen, Fehler ≠ leere Liste | Kein Timeout | Mittel | 20-s-Timeout; Tests: Fehler/Strukturfehler brechen ab | AT |
| Wabenhain: Sichtbarkeit | Letzter Lauf erkennbar | Nur direkt nach Klick | Niedrig | „Letzter vollständiger Lauf“ im Panel | CR |
| Start-/Heute-Ansicht | Nächster Schritt klar | Kennzahlen-Kacheln statt Aufgaben | Hoch (UX) | „Als Nächstes“ + „Außerdem heute“, Rückgängig | AT (Logik) + MP |
| Bewegung | Einstellbar, System respektiert | Nur motion-safe-Klassen |
Mittel | Voll/Dezent/Aus je Gerät | MP |
| Etiketten-Schnittmarken | Anlegekante für Papierschneider | Keine Marken, Zuschnitt nach Augenmaß | Mittel | Haarlinien-Marken im Blattrand an jeder Schnittkante, je Vorlage abschaltbar | AT + MP |
| Folge-Kontrollen | Nachkontrolle nach Maßnahme | Keine | Mittel | Regeln „Nach Behandlung/Fütterung“, standardmäßig aus, Frist „Fällig nach (Tagen)“ | AT |
| Stockkarte je Volk | Vollständige Historie als PDF | Nur Jahresbericht | Mittel | colony-record-card.pdf, optional je Jahr |
AT + MP |
| Bestandsbuch Tierarzneimittel | Pflichtangaben Art. 108 VO (EU) 2019/6 | Lieferant, Erwerbsbeleg, Tierarzt, Standort am Behandlungstag, Halter fehlten | Hoch (Recht) | Felder ergänzt, Stand je Behandlung gespeichert, PDF je Stand, fehlende Pflichtangaben als „FEHLT“ | AT + MP |
| Ein-/Auswinterung & Verluste | Winterverluste je Volk und Stand nachvollziehbar | Nur Volksstatus, kein Bezug zum Winter, keine Ursache | Mittel | WinterCheck je Volk/Winter/Saison, Verlustkategorien nach COLOSS, Übersicht mit Verlustrate; nicht ausgewinterte Völker zählen nie als überlebt |
AT + MP |
| E2E-Tests | Grün | 23 rot (1 Produktfehler, 3 veraltete Tests) | – | behoben | AT |
Prüfungen (letzter Lauf)
- Backend: Typecheck, ESLint, 550 Unit-Tests, 211 E2E-Tests (isolierte Postgres 17),
nest build– grün. - Frontend: Typecheck, ESLint, 48 Tests,
next build– grün. Design-Detektor (impeccable): 0 Befunde. - Wabenhain: Typecheck, ESLint (geänderte Dateien), 538 Tests – grün.
- Manuell (Browser, lokale Demo-Daten): Login, Heute-Ansicht Desktop/Mobil, Abhaken in Liste und „Als Nächstes“, Rückgängig (stellt vorherigen Status her), Profil-Bewegung „Aus“ wirkt, Aufgabenliste mobil.
Zuständigkeit (Quelle der Wahrheit)
ApiCore und Wabenhain bleiben getrennte Pakete; Verbindung nur über die HTTP-API von ApiCore.
| Information | Maßgeblich | Sync-Verhalten (Wabenhain) |
|---|---|---|
| Stand, Völker, Durchsichten, Behandlungen, interne Notizen | ApiCore | wird nicht übertragen |
| Ernte: Datum, Jahr | ApiCore | bei jedem Lauf aktualisiert |
| Ernte: Sorte, Ort, Text | Wabenhain | nur Vorbelegung unbearbeiteter Entwürfe |
| Charge: Losnummer, Abfülldatum, MHD, abgefüllte Gläser | ApiCore | bei jedem Lauf aktualisiert (Zuordnung über ApiCore-ID) |
| Charge: Shop-Bestand, Bilder, Ernte-Zuordnung | Wabenhain | nie geändert; Bestand > Abfüllmenge wird gemeldet |
| Produkt: Name, Text, Gewicht, Preis, Bilder, Sichtbarkeit | Wabenhain | nur beim ersten Anlegen vorbelegt |
| Bestellungen, Kunden, Bewertungen | Wabenhain | nie Richtung ApiCore |
Umgesetzt in Wabenhain d38f430 (AT: Entscheidungslogik; CR: DB-Ablauf der Server-Action).
Nächste Schritte
Zuständigkeit pro Feld im Sync– erledigt.Eigene, versionierte Sync-Schnittstelle– erledigt:GET /api/v1/shop-sync(Vertragsversion 1, Feld-Allowlist, Berechtigungshop-sync:read). Bewusst ohne „geändert seit“: kleine Datenmenge, Voll-Abgleich heilt verpasste Läufe selbst. Wabenhain nutzt sie seit5642f0c; seit3bc0693ausschließlich (kein Rückfall auf andere Endpunkte).Nur-Lese-API-Schlüssel– erledigt: Verwaltung → Automatisierung → API-Schlüssel. Nur Hash gespeichert, Klartext einmalig angezeigt, Scope nurshop-sync:read, widerrufbar, optional befristet, „zuletzt benutzt“ sichtbar. Wabenhain liest nur nochAPICORE_API_KEY; der Passwort-Login ist entfernt (3bc0693).- Ende-zu-Ende-Test beider Systeme gegen Test-Instanzen.
- Merge/Push.
Offen / Entscheidungen
- Wabenhain-Sync gegen echtes ApiCore nicht Ende zu Ende getestet (keine Zugangsdaten/Testinstanz verbunden). Mapping, Client und Schutzlogik sind unit-getestet bzw. per Code geprüft.
Service-Konto statt API-Schlüssel– erledigt: nur noch API-Schlüssel mit Scopeshop-sync:read.- Status „blockiert“ existiert im Aufgabenmodell nicht. Nicht ergänzt (Schemaänderung + fachliche Definition nötig).
- Produktbeschreibung aus ApiCore wird in Wabenhain übernommen und auf der öffentlichen Herkunftsseite gezeigt – gilt damit als öffentlich. Falls sie intern gemeint ist: klären.
- Automatische Vorschläge haben standardmäßig keinen Termin (keine erfundene Frist);
je Regel über
config.dueInDayseinstellbar. - Übrige Formulare/Seiten wurden nicht einzeln überarbeitet (Fokus: Heute, Aufgaben, Profil).
Bestandsbuch (Tierarzneimittel)
Grundlage: Art. 108 VO (EU) 2019/6, abgeglichen mit dem Muster-Formblatt des Veterinäramts Kassel (Stand März 2026) und der FAQ des LGL Bayern. Gilt für jedes Tierarzneimittel, auch freiverkäufliche Säuren; Aufbewahrung 5 Jahre.
- Export: Stand → „Bestandsbuch {Jahr}“ (
/export/treatment-log.pdf?year=&apiaryId=), ein Blatt je Stand. - Gleiche Behandlungen mehrerer Völker (Mittel, Charge, Menge, Zeitraum, Bezug) stehen in einer Zeile.
- Standort am Behandlungstag: seit dieser Version mit der Behandlung gespeichert (
Treatment.apiaryId). Für ältere Einträge aus der Umsetz-Historie abgeleitet; ist das unsicher, markiert*die Zeile. - Fehlende Pflichtangaben erscheinen als „FEHLT“ statt leer – das Blatt sieht nie vollständiger aus, als es ist.
- Name und Anschrift des Halters: Verwaltung → Automatisierung → Stammdaten & Web. Erscheinen nur im
Bestandsbuch; die öffentliche Chargen-Seite gibt sie nachweislich nicht aus (Test in
public.service.spec.ts).
Überwinterung (Ein-/Auswinterung & Verluste)
- Seite „Überwinterung“ (Betrieb): je Winter (2026 = Winter 2026/27) eine Einwinterung und eine Auswinterung pro Volk. „Als Nächstes“ nennt die noch nicht eingewinterten Völker; „Auswintern“ erscheint erst nach der Einwinterung oder ab Januar.
- Verlustursachen: die drei Kategorien des COLOSS-Monitorings (tot/leer, unlösbares Königinnenproblem, Naturereignis). Keine Diagnose-Liste – vermutete Gründe gehören in die Notiz.
- Verlustrate = verloren / eingewintert (wie COLOSS). Solange Völker nicht ausgewintert sind, heißt sie „vorläufig“; ohne jede Auswinterung wird „–“ statt „0 %“ angezeigt.
- „Volk als abgestorben kennzeichnen“ setzt den Status nur auf ausdrücklichen Wunsch (Häkchen, vorbelegt), in derselben Transaktion und mit Audit-Eintrag.
- Rechte
winter-checks:read/create/update: per Migration an Imker und Mitarbeiter wie Durchsichten, Nur-Lesen-Rollen nur lesen. Einträge sind im Backup enthalten. - Quelle Verlustkategorien: COLOSS-Monitoring (z. B. Gray et al. 2020, J. Apic. Res., doi:10.1080/00218839.2020.1797272).