apiVersion: v1
kind: Namespace
metadata:
  name: chittychain
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: chittychain-api
  namespace: chittychain
  labels:
    app: chittychain-api
    version: v1
spec:
  replicas: 3
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxUnavailable: 1
      maxSurge: 1
  selector:
    matchLabels:
      app: chittychain-api
  template:
    metadata:
      labels:
        app: chittychain-api
        version: v1
      annotations:
        prometheus.io/scrape: "true"
        prometheus.io/port: "5000"
        prometheus.io/path: "/metrics"
    spec:
      securityContext:
        runAsNonRoot: true
        runAsUser: 1000
        fsGroup: 1000
      serviceAccountName: chittychain-api
      containers:
      - name: api
        image: chittychain/api:latest
        imagePullPolicy: Always
        ports:
        - containerPort: 5000
          name: http
          protocol: TCP
        env:
        - name: NODE_ENV
          value: "production"
        - name: PORT
          value: "5000"
        - name: DATABASE_URL
          valueFrom:
            secretKeyRef:
              name: chittychain-secrets
              key: database-url
        - name: JWT_SECRET
          valueFrom:
            secretKeyRef:
              name: chittychain-secrets
              key: jwt-secret
        - name: ENCRYPTION_KEY
          valueFrom:
            secretKeyRef:
              name: chittychain-secrets
              key: encryption-key
        - name: VAULT_TOKEN
          valueFrom:
            secretKeyRef:
              name: chittychain-secrets
              key: vault-token
        - name: STRIPE_SECRET_KEY
          valueFrom:
            secretKeyRef:
              name: chittychain-secrets
              key: stripe-secret
        resources:
          requests:
            memory: "512Mi"
            cpu: "500m"
          limits:
            memory: "1Gi"
            cpu: "1000m"
        livenessProbe:
          httpGet:
            path: /health
            port: 5000
          initialDelaySeconds: 30
          periodSeconds: 30
          timeoutSeconds: 10
          failureThreshold: 3
        readinessProbe:
          httpGet:
            path: /health
            port: 5000
          initialDelaySeconds: 10
          periodSeconds: 10
          timeoutSeconds: 5
          failureThreshold: 3
        securityContext:
          allowPrivilegeEscalation: false
          readOnlyRootFilesystem: true
          capabilities:
            drop:
            - ALL
        volumeMounts:
        - name: tmp
          mountPath: /tmp
        - name: uploads
          mountPath: /app/uploads
      volumes:
      - name: tmp
        emptyDir: {}
      - name: uploads
        persistentVolumeClaim:
          claimName: chittychain-uploads
---
apiVersion: v1
kind: Service
metadata:
  name: chittychain-api-service
  namespace: chittychain
  labels:
    app: chittychain-api
spec:
  type: ClusterIP
  ports:
  - port: 80
    targetPort: 5000
    protocol: TCP
    name: http
  selector:
    app: chittychain-api
---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: chittychain-api
  namespace: chittychain
  labels:
    app: chittychain-api
---
apiVersion: v1
kind: Secret
metadata:
  name: chittychain-secrets
  namespace: chittychain
type: Opaque
stringData:
  database-url: "postgresql://user:password@postgres:5432/chittychain"
  jwt-secret: "your-production-jwt-secret-32-characters-min"
  encryption-key: "your-production-encryption-key-32-chars!"
  vault-token: "your-vault-token"
  stripe-secret: "sk_live_your_stripe_secret_key"
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: chittychain-uploads
  namespace: chittychain
spec:
  accessModes:
    - ReadWriteMany
  resources:
    requests:
      storage: 100Gi
  storageClassName: fast-ssd
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: chittychain-api-ingress
  namespace: chittychain
  annotations:
    kubernetes.io/ingress.class: nginx
    cert-manager.io/cluster-issuer: letsencrypt-prod
    nginx.ingress.kubernetes.io/force-ssl-redirect: "true"
    nginx.ingress.kubernetes.io/rate-limit: "100"
    nginx.ingress.kubernetes.io/rate-limit-window: "1m"
    nginx.ingress.kubernetes.io/proxy-body-size: "100m"
spec:
  tls:
  - hosts:
    - api.chittychain.com
    secretName: chittychain-api-tls
  rules:
  - host: api.chittychain.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: chittychain-api-service
            port:
              number: 80
---
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: chittychain-api-hpa
  namespace: chittychain
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: chittychain-api
  minReplicas: 3
  maxReplicas: 20
  metrics:
  - type: Resource
    resource:
      name: cpu
      target:
        type: Utilization
        averageUtilization: 70
  - type: Resource
    resource:
      name: memory
      target:
        type: Utilization
        averageUtilization: 80
  behavior:
    scaleUp:
      stabilizationWindowSeconds: 120
      policies:
      - type: Percent
        value: 100
        periodSeconds: 60
    scaleDown:
      stabilizationWindowSeconds: 300
      policies:
      - type: Percent
        value: 50
        periodSeconds: 60
---
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
  name: chittychain-api-pdb
  namespace: chittychain
spec:
  minAvailable: 2
  selector:
    matchLabels:
      app: chittychain-api
---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: chittychain-api-netpol
  namespace: chittychain
spec:
  podSelector:
    matchLabels:
      app: chittychain-api
  policyTypes:
  - Ingress
  - Egress
  ingress:
  - from:
    - namespaceSelector:
        matchLabels:
          name: ingress-nginx
    ports:
    - protocol: TCP
      port: 5000
  - from:
    - namespaceSelector:
        matchLabels:
          name: monitoring
    ports:
    - protocol: TCP
      port: 5000
  egress:
  - to:
    - namespaceSelector:
        matchLabels:
          name: database
    ports:
    - protocol: TCP
      port: 5432
  - to: []
    ports:
    - protocol: TCP
      port: 443
    - protocol: TCP
      port: 80
    - protocol: UDP
      port: 53