erp-mecanicas-diesel-backen.../src/main.ts
Adrian Flores Cortes 7e0d4ee841 feat(MMD-011): Implement Dispatch Center module
Add complete dispatch module for incident assignment:

Entities (7):
- DispatchBoard: Board configuration
- UnitStatus: Real-time unit state
- TechnicianSkill: Skills and certifications
- TechnicianShift: Shift schedules
- DispatchRule: Assignment rules
- EscalationRule: Escalation rules
- DispatchLog: Audit trail

Services (4):
- DispatchService: Unit management, assignments, suggestions
- SkillService: Skill CRUD, validation, matrix
- ShiftService: Shift management, availability
- RuleService: Dispatch and escalation rules

Controllers (4):
- DispatchController: /api/v1/dispatch
- SkillController: /api/v1/dispatch/skills
- ShiftController: /api/v1/dispatch/shifts
- RuleController: /api/v1/dispatch/rules

Integrated in main.ts with routes and documentation

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-27 02:21:40 -06:00

310 lines
13 KiB
TypeScript

/**
* Main Entry Point
* Mecánicas Diesel Backend - ERP Suite
*/
import 'reflect-metadata';
import express from 'express';
import cors from 'cors';
import helmet from 'helmet';
import compression from 'compression';
import morgan from 'morgan';
import { config } from 'dotenv';
import { DataSource } from 'typeorm';
// Controllers
import { createAuthController } from './modules/auth/auth.controller';
import { createUsersController } from './modules/users/users.controller';
import { createServiceOrderController } from './modules/service-management/controllers/service-order.controller';
import { createQuoteController } from './modules/service-management/controllers/quote.controller';
import { createDiagnosticController } from './modules/service-management/controllers/diagnostic.controller';
import { createVehicleController } from './modules/vehicle-management/controllers/vehicle.controller';
import { createFleetController } from './modules/vehicle-management/controllers/fleet.controller';
import { createPartController } from './modules/parts-management/controllers/part.controller';
import { createSupplierController } from './modules/parts-management/controllers/supplier.controller';
import { createCustomersRouter } from './modules/customers/controllers/customers.controller';
// GPS Module Controllers
import { createGpsDeviceController } from './modules/gps/controllers/gps-device.controller';
import { createGpsPositionController } from './modules/gps/controllers/gps-position.controller';
import { createGeofenceController } from './modules/gps/controllers/geofence.controller';
import { createRouteSegmentController } from './modules/gps/controllers/route-segment.controller';
// Assets Module Controllers
import { createAssetController } from './modules/assets/controllers/asset.controller';
import { createAssetAssignmentController } from './modules/assets/controllers/asset-assignment.controller';
import { createAssetAuditController } from './modules/assets/controllers/asset-audit.controller';
import { createAssetMaintenanceController } from './modules/assets/controllers/asset-maintenance.controller';
// Dispatch Module Controllers
import { createDispatchController } from './modules/dispatch/controllers/dispatch.controller';
import { createSkillController } from './modules/dispatch/controllers/skill.controller';
import { createShiftController } from './modules/dispatch/controllers/shift.controller';
import { createRuleController } from './modules/dispatch/controllers/rule.controller';
// Payment Terminals Module
import { PaymentTerminalsModule } from './modules/payment-terminals';
// Entities - Auth
import { User } from './modules/auth/entities/user.entity';
import { RefreshToken } from './modules/auth/entities/refresh-token.entity';
import { Workshop } from './modules/auth/entities/workshop.entity';
// Entities - Service Management
import { ServiceOrder } from './modules/service-management/entities/service-order.entity';
import { OrderItem } from './modules/service-management/entities/order-item.entity';
import { Diagnostic } from './modules/service-management/entities/diagnostic.entity';
import { Quote } from './modules/service-management/entities/quote.entity';
import { WorkBay } from './modules/service-management/entities/work-bay.entity';
import { Service } from './modules/service-management/entities/service.entity';
import { Vehicle } from './modules/vehicle-management/entities/vehicle.entity';
import { Fleet } from './modules/vehicle-management/entities/fleet.entity';
import { VehicleEngine } from './modules/vehicle-management/entities/vehicle-engine.entity';
import { EngineCatalog } from './modules/vehicle-management/entities/engine-catalog.entity';
import { MaintenanceReminder } from './modules/vehicle-management/entities/maintenance-reminder.entity';
import { Part } from './modules/parts-management/entities/part.entity';
import { PartCategory } from './modules/parts-management/entities/part-category.entity';
import { Supplier } from './modules/parts-management/entities/supplier.entity';
import { WarehouseLocation } from './modules/parts-management/entities/warehouse-location.entity';
// Entities - Customers
import { Customer } from './modules/customers/entities/customer.entity';
// Entities - Payment Terminals
import { TenantTerminalConfig } from './modules/payment-terminals/entities/tenant-terminal-config.entity';
import { TerminalPayment } from './modules/payment-terminals/entities/terminal-payment.entity';
import { TerminalWebhookEvent } from './modules/payment-terminals/entities/terminal-webhook-event.entity';
// Entities - GPS
import { GpsDevice } from './modules/gps/entities/gps-device.entity';
import { GpsPosition } from './modules/gps/entities/gps-position.entity';
import { Geofence } from './modules/gps/entities/geofence.entity';
import { GeofenceEvent } from './modules/gps/entities/geofence-event.entity';
import { RouteSegment } from './modules/gps/entities/route-segment.entity';
// Entities - Assets
import { Asset } from './modules/assets/entities/asset.entity';
import { AssetCategory } from './modules/assets/entities/asset-category.entity';
import { AssetAssignment } from './modules/assets/entities/asset-assignment.entity';
import { AssetAudit } from './modules/assets/entities/asset-audit.entity';
import { AssetAuditItem } from './modules/assets/entities/asset-audit-item.entity';
import { AssetMaintenance } from './modules/assets/entities/asset-maintenance.entity';
// Entities - Dispatch
import { DispatchBoard } from './modules/dispatch/entities/dispatch-board.entity';
import { UnitStatus } from './modules/dispatch/entities/unit-status.entity';
import { TechnicianSkill } from './modules/dispatch/entities/technician-skill.entity';
import { TechnicianShift } from './modules/dispatch/entities/technician-shift.entity';
import { DispatchRule } from './modules/dispatch/entities/dispatch-rule.entity';
import { EscalationRule } from './modules/dispatch/entities/escalation-rule.entity';
import { DispatchLog } from './modules/dispatch/entities/dispatch-log.entity';
// Load environment variables
config();
const app = express();
const PORT = process.env.PORT || 3011;
// Database configuration
const AppDataSource = new DataSource({
type: 'postgres',
host: process.env.DB_HOST || 'localhost',
port: parseInt(process.env.DB_PORT || '5432', 10),
username: process.env.DB_USER || 'postgres',
password: process.env.DB_PASSWORD || 'postgres',
database: process.env.DB_NAME || 'mecanicas_diesel',
schema: process.env.DB_SCHEMA || 'public',
entities: [
// Auth
User,
RefreshToken,
Workshop,
// Service Management
ServiceOrder,
OrderItem,
Diagnostic,
Quote,
WorkBay,
Service,
// Vehicle Management
Vehicle,
Fleet,
VehicleEngine,
EngineCatalog,
MaintenanceReminder,
// Parts Management
Part,
PartCategory,
Supplier,
WarehouseLocation,
// Customers
Customer,
// Payment Terminals
TenantTerminalConfig,
TerminalPayment,
TerminalWebhookEvent,
// GPS
GpsDevice,
GpsPosition,
Geofence,
GeofenceEvent,
RouteSegment,
// Assets
Asset,
AssetCategory,
AssetAssignment,
AssetAudit,
AssetAuditItem,
AssetMaintenance,
// Dispatch
DispatchBoard,
UnitStatus,
TechnicianSkill,
TechnicianShift,
DispatchRule,
EscalationRule,
DispatchLog,
],
synchronize: process.env.NODE_ENV === 'development',
logging: process.env.NODE_ENV === 'development',
});
// Middleware
app.use(helmet());
app.use(cors({
origin: process.env.CORS_ORIGINS?.split(',') || ['http://localhost:3000', 'http://localhost:5175'],
credentials: true,
}));
app.use(compression());
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
app.use(morgan(process.env.NODE_ENV === 'production' ? 'combined' : 'dev'));
// Health check
app.get('/health', (_req, res) => {
res.json({
status: 'healthy',
service: 'mecanicas-diesel-backend',
version: '0.1.0',
timestamp: new Date().toISOString(),
database: AppDataSource.isInitialized ? 'connected' : 'disconnected',
});
});
// Initialize database and routes
async function bootstrap() {
try {
// Initialize database connection
await AppDataSource.initialize();
console.log('📦 Database connection established');
// Register API routes
app.use('/api/v1/auth', createAuthController(AppDataSource));
app.use('/api/v1/users', createUsersController(AppDataSource));
app.use('/api/v1/service-orders', createServiceOrderController(AppDataSource));
app.use('/api/v1/quotes', createQuoteController(AppDataSource));
app.use('/api/v1/diagnostics', createDiagnosticController(AppDataSource));
app.use('/api/v1/vehicles', createVehicleController(AppDataSource));
app.use('/api/v1/fleets', createFleetController(AppDataSource));
app.use('/api/v1/parts', createPartController(AppDataSource));
app.use('/api/v1/suppliers', createSupplierController(AppDataSource));
app.use('/api/v1/customers', createCustomersRouter(AppDataSource));
// GPS Module Routes
app.use('/api/v1/gps/devices', createGpsDeviceController(AppDataSource));
app.use('/api/v1/gps/positions', createGpsPositionController(AppDataSource));
app.use('/api/v1/gps/geofences', createGeofenceController(AppDataSource));
app.use('/api/v1/gps/routes', createRouteSegmentController(AppDataSource));
console.log('📡 GPS module initialized');
// Assets Module Routes
app.use('/api/v1/assets', createAssetController(AppDataSource));
app.use('/api/v1/assets/assignments', createAssetAssignmentController(AppDataSource));
app.use('/api/v1/assets/audits', createAssetAuditController(AppDataSource));
app.use('/api/v1/assets/maintenance', createAssetMaintenanceController(AppDataSource));
console.log('📦 Assets module initialized');
// Dispatch Module Routes
app.use('/api/v1/dispatch', createDispatchController(AppDataSource));
app.use('/api/v1/dispatch/skills', createSkillController(AppDataSource));
app.use('/api/v1/dispatch/shifts', createShiftController(AppDataSource));
app.use('/api/v1/dispatch/rules', createRuleController(AppDataSource));
console.log('📋 Dispatch module initialized');
// Payment Terminals Module
const paymentTerminals = new PaymentTerminalsModule({ dataSource: AppDataSource });
app.use('/api/v1', paymentTerminals.router);
app.use('/webhooks', paymentTerminals.webhookRouter);
console.log('💳 Payment Terminals module initialized');
// API documentation endpoint
app.get('/api/v1', (_req, res) => {
res.json({
name: 'Mecánicas Diesel API',
version: '1.0.0',
endpoints: {
auth: '/api/v1/auth',
users: '/api/v1/users',
customers: '/api/v1/customers',
serviceOrders: '/api/v1/service-orders',
quotes: '/api/v1/quotes',
diagnostics: '/api/v1/diagnostics',
vehicles: '/api/v1/vehicles',
fleets: '/api/v1/fleets',
parts: '/api/v1/parts',
suppliers: '/api/v1/suppliers',
paymentTerminals: '/api/v1/payment-terminals',
mercadopago: '/api/v1/mercadopago',
clip: '/api/v1/clip',
gps: {
devices: '/api/v1/gps/devices',
positions: '/api/v1/gps/positions',
geofences: '/api/v1/gps/geofences',
routes: '/api/v1/gps/routes',
},
assets: {
base: '/api/v1/assets',
assignments: '/api/v1/assets/assignments',
audits: '/api/v1/assets/audits',
maintenance: '/api/v1/assets/maintenance',
},
dispatch: {
base: '/api/v1/dispatch',
skills: '/api/v1/dispatch/skills',
shifts: '/api/v1/dispatch/shifts',
rules: '/api/v1/dispatch/rules',
},
},
documentation: '/api/v1/docs',
});
});
// 404 handler
app.use((_req, res) => {
res.status(404).json({ error: 'Not Found' });
});
// Error handler
app.use((err: Error, _req: express.Request, res: express.Response, _next: express.NextFunction) => {
console.error(err.stack);
res.status(500).json({
error: 'Internal Server Error',
message: process.env.NODE_ENV === 'development' ? err.message : undefined,
});
});
// Start server
app.listen(PORT, () => {
console.log(`🔧 Mecánicas Diesel Backend running on port ${PORT}`);
console.log(`📊 Environment: ${process.env.NODE_ENV || 'development'}`);
console.log(`🏥 Health check: http://localhost:${PORT}/health`);
console.log(`📚 API Root: http://localhost:${PORT}/api/v1`);
});
} catch (error) {
console.error('Failed to start server:', error);
process.exit(1);
}
}
bootstrap();