Improve the frontend and fix TODOs
This commit is contained in:
211
Tiltfile
211
Tiltfile
@@ -1,6 +1,41 @@
|
||||
# Tiltfile for Bakery IA - Local Development
|
||||
# This replaces Skaffold for faster, smarter local Kubernetes development
|
||||
# Tiltfile for Bakery IA - Secure Local Development
|
||||
# Includes TLS encryption, strong passwords, PVCs, and audit logging
|
||||
|
||||
# =============================================================================
|
||||
# SECURITY SETUP
|
||||
# =============================================================================
|
||||
print("""
|
||||
======================================
|
||||
🔐 Bakery IA Secure Development Mode
|
||||
======================================
|
||||
|
||||
Security Features:
|
||||
✅ TLS encryption for PostgreSQL and Redis
|
||||
✅ Strong 32-character passwords
|
||||
✅ PersistentVolumeClaims (no data loss)
|
||||
✅ pgcrypto extension for encryption
|
||||
✅ PostgreSQL audit logging
|
||||
|
||||
Applying security configurations...
|
||||
""")
|
||||
|
||||
# Apply security configurations before loading main manifests
|
||||
local_resource('security-setup',
|
||||
cmd='''
|
||||
echo "📦 Applying security secrets and configurations..."
|
||||
kubectl apply -f infrastructure/kubernetes/base/secrets.yaml
|
||||
kubectl apply -f infrastructure/kubernetes/base/secrets/postgres-tls-secret.yaml
|
||||
kubectl apply -f infrastructure/kubernetes/base/secrets/redis-tls-secret.yaml
|
||||
kubectl apply -f infrastructure/kubernetes/base/configs/postgres-init-config.yaml
|
||||
kubectl apply -f infrastructure/kubernetes/base/configmaps/postgres-logging-config.yaml
|
||||
echo "✅ Security configurations applied"
|
||||
''',
|
||||
labels=['security'],
|
||||
auto_init=True)
|
||||
|
||||
# =============================================================================
|
||||
# LOAD KUBERNETES MANIFESTS
|
||||
# =============================================================================
|
||||
# Load Kubernetes manifests using Kustomize
|
||||
k8s_yaml(kustomize('infrastructure/kubernetes/overlays/dev'))
|
||||
|
||||
@@ -74,7 +109,7 @@ def build_python_service(service_name, service_path):
|
||||
# Sync service code
|
||||
sync('./services/' + service_path, '/app'),
|
||||
|
||||
# Sync shared libraries
|
||||
# Sync shared libraries (includes updated TLS connection code)
|
||||
sync('./shared', '/app/shared'),
|
||||
|
||||
# Sync scripts
|
||||
@@ -123,25 +158,73 @@ build_python_service('demo-session-service', 'demo_session')
|
||||
# RESOURCE DEPENDENCIES & ORDERING
|
||||
# =============================================================================
|
||||
|
||||
# Databases and infrastructure should start first
|
||||
k8s_resource('auth-db', labels=['databases'])
|
||||
k8s_resource('tenant-db', labels=['databases'])
|
||||
k8s_resource('training-db', labels=['databases'])
|
||||
k8s_resource('forecasting-db', labels=['databases'])
|
||||
k8s_resource('sales-db', labels=['databases'])
|
||||
k8s_resource('external-db', labels=['databases'])
|
||||
k8s_resource('notification-db', labels=['databases'])
|
||||
k8s_resource('inventory-db', labels=['databases'])
|
||||
k8s_resource('recipes-db', labels=['databases'])
|
||||
k8s_resource('suppliers-db', labels=['databases'])
|
||||
k8s_resource('pos-db', labels=['databases'])
|
||||
k8s_resource('orders-db', labels=['databases'])
|
||||
k8s_resource('production-db', labels=['databases'])
|
||||
k8s_resource('demo-session-db', labels=['databases'])
|
||||
# Security setup must complete before databases start
|
||||
k8s_resource('auth-db', resource_deps=['security-setup'], labels=['databases'])
|
||||
k8s_resource('tenant-db', resource_deps=['security-setup'], labels=['databases'])
|
||||
k8s_resource('training-db', resource_deps=['security-setup'], labels=['databases'])
|
||||
k8s_resource('forecasting-db', resource_deps=['security-setup'], labels=['databases'])
|
||||
k8s_resource('sales-db', resource_deps=['security-setup'], labels=['databases'])
|
||||
k8s_resource('external-db', resource_deps=['security-setup'], labels=['databases'])
|
||||
k8s_resource('notification-db', resource_deps=['security-setup'], labels=['databases'])
|
||||
k8s_resource('inventory-db', resource_deps=['security-setup'], labels=['databases'])
|
||||
k8s_resource('recipes-db', resource_deps=['security-setup'], labels=['databases'])
|
||||
k8s_resource('suppliers-db', resource_deps=['security-setup'], labels=['databases'])
|
||||
k8s_resource('pos-db', resource_deps=['security-setup'], labels=['databases'])
|
||||
k8s_resource('orders-db', resource_deps=['security-setup'], labels=['databases'])
|
||||
k8s_resource('production-db', resource_deps=['security-setup'], labels=['databases'])
|
||||
k8s_resource('alert-processor-db', resource_deps=['security-setup'], labels=['databases'])
|
||||
k8s_resource('demo-session-db', resource_deps=['security-setup'], labels=['databases'])
|
||||
|
||||
k8s_resource('redis', labels=['infrastructure'])
|
||||
k8s_resource('redis', resource_deps=['security-setup'], labels=['infrastructure'])
|
||||
k8s_resource('rabbitmq', labels=['infrastructure'])
|
||||
|
||||
# Verify TLS certificates are mounted correctly
|
||||
local_resource('verify-tls',
|
||||
cmd='''
|
||||
echo "🔍 Verifying TLS configuration..."
|
||||
sleep 5 # Wait for pods to be ready
|
||||
|
||||
# Check if auth-db pod exists and has TLS certs
|
||||
AUTH_POD=$(kubectl get pods -n bakery-ia -l app.kubernetes.io/name=auth-db -o jsonpath='{.items[0].metadata.name}' 2>/dev/null || echo "")
|
||||
|
||||
if [ -n "$AUTH_POD" ]; then
|
||||
echo " Checking PostgreSQL TLS certificates..."
|
||||
kubectl exec -n bakery-ia "$AUTH_POD" -- ls -la /tls/ 2>/dev/null && \
|
||||
echo " ✅ PostgreSQL TLS certificates mounted" || \
|
||||
echo " ⚠️ PostgreSQL TLS certificates not found (pods may still be starting)"
|
||||
fi
|
||||
|
||||
# Check if redis pod exists and has TLS certs
|
||||
REDIS_POD=$(kubectl get pods -n bakery-ia -l app.kubernetes.io/name=redis -o jsonpath='{.items[0].metadata.name}' 2>/dev/null || echo "")
|
||||
|
||||
if [ -n "$REDIS_POD" ]; then
|
||||
echo " Checking Redis TLS certificates..."
|
||||
kubectl exec -n bakery-ia "$REDIS_POD" -- ls -la /tls/ 2>/dev/null && \
|
||||
echo " ✅ Redis TLS certificates mounted" || \
|
||||
echo " ⚠️ Redis TLS certificates not found (pods may still be starting)"
|
||||
fi
|
||||
|
||||
echo "✅ TLS verification complete"
|
||||
''',
|
||||
resource_deps=['auth-db', 'redis'],
|
||||
auto_init=True,
|
||||
trigger_mode=TRIGGER_MODE_MANUAL,
|
||||
labels=['security'])
|
||||
|
||||
# Verify PVCs are bound
|
||||
local_resource('verify-pvcs',
|
||||
cmd='''
|
||||
echo "🔍 Verifying PersistentVolumeClaims..."
|
||||
kubectl get pvc -n bakery-ia | grep -E "NAME|db-pvc" || echo " ⚠️ PVCs not yet bound"
|
||||
PVC_COUNT=$(kubectl get pvc -n bakery-ia -o json | jq '.items | length')
|
||||
echo " Found $PVC_COUNT PVCs"
|
||||
echo "✅ PVC verification complete"
|
||||
''',
|
||||
resource_deps=['auth-db'],
|
||||
auto_init=True,
|
||||
trigger_mode=TRIGGER_MODE_MANUAL,
|
||||
labels=['security'])
|
||||
|
||||
# Nominatim geocoding service (excluded in dev via kustomize patches)
|
||||
# Uncomment these if you want to test nominatim locally
|
||||
# k8s_resource('nominatim',
|
||||
@@ -178,33 +261,10 @@ k8s_resource('production-migration', resource_deps=['production-db'], labels=['m
|
||||
k8s_resource('alert-processor-migration', resource_deps=['alert-processor-db'], labels=['migrations'])
|
||||
k8s_resource('demo-session-migration', resource_deps=['demo-session-db'], labels=['migrations'])
|
||||
|
||||
# Alert processor DB
|
||||
k8s_resource('alert-processor-db', labels=['databases'])
|
||||
|
||||
# =============================================================================
|
||||
# DEMO INITIALIZATION JOBS
|
||||
# =============================================================================
|
||||
# Demo seed jobs run in strict order to ensure data consistency across services:
|
||||
#
|
||||
# Helm Hook Weight Order (5-40):
|
||||
# Weight 5: demo-seed-users → Creates demo user accounts (with staff) in auth service
|
||||
# Weight 10: demo-seed-tenants → Creates demo tenant records (depends on users)
|
||||
# Weight 15: demo-seed-tenant-members → Links staff users to tenants (depends on users & tenants)
|
||||
# Weight 10: demo-seed-subscriptions → Creates enterprise subscriptions for demo tenants
|
||||
# Weight 15: demo-seed-inventory → Creates ingredients & finished products (depends on tenants)
|
||||
# Weight 15: demo-seed-recipes → Creates recipes using ingredient IDs (depends on inventory)
|
||||
# Weight 15: demo-seed-suppliers → Creates suppliers with price lists for ingredients (depends on inventory)
|
||||
# Weight 21: demo-seed-purchase-orders → Creates demo POs in various states (depends on suppliers)
|
||||
# Weight 15: demo-seed-sales → Creates historical sales data using finished product IDs (depends on inventory)
|
||||
# Weight 15: demo-seed-ai-models → Creates fake AI model entries (depends on inventory)
|
||||
# Weight 20: demo-seed-stock → Creates stock batches with expiration dates (depends on inventory)
|
||||
# Weight 22: demo-seed-quality-templates → Creates quality check templates (depends on production migration)
|
||||
# Weight 25: demo-seed-customers → Creates customer records (depends on orders migration)
|
||||
# Weight 25: demo-seed-equipment → Creates production equipment (depends on production migration)
|
||||
# Weight 30: demo-seed-production-batches → Creates production batches (depends on recipes, equipment)
|
||||
# Weight 30: demo-seed-orders → Creates orders with line items (depends on customers)
|
||||
# Weight 35: demo-seed-procurement → Creates procurement plans (depends on orders migration)
|
||||
# Weight 40: demo-seed-forecasts → Creates demand forecasts (depends on forecasting migration)
|
||||
# Demo seed jobs run in strict order to ensure data consistency across services
|
||||
|
||||
# Weight 5: Seed users (auth service) - includes staff users
|
||||
k8s_resource('demo-seed-users',
|
||||
@@ -246,11 +306,6 @@ k8s_resource('demo-seed-suppliers',
|
||||
resource_deps=['suppliers-migration', 'demo-seed-inventory'],
|
||||
labels=['demo-init'])
|
||||
|
||||
# Weight 21: Seed purchase orders (uses suppliers and demonstrates auto-approval workflow)
|
||||
k8s_resource('demo-seed-purchase-orders',
|
||||
resource_deps=['suppliers-migration', 'demo-seed-suppliers'],
|
||||
labels=['demo-init'])
|
||||
|
||||
# Weight 15: Seed sales (uses finished product IDs from inventory)
|
||||
k8s_resource('demo-seed-sales',
|
||||
resource_deps=['sales-migration', 'demo-seed-inventory'],
|
||||
@@ -296,11 +351,6 @@ k8s_resource('demo-seed-procurement',
|
||||
resource_deps=['orders-migration', 'demo-seed-tenants'],
|
||||
labels=['demo-init'])
|
||||
|
||||
# Weight 35: Seed POS configurations (pos service)
|
||||
k8s_resource('demo-seed-pos-configs',
|
||||
resource_deps=['pos-migration', 'demo-seed-tenants'],
|
||||
labels=['demo-init'])
|
||||
|
||||
# Weight 40: Seed demand forecasts (forecasting service)
|
||||
k8s_resource('demo-seed-forecasts',
|
||||
resource_deps=['forecasting-migration', 'demo-seed-tenants'],
|
||||
@@ -367,17 +417,11 @@ k8s_resource('alert-processor-service',
|
||||
resource_deps=['alert-processor-migration', 'redis', 'rabbitmq'],
|
||||
labels=['services'])
|
||||
|
||||
k8s_resource('alert-processor-api',
|
||||
resource_deps=['alert-processor-migration', 'redis'],
|
||||
labels=['services'])
|
||||
|
||||
k8s_resource('demo-session-service',
|
||||
resource_deps=['demo-session-migration', 'redis'],
|
||||
labels=['services'])
|
||||
|
||||
# Apply environment variable patch to demo-session-service with the inventory image
|
||||
# Note: This fetches the CURRENT image tag dynamically when the resource runs
|
||||
# Runs after both services are deployed to ensure correct image tag is used
|
||||
local_resource('patch-demo-session-env',
|
||||
cmd='''
|
||||
# Wait a moment for deployments to stabilize
|
||||
@@ -391,16 +435,13 @@ local_resource('patch-demo-session-env',
|
||||
|
||||
echo "✅ Set CLONE_JOB_IMAGE to: $INVENTORY_IMAGE"
|
||||
''',
|
||||
resource_deps=['demo-session-service', 'inventory-service'], # Wait for BOTH services
|
||||
auto_init=True, # Run automatically on Tilt startup
|
||||
resource_deps=['demo-session-service', 'inventory-service'],
|
||||
auto_init=True,
|
||||
labels=['config'])
|
||||
|
||||
# =============================================================================
|
||||
# DATA INITIALIZATION JOBS (External Service v2.0)
|
||||
# =============================================================================
|
||||
# External data initialization job loads 24 months of historical data
|
||||
# This should run AFTER external migration but BEFORE external-service starts
|
||||
|
||||
k8s_resource('external-data-init',
|
||||
resource_deps=['external-migration', 'redis'],
|
||||
labels=['data-init'])
|
||||
@@ -408,12 +449,10 @@ k8s_resource('external-data-init',
|
||||
# =============================================================================
|
||||
# CRONJOBS
|
||||
# =============================================================================
|
||||
|
||||
k8s_resource('demo-session-cleanup',
|
||||
resource_deps=['demo-session-service'],
|
||||
labels=['cronjobs'])
|
||||
|
||||
# External data rotation cronjob (runs monthly on 1st at 2am UTC)
|
||||
k8s_resource('external-data-rotation',
|
||||
resource_deps=['external-service'],
|
||||
labels=['cronjobs'])
|
||||
@@ -421,9 +460,6 @@ k8s_resource('external-data-rotation',
|
||||
# =============================================================================
|
||||
# GATEWAY & FRONTEND
|
||||
# =============================================================================
|
||||
# Gateway and Frontend depend on services being ready
|
||||
# Access via ingress: http://localhost (frontend) and http://localhost/api (gateway)
|
||||
|
||||
k8s_resource('gateway',
|
||||
resource_deps=['auth-service'],
|
||||
labels=['frontend'])
|
||||
@@ -463,14 +499,43 @@ watch_settings(
|
||||
'**/.coverage',
|
||||
'**/dist/**',
|
||||
'**/build/**',
|
||||
'**/*.egg-info/**'
|
||||
'**/*.egg-info/**',
|
||||
# Ignore TLS certificate files (don't trigger rebuilds)
|
||||
'**/infrastructure/tls/**/*.pem',
|
||||
'**/infrastructure/tls/**/*.cnf',
|
||||
'**/infrastructure/tls/**/*.csr',
|
||||
'**/infrastructure/tls/**/*.srl',
|
||||
]
|
||||
)
|
||||
|
||||
# Print security status on startup
|
||||
print("""
|
||||
✅ Security setup complete!
|
||||
|
||||
Database Security Features Active:
|
||||
🔐 TLS encryption: PostgreSQL and Redis
|
||||
🔑 Strong passwords: 32-character cryptographic
|
||||
💾 Persistent storage: PVCs for all databases
|
||||
🔒 Column encryption: pgcrypto extension
|
||||
📋 Audit logging: PostgreSQL query logging
|
||||
|
||||
Access your application:
|
||||
Frontend: http://localhost:3000 (or via ingress)
|
||||
Gateway: http://localhost:8000 (or via ingress)
|
||||
|
||||
Verify security:
|
||||
kubectl get pvc -n bakery-ia
|
||||
kubectl get secrets -n bakery-ia | grep tls
|
||||
kubectl logs -n bakery-ia <db-pod> | grep SSL
|
||||
|
||||
Security documentation:
|
||||
docs/SECURITY_IMPLEMENTATION_COMPLETE.md
|
||||
docs/DATABASE_SECURITY_ANALYSIS_REPORT.md
|
||||
|
||||
======================================
|
||||
""")
|
||||
|
||||
# Optimize for local development
|
||||
# - Automatically stream logs from services with errors
|
||||
# - Group resources by labels for better organization
|
||||
#
|
||||
# Note: You may see "too many open files" warnings on macOS with many services.
|
||||
# This is a Kind/Kubernetes limitation and doesn't affect service functionality.
|
||||
# To work on specific services only, use: tilt up <service-name> <service-name>
|
||||
|
||||
Reference in New Issue
Block a user