feat: platform backbone and field capture, first part (checkpoint)

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]>
This commit is contained in:
Nick SzaunigandClaude Opus 5.5 committed 2026-10-13 17:57:54 +02:00
1 parent 10cbe9bf2d
commit c01a38835a
340 files changed
+25695 -1808

No files matched your search

@@ -0,0 +1,39 @@
# Vorlage – keine echten Werte. Kopieren, echte Werte setzen, per `kubectl apply` außerhalb
# der Versionskontrolle anwenden (oder ueber Secret-Manager/Sealed-Secrets im Cluster).
apiVersion: v1
kind: Secret
metadata:
name: apicore-backend-secret
type: Opaque
stringData:
# Host ist der In-Cluster-Service aus deploy/k8s/base/postgres/service.yaml.
# Anderer Namespace als das Backend? Dann FQDN nutzen:
# apicore-postgres.<namespace>.svc.cluster.local
DATABASE_URL: "postgresql://apicore:change-me-postgres-password@apicore-postgres:5432/apicore?schema=public"
# Mindestens 32 Zeichen (server-seitig erzwungen, Start bricht sonst ab) -
# signiert jedes Access-/MFA-/SSO-Token. TOTP- und Webhook-Secrets aus der
# Zeit vor den eigenen Schluesseln (unten) sind noch damit verschluesselt:
# erst nach dem rekey-Job rotieren. Erzeugen z.B. mit: openssl rand -hex 32
JWT_ACCESS_SECRET: "change-me-to-a-random-value-at-least-32-characters-long"
JWT_REFRESH_SECRET: "change-me-refresh-secret"
# One encryption key per purpose (TOTP secrets, webhook signing secrets,
# backup files). Required in production: at least 32 characters each, all
# three different from each other and from both JWT secrets.
# BACKUP_ENCRYPTION_KEY (with MFA_/WEBHOOK_ENCRYPTION_KEY for MFA and webhook
# secrets) is needed to restore backups on another deployment.
# Rotation: old value to <NAME>_PREVIOUS, new <NAME>, run the rekey job,
# then remove <NAME>_PREVIOUS (backup files are not resealed: keep
# BACKUP_ENCRYPTION_KEY_PREVIOUS while older files must restore).
MFA_ENCRYPTION_KEY: "change-me-to-a-third-random-value-at-least-32-characters"
WEBHOOK_ENCRYPTION_KEY: "change-me-to-a-fourth-random-value-at-least-32-characters"
BACKUP_ENCRYPTION_KEY: "change-me-to-another-random-value-at-least-32-characters"
# MFA_ENCRYPTION_KEY_PREVIOUS: ""
# WEBHOOK_ENCRYPTION_KEY_PREVIOUS: ""
# BACKUP_ENCRYPTION_KEY_PREVIOUS: ""
# Entra ID App-Registrierung (SSO). Siehe configmap.example.yaml
# fuer OIDC_ISSUER_URL/OIDC_REDIRECT_URI. Wird auch fuer die
# M365-Kalender-Synchronisation wiederverwendet - dafuer in der
# App-Registrierung zusaetzlich die Application-Permission
# "Calendars.ReadWrite" hinzufuegen (Admin-Consent noetig).
OIDC_CLIENT_ID: "change-me-entra-client-id"
OIDC_CLIENT_SECRET: "change-me-entra-client-secret"