116 lines
4.4 KiB
JavaScript
116 lines
4.4 KiB
JavaScript
require('dotenv').config();
|
|
|
|
const moment = require('moment');
|
|
moment.locale('en');
|
|
const express = require('express');
|
|
const path = require('path');
|
|
const { DB_PATH, initialize } = require('./db');
|
|
const { logEvent } = require('./logger');
|
|
const { createCorsMiddleware } = require('./middleware/cors');
|
|
const { requireAuth } = require('./middleware/auth');
|
|
const { resolveCompany } = require('./middleware/company');
|
|
|
|
const adminRoutes = require('./routes/admin');
|
|
const alertRoutes = require('./routes/alerts');
|
|
const assetRoutes = require('./routes/assets');
|
|
const assignmentRoutes = require('./routes/assignments');
|
|
const authRoutes = require('./routes/auth');
|
|
const bookRoutes = require('./routes/books');
|
|
const closeRoutes = require('./routes/close');
|
|
const contactRoutes = require('./routes/contacts');
|
|
const dashboardRoutes = require('./routes/dashboard');
|
|
const dataPortabilityRoutes = require('./routes/dataPortability');
|
|
const disposalRoutes = require('./routes/disposals');
|
|
const leaseRoutes = require('./routes/leases');
|
|
const partRoutes = require('./routes/parts');
|
|
const pmRoutes = require('./routes/pm');
|
|
const profileRoutes = require('./routes/profile');
|
|
const referenceRoutes = require('./routes/reference');
|
|
const reportRoutes = require('./routes/reports');
|
|
const serviceNowRoutes = require('./routes/servicenow');
|
|
const teamsRoutes = require('./routes/teams');
|
|
const taxRuleRoutes = require('./routes/taxRules');
|
|
const templateRoutes = require('./routes/templates');
|
|
const workdayRoutes = require('./routes/workday');
|
|
|
|
console.log(`${moment().format()} ✅ Starting DepreCore server with database at ${DB_PATH}`);
|
|
function createApp() {
|
|
initialize();
|
|
|
|
const app = express();
|
|
app.use(createCorsMiddleware());
|
|
app.use(express.json({ limit: '12mb' }));
|
|
console.log(`${moment().format()} ✅ Express app initialized with JSON body parsing and CORS middleware`);
|
|
|
|
// HTTP access log — one event per API request (method, path, status, duration). Skips the health
|
|
// probe and the log-viewer endpoint itself so the viewer doesn't generate noise about itself.
|
|
app.use((req, res, next) => {
|
|
if (!req.path.startsWith('/api') || req.path === '/api/health' || req.path.startsWith('/api/app-logs')) return next();
|
|
const started = Date.now();
|
|
res.on('finish', () => {
|
|
logEvent('http', `${req.method} ${req.originalUrl.split('?')[0]} → ${res.statusCode}`, {
|
|
method: req.method,
|
|
path: req.originalUrl.split('?')[0],
|
|
status: res.statusCode,
|
|
duration_ms: Date.now() - started,
|
|
ip: req.ip
|
|
}, res.statusCode >= 500 ? 'error' : (res.statusCode >= 400 ? 'warn' : 'info'));
|
|
});
|
|
return next();
|
|
});
|
|
|
|
app.get('/api/health', (req, res) => {
|
|
res.json({ ok: true, app: 'DepreCore', database: DB_PATH });
|
|
});
|
|
console.log(`${moment().format()} ✅ Health check endpoint registered at /api/health`);
|
|
|
|
app.use('/api', authRoutes);
|
|
app.use('/api', requireAuth);
|
|
app.use('/api', resolveCompany);
|
|
app.use('/api', profileRoutes);
|
|
app.use('/api', dashboardRoutes);
|
|
app.use('/api', referenceRoutes);
|
|
app.use('/api', assetRoutes);
|
|
app.use('/api', alertRoutes);
|
|
app.use('/api', bookRoutes);
|
|
app.use('/api', closeRoutes);
|
|
app.use('/api', contactRoutes);
|
|
app.use('/api', disposalRoutes);
|
|
app.use('/api', leaseRoutes);
|
|
app.use('/api', partRoutes);
|
|
app.use('/api', pmRoutes);
|
|
app.use('/api', assignmentRoutes);
|
|
app.use('/api', templateRoutes);
|
|
app.use('/api', taxRuleRoutes);
|
|
app.use('/api', reportRoutes);
|
|
app.use('/api', serviceNowRoutes);
|
|
app.use('/api', teamsRoutes);
|
|
app.use('/api', dataPortabilityRoutes);
|
|
app.use('/api', adminRoutes);
|
|
app.use('/api', workdayRoutes);
|
|
console.log(`${moment().format()} ✅ API routes registered under /api`);
|
|
|
|
const distPath = path.join(process.cwd(), 'dist');
|
|
app.use(express.static(distPath));
|
|
console.log(`${moment().format()} ✅ Static file serving configured for ${distPath}`);
|
|
|
|
app.get(/.*/, (req, res, next) => {
|
|
if (req.path.startsWith('/api')) return next();
|
|
return res.sendFile(path.join(distPath, 'index.html'));
|
|
});
|
|
|
|
app.use((error, req, res, next) => {
|
|
if (res.headersSent) return next(error);
|
|
const status = error.status || 500;
|
|
console.error(`${moment().format()} ❌ Error: ${error.message}\n${error.stack}`);
|
|
return res.status(status).json({ error: error.message || 'DepreCore server error' });
|
|
});
|
|
console.log(`${moment().format()} ✅ Global error handler registered`);
|
|
|
|
return app;
|
|
}
|
|
|
|
module.exports = {
|
|
createApp
|
|
};
|