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>
310 lines
13 KiB
TypeScript
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();
|