farmcontrol-api/src/index.js
Tom Butcher 1c51766da6
All checks were successful
farmcontrol/farmcontrol-api/pipeline/head This commit looks good
Add user group management functionality and refactor permission settings
This commit introduces a new feature for managing user groups within the application, including the creation of a `usergroup.schema.js` file for the Mongoose schema and corresponding route handlers for CRUD operations. Additionally, the permission settings functionality has been refactored to use a singular `permissionSetting` model instead of the previous plural form. Tests have been added to ensure the functionality of both user groups and permission settings services, enhancing the application's capability to manage user roles and permissions effectively.
2026-08-20 15:04:52 +01:00

225 lines
6.5 KiB
JavaScript

import express from 'express';
import bodyParser from 'body-parser';
import cors from 'cors';
import config from './config.js';
import { dbConnect } from './database/mongo.js';
import { redisServer } from './database/redis.js';
import {
authRoutes,
userRoutes,
userGroupRoutes,
permissionSettingsRoutes,
appPasswordRoutes,
fileRoutes,
printerRoutes,
printerProfileRoutes,
filamentProfileRoutes,
jobRoutes,
subJobRoutes,
gcodeFileRoutes,
filamentRoutes,
filamentSkuRoutes,
spotlightRoutes,
partRoutes,
partSkuRoutes,
productRoutes,
productCategoryRoutes,
productSkuRoutes,
vendorRoutes,
materialRoutes,
partStockRoutes,
productStockRoutes,
filamentStockRoutes,
purchaseOrderRoutes,
orderItemRoutes,
shipmentRoutes,
stockAuditRoutes,
stockLocationRoutes,
stockTransferRoutes,
stockEventRoutes,
auditLogRoutes,
noteTypeRoutes,
noteRoutes,
hostRoutes,
documentSizesRoutes,
documentTemplatesRoutes,
documentPrintersRoutes,
documentJobsRoutes,
courierRoutes,
courierServiceRoutes,
taxRateRoutes,
taxRecordRoutes,
invoiceRoutes,
paymentRoutes,
clientRoutes,
salesOrderRoutes,
marketplaceRoutes,
listingRoutes,
listingVarientRoutes,
userNotifierRoutes,
notificationRoutes,
odataRoutes,
rssRoutes,
excelRoutes,
csvRoutes,
appLaunchRoutes,
appUpdateRoutes,
serverRoutes,
slicerRoutes,
} from './routes/index.js';
import path from 'path';
import * as fs from 'fs';
import log4js from 'log4js';
import { populateUserMiddleware } from './services/misc/auth.js';
import { natsServer } from './database/nats.js';
import { initializeBuckets } from './database/ceph.js';
import { getEnvironment } from './config.js';
import { startPDFBrowser } from './templates/pdffactory.js';
const PORT = config.server.port;
const app = express();
const logger = log4js.getLogger('App');
logger.level = config.server.logLevel;
app.use(log4js.connectLogger(logger, { level: 'trace' }));
const allowedOrigins = [
...new Set(
[
...(config.server.corsOrigins || []),
config.app.urlClient,
config.app.urlElectronClient,
].filter(Boolean)
),
];
const corsOptions = {
origin: function (origin, callback) {
if (!origin) return callback(null, true);
if (allowedOrigins.includes('*')) return callback(null, true);
if (allowedOrigins.includes(origin)) return callback(null, true);
logger.warn(`Allowed origins: ${allowedOrigins.join(', ')}`);
callback(new Error(`Not allowed by CORS - ${origin}`));
},
credentials: true,
};
// Initialize application
async function initializeApp() {
logger.info('Initializing application...');
logger.info(`Environment: ${getEnvironment()}`);
logger.info(`Port: ${PORT}`);
logger.info(`Log Level: ${config.server.logLevel}`);
try {
// Connect to database
await dbConnect();
// Connect to Redis (required for excel temp tokens, sessions, cache)
await redisServer.connect();
// Connect to NATS
await natsServer.connect();
// Initialize Ceph buckets
try {
await initializeBuckets();
} catch (err) {
logger.error('Failed to initialize Ceph buckets:', err);
// Don't throw error - allow app to start without Ceph for development
}
try {
await startPDFBrowser();
} catch (err) {
logger.error('Failed to start persistent Puppeteer browser:', err);
}
// Start server
app.listen(PORT, () => logger.info(`Server listening to port ${PORT}`));
logger.info(`Allowed origins: ${allowedOrigins.join(', ')}`);
} catch (err) {
logger.error('Failed to initialize application:', err);
process.exit(1);
}
}
// Configure middleware
app.use(cors(corsOptions));
app.use(bodyParser.json({ type: 'application/json', strict: false, limit: '50mb' }));
app.use(express.json());
app.use(populateUserMiddleware);
app.get('/', function (req, res) {
const __dirname = fs.realpathSync('.');
res.sendFile(path.join(__dirname, '/src/landing/index.html'));
});
app.use('/auth', authRoutes);
app.use('/users', userRoutes);
app.use('/usergroups', userGroupRoutes);
app.use('/permissionsettings', permissionSettingsRoutes);
app.use('/apppasswords', appPasswordRoutes);
app.use('/files', fileRoutes);
app.use('/spotlight', spotlightRoutes);
app.use('/printers', printerRoutes);
app.use('/printerprofiles', printerProfileRoutes);
app.use('/filamentprofiles', filamentProfileRoutes);
app.use('/hosts', hostRoutes);
app.use('/jobs', jobRoutes);
app.use('/subjobs', subJobRoutes);
app.use('/gcodefiles', gcodeFileRoutes);
app.use('/filaments', filamentRoutes);
app.use('/filamentskus', filamentSkuRoutes);
app.use('/parts', partRoutes);
app.use('/partskus', partSkuRoutes);
app.use('/products', productRoutes);
app.use('/productcategories', productCategoryRoutes);
app.use('/productskus', productSkuRoutes);
app.use('/vendors', vendorRoutes);
app.use('/materials', materialRoutes);
app.use('/partstocks', partStockRoutes);
app.use('/productstocks', productStockRoutes);
app.use('/filamentstocks', filamentStockRoutes);
app.use('/purchaseorders', purchaseOrderRoutes);
app.use('/orderitems', orderItemRoutes);
app.use('/shipments', shipmentRoutes);
app.use('/stockevents', stockEventRoutes);
app.use('/stockaudits', stockAuditRoutes);
app.use('/stocklocations', stockLocationRoutes);
app.use('/stocktransfers', stockTransferRoutes);
app.use('/auditlogs', auditLogRoutes);
app.use('/notetypes', noteTypeRoutes);
app.use('/documentsizes', documentSizesRoutes);
app.use('/documenttemplates', documentTemplatesRoutes);
app.use('/documentprinters', documentPrintersRoutes);
app.use('/documentjobs', documentJobsRoutes);
app.use('/couriers', courierRoutes);
app.use('/courierservices', courierServiceRoutes);
app.use('/taxrates', taxRateRoutes);
app.use('/taxrecords', taxRecordRoutes);
app.use('/invoices', invoiceRoutes);
app.use('/payments', paymentRoutes);
app.use('/clients', clientRoutes);
app.use('/salesorders', salesOrderRoutes);
app.use('/marketplaces', marketplaceRoutes);
app.use('/listings', listingRoutes);
app.use('/listingvarients', listingVarientRoutes);
app.use('/notes', noteRoutes);
app.use('/usernotifiers', userNotifierRoutes);
app.use('/notifications', notificationRoutes);
app.use('/odata', odataRoutes);
app.use('/rss', rssRoutes);
app.use('/excel', excelRoutes);
app.use('/csv', csvRoutes);
app.use('/applaunch', appLaunchRoutes);
app.use('/appupdate', appUpdateRoutes);
app.use('/server', serverRoutes);
app.use('/slicer', slicerRoutes);
// Start the application
if (process.env.NODE_ENV !== 'test') {
initializeApp();
}
export default app;