Commit Graph
150 Commits
Author SHA1 Message Date
Nick Szaunig 63ab0e842d docs: NFC-Tags in TASKS.md abgehakt 2026-08-25 01:50:26 +02:00
Nick Szaunig 53b781aa04 feat: NFC-Tags beschreiben mit demselben Deep-Link wie der QR-Code
Neuer Endpunkt GET /api/v1/qr/:entityType/:id/link liefert den vom
QR-Dienst bereits genutzten Deep-Link als reine URL statt als SVG,
damit die Web-NFC-API (client-seitig, Chrome/Android) ihn per
NDEFReader.write() auf einen physischen NFC-Tag schreiben kann.
QrService.resolveUrl() ist aus generateSvg() herausgezogen, damit
beide Endpunkte exakt denselben Link erzeugen.

Der bestehende QrCodeDialog bekommt dadurch für alle sechs
QR-fähigen Entitäten (Völker, Bienenstände, Königinnen, Honigchargen,
Lagerbehälter, Abfüllungen) automatisch einen "Auf NFC-Tag
schreiben"-Button, der nur erscheint, wenn window.NDEFReader
tatsächlich existiert – kein Fallback für andere Browser oder iOS,
wie in der Lastenheft vorgesehen.
2026-08-25 01:50:14 +02:00
Nick Szaunig f346859121 docs: Herkunftsseiten + QR-Code in TASKS.md abgehakt 2026-08-25 01:36:08 +02:00
Nick Szaunig d56550c0e5 feat: öffentliche Herkunftsseiten für Honigchargen + Kunden-QR-Code
Neuer unauthentifizierter Endpunkt GET /api/v1/public/batches/:lot
(Abschnitt 27 der Lastenheft) liefert kontrolliert freigegebene
Rückverfolgbarkeitsdaten einer Abfüllcharge – Produkt, Erntemonat,
Bienenstand-Namen, Schleuderdatum, Wassergehalt – ohne interne IDs,
Adressen oder Koordinaten preiszugeben. Die neue Seite /herkunft/{lot}
liegt außerhalb der (app)-Route-Group und damit ohne Login/Sidebar,
gedacht als Ziel eines QR-Codes auf dem Honigglas. Der bestehende
QR-Dienst kennt jetzt den Entity-Typ "bottling-batches" und verlinkt
intern auf diese neue öffentliche Seite; ein entsprechender
QR-Code-Button samt Klartext-Link steht ab sofort auf der
Abfüllungs-Detailseite bereit.
2026-08-25 01:35:47 +02:00
Nick Szaunig 711536f299 docs: Offline-PWA in TASKS.md abgehakt 2026-08-25 01:14:28 +02:00
Nick Szaunig eb66c4bd53 feat: offline-fähige PWA mit IndexedDB-Sync für Durchsichten
Service Worker (public/sw.js) cached die App-Shell für Seiten-GETs
(network-first, cache-fallback). Durchsichten, die offline gespeichert
werden, landen in einer IndexedDB-Warteschlange (idb) statt zu
scheitern und werden automatisch synchronisiert, sobald wieder
Netzwerk verfügbar ist (Mount + online-Event), mit manuellem Retry
über ein Badge im App-Header. Ein modulweiter In-Flight-Lock in
sync.ts verhindert doppelte Synchronisierung bei gleichzeitigen
Aufrufen (gefunden über React-StrictMode-Doppel-Mount, das ohne den
Lock dieselbe Durchsicht zweimal anlegte).
2026-08-25 01:14:18 +02:00
Nick Szaunig 20239885b4 docs: Kartenansicht in TASKS.md als fertig markiert
Siehe vorherigen Commit fuer Implementierung und Live-Verifikation.
2026-08-25 00:40:39 +02:00
Nick Szaunig aa3a777381 feat(frontend): Kartenansicht für Bienenstände (Später-Liste)
Neue Seite /apiaries/map zeigt alle Bienenstände mit hinterlegten
Koordinaten auf einer Leaflet-Karte (OpenStreetMap-Kacheln), mit
Marker-Popup, das zum jeweiligen Bienenstand verlinkt. Karte wird
per next/dynamic mit ssr:false geladen, da Leaflet auf window/document
zugreift.

Breiten-/Längengrad waren zwar seit dem MVP im Backend-DTO vorhanden,
aber über kein Formular erreichbar – ohne diese Lücke wäre die Karte
dauerhaft leer geblieben. Daher Breitengrad-/Längengrad-Felder auf der
Bienenstand-Anlegen- und Bearbeiten-Seite ergänzt.

Marker-Icons werden aus public/leaflet/ bedient statt aus
node_modules-Bild-Imports, da Turbopack Bilder aus node_modules nicht
als StaticImageData auflöst (führte zu "iconUrl not set"-Laufzeitfehler,
live im Browser gefunden und behoben) – der von Leaflet empfohlene
Workaround für Bundler-Icon-Probleme.

Live verifiziert: Koordinaten speichern, Karte zeigt Marker an
korrekter Position, Popup verlinkt korrekt, Empty State bei fehlenden
Koordinaten, mobile Breite ohne Overflow. Zero Konsolenfehler.
2026-08-25 00:38:08 +02:00
Nick Szaunig 4b9f5c7f47 docs: v1.x-Kette end-to-end live verifiziert, v1.x vollständig abgehakt
Kompletten Ablauf live im Browser durchgeklickt: E2E-Kette-Stand ->
E2E-V-001 -> E2E-Q-001 (zugewiesen) -> Durchsicht -> Behandlung
(Ameisensäure) -> Ernte -> Schleuderung -> Honigcharge E2E-HC-001 ->
Lagerbehälter LB-01 (Umlagerung) -> Abfüllung E2E-LOT-001 -> Produkt
"Sommerhonig 500g". Jeder Schritt mit korrekt verknüpften Daten und
ohne Konsolenfehler bestätigt.

Damit ist die gesamte v1.x-Liste aus TASKS.md abgeschlossen.
2026-08-24 23:31:03 +02:00
Nick Szaunig c50c674e94 docs: Modul 33 (Import) und Build-Grün-Checks in TASKS.md abgehakt
Backend und Frontend beide fertig, getestet und live verifiziert
(siehe die beiden vorherigen Commits). Gesamter Backend- und
Frontend-Build war während der gesamten v1.x-Arbeit durchgehend grün.

Offen bleibt nur noch die abschließende End-to-End-Verifikation der
erweiterten Kernkette (Stand -> Volk -> ... -> Produkt) als
zusammenhängender manueller Durchlauf.
2026-08-24 23:07:42 +02:00
Nick Szaunig dfea017f75 feat(frontend): CSV-Import-Seite mit Ergebnisbericht (Modul 33)
Neue Seite /settings/import (nur Administrator, Sidebar-Link unter
Verwaltung): Datentyp wählen (Bienenstände/Völker/Königinnen), CSV-Datei
hochladen, danach Ergebnisbericht mit Zusammenfassung (erstellt/
übersprungen/Fehler) und Zeile-für-Zeile-Tabelle inkl. Statusbadge und
Fehlermeldung.

Live gegen das Backend verifiziert: Upload einer CSV mit einer gültigen
und einer ungültigen Zeile erzeugt korrekt 1 erstellt / 1 Fehler mit
Validierungsmeldung, der neu angelegte Bienenstand erscheint danach in
der regulären Bienenstände-Liste. Zero Konsolenfehler.
2026-08-24 23:07:07 +02:00
Nick Szaunig 4f2f31c05f feat(backend): CSV-Import für Stammdaten (Modul 33)
Neues ImportModule mit einem abhängigkeitsfreien CSV-Parser
(src/import/csv.ts, RFC4180-artig: Quoting, escapte Anführungszeichen,
CRLF/LF) passend zum bereits im ExportModule verwendeten
Schreibformat, sodass exportierte CSVs unverändert wieder importierbar
sind.

Endpunkt: POST /import/:entity (multipart, nur Administrator) für
apiaries, colonies, queens. Jede Zeile wird über die exakt gleichen
class-validator-DTOs geprüft, die auch die regulären POST-Endpunkte
nutzen (CreateApiaryDto/CreateColonyDto/CreateQueenDto) – keine
duplizierte Validierungslogik.

Ergebnisbericht pro Zeile (erstellt/übersprungen/Fehler + Meldung):
- Colonies/Queens: Zeilen mit bereits existierendem Code werden
  übersprungen statt einen Fehler zu werfen (idempotenter Re-Import)
- Colonies lösen den Bienenstand über eine "apiaryName"-Spalte auf
  (case-insensitive), da eine CSV keine internen IDs kennen kann;
  unbekannter Name → Fehlerzeile statt Abbruch des gesamten Imports

Unit-Tests für den CSV-Parser (Quoting, escapte Anführungszeichen,
CRLF, leere Zeilen) und den ImportService (alle drei Entitäten,
Validierungsfehler, Duplikat-Skip, unbekannter Bienenstand). E2E-Tests
über echten multipart-Upload (Rollenprüfung, Dateiendungsprüfung, alle
drei Entitäten, Re-Import-Idempotenz).
2026-08-24 23:00:46 +02:00
Nick Szaunig e051ad956b docs: Modul 30 (Automatisierungen) in TASKS.md als fertig markiert
Backend und Frontend beide fertig, getestet und live verifiziert
(siehe die beiden vorherigen Commits).
2026-08-24 22:47:58 +02:00
Nick Szaunig 5d32026092 feat(frontend): Automatisierungen-Verwaltung + erreichbare Trigger (Modul 30)
Neue Seite /settings/automation-rules (nur Administrator, Sidebar-Link
unter Verwaltung): zeigt alle drei fest hinterlegten Regeln mit
Beschreibung, Aktiv/Inaktiv-Umschalter, editierbarem Aufgabentext und
– nur bei Varroa-Schwellenwert – editierbarem Schwellenwert.

Zusätzlich zwei Lücken im Durchsicht-Formular geschlossen, ohne die
wären zwei der drei Trigger über die Oberfläche nie auslösbar gewesen:
- "Stifte vorhanden"-Checkbox ergänzt (eggsPresent wurde vom Formular
  bisher gar nicht gesendet, obwohl Backend und Typ es unterstützen)
- "Futtervorrat ausreichend"-Checkbox durch ein Select mit
  ausreichend/niedrig/kritisch ersetzt (bisher nur binär, "kritisch"
  war nicht erreichbar)

Live gegen das Backend verifiziert: Speichern einer Durchsicht mit
Königin nicht gesehen + keine Stifte erzeugt automatisch die erwartete
Aufgabe (sichtbar unter /tasks) und eine Benachrichtigung, zero
Konsolenfehler. Aktiv/Inaktiv-Umschalter auf der Automatisierungen-Seite
live getestet.
2026-08-24 17:34:29 +02:00
Nick Szaunig 3f47a6ae8d feat(backend): Automatisierungen mit drei fest hinterlegten Triggern (Modul 30)
Neues AutomationModule mit AutomationRule-Modell (ein Row je Trigger-Typ,
per Unique Constraint erzwungen). Drei fest im Code hinterlegte Trigger,
die Admins nur aktivieren/deaktivieren bzw. deren Konfiguration/Aufgaben-
text anpassen können:

- QUEENLESS_NO_EGGS: Königin nicht gesehen UND keine Stifte vorhanden
  (bei Durchsicht) → Kontrollaufgabe
- VARROA_THRESHOLD: Varroa-Schwellenwert überschritten (konfigurierbar,
  Standard 10 Milben/Tag) → Behandlungsprüfung
- FEED_STATUS_CRITICAL: Futterstatus "kritisch" (bei Durchsicht) →
  Fütterungsaufgabe

Jeder ausgelöste Trigger erzeugt eine Task UND eine Notification sowie
einen Audit-Log-Eintrag; Tasks lösen zusätzlich das bestehende
task.created-Webhook aus. InspectionsService und VarroaService rufen
die Auswertung direkt nach dem jeweiligen Erstellen auf.

Neue Endpunkte (nur Administrator): GET/PATCH /automation-rules.

Unit-Tests für AutomationService (alle drei Trigger, Deaktivierung,
Update mit Audit-Log) sowie E2E-Tests (Rollen-Check, alle drei Trigger
end-to-end über echte Inspection-/Varroa-Endpunkte, Deaktivierung
verhindert weitere Trigger). E2E-Suite zweimal hintereinander grün
verifiziert (Idempotenz der globalen Regel-Zeilen sichergestellt).
Migration auf Dev- und Test-Datenbank angewendet.
2026-08-24 17:25:42 +02:00
Nick Szaunig 42a2be31b4 docs: Modul 32 (Lagerbehälter-Umlagerung) in TASKS.md als fertig markiert
Backend und Frontend beide fertig, getestet und live verifiziert
(siehe die beiden vorherigen Commits).
2026-08-24 17:07:11 +02:00
Nick Szaunig 15f5ab57ae feat(frontend): Lagerbehälter-Sektion und Umlagerungshistorie (Modul 32)
Neue HoneyBatchStorageCard-Komponente auf der Honigcharge-Detailseite:
zeigt den aktuell zugeordneten Lagerbehälter, einen "Umlagern"-Dialog
(Ziel-Lagerbehälter wählen, optionale Notiz) und die vollständige
Umlagerungshistorie (von/nach, Zeitpunkt, Notiz) im etablierten
EmptyState-Stil.

HoneyBatch-Typ um storageContainer erweitert, neue
HoneyBatchRelocation/RelocateHoneyBatchInput-Typen und passende
API-Funktionen ergänzt. Live gegen das Backend verifiziert: Umlagerung
zwischen zwei echten Lagerbehältern aktualisiert die Anzeige und die
Historie korrekt, zero Konsolenfehler.
2026-08-24 17:06:54 +02:00
Nick Szaunig 59a320ae36 feat(backend): Lagerbehälter-Umlagerung für Honigchargen (Modul 32)
Neues HoneyBatchRelocation-Modell dokumentiert jede Umlagerung einer
Honigcharge zwischen Lagerbehältern (von/nach, Zeitpunkt, Benutzer,
Notiz). HoneyBatchesService.relocate() aktualisiert
HoneyBatch.storageContainerId transaktional zusammen mit dem
Historieneintrag; wirft NotFoundException bei unbekanntem Zielbehälter.

Neue Endpunkte: POST /honey-batches/:id/relocate,
GET /honey-batches/:id/relocations. honeyBatchInclude liefert jetzt
zusätzlich den aktuell zugeordneten storageContainer mit.

Unit- und E2E-Tests ergänzt (Mehrfachumlagerung, Historienreihenfolge,
404 bei unbekanntem Behälter). Migration auf Dev- und Test-Datenbank
angewendet.
2026-08-24 16:55:15 +02:00
Nick Szaunig fa13543578 docs: Modul 29 (Dokumente und Bilder) in TASKS.md als fertig markiert
Backend war bereits fertig, Frontend-Upload-Widget wurde soeben ergänzt
und live verifiziert (siehe vorheriger Commit). Anmerkung ergänzt, dass
Durchsicht keine eigene Detailseite hat und daher aktuell nicht
angebunden ist.
2026-08-24 16:43:36 +02:00
Nick Szaunig a21563cc76 feat(frontend): Dokumente-Upload-Widget (Modul 29 Frontend)
Backend war bereits fertig, das Frontend fehlte bislang. Neue
gemeinsame DocumentUploadCard-Komponente (Liste hochgeladener Dateien,
Upload per Dateiauswahl, Download, Löschen mit Bestätigungsdialog da
unumkehrbar) plus dazugehöriges src/lib/documents/ API-Modul.

apiFetch erzwingt bislang immer Content-Type: application/json, was
multipart-Uploads verhindert hätte – daher neue apiFetchFormData-
Hilfsfunktion in api-client.ts ergänzt (kein manuell gesetzter
Content-Type, damit der Browser die multipart-Boundary selbst setzt).

Eingebunden auf allen Detailseiten, die laut TASKS.md Modul 29 vorsehen
und tatsächlich eine eigene Route haben: Bienenstand, Volk, Königin,
Honigcharge. Durchsicht hat keine eigene Detailseite (nur Einträge in
der Volk-Unterliste) und wird daher vorerst ausgelassen.

Live verifiziert: Upload, Download und Löschen (inkl. Bestätigungsdialog)
funktionieren End-to-End gegen das Backend, zero Konsolenfehler auf
allen vier Detailseiten.
2026-08-24 16:43:18 +02:00
Nick Szaunig 9a32c6c11d feat(frontend): Icon-Badges auf Abfüllungs- und Ernte-Detailkarten
Header von BottlingBatchDetailPage und HarvestDetailPage um Icon-Badge
(Package bzw. Boxes im Honig-Gradient) ergänzt, konsistent zum bereits
überarbeiteten Look aller anderen Detailseiten. Schließt die letzten
beiden verbliebenen Detailseiten ohne Icon-Badge ab.
2026-08-24 14:50:34 +02:00
Nick Szaunig c0922387fd feat(frontend): EmptyState statt Fließtext in verschachtelten Listen
Ersetzt den bisherigen reinen Fließtext ("Noch keine X dokumentiert.")
durch die gemeinsame EmptyState-Komponente (Icon, Titel, Beschreibung)
in allen verschachtelten Listen auf den Volk- und Königin-Detailseiten:
Fütterung, Behandlungen, Varroa, Durchsichten, Historie (Volk und
Königin), Bewertungen und Honigmessungen.

Rundet den bereits umgesetzten EmptyState-Look der Hauptlistenseiten
konsistent auf die Detailseiten-Unterkarten ab.
2026-08-24 00:27:04 +02:00
Nick Szaunig e889edd6c5 feat(frontend): PageHeader mit Icon auf allen 13 "Neu"-Formularseiten
Ersetzt die bisherige schlichte CardTitle-Überschrift durch die
gemeinsame PageHeader-Komponente (Icon-Badge im passenden Gradient,
Titel, kurze Beschreibung) auf allen Formularseiten zum Anlegen neuer
Datensätze (Bienenstände, Völker, Königinnen, Aufgaben, Produkte,
Inventar, Schleuderungen, Abfüllungen, Durchsichten, Varroamessungen,
Behandlungen, Fütterungen, Ernten).

Konsistent zum bereits überarbeiteten Look der Listen- und Detailseiten;
die Beschreibungszeile gibt zusätzlich beim Öffnen sofort Kontext, was
die Seite tut – hilfreich für Nutzer, die schnell zwischen vielen
Formularen wechseln.
2026-08-24 00:21:41 +02:00
Nick Szaunig ebfbd2ef6d feat(frontend): Leerer-Zustand-Komponente für alle Listenseiten
Neue gemeinsame EmptyState-Komponente (Icon in Kreis, Titel, Beschreibung,
gestrichelter Rahmen) und Einbindung auf allen 9 Listenseiten mit Tabellen
(Völker, Bienenstände, Königinnen, Aufgaben, Honigchargen, Benutzer,
Inventar, Produkte, Lager mit Behältern und Artikeln).

Bug behoben: Bei leerem Datensatz wurde bisher nur eine Tabelle mit
Kopfzeile und keinerlei Inhalt oder Erklärung angezeigt – wirkte wie ein
Ladefehler statt eines normalen "noch keine Daten"-Zustands. Besonders
für neurodivergente Nutzer wichtig, da Unklarheit über den Systemzustand
("ist das kaputt oder einfach leer?") unnötige kognitive Last erzeugt.
2026-08-23 21:03:59 +02:00
Nick Szaunig fc88c272ae feat(frontend): Icon-Badges auf Honigcharge- und Inventar-Detailkarten
Header von HoneyBatchDetailPage und EquipmentDetailPage um Icon-Badge
(Droplet im Honig-Gradient bzw. Wrench im Himmel-Gradient) ergänzt,
konsistent zum bereits überarbeiteten Look der übrigen Detailseiten.
2026-08-23 20:59:28 +02:00
Nick Szaunig 5be352c4a0 feat(frontend): Icon-Badges auf Detailseiten-Karten (Volk/Bienenstand/Königin)
Header von ColonyEditCard, ApiaryEditCard und QueenEditCard um Icon-Badge
im Honig-/Salbei-Gradient ergänzt, passend zum bereits überarbeiteten
Look der Listen- und Übersichtsseiten.

Zusätzlich Bug behoben: ColonyEditCard und QueenEditCard nutzten bislang
ein hartcodiertes ACTIVE-Ternary statt der gemeinsamen statusTone()-Hilfsfunktion,
wodurch z. B. WEAK/CONSPICUOUS/DISSOLVED-Völker und LOST/DECEASED-Königinnen
auf der eigenen Detailseite nur als neutrales "secondary"-Badge statt in
Warn-/Fehlerfarbe erschienen.
2026-08-23 20:57:01 +02:00
Nick Szaunig 6c764bf885 feat(frontend): PageHeader auf den restlichen Hauptseiten
Inventar, Produkte, Lager, Kalender, Suche und Audit-Log bekommen den
gleichen Gradient-Icon-Header wie die uebrigen Seiten. Lager-Seite hatte
zwei h1-artige Ueberschriften fuer zwei Abschnitte (Lagerbehaelter/
Lagerartikel) auf einer Seite; jetzt ein PageHeader fuer die Seite plus
gleich grosse Unterueberschriften fuer beide Abschnitte statt
uneinheitlicher Groessen.
2026-08-23 20:48:03 +02:00
Nick Szaunig 805effb60b feat(frontend): kontrastreichere Tabs
Aktiver Tab war kaum vom Tab-Leisten-Hintergrund zu unterscheiden
(fast gleicher Ton). Jetzt weisser Karten-Hintergrund mit Schatten
und Primaerfarben-Text fuer den aktiven Tab, groesserer Radius/Padding
passend zum Rest der Oberflaeche.
2026-08-23 20:33:09 +02:00
Nick Szaunig 60b59c120a feat(frontend): einheitliche Seiten-Header mit Icon-Badge
Neue PageHeader-Komponente (Gradient-Icon-Badge + Titel + Beschreibung
+ Aktionen) ersetzt die nackten <h1>-Zeilen auf den meistgenutzten
Seiten (Voelker, Bienenstaende, Koeniginnen, Aufgaben, Honigchargen,
Statistik, Webhooks, Benutzerverwaltung). Gradient variiert pro
Bereich (Honig/Salbei/Himmel), passend zum jeweiligen Sidebar-Icon.
2026-08-23 20:31:03 +02:00
Nick Szaunig 3af56c96fa feat(frontend): Gradient-Buttons, weichere Formulare und Dialoge
Primaerer Button-Stil nutzt jetzt den Honig-Gradient statt Volltonfarbe,
mit Schatten und Hover-Lift. Buttons/Inputs/Select/Textarea/Dialog auf
rounded-xl bzw. rounded-2xl vereinheitlicht, Formularfelder mit Karten-
hintergrund, dezentem Schatten und Hover-Rahmen statt nacktem Rand.
Dialog-Footer-Radius/Aussenabstand an das groessere Popup-Padding
angepasst, sonst waere die Ecke am Fusszeilen-Rand versetzt gewesen.
2026-08-23 20:23:54 +02:00
Nick Szaunig 6a97ebc594 feat(frontend): Karten-Rahmen und ruhigere Typografie fuer alle Tabellen
Die geteilte Table-Komponente (11 Listenseiten: Voelker, Bienenstaende,
Koeniginnen, Aufgaben, Honigchargen, Inventar, Produkte, Lager, Benutzer,
Audit-Log, Webhooks) bekommt jetzt denselben Karten-Rahmen/Schatten wie
der Rest der Oberflaeche statt nackt auf dem Hintergrund zu schweben,
plus getoente Kopfzeile, ruhigere Uppercase-Spaltentitel und mehr
Zeilenabstand.
2026-08-23 20:13:56 +02:00
Nick Szaunig 5cacc3c60d feat(frontend): moderneres visuelles Redesign (Farben, Tiefe, Dashboard-Hero)
Kartenhintergrund und Seitenhintergrund waren fast farbgleich, wodurch
alles flach wirkte trotz vorhandenem Schatten. Staerkerer Kontrast
(--background/--card/--muted/--border), neue Gradient- und
Schatten-Tokens (--gradient-honey/-sage/-sky, --shadow-soft/-elevated).

Card-Komponente: rounded-2xl, echter sichtbarer Schatten, optionaler
Hover-Lift (interactive-Prop). Sidebar: solide Gradient-Badge, kraeftiger
Active-Pill-Zustand statt blassem Tint. Header: sticky mit Blur-Schatten
statt hartem Rand. Dashboard: Gradient-Hero mit Begruessung und
Honeycomb-Muster, farbige Gradient-Icon-Badges pro KPI-Kachel,
Hinweise-Zeilen mit Icon statt rohem Enum-Badge (dabei toten
CONSPICUOUS_COLONY-Style-Key gefunden und auf COLONY_ATTENTION
korrigiert). Honeycomb-Hintergrund aus der Login-Seite in eine
gemeinsame Komponente extrahiert und dort mit dem gleichen
Gradient-Badge-Header konsistent gemacht.
2026-08-23 20:10:33 +02:00
Nick Szaunig 6ab028d1be feat(frontend): confirmation dialogs and undo for destructive-feeling actions
Volk aufloesen, Bienenstand deaktivieren, Benutzer deaktivieren und
Webhook loeschen liefen bisher ohne jede Rueckfrage direkt auf Klick.
Neue wiederverwendbare ConfirmDialog-Komponente erzwingt jetzt eine
bewusste Bestaetigung. Zusaetzlich zeigen Volk/Bienenstand/Benutzer
nach dem Aufloesen/Deaktivieren einen Reaktivieren-Button (nutzt die
neuen Backend-Endpunkte), da diese Aktionen nie ein echtes Loeschen
sind und ein versehentlicher Klick bisher nicht rueckgaengig zu
machen war.
2026-08-23 11:50:45 +02:00
Nick Szaunig 57979f0371 feat(backend): activate endpoint for deactivated users
Symmetrisch zu Modul-27/28-Fix fuer Colony/Apiary: kein Weg, einen
versehentlich deaktivierten Benutzer wieder zu aktivieren. Neuer
POST :id/activate-Endpunkt setzt isActive zurueck auf true und
loescht deactivatedAt; ConflictException wenn bereits aktiv.
2026-08-23 11:44:52 +02:00
Nick Szaunig 6346bfab1d feat(backend): reactivate endpoint for dissolved colonies and inactive apiaries
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.
2026-08-23 11:37:06 +02:00
Nick Szaunig 4a9fdd5c71 feat(backend): Dokumente und Bilder mit lokalem Datei-Upload (Modul 29)
DocumentsModule (Document: entityType/entityId, Dateiname, MIME-Typ,
Groesse, Speicherpfad, Hochgeladen-von) fuer Bienenstand/Volk/Koenigin/
Durchsicht/Honigcharge. Upload als multipart/form-data (Multer, 10 MB
Limit, MIME-Allowlist jpeg/png/webp/pdf), Speicherung unter
DOCUMENTS_STORAGE_PATH (austauschbar). ARCHITECTURE.md Annahme 7
dokumentiert die Multi-Replica-Einschraenkung ohne geteiltes Volume.
2026-08-23 11:29:22 +02:00
Nick Szaunig e4d5af5fa7 feat(frontend): Webhook-Verwaltung fuer Administratoren (Modul 28)
/settings/webhooks: Liste, Anlage-Dialog mit Ereignis-Auswahl und
einmaliger Secret-Anzeige (Kopieren), Loeschen. Sidebar-Eintrag unter
Verwaltung. Live in Chrome verifiziert (Anlegen/Kopieren/Loeschen,
SSRF-Ablehnung, Mobile-Breakpoint); dabei einen Reset-Bug im
Anlage-Dialog gefunden und behoben (Fertig-Button loeschte den
Dialogzustand nicht, da onOpenChange bei programmatischem Schliessen
nicht feuert).
2026-08-23 11:15:48 +02:00
Nick Szaunig 79010a926b fix(backend): close two SSRF bypasses in webhook URL validation
1. The URL guard only classified IP-literal hostnames; any plain domain
   name (the common case) skipped validation entirely. Hostnames are now
   resolved via DNS and every returned address is checked against the
   same private/loopback/link-local ranges (net.BlockList), so an
   attacker-controlled domain pointed at an internal IP is rejected too.
2. fetch() follows redirects by default, so a registered public URL could
   302 to an internal target at delivery time. Delivery now uses
   redirect: 'manual' so such a redirect is never followed.
2026-08-23 11:08:40 +02:00
Nick Szaunig a0f7573af5 fix(backend): block SSRF via webhook subscription URLs
WebhooksService.create() rejected obviously private, loopback, or
link-local URLs (incl. cloud metadata 169.254.169.254 and the
decimal/octal/hex IPv4 shorthand encodings the WHATWG URL parser
normalizes) so an admin-configured webhook can no longer be used to
proxy requests into internal infrastructure. Registration-time only,
no DNS resolution (DNS-rebinding is out of scope for this check).
2026-08-23 07:05:53 +02:00
Nick Szaunig 2458927d38 fix(backend): DELETE /webhooks/:id returns 204 No Content
Matches REST convention and the frontend api-client's existing 204
fast-path, avoiding a JSON-parse crash on an empty response body.
2026-08-23 06:58:13 +02:00
Nick Szaunig 59fdc816a0 feat(backend): Webhooks mit HMAC-signierter Auslieferung (Modul 28)
WebhooksModule (WebhookSubscription: URL, Events, Secret, aktiv) mit
Event-Dispatcher, angehaengt an 10 Ereignisse in 8 bestehenden Services
(colony.created, inspection.created, queen.created, queen.replaced,
harvest.created, batch.created, batch.updated, product.stock_changed,
task.created, task.completed). Auslieferung ist best-effort und blockiert
die ausloesende Anfrage nicht bei Fehlern.
2026-08-23 06:56:56 +02:00
Nick Szaunig 8856d7d0f5 feat(frontend): Statistik-Seite mit animierten Auswertungen (Modul 27)
Tab-basierte /statistics-Seite (Voelker, Koeniginnen, Bienenstaende,
Varroa, Honig, Futter) mit animierten Balkendiagrammen, Sidebar-Eintrag
und Live-Verifikation ueber alle Tabs sowie Mobile-Breakpoint.
2026-08-23 06:41:16 +02:00
Nick Szaunig e8177432b0 feat(backend): Statistik- und Reporting-Endpunkte (Modul 27)
Aggregations-Endpunkte fuer Voelker, Koeniginnen, Bienenstaende, Varroa,
Honig und Fuetterung nach Lastenheft Abschnitt 4.26.
2026-08-23 06:33:50 +02:00
Nick Szaunig 8080a7f5ec feat(frontend): Toast-Bestaetigungen fuer Schnellerfassung
Sonner-Toaster global eingebunden. Erfolgs-Toast auf allen sechs
Schnellerfassungs-Formularen (Durchsicht, Varroa, Behandlung,
Fuetterung, Aufgabe, Ernte) - ohne Toast blieb nach dem Speichern
und Wegnavigieren keine sichtbare Bestaetigung, dass die Eingabe
gespeichert wurde. Wichtig fuer klares Feedback bei zeitkritischer
Erfassung am Bienenstand.
2026-08-23 06:24:14 +02:00
Nick Szaunig ecb3afe1f5 feat(frontend): Linksseitige Navigation, Seitenanimation, ADHS-freundliche Gruppierung
Ersetzt die horizontale Kopfzeilen-Navigation durch eine feste
Sidebar links: gruppiert nach Betrieb / Arbeit / Ernte & Lager /
Verwaltung mit Icon+Label je Eintrag, um kognitive Last zu
reduzieren. Aktiver Zustand klar farblich hervorgehoben. Mobile
Ansicht (Bottom-Nav + FAB) bleibt unveraendert bestehen.

Sanfte, kurze Seitenuebergangsanimation (PageTransition, respektiert
prefers-reduced-motion ueber motion-safe:) fuer Orientierung ohne
Ablenkung.

Ausserdem: wiederkehrenden Anzeigefehler in Status-Filtern behoben
(Select zeigte den rohen Sentinel-Wert "ALL" statt "Alle Status" an)
auf Voelker-, Honigchargen-, Aufgaben-, Koeniginnen- und
Bienenstand-Listen. Live in Desktop-, Tablet- und Mobilbreite
verifiziert, kein horizontales Overflow.
2026-08-23 06:18:35 +02:00
Nick Szaunig fb2b09a929 feat(frontend): Koeniginnenbewertung (Modul 31)
Bewertungsformular (Volksstaerke, Sanftmut, Wabensitz, Schwarm-
trieb, Brutbild, Honigertrag je 1-5) plus Verlauf auf der
Koenigin-Detailseite. Live verifiziert.
2026-08-22 23:01:28 +02:00
Nick Szaunig 50268fa591 feat(backend): Koeniginnenbewertung (Modul 31)
QueenEvaluation-Modell (Volksstaerke, Sanftmut, Wabensitz, Schwarm-
trieb, Brutbild, Honigertrag je Skala 1-5) als Sub-Ressource der
Queens-API: GET/POST /queens/:id/evaluations. Vorgezogen vor Modul
27 (Statistik), da dessen Koeniginnen-Auswertungen auf diesen Daten
aufbauen.
2026-08-22 22:55:36 +02:00
Nick Szaunig 0fc13952fb feat(frontend): Benachrichtigungssystem (Modul 26)
NotificationBell in der Kopfzeile: ungelesene Anzahl als Badge,
Dropdown mit Prioritaets-Badges (INFO/HINWEIS/WARNUNG/KRITISCH),
Klick markiert als gelesen und fuehrt zum verknuepften Objekt.
Ausserdem IDOR im Backend gefunden und behoben (siehe vorheriger
Commit) - live mit einem echten Datensatz verifiziert.
2026-08-22 22:50:45 +02:00
Nick Szaunig 75f0d4fd51 fix(backend): IDOR in POST /notifications/:id/read (Modul 26)
markRead() pruefte bisher nicht, ob die Benachrichtigung dem
anfragenden Nutzer gehoert - jeder authentifizierte Nutzer konnte
fremde Benachrichtigungen als gelesen markieren. Jetzt: 403 bei
fremder Benachrichtigung, weiterhin erlaubt fuer eigene und
Broadcast-Benachrichtigungen (userId = null). E2E-Regressionstest
ergaenzt.
2026-08-22 22:50:00 +02:00
Nick Szaunig a57cde1f9a feat(backend): Benachrichtigungssystem (Modul 26)
NotificationsModule: Notification-Modell mit Prioritaeten INFO/
HINWEIS/WARNUNG/KRITISCH, GET /notifications (eigene + Broadcast),
POST /notifications/:id/read. record() als interne API fuer
kuenftige Automatisierungsregeln (Modul 30) vorgesehen.
2026-08-22 22:43:38 +02:00