Some checks are pending
CI Pipeline / changes (push) Waiting to run
CI Pipeline / core (push) Blocked by required conditions
CI Pipeline / trading-backend (push) Blocked by required conditions
CI Pipeline / trading-data-service (push) Blocked by required conditions
CI Pipeline / trading-frontend (push) Blocked by required conditions
CI Pipeline / erp-core (push) Blocked by required conditions
CI Pipeline / erp-mecanicas (push) Blocked by required conditions
CI Pipeline / gamilit-backend (push) Blocked by required conditions
CI Pipeline / gamilit-frontend (push) Blocked by required conditions
121 lines
3.1 KiB
TypeScript
121 lines
3.1 KiB
TypeScript
import 'reflect-metadata';
|
|
import express, { Application, Request, Response, NextFunction } from 'express';
|
|
import cors from 'cors';
|
|
import helmet from 'helmet';
|
|
import compression from 'compression';
|
|
import morgan from 'morgan';
|
|
|
|
// Route imports
|
|
import branchRoutes from './modules/branches/routes/branch.routes';
|
|
import posRoutes from './modules/pos/routes/pos.routes';
|
|
|
|
// Error type
|
|
interface AppError extends Error {
|
|
statusCode?: number;
|
|
status?: string;
|
|
isOperational?: boolean;
|
|
}
|
|
|
|
// Create Express app
|
|
const app: Application = express();
|
|
|
|
// Security middleware
|
|
app.use(helmet());
|
|
|
|
// CORS configuration
|
|
app.use(cors({
|
|
origin: process.env.CORS_ORIGIN?.split(',') || ['http://localhost:3000', 'http://localhost:5173'],
|
|
credentials: true,
|
|
methods: ['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'OPTIONS'],
|
|
allowedHeaders: ['Content-Type', 'Authorization', 'X-Tenant-ID', 'X-Branch-ID'],
|
|
}));
|
|
|
|
// Compression
|
|
app.use(compression());
|
|
|
|
// Body parsing
|
|
app.use(express.json({ limit: '10mb' }));
|
|
app.use(express.urlencoded({ extended: true, limit: '10mb' }));
|
|
|
|
// Request logging
|
|
if (process.env.NODE_ENV !== 'test') {
|
|
app.use(morgan(process.env.NODE_ENV === 'production' ? 'combined' : 'dev'));
|
|
}
|
|
|
|
// Health check endpoint
|
|
app.get('/health', (_req: Request, res: Response) => {
|
|
res.json({
|
|
status: 'healthy',
|
|
timestamp: new Date().toISOString(),
|
|
version: process.env.npm_package_version || '0.1.0',
|
|
environment: process.env.NODE_ENV || 'development',
|
|
});
|
|
});
|
|
|
|
// API version info
|
|
app.get('/api', (_req: Request, res: Response) => {
|
|
res.json({
|
|
name: 'ERP Retail API',
|
|
version: '0.1.0',
|
|
modules: [
|
|
'branches',
|
|
'pos',
|
|
'cash',
|
|
'inventory',
|
|
'customers',
|
|
'pricing',
|
|
'invoicing',
|
|
'ecommerce',
|
|
'purchases',
|
|
],
|
|
});
|
|
});
|
|
|
|
// API Routes
|
|
app.use('/api/branches', branchRoutes);
|
|
app.use('/api/pos', posRoutes);
|
|
// TODO: Add remaining route modules as they are implemented
|
|
// app.use('/api/cash', cashRouter);
|
|
// app.use('/api/inventory', inventoryRouter);
|
|
// app.use('/api/customers', customersRouter);
|
|
// app.use('/api/pricing', pricingRouter);
|
|
// app.use('/api/invoicing', invoicingRouter);
|
|
// app.use('/api/ecommerce', ecommerceRouter);
|
|
// app.use('/api/purchases', purchasesRouter);
|
|
|
|
// 404 handler
|
|
app.use((_req: Request, res: Response) => {
|
|
res.status(404).json({
|
|
success: false,
|
|
error: {
|
|
code: 'NOT_FOUND',
|
|
message: 'The requested resource was not found',
|
|
},
|
|
});
|
|
});
|
|
|
|
// Global error handler
|
|
app.use((err: AppError, _req: Request, res: Response, _next: NextFunction) => {
|
|
const statusCode = err.statusCode || 500;
|
|
const status = err.status || 'error';
|
|
|
|
// Log error
|
|
console.error('Error:', {
|
|
message: err.message,
|
|
stack: process.env.NODE_ENV === 'development' ? err.stack : undefined,
|
|
statusCode,
|
|
});
|
|
|
|
// Send response
|
|
res.status(statusCode).json({
|
|
success: false,
|
|
error: {
|
|
code: status.toUpperCase().replace(/ /g, '_'),
|
|
message: err.isOperational ? err.message : 'An unexpected error occurred',
|
|
...(process.env.NODE_ENV === 'development' && { stack: err.stack }),
|
|
},
|
|
});
|
|
});
|
|
|
|
export default app;
|