# K3s — спецификация микросервисов

## 1. Обзор инфраструктуры K3s

```
┌─────────────────────────────────────────────────────────────────────────────┐
│                           K3s Cluster                                        │
├─────────────────────────────────────────────────────────────────────────────┤
│  Ingress (Traefik)                                                           │
│  api.perplexica.local → path-based routing к микросервисам                    │
│  auth.perplexica.local → auth-svc:3000                                        │
│  *.perplexica.local → web (static)                                            │
└─────────────────────────────────────────────────────────────────────────────┘
         │
         ├── Namespace: perplexica
         │   ├── chat-svc (Deployment, HPA, Service)
         │   ├── search-svc
         │   ├── discover-svc
         │   ├── finance-svc
         │   ├── travel-svc
         │   ├── media-svc
         │   ├── projects-svc (включая Collections)
         │   ├── library-svc
         │   ├── memory-svc
         │   ├── create-svc
         │   ├── audit-svc
         │   ├── notifications-svc
         │   ├── upload-svc
         │   ├── billing-svc
         │   └── cache-worker (CronJob: discover, finance, travel+inspiration)
         │
         ├── Namespace: perplexica-auth
         │   └── auth-svc
         │
         ├── Namespace: perplexica-infra
         │   ├── redis (StatefulSet или Helm)
         │   ├── postgresql
         │   ├── minio
         │   └── searxng (очередь запросов в search-svc/media-svc; при росте — пул)
         │
         └── Namespace: perplexica-gateway
             └── traefik / kong
```

## 2. Переменные окружения (общие)

| Переменная | Описание | Источник |
|------------|----------|----------|
| `REDIS_URL` | redis://redis:6379 | Secret |
| `POSTGRES_URL` | Connection string | Secret |
| `JWT_PUBLIC_KEY` | Для валидации токенов | ConfigMap/Secret |
| `AUTH_SERVICE_URL` | http://auth-svc:3000 | Service DNS |
| `SEARXNG_URL` | http://searxng:8080 | Service DNS |
| `OPENAI_API_KEY` | LLM | Secret |
| `LLM_PROVIDER` | openai \| ollama | ConfigMap |
| `MINIO_ENDPOINT` | Для файлов | ConfigMap |

## 3. Детальные манифесты

### 3.1 chat-svc

```yaml
# chat-svc deployment
apiVersion: apps/v1
kind: Deployment
metadata:
  name: chat-svc
  namespace: perplexica
spec:
  replicas: 3
  selector:
    matchLabels:
      app: chat-svc
  template:
    metadata:
      labels:
        app: chat-svc
    spec:
      containers:
        - name: chat-svc
          image: perplexica/chat-svc:latest
          ports:
            - containerPort: 3000
          env:
            - name: REDIS_URL
              valueFrom:
                secretKeyRef:
                  name: redis-credentials
                  key: url
            - name: AUTH_SERVICE_URL
              value: "http://auth-svc.perplexica-auth:3000"
          resources:
            requests:
              cpu: 200m
              memory: 512Mi
            limits:
              cpu: 2000m
              memory: 2Gi
          livenessProbe:
            httpGet:
              path: /health
              port: 3000
            initialDelaySeconds: 10
            periodSeconds: 10
          readinessProbe:
            httpGet:
              path: /ready
              port: 3000
            initialDelaySeconds: 5
            periodSeconds: 5
---
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: chat-svc-hpa
  namespace: perplexica
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: chat-svc
  minReplicas: 2
  maxReplicas: 8
  metrics:
    - type: Resource
      resource:
        name: cpu
        target:
          type: Utilization
          averageUtilization: 70
---
apiVersion: v1
kind: Service
metadata:
  name: chat-svc
  namespace: perplexica
spec:
  selector:
    app: chat-svc
  ports:
    - port: 3000
      targetPort: 3000
```

### 3.2 search-svc

```yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: search-svc
  namespace: perplexica
spec:
  replicas: 2
  selector:
    matchLabels:
      app: search-svc
  template:
    metadata:
      labels:
        app: search-svc
    spec:
      containers:
        - name: search-svc
          image: perplexica/search-svc:latest
          ports:
            - containerPort: 3001
          env:
            - name: SEARXNG_URL
              value: "http://searxng.perplexica-infra:8080"
            - name: REDIS_URL
              valueFrom:
                secretKeyRef:
                  name: redis-credentials
                  key: url
          livenessProbe:
            httpGet:
              path: /health
              port: 3001
            initialDelaySeconds: 10
            periodSeconds: 10
          readinessProbe:
            httpGet:
              path: /ready
              port: 3001
            initialDelaySeconds: 5
            periodSeconds: 5
          resources:
            requests:
              cpu: 100m
              memory: 256Mi
            limits:
              cpu: 1000m
              memory: 1Gi
---
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: search-svc-hpa
  namespace: perplexica
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: search-svc
  minReplicas: 2
  maxReplicas: 6
  metrics:
    - type: Resource
      resource:
        name: cpu
        target:
          type: Utilization
          averageUtilization: 70
---
apiVersion: v1
kind: Service
metadata:
  name: search-svc
  namespace: perplexica
spec:
  selector:
    app: search-svc
  ports:
    - port: 3001
      targetPort: 3001
```

### 3.3 discover-svc

```yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: discover-svc
  namespace: perplexica
spec:
  replicas: 2
  selector:
    matchLabels:
      app: discover-svc
  template:
    metadata:
      labels:
        app: discover-svc
    spec:
      containers:
        - name: discover-svc
          image: perplexica/discover-svc:latest
          ports:
            - containerPort: 3002
          env:
            - name: REDIS_URL
              valueFrom:
                secretKeyRef:
                  name: redis-credentials
                  key: url
          livenessProbe:
            httpGet:
              path: /health
              port: 3002
            initialDelaySeconds: 5
            periodSeconds: 10
          readinessProbe:
            httpGet:
              path: /ready
              port: 3002
            initialDelaySeconds: 3
            periodSeconds: 5
          resources:
            requests:
              cpu: 50m
              memory: 128Mi
            limits:
              cpu: 500m
              memory: 512Mi
---
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: discover-svc-hpa
  namespace: perplexica
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: discover-svc
  minReplicas: 1
  maxReplicas: 4
  metrics:
    - type: Resource
      resource:
        name: cpu
        target:
          type: Utilization
          averageUtilization: 70
---
apiVersion: v1
kind: Service
metadata:
  name: discover-svc
  namespace: perplexica
spec:
  selector:
    app: discover-svc
  ports:
    - port: 3002
      targetPort: 3002
```

### 3.4 finance-svc

```yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: finance-svc
  namespace: perplexica
spec:
  replicas: 2
  selector:
    matchLabels:
      app: finance-svc
  template:
    metadata:
      labels:
        app: finance-svc
    spec:
      containers:
        - name: finance-svc
          image: perplexica/finance-svc:latest
          ports:
            - containerPort: 3003
          env:
            - name: REDIS_URL
              valueFrom:
                secretKeyRef:
                  name: redis-credentials
                  key: url
            - name: FMP_API_KEY
              valueFrom:
                secretKeyRef:
                  name: finance-keys
                  key: fmp
          livenessProbe:
            httpGet:
              path: /health
              port: 3003
            initialDelaySeconds: 5
            periodSeconds: 10
          readinessProbe:
            httpGet:
              path: /ready
              port: 3003
            initialDelaySeconds: 3
            periodSeconds: 5
          resources:
            requests:
              cpu: 50m
              memory: 128Mi
            limits:
              cpu: 500m
              memory: 512Mi
---
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: finance-svc-hpa
  namespace: perplexica
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: finance-svc
  minReplicas: 1
  maxReplicas: 4
  metrics:
    - type: Resource
      resource:
        name: cpu
        target:
          type: Utilization
          averageUtilization: 70
---
apiVersion: v1
kind: Service
metadata:
  name: finance-svc
  namespace: perplexica
spec:
  selector:
    app: finance-svc
  ports:
    - port: 3003
      targetPort: 3003
```

### 3.5 travel-svc

```yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: travel-svc
  namespace: perplexica
spec:
  replicas: 2
  selector:
    matchLabels:
      app: travel-svc
  template:
    metadata:
      labels:
        app: travel-svc
    spec:
      containers:
        - name: travel-svc
          image: perplexica/travel-svc:latest
          ports:
            - containerPort: 3004
          env:
            - name: REDIS_URL
              valueFrom:
                secretKeyRef:
                  name: redis-credentials
                  key: url
            - name: TRIPADVISOR_API_KEY
              valueFrom:
                secretKeyRef:
                  name: travel-keys
                  key: tripadvisor
          livenessProbe:
            httpGet:
              path: /health
              port: 3004
            initialDelaySeconds: 5
            periodSeconds: 10
          readinessProbe:
            httpGet:
              path: /ready
              port: 3004
            initialDelaySeconds: 3
            periodSeconds: 5
          resources:
            requests:
              cpu: 50m
              memory: 128Mi
            limits:
              cpu: 500m
              memory: 512Mi
---
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: travel-svc-hpa
  namespace: perplexica
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: travel-svc
  minReplicas: 1
  maxReplicas: 4
  metrics:
    - type: Resource
      resource:
        name: cpu
        target:
          type: Utilization
          averageUtilization: 70
---
apiVersion: v1
kind: Service
metadata:
  name: travel-svc
  namespace: perplexica
spec:
  selector:
    app: travel-svc
  ports:
    - port: 3004
      targetPort: 3004
```

### 3.6 media-svc

```yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: media-svc
  namespace: perplexica
spec:
  replicas: 2
  selector:
    matchLabels:
      app: media-svc
  template:
    metadata:
      labels:
        app: media-svc
    spec:
      containers:
        - name: media-svc
          image: perplexica/media-svc:latest
          ports:
            - containerPort: 3005
          env:
            - name: SEARXNG_URL
              value: "http://searxng.perplexica-infra:8080"
            - name: REDIS_URL
              valueFrom:
                secretKeyRef:
                  name: redis-credentials
                  key: url
          livenessProbe:
            httpGet:
              path: /health
              port: 3005
            initialDelaySeconds: 5
            periodSeconds: 10
          readinessProbe:
            httpGet:
              path: /ready
              port: 3005
            initialDelaySeconds: 3
            periodSeconds: 5
          resources:
            requests:
              cpu: 50m
              memory: 128Mi
            limits:
              cpu: 500m
              memory: 512Mi
---
apiVersion: v1
kind: Service
metadata:
  name: media-svc
  namespace: perplexica
spec:
  selector:
    app: media-svc
  ports:
    - port: 3005
      targetPort: 3005
```

### 3.7 library-svc

```yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: library-svc
  namespace: perplexica
spec:
  replicas: 2
  selector:
    matchLabels:
      app: library-svc
  template:
    metadata:
      labels:
        app: library-svc
    spec:
      containers:
        - name: library-svc
          image: perplexica/library-svc:latest
          ports:
            - containerPort: 3009
          env:
            - name: POSTGRES_URL
              valueFrom:
                secretKeyRef:
                  name: db-credentials
                  key: url
            - name: AUTH_SERVICE_URL
              value: "http://auth-svc.perplexica-auth:3000"
          livenessProbe:
            httpGet:
              path: /health
              port: 3009
            initialDelaySeconds: 5
            periodSeconds: 10
          readinessProbe:
            httpGet:
              path: /ready
              port: 3009
            initialDelaySeconds: 3
            periodSeconds: 5
          resources:
            requests:
              cpu: 50m
              memory: 128Mi
            limits:
              cpu: 500m
              memory: 512Mi
---
apiVersion: v1
kind: Service
metadata:
  name: library-svc
  namespace: perplexica
spec:
  selector:
    app: library-svc
  ports:
    - port: 3009
      targetPort: 3009
```

### 3.8 projects-svc

```yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: projects-svc
  namespace: perplexica
spec:
  replicas: 2
  selector:
    matchLabels:
      app: projects-svc
  template:
    metadata:
      labels:
        app: projects-svc
    spec:
      containers:
        - name: projects-svc
          image: perplexica/projects-svc:latest
          ports:
            - containerPort: 3006
          env:
            - name: POSTGRES_URL
              valueFrom:
                secretKeyRef:
                  name: db-credentials
                  key: url
            - name: MINIO_ENDPOINT
              value: "http://minio.perplexica-infra:9000"
          livenessProbe:
            httpGet:
              path: /health
              port: 3006
            initialDelaySeconds: 5
            periodSeconds: 10
          readinessProbe:
            httpGet:
              path: /ready
              port: 3006
            initialDelaySeconds: 3
            periodSeconds: 5
          resources:
            requests:
              cpu: 100m
              memory: 256Mi
            limits:
              cpu: 1000m
              memory: 1Gi
---
apiVersion: v1
kind: Service
metadata:
  name: projects-svc
  namespace: perplexica
spec:
  selector:
    app: projects-svc
  ports:
    - port: 3006
      targetPort: 3006
```

### 3.9 upload-svc

```yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: upload-svc
  namespace: perplexica
spec:
  replicas: 2
  selector:
    matchLabels:
      app: upload-svc
  template:
    metadata:
      labels:
        app: upload-svc
    spec:
      containers:
        - name: upload-svc
          image: perplexica/upload-svc:latest
          ports:
            - containerPort: 3007
          env:
            - name: MINIO_ENDPOINT
              value: "http://minio.perplexica-infra:9000"
            - name: OPENAI_API_KEY
              valueFrom:
                secretKeyRef:
                  name: llm-credentials
                  key: openai
          livenessProbe:
            httpGet:
              path: /health
              port: 3007
            initialDelaySeconds: 15
            periodSeconds: 15
          readinessProbe:
            httpGet:
              path: /ready
              port: 3007
            initialDelaySeconds: 5
            periodSeconds: 5
          resources:
            requests:
              cpu: 200m
              memory: 512Mi
            limits:
              cpu: 2000m
              memory: 2Gi
---
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: upload-svc-hpa
  namespace: perplexica
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: upload-svc
  minReplicas: 1
  maxReplicas: 4
  metrics:
    - type: Resource
      resource:
        name: cpu
        target:
          type: Utilization
          averageUtilization: 70
---
apiVersion: v1
kind: Service
metadata:
  name: upload-svc
  namespace: perplexica
spec:
  selector:
    app: upload-svc
  ports:
    - port: 3007
      targetPort: 3007
```

### 3.10 billing-svc

```yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: billing-svc
  namespace: perplexica
spec:
  replicas: 2
  selector:
    matchLabels:
      app: billing-svc
  template:
    metadata:
      labels:
        app: billing-svc
    spec:
      containers:
        - name: billing-svc
          image: perplexica/billing-svc:latest
          ports:
            - containerPort: 3008
          env:
            - name: POSTGRES_URL
              valueFrom:
                secretKeyRef:
                  name: db-credentials
                  key: url
            - name: YOOKASSA_SHOP_ID
              valueFrom:
                secretKeyRef:
                  name: yookassa-credentials
                  key: shop_id
            - name: YOOKASSA_SECRET
              valueFrom:
                secretKeyRef:
                  name: yookassa-credentials
                  key: secret
          livenessProbe:
            httpGet:
              path: /health
              port: 3008
            initialDelaySeconds: 5
            periodSeconds: 10
          readinessProbe:
            httpGet:
              path: /ready
              port: 3008
            initialDelaySeconds: 3
            periodSeconds: 5
          resources:
            requests:
              cpu: 50m
              memory: 128Mi
            limits:
              cpu: 500m
              memory: 512Mi
---
apiVersion: v1
kind: Service
metadata:
  name: billing-svc
  namespace: perplexica
spec:
  selector:
    app: billing-svc
  ports:
    - port: 3008
      targetPort: 3008
```

### 3.11 memory-svc

```yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: memory-svc
  namespace: perplexica
spec:
  replicas: 2
  selector:
    matchLabels:
      app: memory-svc
  template:
    metadata:
      labels:
        app: memory-svc
    spec:
      containers:
        - name: memory-svc
          image: perplexica/memory-svc:latest
          ports:
            - containerPort: 3010
          env:
            - name: POSTGRES_URL
              valueFrom:
                secretKeyRef:
                  name: db-credentials
                  key: url
            - name: REDIS_URL
              valueFrom:
                secretKeyRef:
                  name: redis-credentials
                  key: url
            - name: OPENAI_API_KEY
              valueFrom:
                secretKeyRef:
                  name: llm-credentials
                  key: openai
          livenessProbe:
            httpGet:
              path: /health
              port: 3010
            initialDelaySeconds: 5
            periodSeconds: 10
          readinessProbe:
            httpGet:
              path: /ready
              port: 3010
            initialDelaySeconds: 3
            periodSeconds: 5
          resources:
            requests:
              cpu: 100m
              memory: 256Mi
            limits:
              cpu: 1000m
              memory: 1Gi
---
apiVersion: v1
kind: Service
metadata:
  name: memory-svc
  namespace: perplexica
spec:
  selector:
    app: memory-svc
  ports:
    - port: 3010
      targetPort: 3010
```

### 3.12 create-svc

```yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: create-svc
  namespace: perplexica
spec:
  replicas: 1
  selector:
    matchLabels:
      app: create-svc
  template:
    metadata:
      labels:
        app: create-svc
    spec:
      containers:
        - name: create-svc
          image: perplexica/create-svc:latest
          ports:
            - containerPort: 3011
          env:
            - name: OPENAI_API_KEY
              valueFrom:
                secretKeyRef:
                  name: llm-credentials
                  key: openai
          livenessProbe:
            httpGet:
              path: /health
              port: 3011
            initialDelaySeconds: 10
            periodSeconds: 15
          readinessProbe:
            httpGet:
              path: /ready
              port: 3011
            initialDelaySeconds: 5
            periodSeconds: 5
          resources:
            requests:
              cpu: 200m
              memory: 512Mi
            limits:
              cpu: 2000m
              memory: 2Gi
---
apiVersion: v1
kind: Service
metadata:
  name: create-svc
  namespace: perplexica
spec:
  selector:
    app: create-svc
  ports:
    - port: 3011
      targetPort: 3011
```

### 3.13 audit-svc

```yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: audit-svc
  namespace: perplexica
spec:
  replicas: 1
  selector:
    matchLabels:
      app: audit-svc
  template:
    metadata:
      labels:
        app: audit-svc
    spec:
      containers:
        - name: audit-svc
          image: perplexica/audit-svc:latest
          ports:
            - containerPort: 3012
          env:
            - name: POSTGRES_URL
              valueFrom:
                secretKeyRef:
                  name: db-credentials
                  key: url
          livenessProbe:
            httpGet:
              path: /health
              port: 3012
            initialDelaySeconds: 5
            periodSeconds: 10
          readinessProbe:
            httpGet:
              path: /ready
              port: 3012
            initialDelaySeconds: 3
            periodSeconds: 5
          resources:
            requests:
              cpu: 50m
              memory: 128Mi
            limits:
              cpu: 500m
              memory: 512Mi
---
apiVersion: v1
kind: Service
metadata:
  name: audit-svc
  namespace: perplexica
spec:
  selector:
    app: audit-svc
  ports:
    - port: 3012
      targetPort: 3012
```

### 3.14 notifications-svc

```yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: notifications-svc
  namespace: perplexica
spec:
  replicas: 1
  selector:
    matchLabels:
      app: notifications-svc
  template:
    metadata:
      labels:
        app: notifications-svc
    spec:
      containers:
        - name: notifications-svc
          image: perplexica/notifications-svc:latest
          ports:
            - containerPort: 3013
          env:
            - name: REDIS_URL
              valueFrom:
                secretKeyRef:
                  name: redis-credentials
                  key: url
            - name: POSTGRES_URL
              valueFrom:
                secretKeyRef:
                  name: db-credentials
                  key: url
            - name: VAPID_PUBLIC_KEY
              valueFrom:
                secretKeyRef:
                  name: notifications-secrets
                  key: vapid_public
            - name: SMTP_URL
              valueFrom:
                secretKeyRef:
                  name: notifications-secrets
                  key: smtp_url
          livenessProbe:
            httpGet:
              path: /health
              port: 3013
            initialDelaySeconds: 5
            periodSeconds: 10
          readinessProbe:
            httpGet:
              path: /ready
              port: 3013
            initialDelaySeconds: 3
            periodSeconds: 5
          resources:
            requests:
              cpu: 50m
              memory: 128Mi
            limits:
              cpu: 500m
              memory: 512Mi
---
apiVersion: v1
kind: Service
metadata:
  name: notifications-svc
  namespace: perplexica
spec:
  selector:
    app: notifications-svc
  ports:
    - port: 3013
      targetPort: 3013
```

### 3.15 cache-worker (CronJob)

```yaml
apiVersion: batch/v1
kind: CronJob
metadata:
  name: cache-worker
  namespace: perplexica
spec:
  schedule: "*/5 * * * *"
  concurrencyPolicy: Forbid
  jobTemplate:
    spec:
      activeDeadlineSeconds: 600   # 10 мин — не допускать зависших задач
      template:
        spec:
          restartPolicy: OnFailure
          containers:
            - name: cache-worker
              image: perplexica/cache-worker:latest
              env:
                - name: REDIS_URL
                  valueFrom:
                    secretKeyRef:
                      name: redis-credentials
                      key: url
                - name: DISCOVER_SVC_URL
                  value: "http://discover-svc:3002"
                - name: FINANCE_SVC_URL
                  value: "http://finance-svc:3003"
                - name: TRAVEL_SVC_URL
                  value: "http://travel-svc:3004"
              resources:
                requests:
                  cpu: 100m
                  memory: 256Mi
                limits:
                  cpu: 500m
                  memory: 512Mi
---
# Отдельные CronJob для разных интервалов
apiVersion: batch/v1
kind: CronJob
metadata:
  name: cache-worker-finance
  namespace: perplexica
spec:
  schedule: "*/2 * * * *"  # каждые 2 мин — finance
  concurrencyPolicy: Forbid
  jobTemplate:
    spec:
      activeDeadlineSeconds: 300   # 5 мин
      template:
        spec:
          restartPolicy: OnFailure
          containers:
            - name: cache-worker
              image: perplexica/cache-worker:latest
              args: ["--task=finance"]
              env:
                - name: REDIS_URL
                  valueFrom:
                    secretKeyRef:
                      name: redis-credentials
                      key: url
                - name: FINANCE_SVC_URL
                  value: "http://finance-svc:3003"
---
apiVersion: batch/v1
kind: CronJob
metadata:
  name: cache-worker-discover
  namespace: perplexica
spec:
  schedule: "*/15 * * * *"  # каждые 15 мин — discover
  concurrencyPolicy: Forbid
  jobTemplate:
    spec:
      activeDeadlineSeconds: 600   # 10 мин
      template:
        spec:
          restartPolicy: OnFailure
          containers:
            - name: cache-worker
              image: perplexica/cache-worker:latest
              args: ["--task=discover"]
              env:
                - name: REDIS_URL
                  valueFrom:
                    secretKeyRef:
                      name: redis-credentials
                      key: url
                - name: DISCOVER_SVC_URL
                  value: "http://discover-svc:3002"
---
apiVersion: batch/v1
kind: CronJob
metadata:
  name: cache-worker-travel
  namespace: perplexica
spec:
  schedule: "0 */4 * * *"  # каждые 4 ч — travel trending + inspiration
  concurrencyPolicy: Forbid
  jobTemplate:
    spec:
      activeDeadlineSeconds: 1200   # 20 мин
      template:
        spec:
          restartPolicy: OnFailure
          containers:
            - name: cache-worker
              image: perplexica/cache-worker:latest
              args: ["--task=travel"]
              env:
                - name: REDIS_URL
                  valueFrom:
                    secretKeyRef:
                      name: redis-credentials
                      key: url
                - name: TRAVEL_SVC_URL
                  value: "http://travel-svc:3004"
```

### 3.16 auth-svc

```yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: auth-svc
  namespace: perplexica-auth
spec:
  replicas: 2
  selector:
    matchLabels:
      app: auth-svc
  template:
    metadata:
      labels:
        app: auth-svc
    spec:
      containers:
        - name: auth-svc
          image: perplexica/auth-svc:latest
          ports:
            - containerPort: 3000
          livenessProbe:
            httpGet:
              path: /health
              port: 3000
            initialDelaySeconds: 5
            periodSeconds: 10
          readinessProbe:
            httpGet:
              path: /ready
              port: 3000
            initialDelaySeconds: 3
            periodSeconds: 5
          env:
            - name: POSTGRES_URL
              valueFrom:
                secretKeyRef:
                  name: db-credentials
                  key: url
            - name: JWT_SECRET
              valueFrom:
                secretKeyRef:
                  name: auth-secrets
                  key: jwt_secret
          resources:
            requests:
              cpu: 100m
              memory: 256Mi
            limits:
              cpu: 500m
              memory: 512Mi
---
apiVersion: v1
kind: Service
metadata:
  name: auth-svc
  namespace: perplexica-auth
spec:
  selector:
    app: auth-svc
  ports:
    - port: 3000
      targetPort: 3000
```

## 4. Ingress

```yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: perplexica-ingress
  namespace: perplexica
  annotations:
    traefik.ingress.kubernetes.io/router.entrypoints: websecure
spec:
  tls:
    - hosts:
        - api.perplexica.local
        - auth.perplexica.local
      secretName: perplexica-tls
  rules:
    # API: path-based маршрутизация к микросервисам
    - host: api.perplexica.local
      http:
        paths:
          - path: /api/v1/discover
            pathType: Prefix
            backend:
              service:
                name: discover-svc
                port:
                  number: 3002
          - path: /api/v1/finance
            pathType: Prefix
            backend:
              service:
                name: finance-svc
                port:
                  number: 3003
          - path: /api/v1/travel
            pathType: Prefix
            backend:
              service:
                name: travel-svc
                port:
                  number: 3004
          - path: /api/v1/media
            pathType: Prefix
            backend:
              service:
                name: media-svc
                port:
                  number: 3005
          - path: /api/v1/collections
            pathType: Prefix
            backend:
              service:
                name: projects-svc
                port:
                  number: 3006
          - path: /api/v1/library
            pathType: Prefix
            backend:
              service:
                name: library-svc
                port:
                  number: 3009
          - path: /api/v1/memory
            pathType: Prefix
            backend:
              service:
                name: memory-svc
                port:
                  number: 3010
          - path: /api/v1/create
            pathType: Prefix
            backend:
              service:
                name: create-svc
                port:
                  number: 3011
          - path: /api/v1/export
            pathType: Prefix
            backend:
              service:
                name: create-svc
                port:
                  number: 3011
          - path: /api/v1/patents
            pathType: Prefix
            backend:
              service:
                name: search-svc
                port:
                  number: 3001
          - path: /api/v1/admin/audit-logs
            pathType: Prefix
            backend:
              service:
                name: audit-svc
                port:
                  number: 3012
          - path: /api/v1/notifications
            pathType: Prefix
            backend:
              service:
                name: notifications-svc
                port:
                  number: 3013
          - path: /api/v1/tasks
            pathType: Prefix
            backend:
              service:
                name: chat-svc
                port:
                  number: 3000
          - path: /api/v1/billing
            pathType: Prefix
            backend:
              service:
                name: billing-svc
                port:
                  number: 3008
          - path: /api/v1/projects
            pathType: Prefix
            backend:
              service:
                name: projects-svc
                port:
                  number: 3006
          - path: /api/v1/upload
            pathType: Prefix
            backend:
              service:
                name: upload-svc
                port:
                  number: 3007
          - path: /api/v1/connectors
            pathType: Prefix
            backend:
              service:
                name: projects-svc
                port:
                  number: 3006
          - path: /api
            pathType: Prefix
            backend:
              service:
                name: chat-svc
                port:
                  number: 3000
    - host: auth.perplexica.local
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: auth-svc
                namespace: perplexica-auth
                port:
                  number: 3000
```

## 5. Структура репозитория сервисов

```
services/
├── chat-svc/           # Mastra, LLM, Writer, Answer Modes, Step-by-step Learning
├── search-svc/         # SearXNG, Researcher actions, Patents
├── discover-svc/       # News aggregation, summarization
├── finance-svc/        # Market data, heatmap, Analyst ratings, SEC, ETF Holdings
├── travel-svc/         # Itineraries, Inspiration Cards, Tripadvisor, Selfbook
├── media-svc/          # Images, Videos
├── projects-svc/       # Spaces CRUD, Collections, files
├── library-svc/        # Threads history, saved (аккаунты)
├── memory-svc/         # AI Memory, Enterprise Memory
├── create-svc/         # Create (таблицы, дашборды), Export, Image generation
├── audit-svc/          # Enterprise audit logs
├── notifications-svc/  # Web Push, Email, напоминания
├── upload-svc/         # File parsing, embeddings
├── billing-svc/        # ЮKassa, subscriptions
├── cache-worker/       # Pre-compute: discover, finance, travel+inspiration
├── auth-svc/           # SSO, JWT, domain sign-up
├── connectors-svc/    # My Connectors (опционально, может быть в projects)
└── api-gateway/        # Kong/Traefik config
```

Каждый сервис — отдельный пакет (Node.js/TypeScript, pnpm/npm workspace).

## 6. Инфраструктура и Secrets

### 6.1 Создание Secrets (перед развёртыванием)

```bash
# Namespace для secrets (в каждом namespace, где нужны)
kubectl create namespace perplexica
kubectl create namespace perplexica-auth

# Redis
kubectl create secret generic redis-credentials -n perplexica \
  --from-literal=url='redis://redis.perplexica-infra:6379'

# PostgreSQL
kubectl create secret generic db-credentials -n perplexica \
  --from-literal=url='postgresql://user:pass@postgresql.perplexica-infra:5432/perplexica'

# Дублировать в perplexica-auth для auth-svc
kubectl create secret generic db-credentials -n perplexica-auth \
  --from-literal=url='postgresql://user:pass@postgresql.perplexica-infra:5432/perplexica'

# Auth
kubectl create secret generic auth-secrets -n perplexica-auth \
  --from-literal=jwt_secret='<random-32-chars>'

# LLM
kubectl create secret generic llm-credentials -n perplexica \
  --from-literal=openai='sk-...'

# Finance (FMP)
kubectl create secret generic finance-keys -n perplexica \
  --from-literal=fmp='<fmp-api-key>'

# Travel (Tripadvisor)
kubectl create secret generic travel-keys -n perplexica \
  --from-literal=tripadvisor='<tripadvisor-api-key>'

# ЮKassa
kubectl create secret generic yookassa-credentials -n perplexica \
  --from-literal=shop_id='<shop-id>' \
  --from-literal=secret='<yookassa-secret>'

# Notifications (Web Push VAPID, SMTP)
kubectl create secret generic notifications-secrets -n perplexica \
  --from-literal=vapid_public='<vapid-public-key>' \
  --from-literal=vapid_private='<vapid-private-key>' \
  --from-literal=smtp_url='smtp://user:pass@smtp.example:587'
```

### 6.2 Инфраструктурные компоненты (Helm)

| Компонент | Helm chart | Namespace |
|-----------|------------|-----------|
| Redis | `bitnami/redis` | perplexica-infra |
| PostgreSQL | `bitnami/postgresql` | perplexica-infra |
| MinIO | `bitnami/minio` | perplexica-infra |
| SearXNG | Собственный Deployment или `docker.io/searxng/searxng` | perplexica-infra |

Пример установки Redis:

```bash
helm repo add bitnami https://charts.bitnami.com/bitnami
helm install redis bitnami/redis -n perplexica-infra \
  --set auth.enabled=false \
  --set master.persistence.enabled=true
```
