apiVersion: v1
data:
  init.sql: |
    -- Create keycloak database and user
    CREATE DATABASE keycloak;
    CREATE USER keycloak WITH PASSWORD 'keycloakpass';
    GRANT ALL PRIVILEGES ON DATABASE keycloak TO keycloak;

    -- Keycloak database permissions
    \c keycloak
    GRANT ALL PRIVILEGES ON SCHEMA public TO keycloak;
    ALTER SCHEMA public OWNER TO keycloak;

    -- Application database permissions
    \c workclub
    GRANT ALL PRIVILEGES ON SCHEMA public TO app;
    ALTER SCHEMA public OWNER TO app;
kind: ConfigMap
metadata:
  labels:
    app: workclub-postgres
    environment: development
  name: postgres-init
  namespace: workclub-dev
---
apiVersion: v1
data:
  api-base-url: http://workclub-api
  cors-origins: http://localhost:3000
  database-host: workclub-postgres
  database-name: workclub
  database-port: "5432"
  keycloak-realm: workclub
  keycloak-url: http://workclub-keycloak
  log-level: Information
kind: ConfigMap
metadata:
  labels:
    app: workclub
    environment: development
  name: workclub-config
  namespace: workclub-dev
---
apiVersion: v1
kind: Service
metadata:
  labels:
    app: workclub-api
    component: backend
    environment: development
  name: workclub-api
  namespace: workclub-dev
spec:
  ports:
  - name: http
    port: 80
    protocol: TCP
    targetPort: 8080
  selector:
    app: workclub-api
    environment: development
  type: ClusterIP
---
apiVersion: v1
kind: Service
metadata:
  labels:
    app: workclub-frontend
    component: frontend
    environment: development
  name: workclub-frontend
  namespace: workclub-dev
spec:
  ports:
  - name: http
    port: 80
    protocol: TCP
    targetPort: 3000
  selector:
    app: workclub-frontend
    environment: development
  type: ClusterIP
---
apiVersion: v1
kind: Service
metadata:
  labels:
    app: workclub-keycloak
    component: auth
    environment: development
  name: workclub-keycloak
  namespace: workclub-dev
spec:
  ports:
  - name: http
    port: 80
    protocol: TCP
    targetPort: 8080
  selector:
    app: workclub-keycloak
    environment: development
  type: ClusterIP
---
apiVersion: v1
kind: Service
metadata:
  labels:
    app: workclub-postgres
    component: database
    environment: development
  name: workclub-postgres
  namespace: workclub-dev
spec:
  ports:
  - name: postgresql
    port: 5432
    protocol: TCP
    targetPort: 5432
  selector:
    app: workclub-postgres
    environment: development
  type: ClusterIP
---
apiVersion: v1
kind: Service
metadata:
  labels:
    app: workclub-postgres
    component: database
    environment: development
  name: workclub-postgres-headless
  namespace: workclub-dev
spec:
  clusterIP: None
  ports:
  - name: postgresql
    port: 5432
    protocol: TCP
    targetPort: 5432
  publishNotReadyAddresses: true
  selector:
    app: workclub-postgres
    environment: development
  type: ClusterIP
---
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: workclub-api
    component: backend
    environment: development
  name: workclub-api
  namespace: workclub-dev
spec:
  replicas: 1
  selector:
    matchLabels:
      app: workclub-api
      environment: development
  template:
    metadata:
      labels:
        app: workclub-api
        component: backend
        environment: development
    spec:
      containers:
      - env:
        - name: ASPNETCORE_ENVIRONMENT
          value: Development
        - name: ASPNETCORE_URLS
          value: http://+:8080
        - name: ConnectionStrings__DefaultConnection
          valueFrom:
            secretKeyRef:
              key: database-connection-string
              name: workclub-secrets
        - name: Keycloak__Url
          valueFrom:
            configMapKeyRef:
              key: keycloak-url
              name: workclub-config
        image: workclub-api:dev
        imagePullPolicy: IfNotPresent
        livenessProbe:
          failureThreshold: 3
          httpGet:
            path: /health/live
            port: http
          initialDelaySeconds: 10
          periodSeconds: 15
          timeoutSeconds: 5
        name: api
        ports:
        - containerPort: 8080
          name: http
          protocol: TCP
        readinessProbe:
          failureThreshold: 2
          httpGet:
            path: /health/ready
            port: http
          initialDelaySeconds: 5
          periodSeconds: 10
          timeoutSeconds: 5
        resources:
          limits:
            cpu: 200m
            memory: 256Mi
          requests:
            cpu: 50m
            memory: 128Mi
        startupProbe:
          failureThreshold: 30
          httpGet:
            path: /health/startup
            port: http
          initialDelaySeconds: 5
          periodSeconds: 10
          timeoutSeconds: 5
---
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: workclub-frontend
    component: frontend
    environment: development
  name: workclub-frontend
  namespace: workclub-dev
spec:
  replicas: 1
  selector:
    matchLabels:
      app: workclub-frontend
      environment: development
  template:
    metadata:
      labels:
        app: workclub-frontend
        component: frontend
        environment: development
    spec:
      containers:
      - env:
        - name: NODE_ENV
          value: production
        - name: NEXT_PUBLIC_API_URL
          valueFrom:
            configMapKeyRef:
              key: api-base-url
              name: workclub-config
        - name: NEXT_PUBLIC_KEYCLOAK_URL
          valueFrom:
            configMapKeyRef:
              key: keycloak-url
              name: workclub-config
        image: workclub-frontend:dev
        imagePullPolicy: IfNotPresent
        livenessProbe:
          failureThreshold: 3
          httpGet:
            path: /api/health
            port: http
          initialDelaySeconds: 10
          periodSeconds: 15
          timeoutSeconds: 5
        name: frontend
        ports:
        - containerPort: 3000
          name: http
          protocol: TCP
        readinessProbe:
          failureThreshold: 2
          httpGet:
            path: /api/health
            port: http
          initialDelaySeconds: 5
          periodSeconds: 10
          timeoutSeconds: 5
        resources:
          limits:
            cpu: 200m
            memory: 256Mi
          requests:
            cpu: 50m
            memory: 128Mi
---
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: workclub-keycloak
    component: auth
    environment: development
  name: workclub-keycloak
  namespace: workclub-dev
spec:
  replicas: 1
  selector:
    matchLabels:
      app: workclub-keycloak
      environment: development
  template:
    metadata:
      labels:
        app: workclub-keycloak
        component: auth
        environment: development
    spec:
      containers:
      - command:
        - start
        env:
        - name: KC_DB
          value: postgres
        - name: KC_DB_URL_HOST
          value: workclub-postgres
        - name: KC_DB_URL_PORT
          value: "5432"
        - name: KC_DB_URL_DATABASE
          value: keycloak
        - name: KC_DB_USERNAME
          value: keycloak
        - name: KC_DB_PASSWORD
          valueFrom:
            secretKeyRef:
              key: keycloak-db-password
              name: workclub-secrets
        - name: KEYCLOAK_ADMIN
          value: admin
        - name: KEYCLOAK_ADMIN_PASSWORD
          valueFrom:
            secretKeyRef:
              key: keycloak-admin-password
              name: workclub-secrets
        - name: KC_HOSTNAME_STRICT
          value: "false"
        - name: KC_PROXY
          value: edge
        - name: KC_HTTP_ENABLED
          value: "true"
        image: quay.io/keycloak/keycloak:26.1
        imagePullPolicy: IfNotPresent
        livenessProbe:
          failureThreshold: 3
          httpGet:
            path: /health/live
            port: http
          initialDelaySeconds: 20
          periodSeconds: 15
          timeoutSeconds: 5
        name: keycloak
        ports:
        - containerPort: 8080
          name: http
          protocol: TCP
        readinessProbe:
          failureThreshold: 2
          httpGet:
            path: /health/ready
            port: http
          initialDelaySeconds: 10
          periodSeconds: 10
          timeoutSeconds: 5
        resources:
          limits:
            cpu: 500m
            memory: 512Mi
          requests:
            cpu: 100m
            memory: 256Mi
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
  labels:
    app: workclub-postgres
    component: database
    environment: development
  name: workclub-postgres
  namespace: workclub-dev
spec:
  replicas: 1
  selector:
    matchLabels:
      app: workclub-postgres
      environment: development
  serviceName: workclub-postgres-headless
  template:
    metadata:
      labels:
        app: workclub-postgres
        component: database
        environment: development
    spec:
      containers:
      - env:
        - name: POSTGRES_DB
          value: workclub
        - name: POSTGRES_USER
          value: app
        - name: POSTGRES_PASSWORD
          valueFrom:
            secretKeyRef:
              key: postgres-password
              name: workclub-secrets
        image: postgres:16-alpine
        imagePullPolicy: IfNotPresent
        livenessProbe:
          exec:
            command:
            - /bin/sh
            - -c
            - pg_isready -U app -d workclub
          failureThreshold: 3
          initialDelaySeconds: 10
          periodSeconds: 15
          timeoutSeconds: 5
        name: postgres
        ports:
        - containerPort: 5432
          name: postgresql
          protocol: TCP
        readinessProbe:
          exec:
            command:
            - /bin/sh
            - -c
            - pg_isready -U app -d workclub
          failureThreshold: 2
          initialDelaySeconds: 5
          periodSeconds: 10
          timeoutSeconds: 5
        resources:
          limits:
            cpu: 500m
            memory: 512Mi
          requests:
            cpu: 100m
            memory: 256Mi
        volumeMounts:
        - mountPath: /var/lib/postgresql/data
          name: postgres-data
          subPath: postgres
        - mountPath: /docker-entrypoint-initdb.d
          name: postgres-init
      volumes:
      - configMap:
          items:
          - key: init.sql
            path: init.sql
          name: postgres-init
        name: postgres-init
  volumeClaimTemplates:
  - metadata:
      labels:
        environment: development
      name: postgres-data
    spec:
      accessModes:
      - ReadWriteOnce
      resources:
        requests:
          storage: 10Gi
      storageClassName: standard
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  labels:
    app: workclub
    environment: development
  name: workclub-ingress
  namespace: workclub-dev
spec:
  rules:
  - host: localhost
    http:
      paths:
      - backend:
          service:
            name: workclub-frontend
            port:
              number: 80
        path: /
        pathType: Prefix
      - backend:
          service:
            name: workclub-api
            port:
              number: 80
        path: /api
        pathType: Prefix
