fix: risk engine command points to services.risk.app, redis password, window quoting

This commit is contained in:
Celes Renata
2026-04-11 14:15:47 -07:00
parent 1c3a5f8285
commit 273a86e2bd
17 changed files with 237 additions and 207 deletions
-3
View File
@@ -4,6 +4,3 @@ description: AI market intelligence and paper-trading platform
type: application
version: 0.1.0
appVersion: "1.0.0"
maintainers:
- name: Celes Renata
email: celes@frameshift.net
@@ -8,8 +8,23 @@ helm.sh/chart: {{ .Chart.Name }}-{{ .Chart.Version }}
{{- end }}
{{/*
Full image path for a service
Pod security context shared across all custom service pods
*/}}
{{- define "stonks.image" -}}
{{ $.Values.imageRegistry }}/{{ .image }}:{{ $.Values.imageTag }}
{{- define "stonks.podSecurityContext" -}}
runAsNonRoot: true
runAsUser: 1000
runAsGroup: 1000
fsGroup: 1000
seccompProfile:
type: RuntimeDefault
{{- end }}
{{/*
Container security context
*/}}
{{- define "stonks.containerSecurityContext" -}}
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
capabilities:
drop: ["ALL"]
{{- end }}
@@ -2,7 +2,7 @@ apiVersion: v1
kind: ConfigMap
metadata:
name: stonks-config
namespace: {{ .Values.namespace }}
namespace: {{ .Release.Namespace }}
labels:
{{- include "stonks.labels" . | nindent 4 }}
data:
@@ -1,50 +1,43 @@
{{- $root := . -}}
{{- range $name, $svc := .Values.services }}
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ $name }}
namespace: {{ $.Values.namespace }}
name: {{ $svc.image }}
namespace: {{ $root.Release.Namespace }}
labels:
app: {{ $name }}
{{- include "stonks.labels" $ | nindent 4 }}
app: {{ $svc.image }}
{{- include "stonks.labels" $root | nindent 4 }}
stonks-oracle/tier: {{ $svc.tier }}
spec:
replicas: {{ $svc.replicas }}
selector:
matchLabels:
app: {{ $name }}
app: {{ $svc.image }}
template:
metadata:
labels:
app: {{ $name }}
app: {{ $svc.image }}
stonks-oracle/tier: {{ $svc.tier }}
spec:
automountServiceAccountToken: false
{{- if $.Values.imagePullSecrets.enabled }}
{{- with $root.Values.imagePullSecrets }}
imagePullSecrets:
- name: {{ $.Values.imagePullSecrets.name }}
{{- toYaml . | nindent 8 }}
{{- end }}
securityContext:
runAsNonRoot: true
runAsUser: 1000
runAsGroup: 1000
fsGroup: 1000
seccompProfile:
type: RuntimeDefault
{{- include "stonks.podSecurityContext" $root | nindent 8 }}
containers:
- name: {{ $name }}
image: {{ $.Values.imageRegistry }}/{{ $svc.image }}:{{ $.Values.imageTag }}
imagePullPolicy: {{ $.Values.imagePullPolicy }}
- name: {{ $svc.image }}
image: {{ $root.Values.image.registry }}/{{ $svc.image }}:{{ $root.Values.image.tag }}
imagePullPolicy: {{ $root.Values.image.pullPolicy }}
{{- if $svc.port }}
ports:
- containerPort: {{ $svc.port }}
{{- end }}
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
capabilities:
drop: ["ALL"]
{{- include "stonks.containerSecurityContext" $root | nindent 12 }}
envFrom:
- configMapRef:
name: stonks-config
@@ -53,12 +46,7 @@ spec:
name: {{ . }}
{{- end }}
resources:
requests:
cpu: {{ $svc.resources.requests.cpu }}
memory: {{ $svc.resources.requests.memory }}
limits:
cpu: {{ $svc.resources.limits.cpu | quote }}
memory: {{ $svc.resources.limits.memory }}
{{- toYaml $svc.resources | nindent 12 }}
{{- if $svc.probes }}
{{- if $svc.probes.readiness }}
readinessProbe:
@@ -1,12 +1,12 @@
{{- if and .Values.imagePullSecrets.enabled .Values.imagePullSecrets.createSecret }}
{{- if .Values.ghcrAuth.enabled }}
apiVersion: v1
kind: Secret
metadata:
name: {{ .Values.imagePullSecrets.name }}
namespace: {{ .Values.namespace }}
name: ghcr-credentials
namespace: {{ .Release.Namespace }}
labels:
{{- include "stonks.labels" . | nindent 4 }}
type: kubernetes.io/dockerconfigjson
data:
.dockerconfigjson: {{ .Values.imagePullSecrets.dockerconfigjson }}
.dockerconfigjson: {{ printf `{"auths":{"%s":{"username":"%s","password":"%s","auth":"%s"}}}` .Values.ghcrAuth.registry .Values.ghcrAuth.username .Values.ghcrAuth.password (printf "%s:%s" .Values.ghcrAuth.username .Values.ghcrAuth.password | b64enc) | b64enc }}
{{- end }}
@@ -3,7 +3,7 @@ apiVersion: apps/v1
kind: Deployment
metadata:
name: hive-metastore
namespace: {{ .Values.namespace }}
namespace: {{ .Release.Namespace }}
labels:
app: hive-metastore
{{- include "stonks.labels" . | nindent 4 }}
@@ -20,17 +20,12 @@ spec:
stonks-oracle/tier: analytics
spec:
automountServiceAccountToken: false
{{- if .Values.imagePullSecrets.enabled }}
{{- with .Values.imagePullSecrets }}
imagePullSecrets:
- name: {{ .Values.imagePullSecrets.name }}
{{- toYaml . | nindent 8 }}
{{- end }}
securityContext:
runAsNonRoot: true
runAsUser: 1000
runAsGroup: 1000
fsGroup: 1000
seccompProfile:
type: RuntimeDefault
{{- include "stonks.podSecurityContext" . | nindent 8 }}
initContainers:
- name: hive-config-init
image: busybox:1.36
@@ -44,7 +39,7 @@ spec:
cat > /hive-config/core-site.xml <<EOF
<?xml version="1.0"?>
<configuration>
<property><name>fs.s3a.endpoint</name><value>http://minio.minio-service.svc.cluster.local:80</value></property>
<property><name>fs.s3a.endpoint</name><value>http://{{ index $.Values.config "MINIO_ENDPOINT" }}</value></property>
<property><name>fs.s3a.access.key</name><value>${MINIO_ACCESS_KEY}</value></property>
<property><name>fs.s3a.secret.key</name><value>${MINIO_SECRET_KEY}</value></property>
<property><name>fs.s3a.path.style.access</name><value>true</value></property>
@@ -101,12 +96,7 @@ spec:
mountPath: /opt/hive/conf/metastore-site.xml
subPath: metastore-site.xml
resources:
requests:
cpu: {{ .Values.hiveMetastore.resources.requests.cpu }}
memory: {{ .Values.hiveMetastore.resources.requests.memory }}
limits:
cpu: {{ .Values.hiveMetastore.resources.limits.cpu | quote }}
memory: {{ .Values.hiveMetastore.resources.limits.memory }}
{{- toYaml .Values.hiveMetastore.resources | nindent 12 }}
volumes:
- name: hive-data
persistentVolumeClaim:
@@ -118,7 +108,7 @@ apiVersion: v1
kind: Service
metadata:
name: hive-metastore
namespace: {{ .Values.namespace }}
namespace: {{ .Release.Namespace }}
spec:
selector:
app: hive-metastore
@@ -130,7 +120,7 @@ apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: hive-metastore-data
namespace: {{ .Values.namespace }}
namespace: {{ .Release.Namespace }}
spec:
accessModes:
- ReadWriteOnce
+84 -11
View File
@@ -1,29 +1,102 @@
{{- if .Values.ingress.enabled }}
{{- range $key, $ing := .Values.ingress.hosts }}
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: stonks-{{ $key }}
namespace: {{ $.Values.namespace }}
name: stonks-query-api-https
namespace: {{ .Release.Namespace }}
annotations:
cert-manager.io/cluster-issuer: {{ $.Values.ingress.clusterIssuer }}
cert-manager.io/cluster-issuer: {{ .Values.ingress.clusterIssuer }}
spec:
ingressClassName: {{ $.Values.ingress.className }}
ingressClassName: {{ .Values.ingress.className }}
tls:
- hosts:
- {{ $ing.host }}
secretName: stonks-{{ $key }}-tls
- {{ .Values.ingress.hosts.queryApi }}
secretName: stonks-api-tls
rules:
- host: {{ $ing.host }}
- host: {{ .Values.ingress.hosts.queryApi }}
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: {{ $ing.service }}
name: query-api
port:
number: {{ $ing.port }}
{{- end }}
number: 8000
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: stonks-registry-https
namespace: {{ .Release.Namespace }}
annotations:
cert-manager.io/cluster-issuer: {{ .Values.ingress.clusterIssuer }}
spec:
ingressClassName: {{ .Values.ingress.className }}
tls:
- hosts:
- {{ .Values.ingress.hosts.symbolRegistry }}
secretName: stonks-registry-tls
rules:
- host: {{ .Values.ingress.hosts.symbolRegistry }}
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: symbol-registry
port:
number: 8000
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: stonks-superset-https
namespace: {{ .Release.Namespace }}
annotations:
cert-manager.io/cluster-issuer: {{ .Values.ingress.clusterIssuer }}
spec:
ingressClassName: {{ .Values.ingress.className }}
tls:
- hosts:
- {{ .Values.ingress.hosts.superset }}
secretName: stonks-dash-tls
rules:
- host: {{ .Values.ingress.hosts.superset }}
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: superset
port:
number: 8088
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: stonks-trino-https
namespace: {{ .Release.Namespace }}
annotations:
cert-manager.io/cluster-issuer: {{ .Values.ingress.clusterIssuer }}
spec:
ingressClassName: {{ .Values.ingress.className }}
tls:
- hosts:
- {{ .Values.ingress.hosts.trino }}
secretName: stonks-trino-tls
rules:
- host: {{ .Values.ingress.hosts.trino }}
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: trino
port:
number: 8080
{{- end }}
@@ -1,7 +1,7 @@
apiVersion: v1
kind: Namespace
metadata:
name: {{ .Values.namespace }}
name: {{ .Release.Namespace }}
labels:
{{- include "stonks.labels" . | nindent 4 }}
kubernetes.io/metadata.name: {{ .Values.namespace }}
kubernetes.io/metadata.name: {{ .Release.Namespace }}
@@ -1,21 +1,19 @@
{{- if .Values.networkPolicies.enabled }}
# Default deny all ingress
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny-ingress
namespace: {{ .Values.namespace }}
namespace: {{ .Release.Namespace }}
spec:
podSelector: {}
policyTypes:
- Ingress
---
# Query API: accept from Traefik ingress
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-query-api-ingress
namespace: {{ .Values.namespace }}
namespace: {{ .Release.Namespace }}
spec:
podSelector:
matchLabels:
@@ -31,16 +29,15 @@ spec:
- protocol: TCP
port: 8000
---
# Symbol Registry API: accept from Traefik ingress
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-symbol-registry-ingress
namespace: {{ .Values.namespace }}
namespace: {{ .Release.Namespace }}
spec:
podSelector:
matchLabels:
app: symbol-registry-api
app: symbol-registry
policyTypes:
- Ingress
ingress:
@@ -52,16 +49,15 @@ spec:
- protocol: TCP
port: 8000
---
# Risk Engine: accept from broker-adapter and query-api
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-risk-engine-ingress
namespace: {{ .Values.namespace }}
namespace: {{ .Release.Namespace }}
spec:
podSelector:
matchLabels:
app: risk-engine
app: risk
policyTypes:
- Ingress
ingress:
@@ -76,12 +72,11 @@ spec:
- protocol: TCP
port: 8000
---
# Superset: accept from Traefik ingress
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-superset-ingress
namespace: {{ .Values.namespace }}
namespace: {{ .Release.Namespace }}
spec:
podSelector:
matchLabels:
@@ -97,12 +92,11 @@ spec:
- protocol: TCP
port: 8088
---
# Trino: accept from Superset, query-api, and Traefik
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-trino-ingress
namespace: {{ .Values.namespace }}
namespace: {{ .Release.Namespace }}
spec:
podSelector:
matchLabels:
@@ -124,12 +118,11 @@ spec:
- protocol: TCP
port: 8080
---
# Hive Metastore: accept from Trino and lake-publisher
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-hive-metastore-ingress
namespace: {{ .Values.namespace }}
namespace: {{ .Release.Namespace }}
spec:
podSelector:
matchLabels:
@@ -148,12 +141,11 @@ spec:
- protocol: TCP
port: 9083
---
# Broker adapter: isolated — no inbound
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: deny-broker-adapter-ingress
namespace: {{ .Values.namespace }}
namespace: {{ .Release.Namespace }}
spec:
podSelector:
matchLabels:
@@ -2,7 +2,7 @@ apiVersion: v1
kind: Secret
metadata:
name: stonks-core-secrets
namespace: {{ .Values.namespace }}
namespace: {{ .Release.Namespace }}
labels:
{{- include "stonks.labels" . | nindent 4 }}
type: Opaque
@@ -15,7 +15,7 @@ apiVersion: v1
kind: Secret
metadata:
name: stonks-broker-secrets
namespace: {{ .Values.namespace }}
namespace: {{ .Release.Namespace }}
labels:
{{- include "stonks.labels" . | nindent 4 }}
type: Opaque
@@ -28,7 +28,7 @@ apiVersion: v1
kind: Secret
metadata:
name: stonks-market-secrets
namespace: {{ .Values.namespace }}
namespace: {{ .Release.Namespace }}
labels:
{{- include "stonks.labels" . | nindent 4 }}
type: Opaque
@@ -41,7 +41,7 @@ apiVersion: v1
kind: Secret
metadata:
name: stonks-dashboard-secrets
namespace: {{ .Values.namespace }}
namespace: {{ .Release.Namespace }}
labels:
{{- include "stonks.labels" . | nindent 4 }}
type: Opaque
@@ -1,14 +1,15 @@
{{- $root := . -}}
{{- range $name, $svc := .Values.services }}
{{- if $svc.port }}
---
apiVersion: v1
kind: Service
metadata:
name: {{ $name }}
namespace: {{ $.Values.namespace }}
name: {{ $svc.image }}
namespace: {{ $root.Release.Namespace }}
spec:
selector:
app: {{ $name }}
app: {{ $svc.image }}
ports:
- port: {{ $svc.port }}
targetPort: {{ $svc.port }}
@@ -3,7 +3,7 @@ apiVersion: apps/v1
kind: Deployment
metadata:
name: superset
namespace: {{ .Values.namespace }}
namespace: {{ .Release.Namespace }}
labels:
app: superset
{{- include "stonks.labels" . | nindent 4 }}
@@ -20,17 +20,12 @@ spec:
stonks-oracle/tier: dashboard
spec:
automountServiceAccountToken: false
{{- if .Values.imagePullSecrets.enabled }}
{{- with .Values.imagePullSecrets }}
imagePullSecrets:
- name: {{ .Values.imagePullSecrets.name }}
{{- toYaml . | nindent 8 }}
{{- end }}
securityContext:
runAsNonRoot: true
runAsUser: 1000
runAsGroup: 1000
fsGroup: 1000
seccompProfile:
type: RuntimeDefault
{{- include "stonks.podSecurityContext" . | nindent 8 }}
containers:
- name: superset
image: apache/superset:latest
@@ -62,12 +57,7 @@ spec:
mountPath: /app/pythonpath/superset_config.py
subPath: superset_config.py
resources:
requests:
cpu: {{ .Values.superset.resources.requests.cpu }}
memory: {{ .Values.superset.resources.requests.memory }}
limits:
cpu: {{ .Values.superset.resources.limits.cpu | quote }}
memory: {{ .Values.superset.resources.limits.memory }}
{{- toYaml .Values.superset.resources | nindent 12 }}
readinessProbe:
httpGet:
path: /health
@@ -86,7 +76,7 @@ apiVersion: v1
kind: Service
metadata:
name: superset
namespace: {{ .Values.namespace }}
namespace: {{ .Release.Namespace }}
spec:
selector:
app: superset
@@ -98,7 +88,7 @@ apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: superset-data
namespace: {{ .Values.namespace }}
namespace: {{ .Release.Namespace }}
spec:
accessModes:
- ReadWriteOnce
@@ -110,12 +100,12 @@ apiVersion: v1
kind: ConfigMap
metadata:
name: superset-config
namespace: {{ .Values.namespace }}
namespace: {{ .Release.Namespace }}
data:
superset_config.py: |
import os
SECRET_KEY = os.getenv("SUPERSET_SECRET_KEY", "stonks-dev-secret-key-change-me")
SQLALCHEMY_DATABASE_URI = "trino://trino@trino.{{ .Values.namespace }}.svc.cluster.local:8080/lakehouse/stonks"
SQLALCHEMY_DATABASE_URI = "trino://trino@trino.{{ .Release.Namespace }}.svc.cluster.local:8080/lakehouse/stonks"
FEATURE_FLAGS = {"ENABLE_TEMPLATE_PROCESSING": True}
CACHE_CONFIG = {
"CACHE_TYPE": "RedisCache",
+11 -21
View File
@@ -3,7 +3,7 @@ apiVersion: apps/v1
kind: Deployment
metadata:
name: trino
namespace: {{ .Values.namespace }}
namespace: {{ .Release.Namespace }}
labels:
app: trino
{{- include "stonks.labels" . | nindent 4 }}
@@ -20,17 +20,12 @@ spec:
stonks-oracle/tier: analytics
spec:
automountServiceAccountToken: false
{{- if .Values.imagePullSecrets.enabled }}
{{- with .Values.imagePullSecrets }}
imagePullSecrets:
- name: {{ .Values.imagePullSecrets.name }}
{{- toYaml . | nindent 8 }}
{{- end }}
securityContext:
runAsNonRoot: true
runAsUser: 1000
runAsGroup: 1000
fsGroup: 1000
seccompProfile:
type: RuntimeDefault
{{- include "stonks.podSecurityContext" . | nindent 8 }}
initContainers:
- name: catalog-init
image: busybox:1.36
@@ -44,21 +39,21 @@ spec:
cat > /catalog/iceberg.properties <<EOF
connector.name=iceberg
iceberg.catalog.type=hive_metastore
hive.metastore.uri=thrift://hive-metastore.{{ $.Values.namespace }}.svc.cluster.local:9083
hive.s3.endpoint=http://minio.minio-service.svc.cluster.local:80
hive.metastore.uri=thrift://hive-metastore.{{ $.Release.Namespace }}.svc.cluster.local:9083
hive.s3.endpoint=http://{{ index $.Values.config "MINIO_ENDPOINT" }}
hive.s3.path-style-access=true
hive.s3.aws-access-key=${MINIO_ACCESS_KEY}
hive.s3.aws-secret-key=${MINIO_SECRET_KEY}
fs.native-s3.enabled=true
s3.endpoint=http://minio.minio-service.svc.cluster.local:80
s3.endpoint=http://{{ index $.Values.config "MINIO_ENDPOINT" }}
s3.path-style-access=true
s3.aws-access-key=${MINIO_ACCESS_KEY}
s3.aws-secret-key=${MINIO_SECRET_KEY}
EOF
cat > /catalog/lakehouse.properties <<EOF
connector.name=hive
hive.metastore.uri=thrift://hive-metastore.{{ $.Values.namespace }}.svc.cluster.local:9083
hive.s3.endpoint=http://minio.minio-service.svc.cluster.local:80
hive.metastore.uri=thrift://hive-metastore.{{ $.Release.Namespace }}.svc.cluster.local:9083
hive.s3.endpoint=http://{{ index $.Values.config "MINIO_ENDPOINT" }}
hive.s3.path-style-access=true
hive.s3.aws-access-key=${MINIO_ACCESS_KEY}
hive.s3.aws-secret-key=${MINIO_SECRET_KEY}
@@ -92,12 +87,7 @@ spec:
- name: catalog-config
mountPath: /etc/trino/catalog
resources:
requests:
cpu: {{ .Values.trino.resources.requests.cpu }}
memory: {{ .Values.trino.resources.requests.memory }}
limits:
cpu: {{ .Values.trino.resources.limits.cpu | quote }}
memory: {{ .Values.trino.resources.limits.memory }}
{{- toYaml .Values.trino.resources | nindent 12 }}
readinessProbe:
httpGet:
path: /v1/info
@@ -112,7 +102,7 @@ apiVersion: v1
kind: Service
metadata:
name: trino
namespace: {{ .Values.namespace }}
namespace: {{ .Release.Namespace }}
spec:
selector:
app: trino
+63 -69
View File
@@ -1,39 +1,36 @@
## Stonks Oracle Helm Values
## Global image settings
image:
registry: ghcr.io/celesrenata/stonks-oracle
pullPolicy: Always
tag: latest
namespace: stonks-oracle
imageRegistry: ghcr.io/celesrenata/stonks-oracle
imageTag: latest
imagePullPolicy: Always
## GHCR image pull secret
imagePullSecrets:
- name: ghcr-credentials
## GHCR authentication for private registry
ghcrAuth:
enabled: true
name: ghcr-credentials
# Set to true to have Helm manage the secret. If false, create it
# manually with: kubectl create secret docker-registry ghcr-credentials ...
createSecret: false
# Base64-encoded .dockerconfigjson — only used when createSecret is true
dockerconfigjson: ""
## ── Services ──────────────────────────────────────────────────────────
## Each service maps to a Deployment. Services with `port` also get a
## ClusterIP Service resource. `secrets` lists which Secret names to
## mount via envFrom.
registry: ghcr.io
username: celesrenata
# base64-encoded dockerconfigjson — override at install time
password: ""
## Service deployments — replicas and resource overrides
services:
scheduler:
image: scheduler
replicas: 1
image: scheduler
command: "python -m services.scheduler.app"
tier: orchestration
secrets: [stonks-core-secrets]
resources:
requests: { cpu: 50m, memory: 64Mi }
limits: { cpu: 200m, memory: 128Mi }
symbol-registry-api:
image: symbol-registry
symbolRegistry:
replicas: 1
image: symbol-registry
command: "uvicorn services.symbol_registry.app:app --host 0.0.0.0 --port 8000"
tier: api
port: 8000
secrets: [stonks-core-secrets]
@@ -44,54 +41,60 @@ services:
readiness: { path: /docs, port: 8000, initialDelay: 5, period: 10 }
liveness: { path: /docs, port: 8000, initialDelay: 10, period: 30 }
ingestion-worker:
image: ingestion
ingestion:
replicas: 2
image: ingestion
command: "python -m services.ingestion.worker"
tier: ingestion
secrets: [stonks-core-secrets, stonks-market-secrets]
resources:
requests: { cpu: 100m, memory: 128Mi }
limits: { cpu: 500m, memory: 256Mi }
parser-worker:
image: parser
parser:
replicas: 2
image: parser
command: "python -m services.parser.worker"
tier: processing
secrets: [stonks-core-secrets]
resources:
requests: { cpu: 100m, memory: 128Mi }
limits: { cpu: 500m, memory: 256Mi }
extractor-worker:
image: extractor
extractor:
replicas: 1
image: extractor
command: "python -m services.extractor.worker"
tier: processing
secrets: [stonks-core-secrets]
resources:
requests: { cpu: 200m, memory: 256Mi }
limits: { cpu: "1", memory: 512Mi }
aggregation-worker:
aggregation:
replicas: 1
image: aggregation
replicas: 1
command: "python -m services.aggregation.worker"
tier: processing
secrets: [stonks-core-secrets]
resources:
requests: { cpu: 100m, memory: 128Mi }
limits: { cpu: 500m, memory: 256Mi }
recommendation-worker:
recommendation:
replicas: 1
image: recommendation
replicas: 1
command: "python -m services.recommendation.worker"
tier: processing
secrets: [stonks-core-secrets]
resources:
requests: { cpu: 100m, memory: 128Mi }
limits: { cpu: 500m, memory: 256Mi }
risk-engine:
image: risk
riskEngine:
replicas: 1
image: risk
command: "uvicorn services.risk.app:app --host 0.0.0.0 --port 8000"
tier: trading
port: 8000
secrets: [stonks-core-secrets, stonks-broker-secrets]
@@ -99,27 +102,30 @@ services:
requests: { cpu: 100m, memory: 128Mi }
limits: { cpu: 500m, memory: 256Mi }
broker-adapter:
image: broker-adapter
brokerAdapter:
replicas: 1
image: broker-adapter
command: "python -m services.adapters.broker_adapter"
tier: trading
secrets: [stonks-core-secrets, stonks-broker-secrets]
resources:
requests: { cpu: 50m, memory: 64Mi }
limits: { cpu: 200m, memory: 128Mi }
lake-publisher:
image: lake-publisher
lakePublisher:
replicas: 1
image: lake-publisher
command: "python -m services.lake_publisher.worker"
tier: analytics
secrets: [stonks-core-secrets]
resources:
requests: { cpu: 100m, memory: 128Mi }
limits: { cpu: 500m, memory: 256Mi }
query-api:
image: query-api
queryApi:
replicas: 1
image: query-api
command: "uvicorn services.api.app:app --host 0.0.0.0 --port 8000"
tier: api
port: 8000
secrets: [stonks-core-secrets]
@@ -129,7 +135,7 @@ services:
probes:
readiness: { path: /docs, port: 8000, initialDelay: 5, period: 10 }
## ── ConfigMap data ────────────────────────────────────────────────────
## ConfigMap data
config:
POSTGRES_HOST: "postgresql-rw.postgresql-service.svc.cluster.local"
POSTGRES_PORT: "5432"
@@ -177,48 +183,35 @@ config:
ALERT_BROKER_ERROR_WINDOW_HOURS: "1"
ALERT_CHECK_INTERVAL_SECONDS: "120"
## ── Secrets ───────────────────────────────────────────────────────────
## Values here are placeholders. Override via --set or a secrets file.
## Secrets
secrets:
core:
POSTGRES_PASSWORD: "REPLACE_ME"
MINIO_ACCESS_KEY: "REPLACE_ME"
MINIO_SECRET_KEY: "REPLACE_ME"
POSTGRES_PASSWORD: ""
MINIO_ACCESS_KEY: ""
MINIO_SECRET_KEY: ""
REDIS_PASSWORD: ""
broker:
BROKER_API_KEY: "REPLACE_ME"
BROKER_API_SECRET: "REPLACE_ME"
BROKER_API_KEY: ""
BROKER_API_SECRET: ""
BROKER_BASE_URL: "https://paper-api.alpaca.markets"
market:
MARKET_DATA_API_KEY: "REPLACE_ME"
MARKET_DATA_API_KEY: ""
dashboard:
SUPERSET_SECRET_KEY: "REPLACE_ME"
SUPERSET_ADMIN_PASSWORD: "REPLACE_ME"
SUPERSET_SECRET_KEY: ""
SUPERSET_ADMIN_PASSWORD: ""
## ── Ingress ───────────────────────────────────────────────────────────
## Ingress
ingress:
enabled: true
className: traefik
clusterIssuer: ca-issuer
hosts:
query-api:
host: stonks-api.celestium.life
service: query-api
port: 8000
registry:
host: stonks-registry.celestium.life
service: symbol-registry-api
port: 8000
superset:
host: stonks-dash.celestium.life
service: superset
port: 8088
trino:
host: stonks-trino.celestium.life
service: trino
port: 8080
queryApi: stonks-api.celestium.life
symbolRegistry: stonks-registry.celestium.life
superset: stonks-dash.celestium.life
trino: stonks-trino.celestium.life
## ── Analytics stack ───────────────────────────────────────────────────
## Analytics stack
trino:
enabled: true
resources:
@@ -239,5 +232,6 @@ superset:
requests: { cpu: 200m, memory: 512Mi }
limits: { cpu: "1", memory: 2Gi }
## Network policies
networkPolicies:
enabled: true
@@ -8,7 +8,7 @@ CREATE TABLE trend_windows (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
entity_type VARCHAR(50) NOT NULL DEFAULT 'company',
entity_id VARCHAR(100) NOT NULL,
window VARCHAR(20) NOT NULL,
"window" VARCHAR(20) NOT NULL,
trend_direction VARCHAR(20) NOT NULL DEFAULT 'neutral',
trend_strength FLOAT DEFAULT 0.5,
confidence FLOAT DEFAULT 0.5,
@@ -21,7 +21,7 @@ CREATE TABLE trend_windows (
generated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
CREATE INDEX idx_trends_entity ON trend_windows(entity_type, entity_id, window);
CREATE INDEX idx_trends_entity ON trend_windows(entity_type, entity_id, "window");
CREATE INDEX idx_trends_generated ON trend_windows(generated_at DESC);
-- ============================================================