apiVersion: v1
kind: Namespace
metadata:
  name: unidesk-dev
  labels:
    app.kubernetes.io/part-of: unidesk
    unidesk.ai/environment: dev
    unidesk.ai/k3s-cluster: d601-native-k3s
---
apiVersion: v1
kind: ResourceQuota
metadata:
  name: unidesk-dev-quota
  namespace: unidesk-dev
  labels:
    app.kubernetes.io/part-of: unidesk
    unidesk.ai/environment: dev
spec:
  hard:
    pods: "30"
    requests.cpu: "4"
    requests.memory: 8Gi
    requests.storage: 30Gi
    limits.cpu: "8"
    limits.memory: 12Gi
    persistentvolumeclaims: "8"
---
apiVersion: v1
kind: LimitRange
metadata:
  name: unidesk-dev-default-limits
  namespace: unidesk-dev
  labels:
    app.kubernetes.io/part-of: unidesk
    unidesk.ai/environment: dev
spec:
  limits:
    - type: Container
      defaultRequest:
        cpu: 50m
        memory: 96Mi
      default:
        cpu: 250m
        memory: 512Mi
      max:
        cpu: "2"
        memory: 5Gi
---
apiVersion: v1
kind: Secret
metadata:
  name: unidesk-dev-runtime-secrets
  namespace: unidesk-dev
  labels:
    app.kubernetes.io/part-of: unidesk
    unidesk.ai/environment: dev
  annotations:
    unidesk.ai/template: "true"
    unidesk.ai/description: "Dev-only placeholder secret; replace values on D601 before exposing dev services."
type: Opaque
stringData:
  POSTGRES_USER: unidesk_dev
  POSTGRES_PASSWORD: change-me-dev-postgres-password
  POSTGRES_DB: unidesk_dev
  DATABASE_URL: postgres://unidesk_dev:change-me-dev-postgres-password@postgres-dev.unidesk-dev.svc.cluster.local:5432/unidesk_dev
  PROVIDER_TOKEN: change-me-D601-dev-provider-token
  UNIDESK_SSH_CLIENT_TOKEN: change-me-dev-scoped-ssh-client-token
  AUTH_USERNAME: admin-dev
  AUTH_PASSWORD: change-me-dev-auth-password
  SESSION_SECRET: change-me-dev-session-secret-minimum-32-characters
  OPENAI_API_KEY: replace-me-openai-api-key
  CRS_OAI_KEY: replace-me-crs-oai-key
  MINIMAX_API_KEY: replace-me-minimax-api-key
---
apiVersion: v1
kind: ConfigMap
metadata:
  name: unidesk-dev-runtime-config
  namespace: unidesk-dev
  labels:
    app.kubernetes.io/part-of: unidesk
    unidesk.ai/environment: dev
data:
  UNIDESK_ENV: dev
  UNIDESK_NAMESPACE: unidesk-dev
  UNIDESK_DEPLOY_REF: origin/master:deploy.json#environments.dev
  UNIDESK_PROVIDER_ID: D601-dev
  UNIDESK_NODE_ID: D601
  UNIDESK_DEV_DATABASE_NAME: unidesk_dev
  UNIDESK_DEV_DATABASE_ALLOWED_HOSTS: postgres-dev,postgres-dev.unidesk-dev,postgres-dev.unidesk-dev.svc,postgres-dev.unidesk-dev.svc.cluster.local
  UNIDESK_DEV_DATABASE_FORBIDDEN_PATTERNS: d601-tcp-egress-gateway,database:5432/unidesk,74.48.78.17:15432
  UNIDESK_SSH_CLIENT_ROUTE_ALLOWLIST: G14,G14:*,D601,D601:*
  DATABASE_VOLUME_NAME: postgres-dev-data
  DATABASE_VOLUME_SIZE: 5Gi
  HEARTBEAT_TIMEOUT_MS: "30000"
  TASK_PENDING_TIMEOUT_MS: "600000"
  DATABASE_POOL_MAX: "2"
  MICROSERVICES_JSON: |
    [
      {
        "id": "code-queue",
        "name": "Code Queue Dev",
        "providerId": "D601-dev",
        "description": "release/v1 dev Code Queue runs inside the unidesk-dev namespace; backend-core-dev proxies it directly to the scheduler/read/write Kubernetes services.",
        "repository": {
          "url": "https://github.com/pikasTech/unidesk",
          "commitId": "6950832600047a3f0c5a847062904959cc79a3da",
          "dockerfile": "src/components/microservices/code-queue/Dockerfile",
          "composeFile": "src/components/microservices/k3sctl-adapter/k3s/dev/unidesk-dev-code-queue.k8s.yaml",
          "composeService": "code-queue",
          "containerName": "k3s:code-queue-dev"
        },
        "backend": {
          "nodeBaseUrl": "http://code-queue-scheduler-dev.unidesk-dev.svc.cluster.local:4222",
          "nodeBindHost": "code-queue-scheduler-dev.unidesk-dev.svc.cluster.local",
          "nodePort": 4222,
          "proxyMode": "dev-k3s-direct",
          "frontendOnly": true,
          "public": false,
          "allowedMethods": ["GET", "HEAD", "POST", "DELETE", "PUT", "PATCH"],
          "allowedPathPrefixes": ["/health", "/live", "/logs", "/api/"],
          "healthPath": "/health",
          "timeoutMs": 30000
        },
        "deployment": {
          "mode": "unidesk-direct"
        },
        "development": {
          "providerId": "D601-dev",
          "sshPassthrough": true,
          "worktreePath": "/home/ubuntu/unidesk-dev-code-queue-deploy"
        },
        "frontend": {
          "route": "/apps/code-queue",
          "integrated": true
        }
      }
    ]
  SESSION_TTL_SECONDS: "28800"
  CODE_QUEUE_MAIN_PROVIDER_ID: D601-dev
  CODE_QUEUE_EXECUTION_PROVIDER_IDS: D601-dev
  CODE_QUEUE_WORKDIR: /workspace-dev
  CODE_QUEUE_REMOTE_WORKDIR: /home/ubuntu/unidesk-dev-workspace
  CODE_QUEUE_DATA_DIR: /var/lib/unidesk-dev/code-queue
  CODE_QUEUE_CODEX_HOME: /var/lib/unidesk-dev/code-queue/codex-home
  CODE_QUEUE_OPENCODE_XDG_DIR: /var/lib/unidesk-dev/code-queue/opencode-xdg
  CODE_QUEUE_DEFAULT_MODEL: gpt-5.5
  CODE_QUEUE_MODELS: gpt-5.5,gpt-5.4-mini,gpt-5.4,deepseek-chat,minimax-m2.7
  CODE_QUEUE_MODEL_REASONING_EFFORTS: gpt-5.5=xhigh
  CODE_QUEUE_NOTIFY_CLAUDEQQ_ENABLED: "false"
  CODE_QUEUE_STARTUP_OA_BACKFILL_ENABLED: "false"
---
apiVersion: v1
kind: ConfigMap
metadata:
  name: unidesk-dev-db-guard
  namespace: unidesk-dev
  labels:
    app.kubernetes.io/part-of: unidesk
    unidesk.ai/environment: dev
data:
  guard-dev-db-url.sh: |
    #!/bin/sh
    set -eu

    database_url="${1:-${DATABASE_URL:-}}"
    expected_name="${UNIDESK_DEV_DATABASE_NAME:-unidesk_dev}"

    if [ -z "$database_url" ]; then
      echo "DATABASE_URL is required for dev DB guard" >&2
      exit 42
    fi

    case "$database_url" in
      *d601-tcp-egress-gateway*|*74.48.78.17:15432*|*database:5432/unidesk*|*/unidesk|*/unidesk\?*)
        echo "refusing production-looking DATABASE_URL in unidesk-dev: $database_url" >&2
        exit 42
        ;;
    esac

    case "$database_url" in
      postgres://*@postgres-dev:5432/"$expected_name"|\
      postgresql://*@postgres-dev:5432/"$expected_name"|\
      postgres://*@postgres-dev.unidesk-dev:5432/"$expected_name"|\
      postgresql://*@postgres-dev.unidesk-dev:5432/"$expected_name"|\
      postgres://*@postgres-dev.unidesk-dev.svc:5432/"$expected_name"|\
      postgresql://*@postgres-dev.unidesk-dev.svc:5432/"$expected_name"|\
      postgres://*@postgres-dev.unidesk-dev.svc.cluster.local:5432/"$expected_name"|\
      postgresql://*@postgres-dev.unidesk-dev.svc.cluster.local:5432/"$expected_name")
        exit 0
        ;;
      *)
        echo "DATABASE_URL must target postgres-dev in unidesk-dev and database $expected_name: $database_url" >&2
        exit 42
        ;;
    esac
---
apiVersion: v1
kind: ConfigMap
metadata:
  name: unidesk-dev-db-init
  namespace: unidesk-dev
  labels:
    app.kubernetes.io/part-of: unidesk
    unidesk.ai/environment: dev
data:
  001_unidesk_dev_schema.sql: |
    BEGIN;

    CREATE TABLE IF NOT EXISTS unidesk_environment_identity (
      key TEXT PRIMARY KEY,
      value TEXT NOT NULL,
      updated_at TIMESTAMPTZ NOT NULL DEFAULT now()
    );

    INSERT INTO unidesk_environment_identity (key, value, updated_at)
    VALUES
      ('environment', 'dev', now()),
      ('namespace', 'unidesk-dev', now()),
      ('database', 'unidesk_dev', now()),
      ('provider_id', 'D601-dev', now()),
      ('deploy_ref', 'origin/master:deploy.json#environments.dev', now())
    ON CONFLICT (key) DO UPDATE SET value = EXCLUDED.value, updated_at = now();

    CREATE TABLE IF NOT EXISTS unidesk_nodes (
      provider_id TEXT PRIMARY KEY,
      name TEXT NOT NULL,
      labels JSONB NOT NULL DEFAULT '{}'::jsonb,
      status TEXT NOT NULL,
      connected_at TIMESTAMPTZ,
      last_heartbeat TIMESTAMPTZ,
      updated_at TIMESTAMPTZ NOT NULL DEFAULT now()
    );

    CREATE TABLE IF NOT EXISTS unidesk_events (
      id BIGSERIAL PRIMARY KEY,
      type TEXT NOT NULL,
      source TEXT NOT NULL,
      payload JSONB NOT NULL DEFAULT '{}'::jsonb,
      created_at TIMESTAMPTZ NOT NULL DEFAULT now()
    );

    CREATE TABLE IF NOT EXISTS unidesk_tasks (
      id TEXT PRIMARY KEY,
      provider_id TEXT NOT NULL,
      command TEXT NOT NULL,
      status TEXT NOT NULL,
      payload JSONB NOT NULL DEFAULT '{}'::jsonb,
      result JSONB,
      created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
      updated_at TIMESTAMPTZ NOT NULL DEFAULT now()
    );

    CREATE TABLE IF NOT EXISTS unidesk_scheduled_tasks (
      id TEXT PRIMARY KEY,
      name TEXT NOT NULL,
      description TEXT NOT NULL DEFAULT '',
      enabled BOOLEAN NOT NULL DEFAULT true,
      schedule_json JSONB NOT NULL DEFAULT '{}'::jsonb,
      action_json JSONB NOT NULL DEFAULT '{}'::jsonb,
      concurrency_policy TEXT NOT NULL DEFAULT 'skip',
      next_run_at TIMESTAMPTZ,
      last_run_at TIMESTAMPTZ,
      last_run_id TEXT,
      created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
      updated_at TIMESTAMPTZ NOT NULL DEFAULT now()
    );

    CREATE TABLE IF NOT EXISTS unidesk_scheduled_task_runs (
      id TEXT PRIMARY KEY,
      schedule_id TEXT NOT NULL REFERENCES unidesk_scheduled_tasks(id) ON DELETE CASCADE,
      trigger_type TEXT NOT NULL,
      status TEXT NOT NULL,
      task_id TEXT,
      result JSONB,
      error TEXT,
      started_at TIMESTAMPTZ,
      finished_at TIMESTAMPTZ,
      duration_ms BIGINT,
      created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
      updated_at TIMESTAMPTZ NOT NULL DEFAULT now()
    );

    CREATE TABLE IF NOT EXISTS unidesk_node_docker_status (
      provider_id TEXT PRIMARY KEY,
      status JSONB NOT NULL DEFAULT '{}'::jsonb,
      collected_at TIMESTAMPTZ,
      updated_at TIMESTAMPTZ NOT NULL DEFAULT now()
    );

    CREATE TABLE IF NOT EXISTS unidesk_node_system_status (
      provider_id TEXT PRIMARY KEY,
      status JSONB NOT NULL DEFAULT '{}'::jsonb,
      collected_at TIMESTAMPTZ,
      updated_at TIMESTAMPTZ NOT NULL DEFAULT now()
    );

    CREATE TABLE IF NOT EXISTS unidesk_node_metric_samples (
      id BIGSERIAL PRIMARY KEY,
      provider_id TEXT NOT NULL,
      collected_at TIMESTAMPTZ NOT NULL,
      cpu_percent DOUBLE PRECISION NOT NULL DEFAULT 0,
      memory_percent DOUBLE PRECISION NOT NULL DEFAULT 0,
      disk_percent DOUBLE PRECISION NOT NULL DEFAULT 0,
      sample JSONB NOT NULL DEFAULT '{}'::jsonb,
      created_at TIMESTAMPTZ NOT NULL DEFAULT now()
    );

    CREATE TABLE IF NOT EXISTS unidesk_code_queue_tasks (
      id TEXT PRIMARY KEY,
      queue_id TEXT NOT NULL DEFAULT 'default',
      status TEXT NOT NULL,
      provider_id TEXT NOT NULL DEFAULT 'D601-dev',
      execution_mode TEXT NOT NULL DEFAULT 'default',
      model TEXT NOT NULL,
      cwd TEXT NOT NULL,
      prompt TEXT NOT NULL,
      base_prompt TEXT NOT NULL DEFAULT '',
      reference_task_ids JSONB NOT NULL DEFAULT '[]'::jsonb,
      reference_injection JSONB,
      reasoning_effort TEXT,
      max_attempts INTEGER NOT NULL,
      current_attempt INTEGER NOT NULL DEFAULT 0,
      current_mode TEXT,
      codex_thread_id TEXT,
      active_turn_id TEXT,
      created_at TIMESTAMPTZ NOT NULL,
      updated_at TIMESTAMPTZ NOT NULL,
      started_at TIMESTAMPTZ,
      finished_at TIMESTAMPTZ,
      read_at TIMESTAMPTZ,
      last_error TEXT,
      last_judge JSONB,
      output_count INTEGER NOT NULL DEFAULT 0,
      event_count INTEGER NOT NULL DEFAULT 0,
      attempt_count INTEGER NOT NULL DEFAULT 0,
      last_output_seq BIGINT NOT NULL DEFAULT 0,
      task_json JSONB NOT NULL
    );

    CREATE TABLE IF NOT EXISTS unidesk_code_queue_queues (
      id TEXT PRIMARY KEY,
      name TEXT NOT NULL DEFAULT '',
      created_at TIMESTAMPTZ NOT NULL,
      updated_at TIMESTAMPTZ NOT NULL
    );

    CREATE TABLE IF NOT EXISTS unidesk_code_queue_workdirs (
      provider_id TEXT NOT NULL,
      execution_mode TEXT NOT NULL DEFAULT 'default',
      path TEXT NOT NULL,
      created_at TIMESTAMPTZ NOT NULL,
      updated_at TIMESTAMPTZ NOT NULL,
      PRIMARY KEY (provider_id, execution_mode, path)
    );

    CREATE TABLE IF NOT EXISTS unidesk_code_queue_notifications (
      id TEXT PRIMARY KEY,
      kind TEXT NOT NULL,
      dedup_key TEXT NOT NULL,
      target TEXT NOT NULL,
      message TEXT NOT NULL,
      created_at TIMESTAMPTZ NOT NULL,
      updated_at TIMESTAMPTZ NOT NULL,
      attempts INTEGER NOT NULL DEFAULT 0,
      next_attempt_at TIMESTAMPTZ NOT NULL,
      last_error TEXT,
      sent_at TIMESTAMPTZ
    );

    ALTER TABLE unidesk_code_queue_tasks ADD COLUMN IF NOT EXISTS queue_id TEXT NOT NULL DEFAULT 'default';
    ALTER TABLE unidesk_code_queue_tasks ADD COLUMN IF NOT EXISTS provider_id TEXT NOT NULL DEFAULT 'D601-dev';
    ALTER TABLE unidesk_code_queue_tasks ADD COLUMN IF NOT EXISTS execution_mode TEXT NOT NULL DEFAULT 'default';
    ALTER TABLE unidesk_code_queue_tasks ADD COLUMN IF NOT EXISTS base_prompt TEXT NOT NULL DEFAULT '';
    ALTER TABLE unidesk_code_queue_tasks ADD COLUMN IF NOT EXISTS reference_task_ids JSONB NOT NULL DEFAULT '[]'::jsonb;
    ALTER TABLE unidesk_code_queue_tasks ADD COLUMN IF NOT EXISTS reference_injection JSONB;
    ALTER TABLE unidesk_code_queue_tasks ADD COLUMN IF NOT EXISTS read_at TIMESTAMPTZ;
    ALTER TABLE unidesk_code_queue_queues ADD COLUMN IF NOT EXISTS name TEXT NOT NULL DEFAULT '';
    ALTER TABLE unidesk_code_queue_workdirs ADD COLUMN IF NOT EXISTS execution_mode TEXT NOT NULL DEFAULT 'default';

    CREATE INDEX IF NOT EXISTS idx_unidesk_nodes_status ON unidesk_nodes(status);
    CREATE INDEX IF NOT EXISTS idx_unidesk_events_created_at ON unidesk_events(created_at DESC);
    CREATE INDEX IF NOT EXISTS idx_unidesk_tasks_provider_status ON unidesk_tasks(provider_id, status);
    CREATE INDEX IF NOT EXISTS idx_unidesk_tasks_updated_at ON unidesk_tasks(updated_at DESC);
    CREATE INDEX IF NOT EXISTS idx_unidesk_tasks_status_updated_at ON unidesk_tasks(status, updated_at DESC);
    CREATE INDEX IF NOT EXISTS idx_unidesk_scheduled_tasks_next_run ON unidesk_scheduled_tasks(enabled, next_run_at);
    CREATE INDEX IF NOT EXISTS idx_unidesk_scheduled_task_runs_schedule_updated ON unidesk_scheduled_task_runs(schedule_id, updated_at DESC);
    CREATE INDEX IF NOT EXISTS idx_unidesk_scheduled_task_runs_status_updated ON unidesk_scheduled_task_runs(status, updated_at DESC);
    CREATE INDEX IF NOT EXISTS idx_unidesk_node_docker_status_updated_at ON unidesk_node_docker_status(updated_at DESC);
    CREATE INDEX IF NOT EXISTS idx_unidesk_node_system_status_updated_at ON unidesk_node_system_status(updated_at DESC);
    CREATE INDEX IF NOT EXISTS idx_unidesk_node_metric_samples_provider_time ON unidesk_node_metric_samples(provider_id, collected_at DESC);
    CREATE INDEX IF NOT EXISTS idx_unidesk_code_queue_tasks_status_updated ON unidesk_code_queue_tasks(status, updated_at DESC);
    CREATE INDEX IF NOT EXISTS idx_unidesk_code_queue_tasks_queue_status_updated ON unidesk_code_queue_tasks(queue_id, status, updated_at DESC);
    CREATE INDEX IF NOT EXISTS idx_unidesk_code_queue_tasks_provider_updated ON unidesk_code_queue_tasks(provider_id, updated_at DESC);
    CREATE INDEX IF NOT EXISTS idx_unidesk_code_queue_tasks_execution_mode_updated ON unidesk_code_queue_tasks(execution_mode, updated_at DESC);
    CREATE INDEX IF NOT EXISTS idx_unidesk_code_queue_tasks_created ON unidesk_code_queue_tasks(created_at DESC);
    CREATE INDEX IF NOT EXISTS idx_unidesk_code_queue_tasks_queue_created ON unidesk_code_queue_tasks(queue_id, created_at DESC, id DESC);
    CREATE INDEX IF NOT EXISTS idx_unidesk_code_queue_tasks_unread_terminal ON unidesk_code_queue_tasks(queue_id, updated_at DESC) WHERE read_at IS NULL AND status IN ('succeeded', 'failed', 'canceled');
    CREATE INDEX IF NOT EXISTS idx_unidesk_code_queue_tasks_model_updated ON unidesk_code_queue_tasks(model, updated_at DESC);
    CREATE INDEX IF NOT EXISTS idx_code_queue_tasks_list ON unidesk_code_queue_tasks(status, updated_at DESC, id DESC);
    CREATE INDEX IF NOT EXISTS idx_code_queue_tasks_queue_updated ON unidesk_code_queue_tasks(queue_id, updated_at DESC, id DESC);

    INSERT INTO unidesk_code_queue_queues (id, name, created_at, updated_at)
    VALUES ('default', 'default', now(), now())
    ON CONFLICT (id) DO UPDATE SET name = EXCLUDED.name, updated_at = GREATEST(unidesk_code_queue_queues.updated_at, EXCLUDED.updated_at);

    COMMIT;
---
apiVersion: v1
kind: Service
metadata:
  name: postgres-dev
  namespace: unidesk-dev
  labels:
    app.kubernetes.io/name: postgres-dev
    app.kubernetes.io/part-of: unidesk
    unidesk.ai/environment: dev
spec:
  type: ClusterIP
  selector:
    app.kubernetes.io/name: postgres-dev
    unidesk.ai/environment: dev
  ports:
    - name: pg
      port: 5432
      targetPort: pg
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: postgres-dev
  namespace: unidesk-dev
  labels:
    app.kubernetes.io/name: postgres-dev
    app.kubernetes.io/part-of: unidesk
    unidesk.ai/environment: dev
spec:
  serviceName: postgres-dev
  replicas: 1
  selector:
    matchLabels:
      app.kubernetes.io/name: postgres-dev
      unidesk.ai/environment: dev
  template:
    metadata:
      labels:
        app.kubernetes.io/name: postgres-dev
        app.kubernetes.io/part-of: unidesk
        unidesk.ai/environment: dev
        unidesk.ai/node-id: D601
    spec:
      nodeSelector:
        unidesk.ai/node-id: D601
      terminationGracePeriodSeconds: 30
      securityContext:
        fsGroup: 70
      containers:
        - name: postgres
          image: postgres:16-alpine
          imagePullPolicy: IfNotPresent
          args:
            - -c
            - shared_buffers=64MB
            - -c
            - max_connections=30
            - -c
            - work_mem=4MB
            - -c
            - maintenance_work_mem=64MB
            - -c
            - effective_cache_size=256MB
          ports:
            - name: pg
              containerPort: 5432
          env:
            - name: POSTGRES_USER
              valueFrom:
                secretKeyRef:
                  name: unidesk-dev-runtime-secrets
                  key: POSTGRES_USER
            - name: POSTGRES_PASSWORD
              valueFrom:
                secretKeyRef:
                  name: unidesk-dev-runtime-secrets
                  key: POSTGRES_PASSWORD
            - name: POSTGRES_DB
              valueFrom:
                secretKeyRef:
                  name: unidesk-dev-runtime-secrets
                  key: POSTGRES_DB
          volumeMounts:
            - name: postgres-dev-data
              mountPath: /var/lib/postgresql/data
          readinessProbe:
            exec:
              command:
                - sh
                - -ec
                - pg_isready -U "$POSTGRES_USER" -d "$POSTGRES_DB"
            periodSeconds: 5
            timeoutSeconds: 3
            failureThreshold: 18
          livenessProbe:
            exec:
              command:
                - sh
                - -ec
                - pg_isready -U "$POSTGRES_USER" -d "$POSTGRES_DB"
            periodSeconds: 10
            timeoutSeconds: 3
            failureThreshold: 6
          startupProbe:
            exec:
              command:
                - sh
                - -ec
                - pg_isready -U "$POSTGRES_USER" -d "$POSTGRES_DB"
            periodSeconds: 5
            timeoutSeconds: 3
            failureThreshold: 60
          resources:
            requests:
              cpu: 100m
              memory: 256Mi
            limits:
              cpu: 500m
              memory: 512Mi
  volumeClaimTemplates:
    - metadata:
        name: postgres-dev-data
        labels:
          app.kubernetes.io/name: postgres-dev
          app.kubernetes.io/part-of: unidesk
          unidesk.ai/environment: dev
      spec:
        accessModes:
          - ReadWriteOnce
        resources:
          requests:
            storage: 5Gi
---
apiVersion: batch/v1
kind: Job
metadata:
  name: unidesk-dev-db-migrate
  namespace: unidesk-dev
  labels:
    app.kubernetes.io/name: unidesk-dev-db-migrate
    app.kubernetes.io/part-of: unidesk
    unidesk.ai/environment: dev
spec:
  backoffLimit: 6
  ttlSecondsAfterFinished: 86400
  template:
    metadata:
      labels:
        app.kubernetes.io/name: unidesk-dev-db-migrate
        app.kubernetes.io/part-of: unidesk
        unidesk.ai/environment: dev
    spec:
      restartPolicy: OnFailure
      nodeSelector:
        unidesk.ai/node-id: D601
      containers:
        - name: migrate
          image: postgres:16-alpine
          imagePullPolicy: IfNotPresent
          env:
            - name: DATABASE_URL
              valueFrom:
                secretKeyRef:
                  name: unidesk-dev-runtime-secrets
                  key: DATABASE_URL
            - name: UNIDESK_DEV_DATABASE_NAME
              valueFrom:
                configMapKeyRef:
                  name: unidesk-dev-runtime-config
                  key: UNIDESK_DEV_DATABASE_NAME
          command:
            - /bin/sh
            - -ec
          args:
            - |
              /etc/unidesk-dev-guard/guard-dev-db-url.sh "$DATABASE_URL"
              until pg_isready -d "$DATABASE_URL"; do
                echo "waiting for postgres-dev"
                sleep 2
              done
              psql "$DATABASE_URL" -v ON_ERROR_STOP=1 -f /migrations/001_unidesk_dev_schema.sql
          volumeMounts:
            - name: db-guard
              mountPath: /etc/unidesk-dev-guard
              readOnly: true
            - name: db-init
              mountPath: /migrations
              readOnly: true
          resources:
            requests:
              cpu: 25m
              memory: 64Mi
            limits:
              cpu: 250m
              memory: 256Mi
      volumes:
        - name: db-guard
          configMap:
            name: unidesk-dev-db-guard
            defaultMode: 0555
        - name: db-init
          configMap:
            name: unidesk-dev-db-init
