- Restore blue PageHeader on Dashboard (/app-components) - Update homepage (/) with subtle header design without blue bar - Add uniform PageHeader styling to application edit page - Fix Rapporten link on homepage to point to /reports overview - Improve header descriptions spacing for better readability
12 KiB
Green Field Deployment Guide
Overzicht
Deze guide beschrijft hoe je de applicatie volledig opnieuw deployt met de nieuwe genormaliseerde database structuur. Aangezien het een green field deployment is, kunnen we alles schoon opzetten.
Stap 1: Database Setup
Option A: PostgreSQL (Aanbevolen voor productie)
1.1 Azure Database for PostgreSQL
# Via Azure Portal of CLI
az postgres flexible-server create \
--resource-group <resource-group> \
--name <server-name> \
--location <location> \
--admin-user <admin-user> \
--admin-password <admin-password> \
--sku-name Standard_B1ms \
--tier Burstable \
--version 14
1.2 Database Aanmaken
-- Connect to PostgreSQL
CREATE DATABASE cmdb_cache;
CREATE DATABASE cmdb_classifications;
-- Create user (optional, can use admin user)
CREATE USER cmdb_user WITH PASSWORD 'secure_password';
GRANT ALL PRIVILEGES ON DATABASE cmdb_cache TO cmdb_user;
GRANT ALL PRIVILEGES ON DATABASE cmdb_classifications TO cmdb_user;
1.3 Connection String
DATABASE_TYPE=postgres
DATABASE_URL=postgresql://cmdb_user:secure_password@<server-name>.postgres.database.azure.com:5432/cmdb_cache?sslmode=require
CLASSIFICATIONS_DATABASE_URL=postgresql://cmdb_user:secure_password@<server-name>.postgres.database.azure.com:5432/cmdb_classifications?sslmode=require
Option B: SQLite (Voor development/testing)
DATABASE_TYPE=sqlite
# Database files worden automatisch aangemaakt in backend/data/
Stap 2: Environment Variables
2.1 Basis Configuratie
Maak .env bestand in project root:
# Server
PORT=3001
NODE_ENV=production
FRONTEND_URL=https://your-domain.com
# Database (zie Stap 1)
DATABASE_TYPE=postgres
DATABASE_URL=postgresql://...
# Jira Assets
JIRA_HOST=https://jira.zuyderland.nl
JIRA_SCHEMA_ID=<your_schema_id>
JIRA_SERVICE_ACCOUNT_TOKEN=<service_account_token>
# Jira Authentication Method
JIRA_AUTH_METHOD=oauth
# OAuth Configuration (als JIRA_AUTH_METHOD=oauth)
JIRA_OAUTH_CLIENT_ID=<client_id>
JIRA_OAUTH_CLIENT_SECRET=<client_secret>
JIRA_OAUTH_CALLBACK_URL=https://your-domain.com/api/auth/callback
JIRA_OAUTH_SCOPES=READ WRITE
# Session
SESSION_SECRET=<generate_secure_random_string>
# AI (configureer per gebruiker in profile settings)
# ANTHROPIC_API_KEY, OPENAI_API_KEY, TAVILY_API_KEY worden per gebruiker ingesteld
2.2 Session Secret Genereren
# Generate secure random string
node -e "console.log(require('crypto').randomBytes(32).toString('hex'))"
Stap 3: Schema Discovery
3.1 Schema Genereren
cd backend
npm run generate-schema
Dit:
- Haalt schema op van Jira Assets API
- Genereert
backend/src/generated/jira-schema.ts - Genereert
backend/src/generated/jira-types.ts
3.2 Schema Populeren in Database
Bij eerste start van de applicatie:
schemaDiscoveryServiceleestOBJECT_TYPESuit generated schema- Populeert
object_typesenattributestabellen - Gebeurt automatisch bij initialisatie
Stap 4: Application Build
4.1 Dependencies Installeren
# Root
npm install
# Backend
cd backend
npm install
# Frontend
cd frontend
npm install
4.2 Build
# Backend
cd backend
npm run build
# Frontend
cd frontend
npm run build
Stap 5: Database Initialisatie
5.1 Automatische Initialisatie
Bij eerste start:
- Normalized schema wordt aangemaakt
- Schema discovery wordt uitgevoerd
- Tabellen worden gevuld met object types en attributes
5.2 Handmatige Verificatie (Optioneel)
-- Check object types
SELECT * FROM object_types ORDER BY sync_priority;
-- Check attributes
SELECT COUNT(*) FROM attributes;
-- Check per type
SELECT object_type_name, COUNT(*) as attr_count
FROM attributes
GROUP BY object_type_name;
Stap 6: Data Sync
6.1 Eerste Sync
# Via API (na deployment)
curl -X POST https://your-domain.com/api/cache/sync \
-H "Authorization: Bearer <token>"
Of via applicatie:
- Ga naar Settings → Cache Management
- Klik "Full Sync"
6.2 Sync Status Checken
curl https://your-domain.com/api/cache/status \
-H "Authorization: Bearer <token>"
Stap 7: Docker Deployment
7.1 Build Images
# Backend
docker build -t cmdb-backend:latest -f backend/Dockerfile .
# Frontend
docker build -t cmdb-frontend:latest -f frontend/Dockerfile .
7.2 Docker Compose (Production)
# docker-compose.prod.yml
version: '3.8'
services:
backend:
image: cmdb-backend:latest
environment:
- DATABASE_TYPE=postgres
- DATABASE_URL=${DATABASE_URL}
- JIRA_HOST=${JIRA_HOST}
- JIRA_SCHEMA_ID=${JIRA_SCHEMA_ID}
- JIRA_SERVICE_ACCOUNT_TOKEN=${JIRA_SERVICE_ACCOUNT_TOKEN}
- SESSION_SECRET=${SESSION_SECRET}
ports:
- "3001:3001"
frontend:
image: cmdb-frontend:latest
ports:
- "80:80"
depends_on:
- backend
nginx:
image: nginx:alpine
volumes:
- ./nginx/nginx.conf:/etc/nginx/nginx.conf
ports:
- "443:443"
depends_on:
- frontend
- backend
7.3 Starten
docker-compose -f docker-compose.prod.yml up -d
Stap 8: Azure App Service Deployment
8.1 Azure Container Registry
# Login
az acr login --name <registry-name>
# Tag images
docker tag cmdb-backend:latest <registry-name>.azurecr.io/cmdb-backend:latest
docker tag cmdb-frontend:latest <registry-name>.azurecr.io/cmdb-frontend:latest
# Push
docker push <registry-name>.azurecr.io/cmdb-backend:latest
docker push <registry-name>.azurecr.io/cmdb-frontend:latest
8.2 App Service Configuratie
Backend App Service:
- Container:
<registry-name>.azurecr.io/cmdb-backend:latest - Environment variables: Alle
.envvariabelen - Port: 3001
Frontend App Service:
- Container:
<registry-name>.azurecr.io/cmdb-frontend:latest - Environment variables:
VITE_API_URL=https://backend-app.azurewebsites.net
8.3 Deployment via Azure DevOps
Zie azure-pipelines.yml voor CI/CD pipeline.
Stap 9: Verificatie
9.1 Health Checks
# Backend health
curl https://backend-app.azurewebsites.net/health
# Frontend
curl https://frontend-app.azurewebsites.net
9.2 Database Verificatie
-- Check object count
SELECT object_type_name, COUNT(*) as count
FROM objects
GROUP BY object_type_name;
-- Check attribute values
SELECT COUNT(*) FROM attribute_values;
-- Check relations
SELECT COUNT(*) FROM object_relations;
9.3 Functionaliteit Testen
- Login - Test authenticatie
- Dashboard - Check of data wordt getoond
- Application List - Test filters
- Application Detail - Test edit functionaliteit
- Sync - Test manual sync
Stap 10: Monitoring & Maintenance
10.1 Logs
# Azure App Service logs
az webapp log tail --name <app-name> --resource-group <resource-group>
# Docker logs
docker-compose logs -f backend
10.2 Database Monitoring
-- Database size
SELECT pg_database_size('cmdb_cache');
-- Table sizes
SELECT
schemaname,
tablename,
pg_size_pretty(pg_total_relation_size(schemaname||'.'||tablename)) AS size
FROM pg_tables
WHERE schemaname = 'public'
ORDER BY pg_total_relation_size(schemaname||'.'||tablename) DESC;
-- Index usage
SELECT
schemaname,
tablename,
indexname,
idx_scan as index_scans
FROM pg_stat_user_indexes
ORDER BY idx_scan DESC;
10.3 Performance Monitoring
- Monitor query performance
- Check sync duration
- Monitor database connections
- Check memory usage
Troubleshooting
Database Connection Issues
# Test connection
psql $DATABASE_URL -c "SELECT 1"
# Check firewall rules (Azure)
az postgres flexible-server firewall-rule list \
--resource-group <resource-group> \
--name <server-name>
Schema Discovery Fails
# Check Jira connection
curl -H "Authorization: Bearer $JIRA_SERVICE_ACCOUNT_TOKEN" \
$JIRA_HOST/rest/insight/1.0/objectschema/list
# Regenerate schema
cd backend
npm run generate-schema
Sync Issues
# Check sync status
curl https://your-domain.com/api/cache/status
# Manual sync for specific type
curl -X POST https://your-domain.com/api/cache/sync/ApplicationComponent
Rollback Plan
Als er problemen zijn:
- Stop applicatie
- Revert code (git)
- Herstart applicatie
Aangezien het green field is, is er geen data migration nodig voor rollback.
Post-Deployment Checklist
- Database verbinding werkt
- Schema discovery succesvol
- Eerste sync voltooid
- Alle object types gesynct
- Queries werken correct
- Filters werken
- Edit functionaliteit werkt
- Authentication werkt
- Logs zijn zichtbaar
- Monitoring is ingesteld
Performance Tips
- Database Indexes - Zijn automatisch aangemaakt
- Connection Pooling - PostgreSQL adapter gebruikt pool (max 20)
- Query Optimization - Gebruik
queryWithFilters()voor gefilterde queries - Sync Frequency - Incremental sync elke 30 seconden (configureerbaar)
Security Checklist
SESSION_SECRETis sterk en uniek- Database credentials zijn secure
- HTTPS is ingeschakeld
- CORS is correct geconfigureerd
- OAuth callback URL is correct
- Environment variables zijn niet gecommit
Extra Tips & Best Practices
Database Performance
-
Connection Pooling
- PostgreSQL adapter gebruikt automatisch connection pooling (max 20)
- Monitor pool usage in production
-
Query Optimization
- Gebruik
queryWithFilters()voor gefilterde queries (veel sneller) - Indexes zijn automatisch aangemaakt
- Monitor slow queries
- Gebruik
-
Sync Performance
- Batch size: 50 objects per batch (configureerbaar via
JIRA_API_BATCH_SIZE) - Incremental sync: elke 30 seconden (configureerbaar via
SYNC_INCREMENTAL_INTERVAL_MS)
- Batch size: 50 objects per batch (configureerbaar via
Monitoring
-
Application Logs
- Check voor schema discovery errors
- Monitor sync duration
- Check query performance
-
Database Metrics
- Table sizes groeien
- Index usage
- Connection pool usage
-
Jira API
- Monitor rate limiting
- Check API response times
- Monitor sync success rate
Backup Strategy
-
Database Backups
- Azure PostgreSQL: automatische dagelijkse backups
- SQLite: maak periodieke copies van
.dbfiles
-
Configuration Backup
- Backup
.envfile (securely!) - Document alle environment variables
- Backup
Scaling Considerations
-
Database
- PostgreSQL kan schalen (vertical scaling)
- Overweeg read replicas voor grote datasets
-
Application
- Stateless design - kan horizontaal schalen
- Session storage in database (scalable)
-
Cache
- Normalized structure is efficient
- Indexes zorgen voor goede performance
Troubleshooting Common Issues
Issue: Schema Discovery Fails
Symptoom: Error bij startup, geen object types in database
Oplossing:
# Check Jira connection
curl -H "Authorization: Bearer $JIRA_SERVICE_ACCOUNT_TOKEN" \
$JIRA_HOST/rest/insight/1.0/objectschema/list
# Regenerate schema
cd backend
npm run generate-schema
# Restart application
Issue: Sync is Slow
Symptoom: Full sync duurt lang
Oplossing:
- Check Jira API response times
- Verhoog batch size (maar niet te veel - rate limiting)
- Check database connection pool
Issue: Queries zijn Langzaam
Symptoom: Filters werken traag
Oplossing:
- Check of indexes bestaan:
\d+ attribute_valuesin PostgreSQL - Gebruik
queryWithFilters()in plaats van JavaScript filtering - Check query execution plan
Issue: Memory Usage Hoog
Symptoom: Applicatie gebruikt veel geheugen
Oplossing:
- Normalized storage gebruikt minder geheugen dan JSONB
- Check of oude cacheStore nog ergens gebruikt wordt
- Monitor object reconstruction (kan N+1 queries veroorzaken)
Development vs Production
Development:
- SQLite is prima voor testing
- Lokale database in
backend/data/ - Geen SSL nodig
Production:
- PostgreSQL is aanbevolen
- Azure Database for PostgreSQL
- SSL vereist
- Connection pooling
- Monitoring ingeschakeld
Migration van Development naar Production
- Schema is hetzelfde - geen migratie nodig
- Data sync - eerste sync haalt alles op van Jira
- Environment variables - update voor productie
- OAuth callback URL - update naar productie domain
End of Guide