version: 1
kind: pikaoa-platform-delivery

metadata:
  id: pikaoa-enterprise
  owner: unidesk
  repository: pikainc/pikaoa
  spec: PJ2026-03
  relatedIssues:
    - 1952
    - 2110
    - 2128
    - 2263
    - 2274

defaults:
  targetId: NC01

modules:
  builtIn:
    - identity
    - partners
    - contracts
    - invoices
    - audit
  extensionContract:
    registration: module-descriptor
    persistence: schema-owned-initialization
    api: versioned-http-routes
    events: transactional-outbox
    workers: named-consumer

developmentRuntime:
  defaultTargetId: NC01
  targets:
    NC01:
      enabled: true
      node: NC01
      route: NC01:k3s
      namespace: pikaoa-dev
      fieldManager: unidesk-pikaoa-development-runtime
      source:
        mode: pac-source-build
        repository: pikainc/pikaoa
        commitPolicy: pac-revision-required
        branch: master
        worktreeRemote: https://github.com/pikainc/pikaoa.git
        readUrl: http://gitea-http.devops-infra.svc.cluster.local:3000/mirrors/pikainc-pikaoa.git
        snapshotPrefix: refs/unidesk/snapshots/gitea-actions/pikaoa-master-nc01
        pullPolicy: IfNotPresent
      ci:
        lane: pikaoa-dev
        namespace: pikaoa-ci
        pipeline: pikaoa-dev-nc01-pac
        pipelineRunPrefix: pikaoa-dev-nc01
        serviceAccountName: pikaoa-dev-nc01-tekton-runner
        workspaceSize: 8Gi
        pipelineTimeout: 20m0s
        toolsImage: 127.0.0.1:5000/hwlab/hwlab-ci-node-tools:node22-alpine-bun-v1
        buildkitImage: 127.0.0.1:5000/hwlab/buildkit:rootless
      build:
        dockerfiles:
          api: deploy/api.Dockerfile
          worker: deploy/worker.Dockerfile
          web: deploy/web.Dockerfile
        images:
          api: 127.0.0.1:5000/pikaoa/api
          worker: 127.0.0.1:5000/pikaoa/worker
          web: 127.0.0.1:5000/pikaoa/web
        cache:
          mode: registry
          refs:
            api: 127.0.0.1:5000/pikaoa/cache-api:development
            worker: 127.0.0.1:5000/pikaoa/cache-worker:development
            web: 127.0.0.1:5000/pikaoa/cache-web:development
        networkMode: host
      gitops:
        readUrl: http://gitea-http.devops-infra.svc.cluster.local:3000/mirrors/pikainc-pikaoa.git
        writeUrl: http://gitea-http.devops-infra.svc.cluster.local:3000/mirrors/pikainc-pikaoa.git
        branch: nc01-pikaoa-dev-gitops
        manifestPath: deploy/gitops/nc01-dev/resources.yaml
        credential:
          secretName: pac-gitea-pikaoa-dev-nc01
          tokenKey: token
          username: unidesk-admin
        author:
          name: PikaOA Development NC01 CI
          email: pikaoa-dev-nc01-ci@unidesk.local
      database:
        configRef: config/platform-db/postgres-nc01.yaml#exports.connectionStrings.pikaoa-dev-database-url
        name: pikaoa_dev
        username: pikaoa_dev
        schema: pikaoa
        connection:
          sourceRef: /root/.unidesk/.state/secrets/platform-infra/pikaoa-dev.env
          sourceKey: DATABASE_URL
          targetKey: DATABASE_URL
      temporal:
        configRef: config/platform-infra/temporal.yaml
        serviceRef:
          namespace: temporal
          name: temporal-frontend
          port: 7233
        logicalNamespace: unidesk
        taskQueue: pikaoa-dev-outbox
        workflow:
          id: pikaoa-dev-outbox-drain
          drainInterval: 5s
          activityTimeout: 1m
          retry:
            initialInterval: 1s
            maximumInterval: 1m
            maximumAttempts: 8
          continueAsNewEvery: 1000
      native:
        stateDir: .state/pikaoa-native
        logDir: .state/pikaoa-native/logs
        api:
          command: pikaoa-api
          pidFile: api.pid
          logFile: api.jsonl
          endpoint: http://127.0.0.1:28080
        worker:
          command: pikaoa-worker
          pidFile: worker.pid
          logFile: worker.jsonl
          endpoint: http://127.0.0.1:29090
        web:
          workingDirectory: web
          command: bun run native:start
          pidFile: native-web.pid
          logFile: native-web.log
          endpoint: http://127.0.0.1:4173
        webProbe:
          runner:
            node: NC01
            lane: v03
          origin:
            name: native
            mode: custom-url
            baseUrl: http://127.0.0.1:4173
            browserProxyMode: direct
      runtime:
        replicas:
          api: 1
          worker: 1
          web: 1
        resources:
          api: { requests: { cpu: 100m, memory: 128Mi }, limits: { cpu: 1, memory: 512Mi } }
          worker: { requests: { cpu: 100m, memory: 128Mi }, limits: { cpu: 1, memory: 512Mi } }
          web: { requests: { cpu: 50m, memory: 64Mi }, limits: { cpu: 500m, memory: 256Mi } }
          initializer: { requests: { cpu: 100m, memory: 128Mi }, limits: { cpu: 1, memory: 512Mi } }
        secretName: pikaoa-dev-runtime
        configMapName: pikaoa-runtime-config
        apiServiceName: pikaoa-api
        apiPort: 8080
        workerMetricsPort: 8081
        webPort: 8080
        webApiUpstreamEnv: PIKAOA_API_UPSTREAM
        attachment:
          storageRoot: /var/lib/pikaoa/attachments
          maxBytes: 104857600
          claimName: pikaoa-attachments
          storageRequest: 10Gi
          storageClassName: null
          fsGroup: 65532
          accessModes:
            - ReadWriteOnce
        outbox:
          batchSize: 50
          maxAttempts: 4
          retryDelay: 2s
        sessionTTL: 8h
        shutdownTimeout: 10s
        administrator:
          username: admin
          password:
            sourceRef: /root/.unidesk/.env/unified-admin-password.txt
            targetKey: PIKAOA_BOOTSTRAP_ADMIN_PASSWORD
        employee:
          username: employee
          password:
            sourceRef: ~/.unidesk/.env/pikaoa-employee-password.txt
            targetKey: PIKAOA_BOOTSTRAP_EMPLOYEE_PASSWORD
        sessionSecret:
          sourceRef: /root/.unidesk/.state/secrets/platform-infra/pikaoa-dev.env
          sourceKey: PIKAOA_SESSION_SECRET
          targetKey: PIKAOA_SESSION_SECRET
        adminToken:
          sourceRef: /root/.unidesk/.state/secrets/platform-infra/pikaoa-dev.env
          sourceKey: OA_ADMIN_TOKEN
          targetKey: OA_ADMIN_TOKEN
      initializer:
        mode: fresh-database-only
        jobName: pikaoa-init
        backoffLimit: 2
        command:
          - /usr/local/bin/pikaoa
          - migrate
          - up
          - --config
          - /etc/pikaoa/pikaoa.yaml
      exposure:
        serviceName: pikaoa-web
        serviceType: NodePort
        hostIP: 127.0.0.1
        port: 32080
        publicBaseUrl: https://oa-dev.hwpod.com
        expectedA: 152.53.229.148
      webProbe:
        enabled: true
        productId: pikaoa
        runner:
          node: NC01
          lane: v03
        origin:
          name: public
          mode: public
          baseUrl: https://oa-dev.hwpod.com
          browserProxyMode: auto
        authentication:
          mode: ui-form-memory
          path: /login
          usernameSelector: input[name="username"]
          passwordSelector: input[name="password"]
          submitSelector: button[type="submit"]
          authenticatedPath: /dashboard
          authenticatedSelector: .app-shell
          credentials:
            configRef: config/secrets-distribution.yaml
            targetId: pikaoa-dev-nc01
            secretName: pikaoa-dev-runtime
            passwordTargetKey: PIKAOA_BOOTSTRAP_ADMIN_PASSWORD
        defaultSmokeProfile: admin-mvp
        smokeProfiles:
          admin-mvp:
            kind: route-matrix
            routes:
              - path: /contracts
                navigationSelector: a[href="/contracts"]
                readySelector: .page-stack h1
                heading: 合同
              - path: /invoices
                navigationSelector: a[href="/invoices"]
                readySelector: .page-stack h1
                heading: 发票
              - path: /attachments
                navigationSelector: a[href="/attachments"]
                readySelector: .page-stack h1
                heading: 附件
            businessAssertions: &pikaoaAdminMvpBusinessAssertions
              contract:
                number: CLI-2026-001
                rowSelector: .data-table tbody tr
                currentVersionLinkSelector: .current-version-band a
                attachmentSectionSelector: '[data-testid="attachment-reference-section"]'
                attachmentName: pikaoa-contract-sample.pdf
              invoice:
                activeNumber: "26954000000057453886"
                voidedNumber: CLI-INV-2026-001
                voidedLabel: 已废弃
                rowSelector: .data-table tbody tr
                attachmentHeaderSelector: .data-table thead th
                attachmentHeaderText: 附件
                attachmentCellSelector: '[data-testid="invoice-attachment-cell"]'
                minimumActiveAttachmentCount: 1
                attachmentSectionSelector: '[data-testid="attachment-reference-section"]'
                attachmentName: pikaoa-invoice-sample.pdf
                layout:
                  toolbarSelector: '[data-testid="invoice-toolbar"]'
                  listWorkspaceSelector: '[data-testid="invoice-list-workspace"]'
                  advancedFiltersSelector: '#invoice-advanced-filters'
                  screenshotName: pikaoa-invoice-list-density.png
                  maxToolbarHeight: 56
                  maxListTop: 220
                  minListVisibleHeight: 700
                  mobile:
                    screenshotName: pikaoa-invoice-list-density-mobile.png
                    viewport: { width: 390, height: 844 }
                    maxToolbarHeight: 120
                    maxListTop: 300
                    minListVisibleHeight: 400
              attachments:
                rowSelector: .reference-list button
                names:
                  - pikaoa-contract-sample.pdf
                  - pikaoa-invoice-sample.pdf
              resourceReferences: &pikaoaAdminMvpResourceReferences
                filter:
                  partnerLinkSelector: .resource-name-link
                  advancedToggleSelector: 'button[aria-controls="contract-advanced-filters"]'
                  comboboxLabel: 伙伴
                  optionSelector: '[role="option"]'
                  submitSelector: '#contract-advanced-filters button[type="submit"]'
                  clearSelector: 'button[aria-label="清除伙伴"]'
                  queryParameter: partnerId
                  apiPath: /api/v1/contracts
                  idSearchLength: 8
                detail:
                  definitionListSelector: .definition-list
                  resourceLinkSelector: .resource-name-link
                  contract: { label: 伙伴, pathPrefix: /business-partners/ }
                  invoice: { label: 合同, pathPrefix: /contracts/ }
                  attachment: { label: 目标, pathPrefix: /contract-versions/ }
              pdf:
                openButtonSelector: 'button[aria-label="打开文件"]'
                contentPathPrefix: /api/v1/attachments/
                contentPathSuffix: /content
                mediaType: application/pdf
            screenshotName: pikaoa-admin-mvp.png
            viewport:
              width: 1920
              height: 1080
            navigationTimeoutMs: 10000
            settleMs: 500
            commandTimeoutSeconds: 55
            outputLimits:
              network: 18
              failures: 12
              routes: 6
      observability:
        configRef: config/platform-infra/observability.yaml
        otlpEndpoint: otel-collector.platform-infra.svc.cluster.local:4317
        prometheus:
          configRef: config/platform-infra/observability.yaml#metricsBackend.discovery.labelSelector
          scrape: true
          apiPath: /metrics
          workerPath: /metrics
        exporterFailure:
          warning: true
          blocking: false
      probes:
        api:
          livenessPath: /healthz
          readinessPath: /readyz
        worker:
          livenessPath: /healthz
          readinessPath: /readyz
        web:
          livenessPath: /healthz
          readinessPath: /healthz

releaseRuntime:
  defaultTargetId: NC01
  targets:
    NC01:
      enabled: true
      node: NC01
      route: NC01:k3s
      namespace: pikaoa
      fieldManager: unidesk-pikaoa-release-runtime
      source:
        mode: pac-source-build
        repository: pikainc/pikaoa
        commitPolicy: pac-revision-required
        branch: release
        worktreeRemote: https://github.com/pikainc/pikaoa.git
        readUrl: http://gitea-http.devops-infra.svc.cluster.local:3000/mirrors/pikainc-pikaoa.git
        snapshotPrefix: refs/unidesk/snapshots/gitea-actions/pikaoa-release-nc01
        pullPolicy: IfNotPresent
      ci:
        lane: pikaoa
        namespace: pikaoa-ci
        pipeline: pikaoa-nc01-pac
        pipelineRunPrefix: pikaoa-nc01
        serviceAccountName: pikaoa-nc01-tekton-runner
        workspaceSize: 8Gi
        pipelineTimeout: 20m0s
        toolsImage: 127.0.0.1:5000/hwlab/hwlab-ci-node-tools:node22-alpine-bun-v1
        buildkitImage: 127.0.0.1:5000/hwlab/buildkit:rootless
      build:
        dockerfiles:
          api: deploy/api.Dockerfile
          worker: deploy/worker.Dockerfile
          web: deploy/web.Dockerfile
        images:
          api: 127.0.0.1:5000/pikaoa/api
          worker: 127.0.0.1:5000/pikaoa/worker
          web: 127.0.0.1:5000/pikaoa/web
        cache:
          mode: registry
          refs:
            api: 127.0.0.1:5000/pikaoa/cache-api:release
            worker: 127.0.0.1:5000/pikaoa/cache-worker:release
            web: 127.0.0.1:5000/pikaoa/cache-web:release
        networkMode: host
      gitops:
        readUrl: http://gitea-http.devops-infra.svc.cluster.local:3000/mirrors/pikainc-pikaoa.git
        writeUrl: http://gitea-http.devops-infra.svc.cluster.local:3000/mirrors/pikainc-pikaoa.git
        branch: nc01-pikaoa-gitops
        manifestPath: deploy/gitops/nc01/resources.yaml
        credential:
          secretName: pac-gitea-pikaoa-nc01
          tokenKey: token
          username: unidesk-admin
        author:
          name: PikaOA NC01 CI
          email: pikaoa-nc01-ci@unidesk.local
      database:
        configRef: config/platform-db/postgres-nc01.yaml#exports.connectionStrings.pikaoa-database-url
        name: pikaoa
        username: pikaoa
        schema: pikaoa
        connection:
          sourceRef: /root/.unidesk/.state/secrets/platform-infra/pikaoa.env
          sourceKey: DATABASE_URL
          targetKey: DATABASE_URL
      temporal:
        configRef: config/platform-infra/temporal.yaml
        serviceRef:
          namespace: temporal
          name: temporal-frontend
          port: 7233
        logicalNamespace: unidesk
        taskQueue: pikaoa-outbox
        workflow:
          id: pikaoa-outbox-drain
          drainInterval: 5s
          activityTimeout: 1m
          retry:
            initialInterval: 1s
            maximumInterval: 1m
            maximumAttempts: 8
          continueAsNewEvery: 1000
      native:
        stateDir: .state/pikaoa-native
        logDir: .state/pikaoa-native/logs
        api:
          command: pikaoa-api
          pidFile: api.pid
          logFile: api.jsonl
          endpoint: http://127.0.0.1:28080
        worker:
          command: pikaoa-worker
          pidFile: worker.pid
          logFile: worker.jsonl
          endpoint: http://127.0.0.1:29090
        web:
          workingDirectory: web
          command: bun run native:start
          pidFile: native-web.pid
          logFile: native-web.log
          endpoint: http://127.0.0.1:4173
        webProbe:
          runner:
            node: NC01
            lane: v03
          origin:
            name: native
            mode: custom-url
            baseUrl: http://127.0.0.1:4173
            browserProxyMode: direct
      runtime:
        replicas:
          api: 1
          worker: 1
          web: 1
        resources:
          api: { requests: { cpu: 250m, memory: 256Mi }, limits: { cpu: 1, memory: 1Gi } }
          worker: { requests: { cpu: 100m, memory: 256Mi }, limits: { cpu: 1, memory: 1Gi } }
          web: { requests: { cpu: 100m, memory: 128Mi }, limits: { cpu: 500m, memory: 512Mi } }
          initializer: { requests: { cpu: 250m, memory: 256Mi }, limits: { cpu: 1, memory: 1Gi } }
        secretName: pikaoa-runtime
        configMapName: pikaoa-runtime-config
        apiServiceName: pikaoa-api
        apiPort: 8080
        workerMetricsPort: 8081
        webPort: 8080
        webApiUpstreamEnv: PIKAOA_API_UPSTREAM
        attachment:
          storageRoot: /var/lib/pikaoa/attachments
          maxBytes: 104857600
          claimName: pikaoa-attachments
          storageRequest: 20Gi
          storageClassName: null
          fsGroup: 65532
          accessModes:
            - ReadWriteOnce
        outbox:
          batchSize: 50
          maxAttempts: 4
          retryDelay: 2s
        sessionTTL: 8h
        shutdownTimeout: 10s
        administrator:
          username: admin
          password:
            sourceRef: /root/.unidesk/.env/unified-admin-password.txt
            targetKey: PIKAOA_BOOTSTRAP_ADMIN_PASSWORD
        employee:
          username: employee
          password:
            sourceRef: ~/.unidesk/.env/pikaoa-employee-password.txt
            targetKey: PIKAOA_BOOTSTRAP_EMPLOYEE_PASSWORD
        sessionSecret:
          sourceRef: /root/.unidesk/.state/secrets/platform-infra/pikaoa.env
          sourceKey: PIKAOA_SESSION_SECRET
          targetKey: PIKAOA_SESSION_SECRET
        adminToken:
          sourceRef: /root/.unidesk/.state/secrets/platform-infra/pikaoa.env
          sourceKey: OA_ADMIN_TOKEN
          targetKey: OA_ADMIN_TOKEN
      initializer:
        mode: fresh-database-only
        jobName: pikaoa-init
        backoffLimit: 2
        command:
          - /usr/local/bin/pikaoa
          - migrate
          - up
          - --config
          - /etc/pikaoa/pikaoa.yaml
      exposure:
        serviceName: pikaoa-web
        serviceType: NodePort
        hostIP: 127.0.0.1
        port: 32096
        publicBaseUrl: https://oa.hwpod.com
        expectedA: 152.53.229.148
      webProbe:
        enabled: true
        productId: pikaoa
        runner:
          node: NC01
          lane: v03
        origin:
          name: public
          mode: public
          baseUrl: https://oa.hwpod.com
          browserProxyMode: auto
        authentication:
          mode: ui-form-memory
          path: /login
          usernameSelector: input[name="username"]
          passwordSelector: input[name="password"]
          submitSelector: button[type="submit"]
          authenticatedPath: /dashboard
          authenticatedSelector: .app-shell
          credentials:
            configRef: config/secrets-distribution.yaml
            targetId: pikaoa-nc01
            secretName: pikaoa-runtime
            passwordTargetKey: PIKAOA_BOOTSTRAP_ADMIN_PASSWORD
        defaultSmokeProfile: admin-mvp
        smokeProfiles:
          admin-mvp:
            kind: route-matrix
            routes:
              - path: /contracts
                navigationSelector: a[href="/contracts"]
                readySelector: .page-stack h1
                heading: 合同
              - path: /invoices
                navigationSelector: a[href="/invoices"]
                readySelector: .page-stack h1
                heading: 发票
              - path: /attachments
                navigationSelector: a[href="/attachments"]
                readySelector: .page-stack h1
                heading: 附件
            businessAssertions:
              contract:
                number: CLI-CTR-20260716-001
                rowSelector: .data-table tbody tr
                currentVersionLinkSelector: .current-version-band a
                attachmentSectionSelector: '[data-testid="attachment-reference-section"]'
                attachmentName: stdin
              invoice:
                activeNumber: "26954000000057453886"
                voidedNumber: CLI-INV-20260716-001
                voidedLabel: 已废弃
                rowSelector: .data-table tbody tr
                attachmentHeaderSelector: .data-table thead th
                attachmentHeaderText: 附件
                attachmentCellSelector: '[data-testid="invoice-attachment-cell"]'
                minimumActiveAttachmentCount: 1
                attachmentSectionSelector: '[data-testid="attachment-reference-section"]'
                attachmentName: stdin
                layout:
                  toolbarSelector: '[data-testid="invoice-toolbar"]'
                  listWorkspaceSelector: '[data-testid="invoice-list-workspace"]'
                  advancedFiltersSelector: '#invoice-advanced-filters'
                  screenshotName: pikaoa-invoice-list-density.png
                  maxToolbarHeight: 56
                  maxListTop: 220
                  minListVisibleHeight: 700
                  mobile:
                    screenshotName: pikaoa-invoice-list-density-mobile.png
                    viewport: { width: 390, height: 844 }
                    maxToolbarHeight: 120
                    maxListTop: 300
                    minListVisibleHeight: 400
              attachments:
                rowSelector: .reference-list button
                names:
                  - stdin
              resourceReferences: *pikaoaAdminMvpResourceReferences
              pdf:
                openButtonSelector: 'button[aria-label="打开文件"]'
                contentPathPrefix: /api/v1/attachments/
                contentPathSuffix: /content
                mediaType: application/pdf
            screenshotName: pikaoa-admin-mvp.png
            viewport:
              width: 1920
              height: 1080
            navigationTimeoutMs: 10000
            settleMs: 500
            commandTimeoutSeconds: 55
            outputLimits:
              network: 18
              failures: 12
              routes: 6
      observability:
        configRef: config/platform-infra/observability.yaml
        otlpEndpoint: otel-collector.platform-infra.svc.cluster.local:4317
        prometheus:
          configRef: config/platform-infra/observability.yaml#metricsBackend.discovery.labelSelector
          scrape: true
          apiPath: /metrics
          workerPath: /metrics
        exporterFailure:
          warning: true
          blocking: false
      probes:
        api:
          livenessPath: /healthz
          readinessPath: /readyz
        worker:
          livenessPath: /healthz
          readinessPath: /readyz
        web:
          livenessPath: /healthz
          readinessPath: /healthz

delivery:
  targets:
    NC01:
      node: NC01
      lane: pikaoa
      route: NC01:k3s
      namespace: pikaoa
      ci:
        namespace: pikaoa-ci
        pipeline: pikaoa-nc01-pac
        pipelineRunPrefix: pikaoa-nc01
        serviceAccountName: pikaoa-nc01-tekton-runner
        serviceAccountAutomount: false
        roleBindingName: pikaoa-nc01-tekton-runner
        workspaceSize: 8Gi
        pipelineTimeout: 20m0s
        toolsImage: 127.0.0.1:5000/hwlab/hwlab-ci-node-tools:node22-alpine-bun-v1
        buildkitImage: 127.0.0.1:5000/hwlab/buildkit:rootless
      source:
        repository: pikainc/pikaoa
        worktreeRemote: https://github.com/pikainc/pikaoa.git
        branch: release
        readUrl: http://gitea-http.devops-infra.svc.cluster.local:3000/mirrors/pikainc-pikaoa.git
        snapshotPrefix: refs/unidesk/snapshots/gitea-actions/pikaoa-release-nc01
      build:
        dockerfiles:
          api: deploy/api.Dockerfile
          worker: deploy/worker.Dockerfile
          web: deploy/web.Dockerfile
        images:
          api: 127.0.0.1:5000/pikaoa/api
          worker: 127.0.0.1:5000/pikaoa/worker
          web: 127.0.0.1:5000/pikaoa/web
        networkMode: host
        proxy:
          http: http://127.0.0.1:10808
          https: http://127.0.0.1:10808
          all: http://127.0.0.1:10808
          noProxy:
            - localhost
            - 127.0.0.1
            - "::1"
            - 127.0.0.1:5000
            - localhost:5000
            - .svc
            - .svc.cluster.local
            - .cluster.local
            - hyueapi.com
            - .hyueapi.com
      gitops:
        readUrl: http://gitea-http.devops-infra.svc.cluster.local:3000/mirrors/pikainc-pikaoa.git
        writeUrl: http://gitea-http.devops-infra.svc.cluster.local:3000/mirrors/pikainc-pikaoa.git
        branch: nc01-pikaoa-gitops
        manifestPath: deploy/gitops/nc01/resources.yaml
        releaseStatePath: deploy/gitops-state/nc01/release.json
        credentialSecretName: pac-gitea-pikaoa-nc01
        credentialTokenKey: token
        credentialUsername: unidesk-admin
        author:
          name: PikaOA NC01 CI
          email: pikaoa-nc01-ci@unidesk.local
      runtime:
        workloads:
          api:
            kind: Deployment
            name: pikaoa-api
            replicas: 2
            serviceName: pikaoa-api
            port: 8080
            healthPath: /healthz
            metricsPath: /metrics
          worker:
            kind: Deployment
            name: pikaoa-worker
            replicas: 1
            healthPort: 8081
            healthPath: /healthz
            metricsPath: /metrics
          web:
            kind: Deployment
            name: pikaoa-web
            replicas: 2
            serviceName: pikaoa-web
            port: 8080
            healthPath: /healthz
        secret:
          configRef: config/secrets-distribution.yaml
          declarationId: pikaoa-runtime
        database:
          configRef: config/platform-db/postgres-nc01.yaml#exports.connectionStrings.pikaoa-database-url
        observability:
          configRef: config/platform-infra/observability.yaml
          otlpEndpoint: otel-collector.platform-infra.svc.cluster.local:4317
          prometheusScrape: true
          propagation:
            - tracecontext
            - baggage
          exporterFailure:
            warning: true
            blocking: false
      attachmentsBackup:
        enabled: true
        nonBlocking: true
        image: restic/restic:0.18.0
        schedule: "17 4 * * *"
        source:
          namespace: pikaoa
          claimName: pikaoa-attachments
          mountPath: /source
          readOnly: true
          excludes:
            - .tmp
        destination:
          type: local-directory
          route: NC01
          path: /var/backups/unidesk/pikaoa/attachments-restic
          mountPath: /repository
        secret:
          configRef: config/secrets-distribution.yaml
          declarationId: pikaoa-attachments-backup
          targetId: pikaoa-nc01
          secretName: pikaoa-attachments-backup
          keys:
            password: RESTIC_PASSWORD
        retention:
          keepDaily: 14
          keepWeekly: 8
          keepMonthly: 12
        maintenance:
          checkSchedule: "23 5 * * 6"
          forgetPruneSchedule: "41 5 * * 0"
        restoreSmoke:
          jobPrefix: pikaoa-attachments-restore-smoke
          emptyDirSizeLimit: 10Gi
          ttlSecondsAfterFinished: 3600
        jobs:
          initJobPrefix: pikaoa-attachments-restic-init
          backupCronJobName: pikaoa-attachments-backup
          checkCronJobName: pikaoa-attachments-restic-check
          forgetPruneCronJobName: pikaoa-attachments-restic-forget-prune
          serviceAccountName: pikaoa-attachments-backup
          fieldManager: unidesk-pikaoa-attachments-backup
      bootstrapUsers:
        administrator:
          username: admin
          passwordSourceRef: /root/.unidesk/.env/unified-admin-password.txt
        employee:
          username: employee
          passwordSourceRef: ~/.unidesk/.env/pikaoa-employee-password.txt
