Files
ApiCore/deploy/k8s/components/backend-roles/worker-deployment.yaml
T
Nick SzaunigandClaude Opus 5.5 fab7f7e12f feat: T4 wave 10 – bottling quality, phenology and honey chain UI, Telegram link/receive and ops
- Bottling quality: water content above the legal limit (strict >) answers
  409 CONFIRMATION_REQUIRED bound to the measured value; prefill for jar
  size, best-before (shelfLifeMonths, month-end clamping) and water content;
  impossible dates give 400; water-content checks in src/common/quality.
- Frontend phenology: "Entwicklung melden" sheet, IndexedDB v4 queue,
  season header on the apiary page, confirmed revoke for all apiaries.
- Frontend honey chain: "Vorschlag aus …" hints with explicit take-over,
  prefill status note, movement ledger with withdraw/correct dialogs.
- Telegram: link tokens (hashed, single use), private-chat receiver with
  lease and offset CAS, bounded poison-update skip, Retry-After, pending
  deliveries skipped on disconnect; system API for deliveries and retry;
  worker-only secret wiring and manifest policy tests.
- ARCHITECTURE.md §7, §9, §10, §11.11–11.13, Annahmen 51–55.

Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
2026-10-14 22:47:17 +02:00

134 lines
3.9 KiB
YAML

# worker-Rolle: Event-Dispatcher, Kalender-Outbox und Webhook-Zustellung
# (Spec 2026-10-12 Abschnitt 2). Kein Service und kein Ingress; Port 3002
# beantwortet nur /health fuer die Probes. Alle Schleifen arbeiten mit
# SKIP LOCKED, mehr als ein Replica waere also moeglich.
apiVersion: apps/v1
kind: Deployment
metadata:
name: apicore-worker
labels:
app: apicore-worker
spec:
replicas: 1
# Wie bei der api: scheitert die Migration, laeuft der alte Worker weiter.
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1
maxUnavailable: 0
selector:
matchLabels:
app: apicore-worker
template:
metadata:
labels:
app: apicore-worker
db-client: "true"
spec:
automountServiceAccountToken: false
terminationGracePeriodSeconds: 30
securityContext:
runAsNonRoot: true
runAsUser: 1000
runAsGroup: 1000
seccompProfile:
type: RuntimeDefault
volumes:
- name: tmp
emptyDir: {}
initContainers:
# Ohne Seed: den fuehrt nur die api aus.
- name: migrate
image: git.encry.de/nick.rosenloecher/apicore-backend
imagePullPolicy: IfNotPresent
command: ["node", "node_modules/prisma/build/index.js", "migrate", "deploy"]
env:
- name: HOME
value: /tmp
- name: CHECKPOINT_DISABLE
value: "1"
envFrom:
- configMapRef:
name: apicore-backend-config
- secretRef:
name: apicore-backend-secret
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
capabilities:
drop: ["ALL"]
volumeMounts:
- name: tmp
mountPath: /tmp
resources:
requests:
cpu: 50m
memory: 192Mi
limits:
cpu: 500m
memory: 512Mi
containers:
- name: apicore-worker
image: git.encry.de/nick.rosenloecher/apicore-backend
imagePullPolicy: IfNotPresent
command: ["node", "dist/worker.js"]
env:
- name: APICORE_ROLE
value: worker
- name: WORKER_HEALTH_PORT
value: "3002"
- name: HOME
value: /tmp
- name: TELEGRAM_BOT_TOKEN
valueFrom:
secretKeyRef:
name: apicore-telegram
key: TELEGRAM_BOT_TOKEN
optional: true
envFrom:
- configMapRef:
name: apicore-backend-config
- secretRef:
name: apicore-backend-secret
ports:
- name: health
containerPort: 3002
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
capabilities:
drop: ["ALL"]
volumeMounts:
- name: tmp
mountPath: /tmp
# /health ist gesund, wenn die DB in hoechstens 5 s antwortet und
# der letzte Dispatcher-Durchlauf hoechstens 2 Minuten her ist.
# Darum timeoutSeconds 5 statt der Vorgabe von 1 s.
startupProbe:
httpGet:
path: /health
port: health
failureThreshold: 30
periodSeconds: 10
timeoutSeconds: 5
livenessProbe:
httpGet:
path: /health
port: health
periodSeconds: 30
failureThreshold: 3
timeoutSeconds: 5
readinessProbe:
httpGet:
path: /health
port: health
periodSeconds: 15
timeoutSeconds: 5
resources:
requests:
cpu: 20m
memory: 128Mi
limits:
cpu: 200m
memory: 256Mi