feat: T4 wave 3 - notifications per user, suggestions API, varroa bands, split/queen events

- Schema III: per-user notifications (broadcast fan-out migration,
  category, link, requiredPermissions filter), notification preferences
  and settings endpoints, calendar withdrawal switch, occupiedFrames
- Suggestions API: list/summary with permission visibility and paging,
  accept/dismiss/reopen incl. bulk, SuggestionView on all responses
- Varroa traffic light by season and method, young colonies, treatment
  effect window, sample-based percentage; shared withdrawal-window helper
  on Berlin calendar days; GET /varroa-measurements/thresholds
- ColonySplit and QueenAssigned domain events with calendar and webhook
  handlers
- Outbox claims compare against now() rounded to timestamp(3); fixes the
  flaky e2e claims of rows written with SQL now()

Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
This commit is contained in:
Nick SzaunigandClaude Opus 5.5 committed 2026-10-14 14:25:24 +02:00
1 parent d99a697739
commit f468dc5f75
87 files changed
+6022 -510

No files matched your search

@@ -15,6 +15,7 @@ import { UpdateHoneyBatchDto } from '../../honey-batches/dto/update-honey-batch.
import { UpdateHoneyMeasurementDto } from '../../honey-batches/dto/update-honey-measurement.dto';
import { UpdateInspectionDto } from '../../inspections/dto/update-inspection.dto';
import { UpdateLabelTemplateDto } from '../../label-templates/dto/update-label-template.dto';
import { UpdateNotificationSettingsDto } from '../../notifications/dto/update-notification-settings.dto';
import { UpdateProductionBatchDto } from '../../production-batches/dto/update-production-batch.dto';
import { UpdateProductDto } from '../../products/dto/update-product.dto';
import { UpdateProfileDto } from '../../profile/dto/update-profile.dto';
@@ -78,9 +79,23 @@ const contracts: Record<string, NullContract> = {
'syncFeeding',
'syncHarvest',
'syncQueenAssignment',
'syncWithdrawal',
],
clearable: ['groupId'],
},
// quietFrom/quietUntil: null clears them, but only as a pair (the service
// judges the merged values).
UpdateNotificationSettingsDto: {
dto: UpdateNotificationSettingsDto,
notNull: [
'taskDueEnabled',
'digestEnabled',
'digestTime',
'telegramCategories',
'telegramDetail',
],
clearable: ['quietFrom', 'quietUntil'],
},
UpdateBottlingBatchDto: {
dto: UpdateBottlingBatchDto,
notNull: [