Files

153 lines
5.7 KiB
JavaScript

const express = require('express');
const router = express.Router();
const { getDb, logAudit } = require('../db');
function apiAuth(req, res, next) {
const apiKey = req.headers['x-api-key'];
if (apiKey === process.env.API_KEY) return next();
if (req.session && req.session.userId) return next();
return res.status(401).json({ error: 'Unauthorized' });
}
const LEADGEN_URL = process.env.LEADGEN_URL || 'http://python-leadgen:3003';
async function proxyLeadgen(path, body, method) {
const https = require('https');
const http = require('http');
const url = new URL(LEADGEN_URL + path);
const client = url.protocol === 'https:' ? https : http;
return new Promise((resolve, reject) => {
const data = body ? JSON.stringify(body) : undefined;
const opts = {
method: method || 'POST',
headers: { 'Content-Type': 'application/json' },
};
if (data) opts.headers['Content-Length'] = Buffer.byteLength(data);
const req = client.request(url, opts, (res) => {
let buf = '';
res.on('data', c => buf += c);
res.on('end', () => { try { resolve(JSON.parse(buf)); } catch(e) { resolve({success:false,error:'Invalid JSON response'}); } });
});
req.on('error', (e) => resolve({success:false,error:'LeadGen service unavailable: '+e.message}));
if (data) req.write(data);
req.end();
});
}
router.post('/leadgen-analyze', async (req, res) => {
try {
const result = await proxyLeadgen('/python-leadgen/analyze', req.body);
res.json(result);
} catch (e) {
res.status(500).json({ success: false, error: 'LeadGen service unavailable: ' + e.message });
}
});
router.post('/leadgen-batch', async (req, res) => {
try {
const result = await proxyLeadgen('/python-leadgen/batch', req.body);
res.json(result);
} catch (e) {
res.status(500).json({ success: false, error: 'LeadGen service unavailable: ' + e.message });
}
});
router.get('/leadgen-config', async (req, res) => {
try {
const result = await proxyLeadgen('/python-leadgen/config', null, 'GET');
res.json(result);
} catch (e) {
res.status(500).json({ success: false, error: e.message });
}
});
router.post('/leadgen-config', async (req, res) => {
try {
const result = await proxyLeadgen('/python-leadgen/config', req.body, 'POST');
res.json(result);
} catch (e) {
res.status(500).json({ success: false, error: e.message });
}
});
router.get('/leadgen-models', async (req, res) => {
try {
const result = await proxyLeadgen('/python-leadgen/models', null, 'GET');
res.json(result);
} catch (e) {
res.status(500).json({ success: false, error: e.message });
}
});
router.use(apiAuth);
router.get('/clients', (req, res) => {
const db = getDb();
const clients = db.prepare('SELECT * FROM clients ORDER BY name').all();
res.json(clients);
});
router.get('/clients/:id', (req, res) => {
const db = getDb();
const client = db.prepare('SELECT * FROM clients WHERE id = ?').get(req.params.id);
if (!client) return res.status(404).json({ error: 'Not found' });
res.json(client);
});
router.post('/clients', (req, res) => {
const db = getDb();
const { name, industry, website, contact_name, contact_email, contact_phone, status, source, notes } = req.body;
if (!name) return res.status(400).json({ error: 'Name is required' });
const result = db.prepare('INSERT INTO clients (name, industry, website, contact_name, contact_email, contact_phone, status, source, notes) VALUES (?,?,?,?,?,?,?,?,?)')
.run(name, industry, website, contact_name, contact_email, contact_phone, status || 'lead', source, notes);
res.status(201).json({ id: result.lastInsertRowid });
});
router.put('/clients/:id', (req, res) => {
const db = getDb();
const { name, industry, website, contact_name, contact_email, contact_phone, status, source, notes } = req.body;
db.prepare("UPDATE clients SET name=?, industry=?, website=?, contact_name=?, contact_email=?, contact_phone=?, status=?, source=?, notes=?, updated_at=datetime('now') WHERE id=?")
.run(name, industry, website, contact_name, contact_email, contact_phone, status, source, notes, req.params.id);
res.json({ ok: true });
});
router.delete('/clients/:id', (req, res) => {
const db = getDb();
db.prepare('DELETE FROM clients WHERE id = ?').run(req.params.id);
res.json({ ok: true });
});
router.get('/engagements', (req, res) => {
const db = getDb();
const engagements = db.prepare('SELECT e.*, c.name as client_name FROM engagements e JOIN clients c ON c.id = e.client_id ORDER BY e.created_at DESC').all();
res.json(engagements);
});
router.get('/assessments', (req, res) => {
const db = getDb();
const assessments = db.prepare('SELECT a.*, c.name as client_name FROM assessments a JOIN clients c ON c.id = a.client_id ORDER BY a.created_at DESC').all();
res.json(assessments);
});
router.get('/racks', (req, res) => {
const db = getDb();
const racks = db.prepare('SELECT r.*, c.name as client_name FROM racks r JOIN clients c ON c.id = r.client_id ORDER BY r.name').all();
res.json(racks);
});
router.get('/stats', (req, res) => {
const db = getDb();
res.json({
clients: db.prepare('SELECT COUNT(*) as cnt FROM clients').get().cnt,
engagements: db.prepare('SELECT COUNT(*) as cnt FROM engagements').get().cnt,
assessments: db.prepare('SELECT COUNT(*) as cnt FROM assessments').get().cnt,
tasks: db.prepare('SELECT COUNT(*) as cnt FROM tasks').get().cnt,
racks: db.prepare('SELECT COUNT(*) as cnt FROM racks').get().cnt,
diagrams: db.prepare('SELECT COUNT(*) as cnt FROM data_diagrams').get().cnt,
invoices: db.prepare('SELECT COUNT(*) as cnt FROM invoices').get().cnt,
timeEntries: db.prepare('SELECT COUNT(*) as cnt FROM time_entries').get().cnt
});
});
module.exports = router;