Files
bakery-ia/Tiltfile
2026-01-12 14:24:14 +01:00

700 lines
28 KiB
Plaintext
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# =============================================================================
# Bakery IA - Tiltfile for Secure Local Development
# =============================================================================
# Features:
# - TLS encryption for PostgreSQL and Redis
# - Strong 32-character passwords with PersistentVolumeClaims
# - PostgreSQL pgcrypto extension and audit logging
# - Organized resource dependencies and live-reload capabilities
# - Local registry for faster image builds and deployments
# =============================================================================
# =============================================================================
# TILT CONFIGURATION
# =============================================================================
# Ensure we're running in the correct context
allow_k8s_contexts('kind-bakery-ia-local')
# Docker registry configuration
# Set USE_DOCKERHUB=true environment variable to push images to Docker Hub
# Otherwise, uses local registry for faster builds and deployments
use_dockerhub = os.getenv('USE_DOCKERHUB', 'false').lower() == 'true'
dockerhub_username = os.getenv('DOCKERHUB_USERNAME', 'uals')
if use_dockerhub:
print("""
🐳 DOCKER HUB MODE ENABLED
Images will be pushed to Docker Hub: docker.io/%s
Make sure you're logged in: docker login
To disable: unset USE_DOCKERHUB or set USE_DOCKERHUB=false
""" % dockerhub_username)
default_registry('docker.io/%s' % dockerhub_username)
else:
print("""
🏠 LOCAL REGISTRY MODE
Using local registry for faster builds: localhost:5001
This registry is created by kubernetes_restart.sh script
To use Docker Hub: export USE_DOCKERHUB=true
""")
default_registry('localhost:5001')
# =============================================================================
# SECURITY & INITIAL 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
Monitoring:
📊 Service metrics available at /metrics endpoints
🔍 Telemetry ready (traces, metrics, logs)
SigNoz deployment optional for local dev (see signoz-info resource)
Applying security configurations...
""")
# Create Docker Hub secret for image pulls (if credentials are available)
local_resource(
'dockerhub-secret',
cmd='''
echo "🐳 Setting up Docker Hub image pull secret..."
# Check if Docker Hub credentials are available
if [ -n "$DOCKERHUB_USERNAME" ] && [ -n "$DOCKERHUB_PASSWORD" ]; then
echo " Found DOCKERHUB_USERNAME and DOCKERHUB_PASSWORD environment variables"
./infrastructure/kubernetes/create-dockerhub-secret.sh
elif [ -f "$HOME/.docker/config.json" ]; then
echo " Attempting to use Docker CLI credentials..."
./infrastructure/kubernetes/create-dockerhub-secret.sh
else
echo " ⚠️ Docker Hub credentials not found"
echo " To enable automatic Docker Hub authentication:"
echo " 1. Run 'docker login', OR"
echo " 2. Set environment variables:"
echo " export DOCKERHUB_USERNAME='your-username'"
echo " export DOCKERHUB_PASSWORD='your-password-or-token'"
echo ""
echo " Continuing without Docker Hub authentication..."
echo " (This is OK for local development using local registry)"
fi
''',
labels=['00-security'],
auto_init=True
)
# 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"
''',
resource_deps=['dockerhub-secret'],
labels=['00-security'],
auto_init=True
)
# 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=['00-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=['00-security']
)
# Install and verify cert-manager
local_resource(
'cert-manager-install',
cmd='''
echo "📦 Installing cert-manager..."
# Check if cert-manager CRDs already exist
if kubectl get crd certificates.cert-manager.io >/dev/null 2>&1; then
echo " ✅ cert-manager CRDs already installed"
else
echo " Installing cert-manager v1.13.2..."
kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.13.2/cert-manager.yaml
echo " Waiting for cert-manager to be ready..."
kubectl wait --for=condition=available --timeout=120s deployment/cert-manager -n cert-manager
kubectl wait --for=condition=available --timeout=120s deployment/cert-manager-webhook -n cert-manager
echo " ✅ cert-manager installed and ready"
fi
echo "✅ cert-manager verification complete"
''',
labels=['00-security'],
auto_init=True
)
# =============================================================================
# LOAD KUBERNETES MANIFESTS
# =============================================================================
k8s_yaml(kustomize('infrastructure/kubernetes/overlays/dev'))
# =============================================================================
# DOCKER BUILD HELPERS
# =============================================================================
# Helper function for Python services with live updates
def build_python_service(service_name, service_path):
docker_build(
'bakery/' + service_name,
context='.',
dockerfile='./services/' + service_path + '/Dockerfile',
live_update=[
# Fall back to full image build if Dockerfile or requirements change
fall_back_on([
'./services/' + service_path + '/Dockerfile',
'./services/' + service_path + '/requirements.txt'
]),
# Sync service code
sync('./services/' + service_path, '/app'),
# Sync shared libraries
sync('./shared', '/app/shared'),
# Sync scripts
sync('./scripts', '/app/scripts'),
# Install new dependencies if requirements.txt changes
run(
'pip install --no-cache-dir -r requirements.txt',
trigger=['./services/' + service_path + '/requirements.txt']
),
# Restart uvicorn on Python file changes (HUP signal triggers graceful reload)
run(
'kill -HUP 1',
trigger=[
'./services/' + service_path + '/**/*.py',
'./shared/**/*.py'
]
),
],
# Ignore common patterns that don't require rebuilds
ignore=[
'.git',
'**/__pycache__',
'**/*.pyc',
'**/.pytest_cache',
'**/node_modules',
'**/.DS_Store'
]
)
# =============================================================================
# INFRASTRUCTURE IMAGES
# =============================================================================
# Frontend (React + Vite)
frontend_debug_env = os.getenv('FRONTEND_DEBUG', 'false')
frontend_debug = frontend_debug_env.lower() == 'true'
if frontend_debug:
print("""
🐛 FRONTEND DEBUG MODE ENABLED
Building frontend with NO minification for easier debugging.
Full React error messages will be displayed.
To disable: unset FRONTEND_DEBUG or set FRONTEND_DEBUG=false
""")
else:
print("""
📦 FRONTEND PRODUCTION MODE
Building frontend with minification for optimized performance.
To enable debug mode: export FRONTEND_DEBUG=true
""")
docker_build(
'bakery/dashboard',
context='./frontend',
dockerfile='./frontend/Dockerfile.kubernetes.debug' if frontend_debug else './frontend/Dockerfile.kubernetes',
live_update=[
sync('./frontend/src', '/app/src'),
sync('./frontend/public', '/app/public'),
],
build_args={
'NODE_OPTIONS': '--max-old-space-size=8192'
},
ignore=[
'playwright-report/**',
'test-results/**',
'node_modules/**',
'.DS_Store'
]
)
# Gateway
docker_build(
'bakery/gateway',
context='.',
dockerfile='./gateway/Dockerfile',
live_update=[
fall_back_on(['./gateway/Dockerfile', './gateway/requirements.txt']),
sync('./gateway', '/app'),
sync('./shared', '/app/shared'),
run('kill -HUP 1', trigger=['./gateway/**/*.py', './shared/**/*.py']),
],
ignore=[
'.git',
'**/__pycache__',
'**/*.pyc',
'**/.pytest_cache',
'**/node_modules',
'**/.DS_Store'
]
)
# =============================================================================
# MICROSERVICE IMAGES
# =============================================================================
# Core Services
build_python_service('auth-service', 'auth')
build_python_service('tenant-service', 'tenant')
# Data & Analytics Services
build_python_service('training-service', 'training')
build_python_service('forecasting-service', 'forecasting')
build_python_service('ai-insights-service', 'ai_insights')
# Operations Services
build_python_service('sales-service', 'sales')
build_python_service('inventory-service', 'inventory')
build_python_service('production-service', 'production')
build_python_service('procurement-service', 'procurement')
build_python_service('distribution-service', 'distribution')
# Supporting Services
build_python_service('recipes-service', 'recipes')
build_python_service('suppliers-service', 'suppliers')
build_python_service('pos-service', 'pos')
build_python_service('orders-service', 'orders')
build_python_service('external-service', 'external')
# Platform Services
build_python_service('notification-service', 'notification')
build_python_service('alert-processor', 'alert_processor')
build_python_service('orchestrator-service', 'orchestrator')
# Demo Services
build_python_service('demo-session-service', 'demo_session')
# Tell Tilt that demo-cleanup-worker uses the demo-session-service image
k8s_image_json_path(
'bakery/demo-session-service',
'{.spec.template.spec.containers[?(@.name=="worker")].image}',
name='demo-cleanup-worker'
)
# =============================================================================
# INFRASTRUCTURE RESOURCES
# =============================================================================
# Redis & RabbitMQ
k8s_resource('redis', resource_deps=['security-setup'], labels=['01-infrastructure'])
k8s_resource('rabbitmq', labels=['01-infrastructure'])
k8s_resource('nominatim', labels=['01-infrastructure'])
# =============================================================================
# MONITORING RESOURCES - SigNoz (Unified Observability)
# =============================================================================
# Deploy SigNoz using Helm with automatic deployment and progress tracking
local_resource(
'signoz-deploy',
cmd='''
echo "📊 Deploying SigNoz Monitoring Stack..."
echo ""
# Ensure Docker Hub secret exists in bakery-ia namespace
echo "🔐 Ensuring Docker Hub secret exists in bakery-ia namespace..."
if ! kubectl get secret dockerhub-creds -n bakery-ia &>/dev/null; then
echo " ⚠️ Docker Hub secret not found, attempting to create..."
./infrastructure/kubernetes/create-dockerhub-secret.sh || echo " Continuing without Docker Hub authentication..."
else
echo " ✅ Docker Hub secret exists"
fi
echo ""
# Check if SigNoz is already deployed
if helm list -n bakery-ia | grep -q signoz; then
echo "✅ SigNoz already deployed, checking status..."
helm status signoz -n bakery-ia
else
echo "🚀 Installing SigNoz..."
# Add SigNoz Helm repository if not already added
helm repo add signoz https://charts.signoz.io 2>/dev/null || true
helm repo update signoz
# Install SigNoz with custom values in the bakery-ia namespace
helm upgrade --install signoz signoz/signoz \
-n bakery-ia \
-f infrastructure/helm/signoz-values-dev.yaml \
--timeout 10m \
--wait
echo ""
echo "✅ SigNoz deployment completed"
fi
echo ""
echo "📈 SigNoz Access Information:"
echo " URL: https://monitoring.bakery-ia.local"
echo " Username: admin"
echo " Password: admin"
echo ""
echo "🔧 OpenTelemetry Collector Endpoints:"
echo " gRPC: localhost:4317"
echo " HTTP: localhost:4318"
echo ""
echo "💡 To check pod status: kubectl get pods -n signoz"
''',
labels=['05-monitoring'],
auto_init=False,
trigger_mode=TRIGGER_MODE_MANUAL,
allow_parallel=False
)
# Track SigNoz pods in Tilt UI using workload tracking
# These will automatically discover pods once SigNoz is deployed
local_resource(
'signoz-status',
cmd='''
echo "📊 SigNoz Status Check"
echo ""
# Check pod status
echo "Current SigNoz pods:"
kubectl get pods -n bakery-ia -l app.kubernetes.io/instance=signoz -o wide 2>/dev/null || echo "No pods found"
echo ""
echo "SigNoz Services:"
kubectl get svc -n bakery-ia -l app.kubernetes.io/instance=signoz 2>/dev/null || echo "No services found"
# Check if all pods are ready
TOTAL_PODS=$(kubectl get pods -n bakery-ia -l app.kubernetes.io/instance=signoz --no-headers 2>/dev/null | wc -l | tr -d ' ')
READY_PODS=$(kubectl get pods -n bakery-ia -l app.kubernetes.io/instance=signoz --field-selector=status.phase=Running --no-headers 2>/dev/null | wc -l | tr -d ' ')
if [ "$TOTAL_PODS" -gt 0 ]; then
echo ""
echo "Pod Status: $READY_PODS/$TOTAL_PODS ready"
if [ "$READY_PODS" -eq "$TOTAL_PODS" ]; then
echo "✅ All SigNoz pods are running!"
echo ""
echo "Access SigNoz at: https://monitoring.bakery-ia.local"
echo "Credentials: admin / admin"
else
echo "⏳ Waiting for pods to become ready..."
fi
fi
''',
labels=['05-monitoring'],
resource_deps=['signoz-deploy'],
auto_init=False,
trigger_mode=TRIGGER_MODE_MANUAL
)
# Optional exporters (in monitoring namespace) - DISABLED since using SigNoz
# k8s_resource('node-exporter', labels=['05-monitoring'])
# k8s_resource('postgres-exporter', resource_deps=['auth-db'], labels=['05-monitoring'])
# =============================================================================
# DATABASE RESOURCES
# =============================================================================
# Core Service Databases
k8s_resource('auth-db', resource_deps=['security-setup'], labels=['06-databases'])
k8s_resource('tenant-db', resource_deps=['security-setup'], labels=['06-databases'])
# Data & Analytics Databases
k8s_resource('training-db', resource_deps=['security-setup'], labels=['06-databases'])
k8s_resource('forecasting-db', resource_deps=['security-setup'], labels=['06-databases'])
k8s_resource('ai-insights-db', resource_deps=['security-setup'], labels=['06-databases'])
# Operations Databases
k8s_resource('sales-db', resource_deps=['security-setup'], labels=['06-databases'])
k8s_resource('inventory-db', resource_deps=['security-setup'], labels=['06-databases'])
k8s_resource('production-db', resource_deps=['security-setup'], labels=['06-databases'])
k8s_resource('procurement-db', resource_deps=['security-setup'], labels=['06-databases'])
k8s_resource('distribution-db', resource_deps=['security-setup'], labels=['06-databases'])
# Supporting Service Databases
k8s_resource('recipes-db', resource_deps=['security-setup'], labels=['06-databases'])
k8s_resource('suppliers-db', resource_deps=['security-setup'], labels=['06-databases'])
k8s_resource('pos-db', resource_deps=['security-setup'], labels=['06-databases'])
k8s_resource('orders-db', resource_deps=['security-setup'], labels=['06-databases'])
k8s_resource('external-db', resource_deps=['security-setup'], labels=['06-databases'])
# Platform Service Databases
k8s_resource('notification-db', resource_deps=['security-setup'], labels=['06-databases'])
k8s_resource('alert-processor-db', resource_deps=['security-setup'], labels=['06-databases'])
k8s_resource('orchestrator-db', resource_deps=['security-setup'], labels=['06-databases'])
# Demo Service Databases
k8s_resource('demo-session-db', resource_deps=['security-setup'], labels=['06-databases'])
# =============================================================================
# MIGRATION JOBS
# =============================================================================
# Core Service Migrations
k8s_resource('auth-migration', resource_deps=['auth-db'], labels=['07-migrations'])
k8s_resource('tenant-migration', resource_deps=['tenant-db'], labels=['07-migrations'])
# Data & Analytics Migrations
k8s_resource('training-migration', resource_deps=['training-db'], labels=['07-migrations'])
k8s_resource('forecasting-migration', resource_deps=['forecasting-db'], labels=['07-migrations'])
k8s_resource('ai-insights-migration', resource_deps=['ai-insights-db'], labels=['07-migrations'])
# Operations Migrations
k8s_resource('sales-migration', resource_deps=['sales-db'], labels=['07-migrations'])
k8s_resource('inventory-migration', resource_deps=['inventory-db'], labels=['07-migrations'])
k8s_resource('production-migration', resource_deps=['production-db'], labels=['07-migrations'])
k8s_resource('procurement-migration', resource_deps=['procurement-db'], labels=['07-migrations'])
k8s_resource('distribution-migration', resource_deps=['distribution-db'], labels=['07-migrations'])
# Supporting Service Migrations
k8s_resource('recipes-migration', resource_deps=['recipes-db'], labels=['07-migrations'])
k8s_resource('suppliers-migration', resource_deps=['suppliers-db'], labels=['07-migrations'])
k8s_resource('pos-migration', resource_deps=['pos-db'], labels=['07-migrations'])
k8s_resource('orders-migration', resource_deps=['orders-db'], labels=['07-migrations'])
k8s_resource('external-migration', resource_deps=['external-db'], labels=['07-migrations'])
# Platform Service Migrations
k8s_resource('notification-migration', resource_deps=['notification-db'], labels=['07-migrations'])
k8s_resource('alert-processor-migration', resource_deps=['alert-processor-db'], labels=['07-migrations'])
k8s_resource('orchestrator-migration', resource_deps=['orchestrator-db'], labels=['07-migrations'])
# Demo Service Migrations
k8s_resource('demo-session-migration', resource_deps=['demo-session-db'], labels=['07-migrations'])
# =============================================================================
# DATA INITIALIZATION JOBS
# =============================================================================
k8s_resource('external-data-init', resource_deps=['external-migration', 'redis'], labels=['08-data-init'])
k8s_resource('nominatim-init', labels=['08-data-init'])
# =============================================================================
# =============================================================================
# APPLICATION SERVICES
# =============================================================================
# Core Services
k8s_resource('auth-service', resource_deps=['auth-migration', 'redis'], labels=['09-services-core'])
k8s_resource('tenant-service', resource_deps=['tenant-migration', 'redis'], labels=['09-services-core'])
# Data & Analytics Services
k8s_resource('training-service', resource_deps=['training-migration', 'redis'], labels=['10-services-analytics'])
k8s_resource('forecasting-service', resource_deps=['forecasting-migration', 'redis'], labels=['10-services-analytics'])
k8s_resource('ai-insights-service', resource_deps=['ai-insights-migration', 'redis', 'forecasting-service', 'production-service', 'procurement-service'], labels=['10-services-analytics'])
# Operations Services
k8s_resource('sales-service', resource_deps=['sales-migration', 'redis'], labels=['11-services-operations'])
k8s_resource('inventory-service', resource_deps=['inventory-migration', 'redis'], labels=['11-services-operations'])
k8s_resource('production-service', resource_deps=['production-migration', 'redis'], labels=['11-services-operations'])
k8s_resource('procurement-service', resource_deps=['procurement-migration', 'redis'], labels=['11-services-operations'])
k8s_resource('distribution-service', resource_deps=['distribution-migration', 'redis', 'rabbitmq'], labels=['11-services-operations'])
# Supporting Services
k8s_resource('recipes-service', resource_deps=['recipes-migration', 'redis'], labels=['12-services-supporting'])
k8s_resource('suppliers-service', resource_deps=['suppliers-migration', 'redis'], labels=['12-services-supporting'])
k8s_resource('pos-service', resource_deps=['pos-migration', 'redis'], labels=['12-services-supporting'])
k8s_resource('orders-service', resource_deps=['orders-migration', 'redis'], labels=['12-services-supporting'])
k8s_resource('external-service', resource_deps=['external-migration', 'external-data-init', 'redis'], labels=['12-services-supporting'])
# Platform Services
k8s_resource('notification-service', resource_deps=['notification-migration', 'redis', 'rabbitmq'], labels=['13-services-platform'])
k8s_resource('alert-processor', resource_deps=['alert-processor-migration', 'redis', 'rabbitmq'], labels=['13-services-platform'])
k8s_resource('orchestrator-service', resource_deps=['orchestrator-migration', 'redis'], labels=['13-services-platform'])
# Demo Services
k8s_resource('demo-session-service', resource_deps=['demo-session-migration', 'redis'], labels=['14-services-demo'])
k8s_resource('demo-cleanup-worker', resource_deps=['demo-session-service', 'redis'], labels=['14-services-demo'])
# =============================================================================
# FRONTEND & GATEWAY
# =============================================================================
k8s_resource('gateway', resource_deps=['auth-service'], labels=['15-frontend'])
k8s_resource('frontend', resource_deps=['gateway'], labels=['15-frontend'])
# =============================================================================
# CRONJOBS (Remaining K8s CronJobs)
# =============================================================================
k8s_resource('demo-session-cleanup', resource_deps=['demo-session-service'], labels=['16-cronjobs'])
k8s_resource('external-data-rotation', resource_deps=['external-service'], labels=['16-cronjobs'])
# =============================================================================
# TILT CONFIGURATION
# =============================================================================
# Update settings
update_settings(
max_parallel_updates=2, # Reduce parallel updates to avoid resource exhaustion
k8s_upsert_timeout_secs=120 # Increase timeout for slower local builds
)
# Watch settings
watch_settings(
ignore=[
'.git/**',
'**/__pycache__/**',
'**/*.pyc',
'**/.pytest_cache/**',
'**/node_modules/**',
'**/.DS_Store',
'**/*.swp',
'**/*.swo',
'**/.venv/**',
'**/venv/**',
'**/.mypy_cache/**',
'**/.ruff_cache/**',
'**/.tox/**',
'**/htmlcov/**',
'**/.coverage',
'**/dist/**',
'**/build/**',
'**/*.egg-info/**',
'**/infrastructure/tls/**/*.pem',
'**/infrastructure/tls/**/*.cnf',
'**/infrastructure/tls/**/*.csr',
'**/infrastructure/tls/**/*.srl',
'**/*.tmp',
'**/*.tmp.*',
'**/migrations/versions/*.tmp.*',
'**/playwright-report/**',
'**/test-results/**',
]
)
# =============================================================================
# STARTUP SUMMARY
# =============================================================================
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
Internal Schedulers Active:
⏰ Alert Priority Recalculation: Hourly @ :15 (alert-processor)
⏰ Usage Tracking: Daily @ 2:00 AM UTC (tenant-service)
Access your application:
Main Application: https://bakery-ia.local
API Endpoints: https://bakery-ia.local/api/v1/...
Local Access: https://localhost
Service Metrics:
Gateway: http://localhost:8000/metrics
Any Service: kubectl port-forward <service> 8000:8000
SigNoz (Unified Observability):
Deploy via Tilt: Trigger 'signoz-deployment' resource
Manual deploy: ./infrastructure/helm/deploy-signoz.sh dev
Access (if deployed): https://monitoring.bakery-ia.local
Username: admin
Password: admin
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
Verify schedulers:
kubectl exec -it -n bakery-ia deployment/alert-processor -- curl localhost:8000/scheduler/status
kubectl logs -f -n bakery-ia -l app=tenant-service | grep "usage tracking"
Documentation:
docs/SECURITY_IMPLEMENTATION_COMPLETE.md
docs/DATABASE_SECURITY_ANALYSIS_REPORT.md
Useful Commands:
# Work on specific services only
tilt up <service-name> <service-name>
# View logs by label
tilt logs 09-services-core
tilt logs 13-services-platform
DNS Configuration:
# To access the application via domain names, add these entries to your hosts file:
# sudo nano /etc/hosts
# Add these lines:
# 127.0.0.1 bakery-ia.local
# 127.0.0.1 monitoring.bakery-ia.local
======================================
""")