# services/bstein-dev-home/backend-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: bstein-dev-home-backend
  namespace: bstein-dev-home
spec:
  replicas: 1
  revisionHistoryLimit: 3
  selector:
    matchLabels:
      app: bstein-dev-home-backend
  template:
    metadata:
      labels:
        app: bstein-dev-home-backend
      annotations:
        vault.hashicorp.com/agent-inject: "true"
        vault.hashicorp.com/role: "bstein-dev-home"
        vault.hashicorp.com/agent-inject-secret-portal-env.sh: "kv/data/atlas/portal/atlas-portal-db"
        vault.hashicorp.com/agent-inject-template-portal-env.sh: |
          {{ with secret "kv/data/atlas/portal/atlas-portal-db" }}
          export PORTAL_DATABASE_URL="{{ .Data.data.PORTAL_DATABASE_URL }}"
          {{ end }}
          {{ with secret "kv/data/atlas/portal/bstein-dev-home-keycloak-admin" }}
          export KEYCLOAK_ADMIN_CLIENT_SECRET="{{ .Data.data.client_secret }}"
          {{ end }}
          {{ with secret "kv/data/atlas/shared/chat-ai-keys-runtime" }}
          export CHAT_KEY_MATRIX="{{ .Data.data.matrix }}"
          export CHAT_KEY_HOMEPAGE="{{ .Data.data.homepage }}"
          export AI_ATLASBOT_TOKEN="{{ .Data.data.homepage }}"
          {{ end }}
          {{ with secret "kv/data/atlas/shared/portal-e2e-client" }}
          export PORTAL_E2E_CLIENT_ID="{{ .Data.data.client_id }}"
          export PORTAL_E2E_CLIENT_SECRET="{{ .Data.data.client_secret }}"
          {{ end }}
          {{ with secret "kv/data/atlas/mailu/mailu-initial-account-secret" }}
          export SMTP_HOST="mailu-front.mailu-mailserver.svc.cluster.local"
          export SMTP_PORT="587"
          export SMTP_STARTTLS="true"
          export SMTP_USE_TLS="false"
          export SMTP_USERNAME="no-reply-portal@bstein.dev"
          export SMTP_PASSWORD="{{ .Data.data.password }}"
          export SMTP_FROM="no-reply-portal@bstein.dev"
          {{ end }}
    spec:
      automountServiceAccountToken: true
      serviceAccountName: bstein-dev-home
      nodeSelector:
        kubernetes.io/arch: arm64
        node-role.kubernetes.io/worker: "true"
      affinity:
        nodeAffinity:
          preferredDuringSchedulingIgnoredDuringExecution:
            - weight: 100
              preference:
                matchExpressions:
                  - key: kubernetes.io/hostname
                    operator: NotIn
                    values: ["titan-13", "titan-15", "titan-17", "titan-19"]
      imagePullSecrets:
        - name: harbor-regcred
      containers:
        - name: backend
          image: registry.bstein.dev/bstein/bstein-dev-home-backend:0.1.1-95
          imagePullPolicy: Always
          command: ["/bin/sh", "-c"]
          args:
            - >-
              . /vault/secrets/portal-env.sh
              && export SMTP_HOST=""
              && exec gunicorn -b 0.0.0.0:8080 --workers 2 --timeout 1200 app:app
          env:
            - name: AI_CHAT_API
              value: http://ollama.ai.svc.cluster.local:11434
            - name: AI_CHAT_MODEL
              value: qwen2.5-coder:1.5b-instruct-q4_0
            - name: AI_CHAT_TIMEOUT_SEC
              value: "480"
            - name: AI_WARM_ENABLED
              value: "false"
            - name: AI_ATLASBOT_ENDPOINT
              value: http://atlasbot.comms.svc.cluster.local:8090/v1/answer
            - name: AI_ATLASBOT_TIMEOUT_SEC
              value: "30"
            - name: AI_ATLASBOT_TIMEOUT_QUICK_SEC
              value: "25"
            - name: AI_ATLASBOT_MODEL_FAST
              value: qwen2.5-coder:1.5b-instruct-q4_0
            - name: AI_ATLASBOT_MODEL_SMART
              value: qwen2.5:14b-instruct-q4_0
            - name: AI_ATLASBOT_MODEL_GENIUS
              value: qwen2.5:14b-instruct-q4_0
            - name: AI_NODE_NAME
              valueFrom:
                fieldRef:
                  fieldPath: spec.nodeName
            - name: AI_NODE_GPU_MAP
              value: |
                {"titan-20": "Jetson Xavier (edge GPU)", "titan-21": "Jetson Xavier (edge GPU)", "titan-22": "RTX 3050 8GB (local GPU)", "titan-24": "RTX 3080 8GB (local GPU)"}
            - name: KEYCLOAK_ENABLED
              value: "true"
            - name: KEYCLOAK_URL
              value: https://sso.bstein.dev
            - name: KEYCLOAK_REALM
              value: atlas
            - name: KEYCLOAK_CLIENT_ID
              value: bstein-dev-home
            - name: KEYCLOAK_ISSUER
              value: https://sso.bstein.dev/realms/atlas
            - name: KEYCLOAK_JWKS_URL
              value: http://keycloak.sso.svc.cluster.local/realms/atlas/protocol/openid-connect/certs
            - name: KEYCLOAK_ADMIN_URL
              value: http://keycloak.sso.svc.cluster.local
            - name: KEYCLOAK_ADMIN_REALM
              value: atlas
            - name: KEYCLOAK_ADMIN_CLIENT_ID
              value: bstein-dev-home-admin
            - name: ARIADNE_URL
              value: http://ariadne.maintenance.svc.cluster.local
            - name: ARIADNE_TIMEOUT_SEC
              value: "10"
            - name: ARIADNE_GAME_MODE_TIMEOUT_SEC
              value: "900"
            - name: ACCOUNT_ALLOWED_GROUPS
              value: ""
            - name: HTTP_CHECK_TIMEOUT_SEC
              value: "15"
            - name: MONERO_GET_INFO_URL
              value: http://monerod.crypto.svc.cluster.local:18084/get_info
            - name: PORTAL_DB_POOL_MIN
              value: "0"
            - name: PORTAL_DB_POOL_MAX
              value: "5"
            - name: PORTAL_DB_CONNECT_TIMEOUT_SEC
              value: "5"
            - name: PORTAL_DB_LOCK_TIMEOUT_SEC
              value: "5"
            - name: PORTAL_DB_STATEMENT_TIMEOUT_SEC
              value: "30"
            - name: PORTAL_DB_IDLE_IN_TX_TIMEOUT_SEC
              value: "10"
            - name: PORTAL_RUN_MIGRATIONS
              value: "false"
            - name: ACCESS_REQUEST_ENABLED
              value: "false"
            - name: ACCESS_REQUEST_SUBMIT_RATE_LIMIT
              value: "30"
            - name: ACCESS_REQUEST_SUBMIT_RATE_WINDOW_SEC
              value: "3600"
            - name: ACCESS_REQUEST_STATUS_RATE_LIMIT
              value: "120"
            - name: ACCESS_REQUEST_STATUS_RATE_WINDOW_SEC
              value: "60"
            - name: ACCESS_REQUEST_INTERNAL_EMAIL_ALLOWLIST
              value: robotuser@bstein.dev
            - name: WGER_NAMESPACE
              value: health
            - name: WGER_USER_SYNC_CRONJOB
              value: wger-user-sync
            - name: WGER_USER_SYNC_WAIT_TIMEOUT_SEC
              value: "90"
            - name: FIREFLY_NAMESPACE
              value: finance
            - name: FIREFLY_USER_SYNC_CRONJOB
              value: firefly-user-sync
            - name: FIREFLY_USER_SYNC_WAIT_TIMEOUT_SEC
              value: "90"
            - name: VAULTWARDEN_ADMIN_SESSION_TTL_SEC
              value: "900"
            - name: VAULTWARDEN_ADMIN_RATE_LIMIT_BACKOFF_SEC
              value: "60"
          ports:
            - name: http
              containerPort: 8080
          readinessProbe:
            httpGet:
              path: /api/healthz
              port: http
            initialDelaySeconds: 2
            periodSeconds: 5
            timeoutSeconds: 3
          livenessProbe:
            httpGet:
              path: /api/healthz
              port: http
            initialDelaySeconds: 10
            periodSeconds: 10
            timeoutSeconds: 3
          resources:
            requests:
              cpu: 100m
              memory: 128Mi
            limits:
              cpu: 500m
              memory: 512Mi
