Files
mek-tech-consulting/routes/assess.js
T

212 lines
8.0 KiB
JavaScript

const express = require('express');
const router = express.Router();
const { getDb } = require('../db');
const questions = [
{
id: 'company',
title: 'Bedrijfsinformatie',
fields: [
{ name: 'company_name', label: 'Bedrijfsnaam', type: 'text', required: true },
{ name: 'industry', label: 'Sector/Industrie', type: 'text', required: true },
{ name: 'current_situation', label: 'Huidige situatie (uitdagingen, doelen)', type: 'textarea', required: true }
]
},
{
id: 'infrastructure',
title: 'Huidige Infrastructuur',
fields: [
{ name: 'servers', label: 'Aantal servers (fysiek/virtueel)', type: 'text' },
{ name: 'storage', label: 'Huidige opslag (TB, type: NAS/SAN/object)', type: 'text' },
{ name: 'network', label: 'Netwerk infrastructuur (switches, bandbreedte)', type: 'textarea' },
{ name: 'virtualization', label: 'Virtualisatie platform (VMware, Hyper-V, Proxmox)', type: 'text' }
]
},
{
id: 'data',
title: 'Data & Analytics',
fields: [
{ name: 'data_volume', label: 'Huidige data volume (TB/maand groei)', type: 'text' },
{ name: 'data_types', label: 'Data types (gestructureerd, ongestructureerd, streaming)', type: 'textarea' },
{ name: 'analytics_tools', label: 'Huidige analytics tools (PowerBI, Tableau, custom)', type: 'text' },
{ name: 'data_governance', label: 'Data governance / compliance eisen (AVG, HIPAA, etc)', type: 'textarea' }
]
},
{
id: 'ai',
title: 'AI & Machine Learning',
fields: [
{ name: 'ai_current', label: 'Huidige AI/ML initiatieven', type: 'textarea' },
{ name: 'ai_goals', label: 'AI doelen (predictie, NLP, computer vision, generatief)', type: 'textarea' },
{ name: 'ai_models', label: 'Gewenste modellen (LLMs, custom modellen, open-source)', type: 'text' },
{ name: 'ai_skills', label: 'Beschikbare AI/Data skills in team', type: 'text' }
]
},
{
id: 'requirements',
title: 'Technische Eisen',
fields: [
{ name: 'performance', label: 'Prestatie eisen (latency, throughput)', type: 'text' },
{ name: 'availability', label: 'Beschikbaarheid (SLA, 99.9%/99.99%)', type: 'text' },
{ name: 'security', label: 'Security eisen (encryptie, IAM, netwerk segmentatie)', type: 'textarea' },
{ name: 'budget', label: 'Budget indicatie (CAPEX/OPEX)', type: 'text' },
{ name: 'timeline', label: 'Gewenste implementatie timeline', type: 'text' }
]
}
];
router.get('/', (req, res) => {
const db = getDb();
const clients = db.prepare('SELECT id, name FROM clients ORDER BY name').all();
res.render('assess', { questions, clients, clientId: null, engagementId: null });
});
router.get('/:clientId', (req, res) => {
const db = getDb();
const clients = db.prepare('SELECT id, name FROM clients ORDER BY name').all();
const client = db.prepare('SELECT * FROM clients WHERE id = ?').get(req.params.clientId);
if (!client) return res.redirect('/assess');
res.render('assess', { questions, clients, clientId: parseInt(req.params.clientId), engagementId: null });
});
router.get('/:clientId/:engagementId', (req, res) => {
const db = getDb();
const clients = db.prepare('SELECT id, name FROM clients ORDER BY name').all();
res.render('assess', {
questions, clients,
clientId: parseInt(req.params.clientId),
engagementId: parseInt(req.params.engagementId)
});
});
router.post('/report', async (req, res) => {
const db = getDb();
const answers = req.body;
const clientId = req.body._client_id || null;
const engagementId = req.body._engagement_id || null;
const report = generateReport(answers);
if (clientId) {
const reportJson = JSON.stringify(report);
const answersJson = JSON.stringify(answers);
db.prepare('INSERT INTO assessments (client_id, engagement_id, answers, report) VALUES (?, ?, ?, ?)')
.run(clientId, engagementId || null, answersJson, reportJson);
const client = db.prepare('SELECT * FROM clients WHERE id = ?').get(clientId);
if (client && client.status === 'lead') {
db.prepare("UPDATE clients SET status = 'active', updated_at = datetime('now') WHERE id = ?").run(clientId);
}
}
res.render('report', { report, answers });
});
function generateReport(data) {
const storageTypes = (data.storage || '').toLowerCase();
const hasDatalake = storageTypes.includes('object') || storageTypes.includes('s3');
const hasHighVolume = parseInt(data.data_volume) > 10 || false;
let datalakeTier = 'Standard';
let aiTier = 'Starter';
if (hasHighVolume) datalakeTier = 'Enterprise';
if (hasDatalake) datalakeTier = 'Advanced';
const aiGoals = (data.ai_goals || '').toLowerCase();
if (aiGoals.includes('generatief') || aiGoals.includes('llm')) aiTier = 'Enterprise';
else if (aiGoals.includes('nlp') || aiGoals.includes('predictie')) aiTier = 'Advanced';
const architecture = {
datalake: {
tier: datalakeTier,
storage: datalakeTier === 'Enterprise' ? 'MinIO/Object Store (multi-region)' : 'MinIO/S3-compatible storage',
compute: datalakeTier === 'Enterprise' ? 'Kubernetes cluster (GPU nodes)' : 'Docker Swarm / Kubernetes',
catalog: 'Apache Iceberg + Hive Metastore',
processing: hasHighVolume ? 'Apache Spark structured streaming' : 'Apache Spark batch processing',
governance: 'Apache Atlas + Ranger (GDPR/HIPAA compliant)'
},
ai: {
tier: aiTier,
serving: aiTier === 'Enterprise' ? 'vLLM + SGLang (multi-GPU)' : 'Ollama / vLLM',
orchestration: aiTier === 'Enterprise' ? 'Kubeflow + MLflow' : 'MLflow',
monitoring: 'Prometheus + Grafana + Evidently AI',
models: aiTier === 'Enterprise' ? 'DeepSeek, Llama, Mixtral (8x7B+)' : 'DeepSeek-Coder, Phi-3, Qwen'
},
infrastructure: {
virtualization: data.virtualization || 'Proxmox VE / VMware vSphere',
network: 'Leaf-Spine architecture (100GbE)',
security: 'Zero Trust + microsegmentatie + HSM',
monitoring: 'Datadog / Grafana + Loki + Tempo'
}
};
const phases = [
{
name: 'Fase 1: Quick Win (0-3 maanden)',
items: [
'Inventarisatie & assessment huidige infrastructuur',
'Proof of Concept: Data lake op MinIO + Spark',
'AI readiness check en model selectie',
'Security baseline implementatie'
]
},
{
name: 'Fase 2: Foundation (3-6 maanden)',
items: [
'Lakehouse architectuur implementatie (Iceberg)',
'Data governance framework roll-out',
'Kubernetes cluster opzetten (Rancher / kubeadm)',
'CI/CD pipeline voor ML modellen (MLflow)'
]
},
{
name: 'Fase 3: AI Ops (6-12 maanden)',
items: [
'vLLM/SGLang serving voor LLMs',
'Automated model retraining & monitoring',
'Self-service data platform voor analytics',
'Cost optimization & FinOps implementatie'
]
}
];
return { architecture, phases };
}
router.get('/report/:id/print', (req, res) => {
const db = getDb();
const assessment = db.prepare(`
SELECT a.*, c.name as company_name
FROM assessments a
LEFT JOIN clients c ON c.id = a.client_id
WHERE a.id = ?
`).get(req.params.id);
if (!assessment) return res.redirect('/');
const answers = JSON.parse(assessment.answers);
const report = JSON.parse(assessment.report);
if (!answers.company_name && assessment.company_name) {
answers.company_name = assessment.company_name;
}
res.render('report-print', { report, answers });
});
router.get('/report/:id', (req, res) => {
const db = getDb();
const assessment = db.prepare(`
SELECT a.*, c.name as company_name
FROM assessments a
LEFT JOIN clients c ON c.id = a.client_id
WHERE a.id = ?
`).get(req.params.id);
if (!assessment) return res.redirect('/');
const answers = JSON.parse(assessment.answers);
const report = JSON.parse(assessment.report);
if (!answers.company_name && assessment.company_name) {
answers.company_name = assessment.company_name;
}
res.render('report', { report, answers });
});
module.exports = router;
module.exports.questions = questions;