- src/lib/motion/tokens.ts und --motion-* in globals.css: Dauern,
Kurven und Feder an einer Stelle; Beute-Bühne liest dieselben Werte.
- AppMotion: LazyMotion strict, Bewegungs-Code (domAnimation) als ein
asynchroner Chunk, 28 kB gzip; check:motion-budget im Docker-Build
neben dem 3D-Budget (Spec 17.6).
- PresenceList: abgehakte Zeilen blenden aus, die übrigen rücken nur bei
„Voll“ nach; „Dezent“ blendet nur, „Aus“ sofort. Die Zeile geht nach
der festen Verzögerung, auch wenn der Server schweigt (Spec 17.5);
Fokus wandert zum nächsten Haken, auch ohne Bewegungs-Chunk.
- Overlays (Sheet, Dialog, Menü, Select) über Base-UI-Start/Ende-Stile
mit Token-Zeiten; Verschiebung und Skalierung nur bei motion-full.
- Kein transition-all, kein Hover-Heben, keine Breiten-Animation von
Daten; Skeleton erst nach 150 ms; Wächter-Regeln für alles davon.
Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
AREAS (37 Bereiche, je Symbol genau einmal; neu compliance, medicines,
voice, hive-systems, system) als einzige Quelle für Kopfzeilen, Menü
und Schnellanlage; PageHeader, DetailHeader und EntityCard nehmen
area statt icon/gradient (Codemod über 72 Dateien). Doppelte Symbole
aufgelöst. BrandMark (Wabe) ersetzt das Verlaufs-Sechseck;
Honig-Banner auf der Startseite durch Überschrift mit Datum ersetzt;
Verläufe aus 33 Verbrauchern entfernt (Token folgen in A4).
Refs #26
Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
- Automation rules propose suggestions instead of creating tasks;
notify per rule config; corrected varroa measurements refresh or
resolve their suggestion
- Inspection values can be taken over into the colony card
(occupiedFrames 0-40, strength deprecated); warning counts use the
same visibility rule as the notification list
- Biotech chains: swarm check after queen cells, queen acceptance
check, split schedules (raise own, queen cell, queen)
- Season autopilot core with A1 inspection due, A2 varroa measurement,
A3 recheck after treatment; colony sync and daily step
- Frontend: suggestions page with groups, bulk accept, undo, paging,
focus management and permission gating
- Frontend: varroa traffic light from seasonal bands, sample size,
one range request for the colony chart
- Notifications: mark-read answers 404 for rows the user may no
longer see
Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
Platform backbone (plan 2026-10-13-plattform-rueckgrat), reviewed tasks:
- run roles api/worker/job/all with shared startup checks (Task 1)
- schema and migration for DomainEvent, deliveries, JobRun, ThrottlerHit (Task 2)
- audit, notifications and domain events written in the same transaction (Task 3)
- dispatcher with SKIP LOCKED claims, retries and stale release (Task 4)
- worker building blocks: tick, LISTEN/NOTIFY wake-up, health (Task 5)
- worker process and entry points (Task 6)
- throttler counters in Postgres (Task 19)
- separate keys per purpose with key ring (Task 20)
- public origin page without exact location (Task 22)
- shop keys split into read and write (Task 23)
- Kustomize base, components, overlay encry, CI validation (Task 26)
Field capture T3 (plan 2026-10-13-t3-erfassung-am-stand), reviewed tasks:
- brood frames, read endpoints, apiary overview and offline pack
- network basics, offline queue v3, navigation sheets, form building blocks
- new inspection with last-time hints and weather, varroa per day,
treatment prefill, apiary page with round
- inspection photo (Task 10) is implemented, review pending
Not rolled out. Remaining tasks follow in later commits.
Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
Backend
- Backup covers every Prisma model (bundle v3); a guard test fails for any
new model that is neither backed up nor explicitly excluded. Unsealed
bundles may only add rows to 27 legacy master/field tables and never
overwrite; counters, ledgers, settings, roles etc. need a sealed file.
Shared import limit BACKUP_MAX_IMPORT_BYTES (default 50 MB, max 256 MB)
with warnings in log and UI; replaced document files are removed after
commit.
- Post-commit side effects (automation, calendar sync, webhooks) run via
runAfterCommit and never turn a committed write into a 500, so retries
with the same Idempotency-Key no longer create duplicates.
- Calendar outbox is multi-replica safe: per-entry claims with stale
takeover, revision-based settle, new Graph event only on 404/410,
transactionId on create, 30 s Graph timeout, URL-encoded ids, GUID
validation for groupId, "run now" in background and resets FAILED.
- Automation tasks are deduplicated under a row lock on the rule.
- Update DTOs follow one null rule: omitted = unchanged, null clears a
nullable field, null on a required field is a 400.
- Varroa mites/day is recomputed on correction; withdrawal status is
checked against the harvest date (?at=), bounded colonyIds; inspection
create is audited; updates re-enqueue calendar entries.
- Dashboard, statistics and apiary/colony guards treat WEAK, CONSPICUOUS
and QUEENLESS colonies as living.
- Prisma errors and body-parser errors are logged without query values or
request bodies.
- Migration 20261012100000_calendar_sync_claims; schema index name aligned
with the existing database object.
Frontend
- Sticky save bar sticks again (no scroll container ancestors, card uses
overflow-clip), safe-area insets, scroll-padding, FAB hidden on forms,
sticky desktop sidebar.
- Inspections record yes / no / not checked instead of silent defaults.
- All living colonies are selectable; shared RecordSelect, EnumSelect,
ChoiceGroup and TriStateField replace per-page copies; selects show
names instead of ids; labels point at real controls.
- Emptied optional fields are sent as null (emptyToNull) so every field
can be cleared; dates default to the local day and are sent via
toApiDate.
- Harvest withdrawal warning uses the harvest date; backup page warns when
a backup outgrows the import limit and lists skipped tables.
Build and docs
- Docker builds fail unless lint, typecheck and unit tests pass.
- ARCHITECTURE.md updated (assumptions 9-12, 19-21, section 8) and spec
docs/superpowers/specs/2026-10-12-plattform-rueckgrat-und-fahrplan-design.md
for the backbone (api/worker/job roles, domain event outbox) and the
feature roadmap T3-T7.
Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
- Pages for raw material lots (beeswax, propolis): list, create in grams
with optional apiary, detail with stock card (harvested / used in
production / withdrawn / remaining) and "used in" batches.
- Production batch form takes the raw material used (lot + grams) and the
batch page shows what it was made from - traceability both ways.
- Sidebar entry "Rohstoffe".
- Removes backend files that were committed into ApiCore-Frontend/src by
mistake in e52a605 (copies of ApiCore-Backend/src/raw-materials).
Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
- Bottling detail shows Abgefüllt / Webshop verkauft / Entnommen / Rest
(negative rest flagged "Prüfen") and the full movement list; buttons
"Entnehmen" (reason, note) and "Inventur korrigieren" (counted
quantity, difference booked).
- Rest column in the bottling list.
- New pages for production batches (list, create, detail with the same
stock card), sidebar entry with its own permission.
- Products get "Art" (honey vs. manufactured goods) and the webshop
category; bottlings only offer honey articles.
Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
- Inputs and selects are 44 px on phones (36 px from sm up); default and
small buttons get 40/36 px on phones.
- Dialogs scroll inside the viewport, so long edit forms keep their
save button reachable on a phone.
- Dialog zoom, sheet slide, sidebar icon scale and stat-bar growth only
move at the motion level "Voll" (motion-full), not at "Dezent".
- QueryState / ErrorState / LoadingState: loading, error with "Erneut
versuchen", empty, data - a failed load can no longer look like an
empty list. EmptyState takes an action for the obvious next step.
Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
- 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]>
Integrations such as the Wabenhain shop sync no longer need a service
account with a password (and without MFA). An admin creates a key under
Verwaltung > Automatisierung > API-Schlüssel.
- Key format ack_<8>_<43>; only its SHA-256 hash is stored, the key is
shown exactly once. Optional expiry, "last used" timestamp, revocation
takes effect immediately; create/revoke are audit-logged without the key.
- A key is not a user: JwtAuthGuard sets request.apiKey, PermissionsGuard
admits it only to routes whose permission is among its scopes and never
to user-only routes. Scopes come from a short allowlist (shop-sync:read).
- Managing keys requires the new permission api-keys:manage.
- Keys are excluded from backups on purpose; a restore means issuing a new
key.
Additive migration (new table).
Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
The sidebar nav sent both entries straight to their "new" creation
form, with no list page to ever browse what had been created -
Schleuderung creation didn't even redirect to a detail page, just to
/colonies, so a saved extraction left no trace anywhere in the UI.
- New /harvests and /extractions list pages (mirrors the existing
products/apiaries list pattern).
- New /extractions/[id] detail page + edit dialog, matching the
harvests one that already existed but had nothing linking to it.
- Sidebar "Ernten"/"Schleuderungen" now point at the list pages instead
of the creation forms.
- Extraction creation now redirects to its detail page instead of
/colonies.
Co-Authored-By: Claude Sonnet 5 <[email protected]>
Adds a one-way push (ApiCore -> M365) of Aufgaben/Durchsichten/
Behandlungen/Fütterungen/Ernten/Königinnen-Zuordnungen into the calendar
of a Microsoft 365 group, via the Graph API.
- CalendarSyncModule (app-only client-credentials Graph auth, separate
from the interactive SSO app registration; new env vars
M365_CALENDAR_TENANT_ID/_CLIENT_ID/_CLIENT_SECRET).
- Outbox + minute-interval cron worker (CalendarSyncOutboxEntry) instead
of a synchronous push, since Graph calls are too slow/flaky to block a
domain create request on; failed syncs retry up to 5 times.
- Per-source-type toggle plus a group-ID field, configurable in
Verwaltung > Automatisierung > Kalender-Sync (Verwaltung > Backup, an
env var still wins on those fields where one applies to related config).
- Hooked into Tasks/Inspections/Treatments/Feedings/Harvests/Queens at
their existing create (and Task update/complete) points; entries render
as all-day Graph events to avoid timezone ambiguity.
- Documents the design decision in ARCHITECTURE.md (Annahme 9), since
this is a net-new capability the lastenheft doesn't scope.
Co-Authored-By: Claude Sonnet 5 <[email protected]>
Menü unter "Verwaltung" wie gewünscht neu strukturiert:
- "Benutzer & Rollen" (/settings/users-roles): Benutzerverwaltung und
Rollen & Rechte als zwei Reiter auf einer Seite (vorher zwei
getrennte Menüpunkte).
- "Automatisierung" (/settings/automation): Webhooks, Wiederkehrende
Aufgaben, Etikettenvorlagen und Social Media Links als Reiter
gebündelt - dazu (eigene Ergänzung, da sonst zwei fast gleich
benannte Menüpunkte "Automatisierung"/"Automatisierungen"
nebeneinander gestanden hätten) auch die bestehenden
Automatisierungsregeln als fünfter Reiter "Regeln".
- "Backup" (/settings/backup): neuer voller Daten-Export/Import
(Commit zuvor) plus der bisherige CSV-Import, beides auf einer Seite.
Aktiver Reiter wird als ?tab=... in der URL gehalten statt nur im
Client-State, damit z.B. "Speichern" im Etiketten-Designer wieder auf
den richtigen Reiter zurückführt.
Technisch: bestehende Seiteninhalte in Reiter-Komponenten extrahiert
(PageHeader entfernt, Rest unverändert übernommen), Dialog-Unterkomponenten
in die neuen Ordner verschoben (git mv, Historie bleibt erhalten). Die
Etiketten-Editor-Routen (/settings/label-templates/new, /[id]) bleiben
unverändert bestehen, nur der Rücksprung nach dem Speichern zeigt jetzt
auf den neuen Reiter. settings/layout.tsx's Berechtigungsliste um
label-templates:read, site-settings:read, backup:export/import ergänzt -
schließt nebenbei eine bestehende Lücke (eine Rolle mit ausschließlich
diesen Rechten wurde vorher faelschlich von der ganzen
Verwaltungssektion ausgesperrt.
Neuer Reiter-Baustein src/components/tab-switcher.tsx (generisch, nach
Vorbild von ActiveHistoryTabs). sidebar.tsx's NavItem.permission
unterstützt jetzt auch ein Array (irgendeine der Berechtigungen reicht),
fuer die neuen gebündelten Menüpunkte.
Lokal verifiziert: typecheck/lint/test/build fehlerfrei, Build zeigt
alle neuen Routen korrekt, Live-Test im Browser (ohne Login) zeigt
sauberen Redirect zu /login ohne Konsolenfehler.
Co-Authored-By: Claude Sonnet 5 <[email protected]>
Abfüllungen hatten keine Übersichtsseite - die Navigation ging direkt
auf /bottling/new, sodass eine angelegte Abfüllung danach nirgends
mehr sichtbar war. Neue Seite /bottling listet alle Abfüllungen
(Archiv), Klick führt zur bestehenden Detail-/Bearbeiten-Seite.
Navigationslink zeigt jetzt auf die Liste statt direkt auf "Neu".
Neues Modul site-settings (Singleton-Tabelle SiteSettings) für
YouTube-/Instagram-/TikTok-Links, verwaltbar unter Verwaltung > Website
(neue Berechtigung site-settings:read/update). Die öffentliche
Herkunftsseite (/herkunft/[lot]) zeigt die konfigurierten Links jetzt
zusätzlich zur Chargen-Herkunft an - PublicService liefert sie über
das bereits oeffentliche /public/batches/:lotNumber mit aus, keine
zusaetzliche unauthentifizierte Route noetig.
Co-Authored-By: Claude Sonnet 5 <[email protected]>
Neue /settings/roles-Seite (Aktiv/Historie, Karten-Grid) zum Anlegen,
Bearbeiten, Deaktivieren und Reaktivieren von Rollen mit einer
Rechte-Matrix (nach Bereich gruppierte Checkboxen, Gruppen-Toggle,
Live-Zaehler), passend zum Backend aus Phase 1-3.
- AuthContext liest Rolle/Rechte jetzt ueber GET /auth/me statt aus
dem JWT (das seit Phase 3 keinen role-Claim mehr traegt); neue
hasPermission()-Hilfsfunktion ersetzt String-Vergleiche gegen "ADMIN".
- Sidebar zeigt Verwaltungs-Eintraege jetzt einzeln nach Berechtigung
(statt Alles-oder-Nichts fuer ADMIN), inkl. neuem "Rollen & Rechte"-
Eintrag.
- Settings-Layout blockt nur noch, wenn gar keine Verwaltungs-
Berechtigung vorhanden ist, statt stur auf die ADMIN-Rolle zu pruefen.
- Benutzerseite: Rollen-Auswahl laedt jetzt aktive Rollen von
GET /roles statt einer festen 5-Werte-Liste; sendet roleId statt
role an POST/PATCH /users.
- Totes jwt.ts (Rolle wurde bislang aus dem Token dekodiert) entfernt.
Live im Browser getestet (Login, Sidebar, Rollen anlegen/bearbeiten/
deaktivieren/reaktivieren, Benutzer-Dialog): dabei einen echten a11y-
Bug gefunden und behoben - Gruppen-Checkboxen fuer mehrwortige
Bereichsnamen ("Wiederkehrende Aufgaben", "Rollen & Rechte") hatten
keinen zugaenglichen Namen, weil die HTML-id ein Leerzeichen enthielt;
jetzt ueber einen Slug erzeugt.
Verifiziert: tsc, lint, build, alle Unit-Tests (14/14) gruen.
Co-Authored-By: Claude Sonnet 5 <[email protected]>
Neue TaskTemplate-Entität mit YEARLY/MONTHLY/INTERVAL_DAYS-Wiederholung.
Fällige Aufgaben werden lazy bei GET /tasks erzeugt (Compare-and-Swap auf
nextDueDate), damit mehrere API-Replicas im Kubernetes-Cluster dieselbe
Vorlage nicht doppelt feuern - ohne zusätzliche Cron-Abhängigkeit.
Frontend: Verwaltungsseite unter /settings/task-templates zum Anlegen,
Auflisten und Deaktivieren von Vorlagen.
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.
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.
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.
/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).
Tab-basierte /statistics-Seite (Voelker, Koeniginnen, Bienenstaende,
Varroa, Honig, Futter) mit animierten Balkendiagrammen, Sidebar-Eintrag
und Live-Verifikation ueber alle Tabs sowie Mobile-Breakpoint.
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.