New enterprise feature

This commit is contained in:
Urtzi Alfaro
2025-11-30 09:12:40 +01:00
parent f9d0eec6ec
commit 972db02f6d
176 changed files with 19741 additions and 1361 deletions

View File

@@ -0,0 +1,169 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: distribution-db
namespace: bakery-ia
labels:
app.kubernetes.io/name: distribution-db
app.kubernetes.io/component: database
app.kubernetes.io/part-of: bakery-ia
spec:
replicas: 1
selector:
matchLabels:
app.kubernetes.io/name: distribution-db
app.kubernetes.io/component: database
template:
metadata:
labels:
app.kubernetes.io/name: distribution-db
app.kubernetes.io/component: database
spec:
securityContext:
fsGroup: 70
initContainers:
- name: fix-tls-permissions
image: busybox:latest
securityContext:
runAsUser: 0
command: ['sh', '-c']
args:
- |
cp /tls-source/* /tls/
chmod 600 /tls/server-key.pem
chmod 644 /tls/server-cert.pem /tls/ca-cert.pem
chown 70:70 /tls/*
ls -la /tls/
volumeMounts:
- name: tls-certs-source
mountPath: /tls-source
readOnly: true
- name: tls-certs-writable
mountPath: /tls
containers:
- name: postgres
image: postgres:17-alpine
command: ["docker-entrypoint.sh", "-c", "config_file=/etc/postgresql/postgresql.conf"]
ports:
- containerPort: 5432
name: postgres
env:
- name: POSTGRES_DB
valueFrom:
configMapKeyRef:
name: bakery-config
key: DISTRIBUTION_DB_NAME
- name: POSTGRES_USER
valueFrom:
secretKeyRef:
name: database-secrets
key: DISTRIBUTION_DB_USER
- name: POSTGRES_PASSWORD
valueFrom:
secretKeyRef:
name: database-secrets
key: DISTRIBUTION_DB_PASSWORD
- name: POSTGRES_INITDB_ARGS
valueFrom:
configMapKeyRef:
name: bakery-config
key: POSTGRES_INITDB_ARGS
- name: PGDATA
value: /var/lib/postgresql/data/pgdata
- name: POSTGRES_HOST_SSL
value: "on"
- name: PGSSLCERT
value: /tls/server-cert.pem
- name: PGSSLKEY
value: /tls/server-key.pem
- name: PGSSLROOTCERT
value: /tls/ca-cert.pem
volumeMounts:
- name: postgres-data
mountPath: /var/lib/postgresql/data
- name: init-scripts
mountPath: /docker-entrypoint-initdb.d
- name: tls-certs-writable
mountPath: /tls
- name: postgres-config
mountPath: /etc/postgresql
readOnly: true
resources:
requests:
memory: "256Mi"
cpu: "100m"
limits:
memory: "512Mi"
cpu: "500m"
livenessProbe:
exec:
command:
- sh
- -c
- pg_isready -U $POSTGRES_USER -d $POSTGRES_DB
initialDelaySeconds: 30
timeoutSeconds: 5
periodSeconds: 10
failureThreshold: 3
readinessProbe:
exec:
command:
- sh
- -c
- pg_isready -U $POSTGRES_USER -d $POSTGRES_DB
initialDelaySeconds: 5
timeoutSeconds: 1
periodSeconds: 5
failureThreshold: 3
volumes:
- name: postgres-data
persistentVolumeClaim:
claimName: distribution-db-pvc
- name: init-scripts
configMap:
name: postgres-init-config
- name: tls-certs-source
secret:
secretName: postgres-tls
- name: tls-certs-writable
emptyDir: {}
- name: postgres-config
configMap:
name: postgres-logging-config
---
apiVersion: v1
kind: Service
metadata:
name: distribution-db-service
namespace: bakery-ia
labels:
app.kubernetes.io/name: distribution-db
app.kubernetes.io/component: database
spec:
type: ClusterIP
ports:
- port: 5432
targetPort: 5432
protocol: TCP
name: postgres
selector:
app.kubernetes.io/name: distribution-db
app.kubernetes.io/component: database
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: distribution-db-pvc
namespace: bakery-ia
labels:
app.kubernetes.io/name: distribution-db
app.kubernetes.io/component: database
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 2Gi

View File

@@ -0,0 +1,78 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: distribution-service-config
data:
# Service settings
SERVICE_NAME: "distribution-service"
APP_NAME: "Bakery Distribution Service"
DESCRIPTION: "Distribution service for enterprise tier bakery management"
VERSION: "1.0.0"
# Database settings
DB_POOL_SIZE: "10"
DB_MAX_OVERFLOW: "20"
DB_POOL_TIMEOUT: "30"
DB_POOL_RECYCLE: "3600"
DB_POOL_PRE_PING: "true"
DB_ECHO: "false"
# Redis settings
REDIS_DB: "7" # Use separate database for distribution service
REDIS_MAX_CONNECTIONS: "50"
REDIS_RETRY_ON_TIMEOUT: "true"
REDIS_SOCKET_KEEPALIVE: "true"
# RabbitMQ settings
RABBITMQ_EXCHANGE: "bakery_events"
RABBITMQ_QUEUE_PREFIX: "distribution"
RABBITMQ_RETRY_ATTEMPTS: "3"
RABBITMQ_RETRY_DELAY: "5"
# Authentication settings
JWT_ALGORITHM: "HS256"
JWT_ACCESS_TOKEN_EXPIRE_MINUTES: "30"
JWT_REFRESH_TOKEN_EXPIRE_DAYS: "7"
ENABLE_SERVICE_AUTH: "true"
# HTTP client settings
HTTP_TIMEOUT: "30"
HTTP_RETRIES: "3"
HTTP_RETRY_DELAY: "1.0"
# CORS settings
CORS_ORIGINS: "http://localhost:3000,http://localhost:3001"
CORS_ALLOW_CREDENTIALS: "true"
CORS_ALLOW_METHODS: "GET,POST,PUT,DELETE,PATCH,OPTIONS"
CORS_ALLOW_HEADERS: "*"
# Rate limiting
RATE_LIMIT_ENABLED: "true"
RATE_LIMIT_REQUESTS: "100"
RATE_LIMIT_WINDOW: "60"
RATE_LIMIT_BURST: "10"
# Monitoring and observability
LOG_LEVEL: "INFO"
PROMETHEUS_ENABLED: "true"
PROMETHEUS_PORT: "9090"
JAEGER_ENABLED: "false"
JAEGER_AGENT_HOST: "jaeger-agent"
JAEGER_AGENT_PORT: "6831"
# Health check settings
HEALTH_CHECK_TIMEOUT: "30"
HEALTH_CHECK_INTERVAL: "30"
# Business rules
MAX_FORECAST_DAYS: "30"
MIN_HISTORICAL_DAYS: "60"
CONFIDENCE_THRESHOLD: "0.8"
# Routing optimization settings
VRP_TIME_LIMIT_SECONDS: "30"
VRP_DEFAULT_VEHICLE_CAPACITY_KG: "1000"
VRP_AVERAGE_SPEED_KMH: "30"
# Service-specific settings
DISTRIBUTION_SERVICE_URL: "http://distribution-service:8000"

View File

@@ -0,0 +1,155 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: distribution-service
namespace: bakery-ia
labels:
app.kubernetes.io/name: distribution-service
app.kubernetes.io/component: microservice
app.kubernetes.io/part-of: bakery-ia
spec:
replicas: 2
selector:
matchLabels:
app.kubernetes.io/name: distribution-service
app.kubernetes.io/component: microservice
template:
metadata:
labels:
app.kubernetes.io/name: distribution-service
app.kubernetes.io/component: microservice
spec:
initContainers:
# Wait for Redis to be ready
- name: wait-for-redis
image: redis:7.4-alpine
command:
- sh
- -c
- |
echo "Waiting for Redis to be ready..."
until redis-cli -h $REDIS_HOST -p $REDIS_PORT --tls --cert /tls/redis-cert.pem --key /tls/redis-key.pem --cacert /tls/ca-cert.pem -a "$REDIS_PASSWORD" ping | grep -q PONG; do
echo "Redis not ready yet, waiting..."
sleep 2
done
echo "Redis is ready!"
env:
- name: REDIS_HOST
valueFrom:
configMapKeyRef:
name: bakery-config
key: REDIS_HOST
- name: REDIS_PORT
valueFrom:
configMapKeyRef:
name: bakery-config
key: REDIS_PORT
- name: REDIS_PASSWORD
valueFrom:
secretKeyRef:
name: redis-secrets
key: REDIS_PASSWORD
volumeMounts:
- name: redis-tls
mountPath: /tls
readOnly: true
- name: wait-for-migration
image: postgres:17-alpine
command:
- sh
- -c
- |
echo "Waiting for distribution database and migrations to be ready..."
# Wait for database to be accessible
until pg_isready -h $DISTRIBUTION_DB_HOST -p $DISTRIBUTION_DB_PORT -U $DISTRIBUTION_DB_USER; do
echo "Database not ready yet, waiting..."
sleep 2
done
echo "Database is ready!"
# Give migrations extra time to complete after DB is ready
echo "Waiting for migrations to complete..."
sleep 10
echo "Ready to start service"
env:
- name: DISTRIBUTION_DB_HOST
valueFrom:
configMapKeyRef:
name: bakery-config
key: DISTRIBUTION_DB_HOST
- name: DISTRIBUTION_DB_PORT
valueFrom:
configMapKeyRef:
name: bakery-config
key: DB_PORT
- name: DISTRIBUTION_DB_USER
valueFrom:
secretKeyRef:
name: database-secrets
key: DISTRIBUTION_DB_USER
containers:
- name: distribution-service
image: bakery/distribution-service:latest
imagePullPolicy: IfNotPresent
ports:
- containerPort: 8000
name: http
envFrom:
- configMapRef:
name: bakery-config
- secretRef:
name: database-secrets
- secretRef:
name: redis-secrets
- secretRef:
name: rabbitmq-secrets
- secretRef:
name: jwt-secrets
livenessProbe:
httpGet:
path: /health
port: 8000
initialDelaySeconds: 30
periodSeconds: 10
timeoutSeconds: 5
readinessProbe:
httpGet:
path: /health
port: 8000
initialDelaySeconds: 5
periodSeconds: 5
timeoutSeconds: 3
resources:
requests:
memory: "256Mi"
cpu: "250m"
limits:
memory: "512Mi"
cpu: "500m"
volumeMounts:
- name: redis-tls
mountPath: /tls
readOnly: true
volumes:
- name: redis-tls
secret:
secretName: redis-tls-secret
---
apiVersion: v1
kind: Service
metadata:
name: distribution-service
namespace: bakery-ia
labels:
app.kubernetes.io/name: distribution-service
app.kubernetes.io/component: microservice
app.kubernetes.io/part-of: bakery-ia
spec:
selector:
app.kubernetes.io/name: distribution-service
app.kubernetes.io/component: microservice
ports:
- protocol: TCP
port: 8000
targetPort: 8000
name: http
type: ClusterIP

View File

@@ -0,0 +1,110 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: distribution-service
labels:
app: distribution-service
tier: backend
spec:
replicas: 2
selector:
matchLabels:
app: distribution-service
template:
metadata:
labels:
app: distribution-service
tier: backend
spec:
containers:
- name: distribution-service
image: bakery/distribution-service:latest
imagePullPolicy: Always
ports:
- containerPort: 8000
name: http
env:
- name: DATABASE_URL
valueFrom:
secretKeyRef:
name: database-secret
key: url
- name: REDIS_URL
valueFrom:
secretKeyRef:
name: redis-secret
key: url
- name: RABBITMQ_URL
valueFrom:
secretKeyRef:
name: rabbitmq-secret
key: url
- name: JWT_SECRET_KEY
valueFrom:
secretKeyRef:
name: auth-secret
key: jwt-secret
- name: ENVIRONMENT
value: "production"
- name: LOG_LEVEL
value: "INFO"
- name: DB_POOL_SIZE
value: "10"
- name: DB_MAX_OVERFLOW
value: "20"
- name: REDIS_MAX_CONNECTIONS
value: "50"
- name: HTTP_TIMEOUT
value: "30"
- name: HTTP_RETRIES
value: "3"
livenessProbe:
httpGet:
path: /health
port: 8000
initialDelaySeconds: 30
periodSeconds: 10
timeoutSeconds: 5
readinessProbe:
httpGet:
path: /health
port: 8000
initialDelaySeconds: 5
periodSeconds: 5
timeoutSeconds: 3
resources:
requests:
memory: "256Mi"
cpu: "250m"
limits:
memory: "512Mi"
cpu: "500m"
securityContext:
runAsNonRoot: true
runAsUser: 1000
allowPrivilegeEscalation: false
readOnlyRootFilesystem: false
capabilities:
drop:
- ALL
securityContext:
runAsNonRoot: true
runAsUser: 1000
fsGroup: 2000
---
apiVersion: v1
kind: Service
metadata:
name: distribution-service
labels:
app: distribution-service
tier: backend
spec:
selector:
app.kubernetes.io/name: distribution-service
ports:
- protocol: TCP
port: 8000
targetPort: 8000
name: http
type: ClusterIP

View File

@@ -60,6 +60,7 @@ data:
ORCHESTRATOR_DB_HOST: "orchestrator-db-service"
ALERT_PROCESSOR_DB_HOST: "alert-processor-db-service"
AI_INSIGHTS_DB_HOST: "ai-insights-db-service"
DISTRIBUTION_DB_HOST: "distribution-db-service"
# Database Configuration
DB_PORT: "5432"
@@ -80,6 +81,7 @@ data:
ORCHESTRATOR_DB_NAME: "orchestrator_db"
ALERT_PROCESSOR_DB_NAME: "alert_processor_db"
AI_INSIGHTS_DB_NAME: "ai_insights_db"
DISTRIBUTION_DB_NAME: "distribution_db"
POSTGRES_INITDB_ARGS: "--encoding=UTF-8 --lc-collate=C --lc-ctype=C"
# ================================================================
@@ -102,6 +104,7 @@ data:
ALERT_PROCESSOR_SERVICE_URL: "http://alert-processor-api:8010"
ORCHESTRATOR_SERVICE_URL: "http://orchestrator-service:8000"
AI_INSIGHTS_SERVICE_URL: "http://ai-insights-service:8000"
DISTRIBUTION_SERVICE_URL: "http://distribution-service:8000"
# ================================================================
# AUTHENTICATION & SECURITY SETTINGS

View File

@@ -0,0 +1,55 @@
apiVersion: batch/v1
kind: Job
metadata:
name: demo-seed-alerts-retail
namespace: bakery-ia
labels:
app: demo-seed
component: initialization
tier: retail
annotations:
"helm.sh/hook": post-install,post-upgrade
"helm.sh/hook-weight": "56" # After retail forecasts (55)
spec:
ttlSecondsAfterFinished: 3600
template:
metadata:
labels:
app: demo-seed-alerts-retail
spec:
initContainers:
- name: wait-for-alert-processor-service
image: curlimages/curl:latest
command:
- sh
- -c
- |
echo "Waiting for alert-processor-api to be ready..."
until curl -f http://alert-processor-api.bakery-ia.svc.cluster.local:8010/health > /dev/null 2>&1; do
echo "alert-processor-api not ready yet, waiting..."
sleep 5
done
echo "alert-processor-api is ready!"
containers:
- name: seed-alerts-retail
image: bakery/alert-processor:latest
command: ["python", "/app/scripts/demo/seed_demo_alerts_retail.py"]
env:
- name: ALERT_PROCESSOR_DATABASE_URL
valueFrom:
secretKeyRef:
name: database-secrets
key: ALERT_PROCESSOR_DATABASE_URL
- name: DEMO_MODE
value: "production"
- name: LOG_LEVEL
value: "INFO"
resources:
requests:
memory: "256Mi"
cpu: "100m"
limits:
memory: "512Mi"
cpu: "500m"
restartPolicy: OnFailure
serviceAccountName: demo-seed-sa

View File

@@ -0,0 +1,55 @@
apiVersion: batch/v1
kind: Job
metadata:
name: demo-seed-customers-retail
namespace: bakery-ia
labels:
app: demo-seed
component: initialization
tier: retail
annotations:
"helm.sh/hook": post-install,post-upgrade
"helm.sh/hook-weight": "53" # After retail sales (52)
spec:
ttlSecondsAfterFinished: 3600
template:
metadata:
labels:
app: demo-seed-customers-retail
spec:
initContainers:
- name: wait-for-orders-service
image: curlimages/curl:latest
command:
- sh
- -c
- |
echo "Waiting for orders-service to be ready..."
until curl -f http://orders-service.bakery-ia.svc.cluster.local:8000/health/ready > /dev/null 2>&1; do
echo "orders-service not ready yet, waiting..."
sleep 5
done
echo "orders-service is ready!"
containers:
- name: seed-customers-retail
image: bakery/orders-service:latest
command: ["python", "/app/scripts/demo/seed_demo_customers_retail.py"]
env:
- name: ORDERS_DATABASE_URL
valueFrom:
secretKeyRef:
name: database-secrets
key: ORDERS_DATABASE_URL
- name: DEMO_MODE
value: "production"
- name: LOG_LEVEL
value: "INFO"
resources:
requests:
memory: "256Mi"
cpu: "100m"
limits:
memory: "512Mi"
cpu: "500m"
restartPolicy: OnFailure
serviceAccountName: demo-seed-sa

View File

@@ -0,0 +1,64 @@
apiVersion: batch/v1
kind: Job
metadata:
name: demo-seed-distribution-history
namespace: bakery-ia
labels:
app: demo-seed
component: initialization
tier: enterprise
annotations:
"helm.sh/hook": post-install,post-upgrade
"helm.sh/hook-weight": "57" # After all retail seeds (56) - CRITICAL for enterprise demo
spec:
ttlSecondsAfterFinished: 3600
template:
metadata:
labels:
app: demo-seed-distribution-history
spec:
initContainers:
- name: wait-for-distribution-service
image: curlimages/curl:latest
command:
- sh
- -c
- |
echo "Waiting for distribution-service to be ready..."
until curl -f http://distribution-service.bakery-ia.svc.cluster.local:8000/health > /dev/null 2>&1; do
echo "distribution-service not ready yet, waiting..."
sleep 5
done
echo "distribution-service is ready!"
- name: wait-for-all-retail-seeds
image: busybox:1.36
command:
- sh
- -c
- |
echo "Waiting 60 seconds for all retail seeds to complete..."
echo "This ensures distribution history has all child data in place"
sleep 60
containers:
- name: seed-distribution-history
image: bakery/distribution-service:latest
command: ["python", "/app/scripts/demo/seed_demo_distribution_history.py"]
env:
- name: DISTRIBUTION_DATABASE_URL
valueFrom:
secretKeyRef:
name: database-secrets
key: DISTRIBUTION_DATABASE_URL
- name: DEMO_MODE
value: "production"
- name: LOG_LEVEL
value: "INFO"
resources:
requests:
memory: "256Mi"
cpu: "100m"
limits:
memory: "512Mi"
cpu: "500m"
restartPolicy: OnFailure
serviceAccountName: demo-seed-sa

View File

@@ -0,0 +1,55 @@
apiVersion: batch/v1
kind: Job
metadata:
name: demo-seed-forecasts-retail
namespace: bakery-ia
labels:
app: demo-seed
component: initialization
tier: retail
annotations:
"helm.sh/hook": post-install,post-upgrade
"helm.sh/hook-weight": "55" # After retail POS (54)
spec:
ttlSecondsAfterFinished: 3600
template:
metadata:
labels:
app: demo-seed-forecasts-retail
spec:
initContainers:
- name: wait-for-forecasting-service
image: curlimages/curl:latest
command:
- sh
- -c
- |
echo "Waiting for forecasting-service to be ready..."
until curl -f http://forecasting-service.bakery-ia.svc.cluster.local:8000/health/ready > /dev/null 2>&1; do
echo "forecasting-service not ready yet, waiting..."
sleep 5
done
echo "forecasting-service is ready!"
containers:
- name: seed-forecasts-retail
image: bakery/forecasting-service:latest
command: ["python", "/app/scripts/demo/seed_demo_forecasts_retail.py"]
env:
- name: FORECASTING_DATABASE_URL
valueFrom:
secretKeyRef:
name: database-secrets
key: FORECASTING_DATABASE_URL
- name: DEMO_MODE
value: "production"
- name: LOG_LEVEL
value: "INFO"
resources:
requests:
memory: "256Mi"
cpu: "100m"
limits:
memory: "512Mi"
cpu: "500m"
restartPolicy: OnFailure
serviceAccountName: demo-seed-sa

View File

@@ -0,0 +1,63 @@
apiVersion: batch/v1
kind: Job
metadata:
name: demo-seed-inventory-retail
namespace: bakery-ia
labels:
app: demo-seed
component: initialization
tier: retail
annotations:
"helm.sh/hook": post-install,post-upgrade
"helm.sh/hook-weight": "50" # After parent inventory (15)
spec:
ttlSecondsAfterFinished: 3600
template:
metadata:
labels:
app: demo-seed-inventory-retail
spec:
initContainers:
- name: wait-for-parent-inventory
image: busybox:1.36
command:
- sh
- -c
- |
echo "Waiting 45 seconds for parent inventory seed to complete..."
sleep 45
- name: wait-for-inventory-service
image: curlimages/curl:latest
command:
- sh
- -c
- |
echo "Waiting for inventory-service to be ready..."
until curl -f http://inventory-service.bakery-ia.svc.cluster.local:8000/health/ready > /dev/null 2>&1; do
echo "inventory-service not ready yet, waiting..."
sleep 5
done
echo "inventory-service is ready!"
containers:
- name: seed-inventory-retail
image: bakery/inventory-service:latest
command: ["python", "/app/scripts/demo/seed_demo_inventory_retail.py"]
env:
- name: INVENTORY_DATABASE_URL
valueFrom:
secretKeyRef:
name: database-secrets
key: INVENTORY_DATABASE_URL
- name: DEMO_MODE
value: "production"
- name: LOG_LEVEL
value: "INFO"
resources:
requests:
memory: "256Mi"
cpu: "100m"
limits:
memory: "512Mi"
cpu: "500m"
restartPolicy: OnFailure
serviceAccountName: demo-seed-sa

View File

@@ -0,0 +1,55 @@
apiVersion: batch/v1
kind: Job
metadata:
name: demo-seed-pos-retail
namespace: bakery-ia
labels:
app: demo-seed
component: initialization
tier: retail
annotations:
"helm.sh/hook": post-install,post-upgrade
"helm.sh/hook-weight": "54" # After retail customers (53)
spec:
ttlSecondsAfterFinished: 3600
template:
metadata:
labels:
app: demo-seed-pos-retail
spec:
initContainers:
- name: wait-for-pos-service
image: curlimages/curl:latest
command:
- sh
- -c
- |
echo "Waiting for pos-service to be ready..."
until curl -f http://pos-service.bakery-ia.svc.cluster.local:8000/health/ready > /dev/null 2>&1; do
echo "pos-service not ready yet, waiting..."
sleep 5
done
echo "pos-service is ready!"
containers:
- name: seed-pos-retail
image: bakery/pos-service:latest
command: ["python", "/app/scripts/demo/seed_demo_pos_retail.py"]
env:
- name: POS_DATABASE_URL
valueFrom:
secretKeyRef:
name: database-secrets
key: POS_DATABASE_URL
- name: DEMO_MODE
value: "production"
- name: LOG_LEVEL
value: "INFO"
resources:
requests:
memory: "256Mi"
cpu: "100m"
limits:
memory: "512Mi"
cpu: "500m"
restartPolicy: OnFailure
serviceAccountName: demo-seed-sa

View File

@@ -0,0 +1,63 @@
apiVersion: batch/v1
kind: Job
metadata:
name: demo-seed-sales-retail
namespace: bakery-ia
labels:
app: demo-seed
component: initialization
tier: retail
annotations:
"helm.sh/hook": post-install,post-upgrade
"helm.sh/hook-weight": "52" # After retail stock (51)
spec:
ttlSecondsAfterFinished: 3600
template:
metadata:
labels:
app: demo-seed-sales-retail
spec:
initContainers:
- name: wait-for-retail-stock
image: busybox:1.36
command:
- sh
- -c
- |
echo "Waiting 30 seconds for retail stock seed to complete..."
sleep 30
- name: wait-for-sales-service
image: curlimages/curl:latest
command:
- sh
- -c
- |
echo "Waiting for sales-service to be ready..."
until curl -f http://sales-service.bakery-ia.svc.cluster.local:8000/health/ready > /dev/null 2>&1; do
echo "sales-service not ready yet, waiting..."
sleep 5
done
echo "sales-service is ready!"
containers:
- name: seed-sales-retail
image: bakery/sales-service:latest
command: ["python", "/app/scripts/demo/seed_demo_sales_retail.py"]
env:
- name: SALES_DATABASE_URL
valueFrom:
secretKeyRef:
name: database-secrets
key: SALES_DATABASE_URL
- name: DEMO_MODE
value: "production"
- name: LOG_LEVEL
value: "INFO"
resources:
requests:
memory: "256Mi"
cpu: "100m"
limits:
memory: "512Mi"
cpu: "500m"
restartPolicy: OnFailure
serviceAccountName: demo-seed-sa

View File

@@ -0,0 +1,51 @@
apiVersion: batch/v1
kind: Job
metadata:
name: demo-seed-stock-retail
namespace: bakery-ia
labels:
app: demo-seed
component: initialization
tier: retail
annotations:
"helm.sh/hook": post-install,post-upgrade
"helm.sh/hook-weight": "51" # After retail inventory (50)
spec:
ttlSecondsAfterFinished: 3600
template:
metadata:
labels:
app: demo-seed-stock-retail
spec:
initContainers:
- name: wait-for-retail-inventory
image: busybox:1.36
command:
- sh
- -c
- |
echo "Waiting 30 seconds for retail inventory seed to complete..."
sleep 30
containers:
- name: seed-stock-retail
image: bakery/inventory-service:latest
command: ["python", "/app/scripts/demo/seed_demo_stock_retail.py"]
env:
- name: INVENTORY_DATABASE_URL
valueFrom:
secretKeyRef:
name: database-secrets
key: INVENTORY_DATABASE_URL
- name: DEMO_MODE
value: "production"
- name: LOG_LEVEL
value: "INFO"
resources:
requests:
memory: "256Mi"
cpu: "100m"
limits:
memory: "512Mi"
cpu: "500m"
restartPolicy: OnFailure
serviceAccountName: demo-seed-sa

View File

@@ -39,6 +39,7 @@ resources:
- migrations/procurement-migration-job.yaml
- migrations/orchestrator-migration-job.yaml
- migrations/ai-insights-migration-job.yaml
- migrations/distribution-migration-job.yaml
# Demo initialization jobs (in Helm hook weight order)
- jobs/demo-seed-rbac.yaml
@@ -64,6 +65,16 @@ resources:
- jobs/demo-seed-orchestration-runs-job.yaml
- jobs/demo-seed-alerts-job.yaml
# Phase 2: Child retail seed jobs (for enterprise demo)
- jobs/demo-seed-inventory-retail-job.yaml
- jobs/demo-seed-stock-retail-job.yaml
- jobs/demo-seed-sales-retail-job.yaml
- jobs/demo-seed-customers-retail-job.yaml
- jobs/demo-seed-pos-retail-job.yaml
- jobs/demo-seed-forecasts-retail-job.yaml
- jobs/demo-seed-alerts-retail-job.yaml
- jobs/demo-seed-distribution-history-job.yaml
# External data initialization job (v2.0)
- jobs/external-data-init-job.yaml
@@ -79,6 +90,10 @@ resources:
- components/databases/rabbitmq.yaml
- components/infrastructure/gateway-service.yaml
# Distribution service
- components/distribution/distribution-deployment.yaml
- components/distribution/distribution-configmap.yaml
# Nominatim geocoding service
- components/nominatim/nominatim.yaml
- jobs/nominatim-init-job.yaml
@@ -104,6 +119,7 @@ resources:
- components/databases/orchestrator-db.yaml
- components/databases/alert-processor-db.yaml
- components/databases/ai-insights-db.yaml
- components/databases/distribution-db.yaml
# Demo session components
- components/demo-session/database.yaml
@@ -186,3 +202,5 @@ images:
newTag: latest
- name: bakery/dashboard
newTag: latest
- name: bakery/distribution-service
newTag: latest

View File

@@ -0,0 +1,60 @@
# Enhanced migration job for distribution service with automatic table creation
apiVersion: batch/v1
kind: Job
metadata:
name: distribution-migration
namespace: bakery-ia
labels:
app.kubernetes.io/name: distribution-migration
app.kubernetes.io/component: migration
app.kubernetes.io/part-of: bakery-ia
spec:
backoffLimit: 3
template:
metadata:
labels:
app.kubernetes.io/name: distribution-migration
app.kubernetes.io/component: migration
spec:
initContainers:
- name: wait-for-db
image: postgres:17-alpine
command: ["sh", "-c", "until pg_isready -h distribution-db-service -p 5432; do sleep 2; done"]
resources:
requests:
memory: "64Mi"
cpu: "50m"
limits:
memory: "128Mi"
cpu: "100m"
containers:
- name: migrate
image: bakery/distribution-service:dev
command: ["python", "/app/shared/scripts/run_migrations.py", "distribution"]
env:
- name: DISTRIBUTION_DATABASE_URL
valueFrom:
secretKeyRef:
name: database-secrets
key: DISTRIBUTION_DATABASE_URL
- name: DATABASE_URL
valueFrom:
secretKeyRef:
name: database-secrets
key: DISTRIBUTION_DATABASE_URL
- name: DB_FORCE_RECREATE
valueFrom:
configMapKeyRef:
name: bakery-config
key: DB_FORCE_RECREATE
optional: true
- name: LOG_LEVEL
value: "INFO"
resources:
requests:
memory: "256Mi"
cpu: "100m"
limits:
memory: "512Mi"
cpu: "500m"
restartPolicy: OnFailure

View File

@@ -27,6 +27,7 @@ data:
ORCHESTRATOR_DB_USER: b3JjaGVzdHJhdG9yX3VzZXI= # orchestrator_user
PROCUREMENT_DB_USER: cHJvY3VyZW1lbnRfdXNlcg== # procurement_user
AI_INSIGHTS_DB_USER: YWlfaW5zaWdodHNfdXNlcg== # ai_insights_user
DISTRIBUTION_DB_USER: ZGlzdHJpYnV0aW9uX3VzZXI= # distribution_user
# Database Passwords (base64 encoded from .env)
AUTH_DB_PASSWORD: djJvOHBqVWRSUVprR1JsbDlOV2JXdGt4WUFGcVBmOWw= # v2o8pjUdRQZkGRll...
@@ -47,6 +48,7 @@ data:
ORCHESTRATOR_DB_PASSWORD: b3JjaGVzdHJhdG9yX3Bhc3MxMjM= # orchestrator_pass123
PROCUREMENT_DB_PASSWORD: cHJvY3VyZW1lbnRfcGFzczEyMw== # procurement_pass123
AI_INSIGHTS_DB_PASSWORD: YWlfaW5zaWdodHNfcGFzczEyMw== # ai_insights_pass123
DISTRIBUTION_DB_PASSWORD: ZGlzdHJpYnV0aW9uX3Bhc3MxMjM= # distribution_pass123
# Database URLs (base64 encoded)
AUTH_DATABASE_URL: cG9zdGdyZXNxbCthc3luY3BnOi8vYXV0aF91c2VyOnYybzhwalVkUlFaa0dSbGw5TldiV3RreFlBRnFQZjlsQGF1dGgtZGItc2VydmljZTo1NDMyL2F1dGhfZGI= # Updated with new password
@@ -67,6 +69,7 @@ data:
ORCHESTRATOR_DATABASE_URL: cG9zdGdyZXNxbCthc3luY3BnOi8vb3JjaGVzdHJhdG9yX3VzZXI6b3JjaGVzdHJhdG9yX3Bhc3MxMjNAb3JjaGVzdHJhdG9yLWRiLXNlcnZpY2U6NTQzMi9vcmNoZXN0cmF0b3JfZGI= # postgresql+asyncpg://orchestrator_user:orchestrator_pass123@orchestrator-db-service:5432/orchestrator_db
PROCUREMENT_DATABASE_URL: cG9zdGdyZXNxbCthc3luY3BnOi8vcHJvY3VyZW1lbnRfdXNlcjpwcm9jdXJlbWVudF9wYXNzMTIzQHByb2N1cmVtZW50LWRiLXNlcnZpY2U6NTQzMi9wcm9jdXJlbWVudF9kYg== # postgresql+asyncpg://procurement_user:procurement_pass123@procurement-db-service:5432/procurement_db
AI_INSIGHTS_DATABASE_URL: cG9zdGdyZXNxbCthc3luY3BnOi8vYWlfaW5zaWdodHNfdXNlcjphaV9pbnNpZ2h0c19wYXNzMTIzQGFpLWluc2lnaHRzLWRiLXNlcnZpY2U6NTQzMi9haV9pbnNpZ2h0c19kYg== # postgresql+asyncpg://ai_insights_user:ai_insights_pass123@ai-insights-db-service:5432/ai_insights_db
DISTRIBUTION_DATABASE_URL: cG9zdGdyZXNxbCthc3luY3BnOi8vZGlzdHJpYnV0aW9uX3VzZXI6ZGlzdHJpYnV0aW9uX3Bhc3MxMjNAZGlzdHJpYnV0aW9uLWRiLXNlcnZpY2U6NTQzMi9kaXN0cmlidXRpb25fZGI= # postgresql+asyncpg://distribution_user:distribution_pass123@distribution-db-service:5432/distribution_db
# Redis URL
REDIS_URL: cmVkaXM6Ly86T3hkbWRKamRWTlhwMzdNTkMySUZvTW5UcGZHR0Z2MWtAcmVkaXMtc2VydmljZTo2Mzc5LzA= # redis://:OxdmdJjdVNXp37MNC2IFoMnTpfGGFv1k@redis-service:6379/0