105 lines
4.4 KiB
JavaScript
105 lines
4.4 KiB
JavaScript
const express = require('express');
|
|
const router = express.Router();
|
|
const path = require('path');
|
|
const fs = require('fs');
|
|
const multer = require('multer');
|
|
const http = require('http');
|
|
|
|
const QS_HOST = process.env.QS_HOST || 'python-quality';
|
|
const QS_PORT = parseInt(process.env.QS_PORT || '3002');
|
|
const SHARED_UPLOAD_DIR = path.join(__dirname, '..', 'data', 'uploads');
|
|
if (!fs.existsSync(SHARED_UPLOAD_DIR)) fs.mkdirSync(SHARED_UPLOAD_DIR, { recursive: true });
|
|
|
|
const storage = multer.diskStorage({
|
|
destination: (req, file, cb) => cb(null, SHARED_UPLOAD_DIR),
|
|
filename: (req, file, cb) => cb(null, Date.now() + '-' + file.originalname)
|
|
});
|
|
const upload = multer({ storage, limits: { fileSize: 100 * 1024 * 1024 } });
|
|
|
|
function qsApi(path, method, body) {
|
|
return new Promise((resolve, reject) => {
|
|
const opts = { hostname: QS_HOST, port: QS_PORT, path, method, headers: { 'Content-Type': 'application/json' }, timeout: 30000 };
|
|
const req = http.request(opts, (res) => {
|
|
let data = '';
|
|
res.on('data', c => data += c);
|
|
res.on('end', () => {
|
|
if (method === 'GET' && res.statusCode >= 400) return reject(new Error('offline'));
|
|
try { resolve(JSON.parse(data)); } catch(e) { resolve({ raw: data }); }
|
|
});
|
|
});
|
|
req.on('error', (e) => reject(e));
|
|
req.on('timeout', () => { req.destroy(); reject(new Error('timeout')); });
|
|
if (body) req.write(JSON.stringify(body));
|
|
req.end();
|
|
});
|
|
}
|
|
|
|
router.get('/', async (req, res) => {
|
|
let files = [];
|
|
let qsStatus = 'offline';
|
|
let services = {};
|
|
try {
|
|
const dirFiles = fs.readdirSync(SHARED_UPLOAD_DIR).filter(f => f !== '.gitkeep');
|
|
files = dirFiles.map(f => ({ file_id: f.split('.')[0], filename: f, size: fs.statSync(path.join(SHARED_UPLOAD_DIR, f)).size }));
|
|
await qsApi('/python-quality/', 'GET');
|
|
qsStatus = 'online';
|
|
} catch (e) { qsStatus = 'offline'; }
|
|
try {
|
|
const { getServicesStatus } = require('../lib/services');
|
|
services = await getServicesStatus();
|
|
} catch (e) {}
|
|
const { getDb } = require('../db');
|
|
const clients = getDb().prepare('SELECT id, name FROM clients ORDER BY name').all();
|
|
const clientId = req.query.client_id || req.session.activeClientId || null;
|
|
res.render('quality-dashboard', { files, qsStatus, services, clients, clientId, uploaded: null, profile: null, report: null, error: null });
|
|
});
|
|
|
|
router.post('/upload', upload.single('file'), async (req, res) => {
|
|
if (!req.file) return res.redirect('/quality');
|
|
try {
|
|
const resp = await qsApi('/python-quality/api/profile', 'POST', { file_id: req.file.filename.split('.')[0], shared_path: path.join(SHARED_UPLOAD_DIR, req.file.filename) });
|
|
const profile = resp.profile || resp;
|
|
const uploaded = { file_id: req.file.filename.split('.')[0], original_name: req.file.originalname, rows: profile.rows, columns: profile.columns };
|
|
res.render('quality-dashboard', { files: [], qsStatus: 'online', uploaded, profile, report: null, error: null });
|
|
} catch (e) {
|
|
res.render('quality-dashboard', { files: [], qsStatus: 'online', uploaded: null, profile: null, report: null, error: 'Kon bestand niet analyseren: ' + (e.message || 'onbekende fout') });
|
|
}
|
|
});
|
|
|
|
router.post('/quality-check/:fileId', async (req, res) => {
|
|
try {
|
|
const result = await qsApi('/python-quality/api/quality-check', 'POST', { file_id: req.params.fileId, checks: ['completeness', 'uniqueness', 'range', 'type'] });
|
|
res.json(result);
|
|
} catch (e) { res.status(500).json({ error: e.message }); }
|
|
});
|
|
|
|
router.get('/profile/:fileId', async (req, res) => {
|
|
try {
|
|
const result = await qsApi('/python-quality/api/profile', 'POST', { file_id: req.params.fileId });
|
|
res.json(result);
|
|
} catch (e) { res.status(500).json({ error: e.message }); }
|
|
});
|
|
|
|
router.get('/report/:reportId', async (req, res) => {
|
|
try {
|
|
const result = await qsApi('/python-quality/api/report/' + req.params.reportId, 'GET');
|
|
res.json(result);
|
|
} catch (e) { res.status(500).json({ error: e.message }); }
|
|
});
|
|
|
|
router.post('/dbt/validate', async (req, res) => {
|
|
try {
|
|
const result = await qsApi('/python-quality/api/dbt/validate', 'POST', req.body);
|
|
res.json(result);
|
|
} catch (e) { res.status(500).json({ error: e.message }); }
|
|
});
|
|
|
|
router.post('/dbt/test', async (req, res) => {
|
|
try {
|
|
const result = await qsApi('/python-quality/api/dbt/test', 'POST', req.body);
|
|
res.json(result);
|
|
} catch (e) { res.status(500).json({ error: e.message }); }
|
|
});
|
|
|
|
module.exports = router;
|