Performance: - SSE dashboard streaming endpoint (GET /v1/admin/status/stream) - Web Worker for markdown rendering (offload from main thread) - IndexedDB chat persistence (replace localStorage, 500msg support) Security: - CSRF protection middleware (Origin/Referer validation) - Content Security Policy + security headers middleware - API key rotation endpoint (POST /v1/admin/keys/rotate) Observability: - OpenTelemetry tracing with graceful NoOp fallback - Structured error codes (FAGI-xxxx taxonomy with ErrorResponse schema) - Audit log export (CSV + JSON at /v1/admin/audit/export/*) Features: - Multi-session management hook (parallel conversations) - Conversation export (markdown/JSON/text download + clipboard) - Head customization UI (enable/disable + weight sliders for 12 heads) Infrastructure: - Kubernetes Helm chart (Deployment, Service, HPA, Ingress) - Database migration versioning (generate, verify commands) - Blue-green deployment manifests (color-based traffic switching) Tests: 598 Python + 56 frontend = 654 total, 0 ruff errors Co-Authored-By: Nakamoto, S <defi@defi-oracle.io>
92 lines
2.6 KiB
YAML
92 lines
2.6 KiB
YAML
apiVersion: apps/v1
|
|
kind: Deployment
|
|
metadata:
|
|
name: {{ .Release.Name }}-api
|
|
labels:
|
|
app: {{ .Release.Name }}
|
|
component: api
|
|
spec:
|
|
replicas: {{ .Values.replicaCount }}
|
|
selector:
|
|
matchLabels:
|
|
app: {{ .Release.Name }}
|
|
component: api
|
|
template:
|
|
metadata:
|
|
labels:
|
|
app: {{ .Release.Name }}
|
|
component: api
|
|
spec:
|
|
containers:
|
|
- name: api
|
|
image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
|
|
imagePullPolicy: {{ .Values.image.pullPolicy }}
|
|
ports:
|
|
- containerPort: 8000
|
|
protocol: TCP
|
|
env:
|
|
{{- range $key, $value := .Values.env }}
|
|
- name: {{ $key }}
|
|
value: {{ $value | quote }}
|
|
{{- end }}
|
|
- name: FUSIONAGI_API_KEY
|
|
valueFrom:
|
|
secretKeyRef:
|
|
name: {{ .Values.secrets.apiKey.existingSecret }}
|
|
key: {{ .Values.secrets.apiKey.key }}
|
|
- name: FUSIONAGI_POSTGRES_DSN
|
|
valueFrom:
|
|
secretKeyRef:
|
|
name: {{ .Values.secrets.postgresDsn.existingSecret }}
|
|
key: {{ .Values.secrets.postgresDsn.key }}
|
|
- name: FUSIONAGI_REDIS_URL
|
|
valueFrom:
|
|
secretKeyRef:
|
|
name: {{ .Values.secrets.redisUrl.existingSecret }}
|
|
key: {{ .Values.secrets.redisUrl.key }}
|
|
{{- with .Values.healthCheck.livenessProbe }}
|
|
livenessProbe:
|
|
{{- toYaml . | nindent 12 }}
|
|
{{- end }}
|
|
{{- with .Values.healthCheck.readinessProbe }}
|
|
readinessProbe:
|
|
{{- toYaml . | nindent 12 }}
|
|
{{- end }}
|
|
resources:
|
|
{{- toYaml .Values.resources.api | nindent 12 }}
|
|
---
|
|
{{- if .Values.frontend.enabled }}
|
|
apiVersion: apps/v1
|
|
kind: Deployment
|
|
metadata:
|
|
name: {{ .Release.Name }}-frontend
|
|
labels:
|
|
app: {{ .Release.Name }}
|
|
component: frontend
|
|
spec:
|
|
replicas: {{ .Values.frontend.replicaCount }}
|
|
selector:
|
|
matchLabels:
|
|
app: {{ .Release.Name }}
|
|
component: frontend
|
|
template:
|
|
metadata:
|
|
labels:
|
|
app: {{ .Release.Name }}
|
|
component: frontend
|
|
spec:
|
|
containers:
|
|
- name: frontend
|
|
image: "{{ .Values.frontend.image.repository }}:{{ .Values.frontend.image.tag }}"
|
|
ports:
|
|
- containerPort: 80
|
|
protocol: TCP
|
|
livenessProbe:
|
|
httpGet:
|
|
path: /
|
|
port: 80
|
|
initialDelaySeconds: 5
|
|
resources:
|
|
{{- toYaml .Values.resources.frontend | nindent 12 }}
|
|
{{- end }}
|