apiVersion: v1
kind: Namespace
metadata:
  name: citizen-birds
---
apiVersion: v1
kind: ConfigMap
metadata:
  name: bird-survey-api-config
  namespace: citizen-birds
data:
  APP_ENV: production
  LOG_LEVEL: info
  OBSERVATION_TIMEZONE: America/Toronto
  TAXONOMY_VERSION: "2026.2"
  ACCEPTED_MEDIA_TYPES: "image/jpeg,image/png,audio/mpeg,audio/wav"
  MAX_PHOTO_SIZE_MB: "12"
  MAX_AUDIO_SIZE_MB: "40"
  MAX_CHECKLIST_RADIUS_METERS: "5000"
  MIN_OBSERVATION_ACCURACY_METERS: "100"
  REVIEW_QUEUE_ENABLED: "true"
  AUTO_FLAG_RARE_SPECIES: "true"
  DATA_EXPORT_SCHEDULE: "0 4 * * *"
  PUBLIC_API_RATE_LIMIT: "120/min"
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: bird-survey-api
  namespace: citizen-birds
  labels:
    app: bird-survey-api
spec:
  replicas: 3
  selector:
    matchLabels:
      app: bird-survey-api
  template:
    metadata:
      labels:
        app: bird-survey-api
    spec:
      containers:
        - name: api
          image: registry.example.org/citizen-birds/survey-api:2026.07.11
          imagePullPolicy: IfNotPresent
          ports:
            - name: http
              containerPort: 8080
          envFrom:
            - configMapRef:
                name: bird-survey-api-config
            - secretRef:
                name: bird-survey-api-secrets
          env:
            - name: DATABASE_HOST
              value: bird-survey-postgres
            - name: REDIS_HOST
              value: bird-survey-redis
            - name: MEDIA_STORAGE_BUCKET
              value: citizen-birds-media
          readinessProbe:
            httpGet:
              path: /health/ready
              port: http
            initialDelaySeconds: 10
            periodSeconds: 15
            timeoutSeconds: 3
          livenessProbe:
            httpGet:
              path: /health/live
              port: http
            initialDelaySeconds: 30
            periodSeconds: 30
            timeoutSeconds: 5
          resources:
            requests:
              cpu: 250m
              memory: 512Mi
            limits:
              cpu: "1"
              memory: 1Gi
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: bird-survey-worker
  namespace: citizen-birds
  labels:
    app: bird-survey-worker
spec:
  replicas: 2
  selector:
    matchLabels:
      app: bird-survey-worker
  template:
    metadata:
      labels:
        app: bird-survey-worker
    spec:
      containers:
        - name: worker
          image: registry.example.org/citizen-birds/survey-worker:2026.07.11
          command: ["./worker"]
          args:
            - "--queues=media-processing,quality-control,exports,notifications"
          envFrom:
            - configMapRef:
                name: bird-survey-api-config
            - secretRef:
                name: bird-survey-api-secrets
          resources:
            requests:
              cpu: 300m
              memory: 768Mi
            limits:
              cpu: "2"
              memory: 2Gi
---
apiVersion: v1
kind: Service
metadata:
  name: bird-survey-api
  namespace: citizen-birds
  labels:
    app: bird-survey-api
spec:
  type: ClusterIP
  selector:
    app: bird-survey-api
  ports:
    - name: http
      port: 80
      targetPort: http
---
apiVersion: batch/v1
kind: CronJob
metadata:
  name: nightly-observation-export
  namespace: citizen-birds
spec:
  schedule: "0 4 * * *"
  successfulJobsHistoryLimit: 3
  failedJobsHistoryLimit: 5
  jobTemplate:
    spec:
      template:
        spec:
          restartPolicy: OnFailure
          containers:
            - name: exporter
              image: registry.example.org/citizen-birds/survey-worker:2026.07.11
              command: ["./export-observations"]
              args:
                - "--format=dwc-archive"
                - "--include-reviewed-only=true"
                - "--destination=s3://bird-survey-exports/nightly/"
              envFrom:
                - configMapRef:
                    name: bird-survey-api-config
                - secretRef:
                    name: bird-survey-api-secrets
              resources:
                requests:
                  cpu: 200m
                  memory: 512Mi
                limits:
                  cpu: "1"
                  memory: 1Gi