# k8s/backend.yaml
# ============================================
# Chat Switchboard - Backend Deployment
# ============================================
# Secrets:
#   switchboard-db-credentials  - POSTGRES_USER, POSTGRES_PASSWORD
#   switchboard-admin           - username, password, email (optional)
#   switchboard-encryption      - ENCRYPTION_KEY (required for v0.9.4+)
#
# PVC:
#   switchboard-storage         - Extraction scratch (always needed)
#   Requires ReadWriteMany (RWX) — see k8s/storage-pvc.yaml
#   With S3 backend, PVC is small (extraction status only, not blobs)
#
# Variables (Gitea CI):
#   STORAGE_CLASS               - StorageClass for PVC (e.g. "cephfs")
#   STORAGE_SIZE                - PVC size (e.g. "10Gi" for PVC, "1Gi" for S3)
#   STORAGE_BACKEND             - "pvc" or "s3" (default: "pvc")
#   EXTRACTION_CONCURRENCY      - Max concurrent extractions (default "3")
#   EXTRACTOR_IMAGE             - Sidecar image (LibreOffice headless)
#
# S3 secrets (Gitea Secrets — only when STORAGE_BACKEND=s3):
#   S3_ENDPOINT                 - e.g. "http://minio:9000" or Ceph RGW URL
#   S3_BUCKET                   - bucket name (must exist before deploy)
#   S3_ACCESS_KEY               - S3 access key
#   S3_SECRET_KEY               - S3 secret key
#
# Admin bootstrap: on every pod start, if SWITCHBOARD_ADMIN_* env vars
# are set, the backend upserts an admin user. Change the secret and
# restart the pod to reset the admin password.
# ============================================
apiVersion: apps/v1
kind: Deployment
metadata:
  name: switchboard-be${DEPLOY_SUFFIX}
  namespace: ${NAMESPACE}
  labels:
    app: switchboard
    component: backend
    env: ${ENVIRONMENT}
spec:
  replicas: ${BE_REPLICAS}
  selector:
    matchLabels:
      app: switchboard
      component: backend
      env: ${ENVIRONMENT}
  template:
    metadata:
      labels:
        app: switchboard
        component: backend
        env: ${ENVIRONMENT}
    spec:
      containers:
      - name: backend
        image: ${BE_IMAGE}:${IMAGE_TAG}
        imagePullPolicy: Always
        ports:
        - containerPort: 8080
          name: http
        env:
        - name: ENVIRONMENT
          value: "${ENVIRONMENT}"
        - name: GIN_MODE
          value: "${GIN_MODE}"
        - name: PORT
          value: "8080"
        - name: BASE_PATH
          value: "${BASE_PATH}"
        - name: POSTGRES_HOST
          value: "${POSTGRES_HOST}"
        - name: POSTGRES_PORT
          value: "${POSTGRES_PORT}"
        - name: POSTGRES_DB
          value: "${DB_NAME}"
        - name: POSTGRES_USER
          valueFrom:
            secretKeyRef:
              name: switchboard-db-credentials
              key: POSTGRES_USER
        - name: POSTGRES_PASSWORD
          valueFrom:
            secretKeyRef:
              name: switchboard-db-credentials
              key: POSTGRES_PASSWORD
        - name: DATABASE_URL
          value: "postgres://$(POSTGRES_USER):$(POSTGRES_PASSWORD)@$(POSTGRES_HOST):$(POSTGRES_PORT)/$(POSTGRES_DB)?sslmode=disable"
        - name: SWITCHBOARD_ADMIN_USERNAME
          valueFrom:
            secretKeyRef:
              name: switchboard-admin
              key: username
              optional: true
        - name: SWITCHBOARD_ADMIN_PASSWORD
          valueFrom:
            secretKeyRef:
              name: switchboard-admin
              key: password
              optional: true
        - name: SWITCHBOARD_ADMIN_EMAIL
          valueFrom:
            secretKeyRef:
              name: switchboard-admin
              key: email
              optional: true
        - name: SEED_USERS
          valueFrom:
            secretKeyRef:
              name: switchboard-seed-users
              key: users
              optional: true
        - name: ENCRYPTION_KEY
          valueFrom:
            secretKeyRef:
              name: switchboard-encryption
              key: ENCRYPTION_KEY
              optional: true
        # File storage (v0.12.0+)
        - name: STORAGE_BACKEND
          value: "${STORAGE_BACKEND}"
        - name: STORAGE_PATH
          value: "/data/storage"
        - name: EXTRACTION_MODE
          value: "sidecar"
        - name: EXTRACTION_CONCURRENCY
          value: "${EXTRACTION_CONCURRENCY}"
        # S3 storage (optional — only used when STORAGE_BACKEND=s3)
        - name: S3_ENDPOINT
          valueFrom:
            secretKeyRef:
              name: switchboard-s3
              key: S3_ENDPOINT
              optional: true
        - name: S3_BUCKET
          valueFrom:
            secretKeyRef:
              name: switchboard-s3
              key: S3_BUCKET
              optional: true
        - name: S3_ACCESS_KEY
          valueFrom:
            secretKeyRef:
              name: switchboard-s3
              key: S3_ACCESS_KEY
              optional: true
        - name: S3_SECRET_KEY
          valueFrom:
            secretKeyRef:
              name: switchboard-s3
              key: S3_SECRET_KEY
              optional: true
        - name: S3_REGION
          valueFrom:
            secretKeyRef:
              name: switchboard-s3
              key: S3_REGION
              optional: true
        - name: S3_PREFIX
          valueFrom:
            secretKeyRef:
              name: switchboard-s3
              key: S3_PREFIX
              optional: true
        - name: S3_FORCE_PATH_STYLE
          value: "true"
        volumeMounts:
        - name: storage
          mountPath: /data/storage
        resources:
          requests:
            memory: "${BE_MEMORY_REQUEST}"
            cpu: "${BE_CPU_REQUEST}"
          limits:
            memory: "${BE_MEMORY_LIMIT}"
            cpu: "${BE_CPU_LIMIT}"
        readinessProbe:
          httpGet:
            path: ${BASE_PATH}/health
            port: 8080
          initialDelaySeconds: 5
          periodSeconds: 10
          timeoutSeconds: 3
          failureThreshold: 3
        livenessProbe:
          httpGet:
            path: ${BASE_PATH}/health
            port: 8080
          initialDelaySeconds: 10
          periodSeconds: 30
          timeoutSeconds: 5
          failureThreshold: 3

      # Extractor sidecar (v0.12.0 Phase 2):
      # Uncomment when switchboard-extractor image is built.
      # See DESIGN-0.12.0.md — Phase 2: Extraction Pipeline.
      #
      # - name: extractor
      #   image: ${EXTRACTOR_IMAGE}:${IMAGE_TAG}
      #   imagePullPolicy: Always
      #   env:
      #   - name: STORAGE_PATH
      #     value: "/data/storage"
      #   - name: EXTRACTION_CONCURRENCY
      #     value: "${EXTRACTION_CONCURRENCY}"
      #   volumeMounts:
      #   - name: storage
      #     mountPath: /data/storage
      #   resources:
      #     requests:
      #       memory: "256Mi"
      #       cpu: "100m"
      #     limits:
      #       memory: "1Gi"
      #       cpu: "1000m"

      volumes:
      - name: storage
        persistentVolumeClaim:
          claimName: switchboard-storage${DEPLOY_SUFFIX}
---
apiVersion: v1
kind: Service
metadata:
  name: switchboard-be${DEPLOY_SUFFIX}
  namespace: ${NAMESPACE}
  labels:
    app: switchboard
    component: backend
    env: ${ENVIRONMENT}
spec:
  selector:
    app: switchboard
    component: backend
    env: ${ENVIRONMENT}
  ports:
  - protocol: TCP
    port: 8080
    targetPort: 8080
    name: http
