erp-construccion-backend-v2/src/server.ts
Adrian Flores Cortes bdf8c878e8 [PROP-CORE-004] feat: Register payment-terminals module in app
- Added PaymentTerminalsModule import and initialization
- Registered routes: /api/v1/payment-terminals, /api/v1/mercadopago, /api/v1/clip
- Registered webhooks: /webhooks/mercadopago, /webhooks/clip
- Updated API info with new endpoints

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-25 03:13:46 -06:00

375 lines
16 KiB
TypeScript

/**
* Server Entry Point
* MVP Sistema Administración de Obra e INFONAVIT
*
* @author Backend-Agent
* @date 2025-11-20
*/
import 'reflect-metadata';
import express, { Application } from 'express';
import cors from 'cors';
import helmet from 'helmet';
import morgan from 'morgan';
import dotenv from 'dotenv';
import { AppDataSource } from './shared/database/typeorm.config';
import { PaymentTerminalsModule } from './modules/payment-terminals';
// Cargar variables de entorno
dotenv.config();
const app: Application = express();
const PORT = process.env.APP_PORT || 3000;
const API_VERSION = process.env.API_VERSION || 'v1';
/**
* Middlewares
*/
app.use(helmet()); // Seguridad HTTP headers
app.use(cors({
origin: process.env.CORS_ORIGIN?.split(',') || '*',
credentials: process.env.CORS_CREDENTIALS === 'true',
}));
app.use(morgan(process.env.LOG_FORMAT || 'dev')); // Logging
app.use(express.json()); // Parse JSON bodies
app.use(express.urlencoded({ extended: true })); // Parse URL-encoded bodies
/**
* Health Check
*/
app.get('/health', (_req, res) => {
res.status(200).json({
status: 'ok',
timestamp: new Date().toISOString(),
environment: process.env.NODE_ENV || 'development',
version: API_VERSION,
});
});
/**
* API Routes
*/
import { proyectoController, fraccionamientoController, createEtapaController, createManzanaController, createLoteController, createPrototipoController } from './modules/construction/controllers';
import { createAuthController } from './modules/auth/controllers/auth.controller';
import { createUsersController } from './modules/users/controllers/users.controller';
import { createConceptoController, createPresupuestoController } from './modules/budgets/controllers';
import { createAvanceObraController, createBitacoraObraController } from './modules/progress/controllers';
import { createEstimacionController, createAnticipoController, createFondoGarantiaController, createRetencionController } from './modules/estimates/controllers';
import { createPuestoController, createEmployeeController } from './modules/hr/controllers';
import { createCapacitacionController, createIncidenteController } from './modules/hse/controllers';
import { createRequisicionController, createConsumoObraController } from './modules/inventory/controllers';
import { createComparativoController } from './modules/purchase/controllers';
import { createDerechohabienteController, createAsignacionController } from './modules/infonavit/controllers';
import { createInspectionController, createTicketController } from './modules/quality/controllers';
import { createContractController, createSubcontractorController } from './modules/contracts/controllers';
import { createReportController, createDashboardController, createKpiController } from './modules/reports/controllers';
import { createCostCenterController, createAuditLogController, createSystemSettingController, createBackupController } from './modules/admin/controllers';
import { createOpportunityController, createBidController, createBidBudgetController, createBidAnalyticsController } from './modules/bidding/controllers';
import { createAccountingController, createAPController, createARController, createCashFlowController, createBankReconciliationController, createReportsController } from './modules/finance/controllers';
// Root API info
app.get(`/api/${API_VERSION}`, (_req, res) => {
res.status(200).json({
message: 'API MVP Sistema Administración de Obra',
version: API_VERSION,
endpoints: {
health: '/health',
docs: `/api/${API_VERSION}/docs`,
auth: `/api/${API_VERSION}/auth`,
users: `/api/${API_VERSION}/users`,
proyectos: `/api/${API_VERSION}/proyectos`,
fraccionamientos: `/api/${API_VERSION}/fraccionamientos`,
etapas: `/api/${API_VERSION}/etapas`,
manzanas: `/api/${API_VERSION}/manzanas`,
lotes: `/api/${API_VERSION}/lotes`,
prototipos: `/api/${API_VERSION}/prototipos`,
conceptos: `/api/${API_VERSION}/conceptos`,
presupuestos: `/api/${API_VERSION}/presupuestos`,
avances: `/api/${API_VERSION}/avances`,
bitacora: `/api/${API_VERSION}/bitacora`,
estimaciones: `/api/${API_VERSION}/estimaciones`,
anticipos: `/api/${API_VERSION}/anticipos`,
'fondos-garantia': `/api/${API_VERSION}/fondos-garantia`,
retenciones: `/api/${API_VERSION}/retenciones`,
puestos: `/api/${API_VERSION}/puestos`,
empleados: `/api/${API_VERSION}/empleados`,
capacitaciones: `/api/${API_VERSION}/capacitaciones`,
incidentes: `/api/${API_VERSION}/incidentes`,
requisiciones: `/api/${API_VERSION}/requisiciones`,
consumos: `/api/${API_VERSION}/consumos`,
comparativos: `/api/${API_VERSION}/comparativos`,
derechohabientes: `/api/${API_VERSION}/derechohabientes`,
asignaciones: `/api/${API_VERSION}/asignaciones`,
inspections: `/api/${API_VERSION}/inspections`,
tickets: `/api/${API_VERSION}/tickets`,
contracts: `/api/${API_VERSION}/contracts`,
subcontractors: `/api/${API_VERSION}/subcontractors`,
reports: `/api/${API_VERSION}/reports`,
dashboards: `/api/${API_VERSION}/dashboards`,
kpis: `/api/${API_VERSION}/kpis`,
'cost-centers': `/api/${API_VERSION}/cost-centers`,
'audit-logs': `/api/${API_VERSION}/audit-logs`,
settings: `/api/${API_VERSION}/settings`,
backups: `/api/${API_VERSION}/backups`,
opportunities: `/api/${API_VERSION}/opportunities`,
bids: `/api/${API_VERSION}/bids`,
'bid-budgets': `/api/${API_VERSION}/bid-budgets`,
'bid-analytics': `/api/${API_VERSION}/bid-analytics`,
accounting: `/api/${API_VERSION}/accounting`,
'accounts-payable': `/api/${API_VERSION}/accounts-payable`,
'accounts-receivable': `/api/${API_VERSION}/accounts-receivable`,
'cash-flow': `/api/${API_VERSION}/cash-flow`,
'bank-reconciliation': `/api/${API_VERSION}/bank-reconciliation`,
'financial-reports': `/api/${API_VERSION}/financial-reports`,
'payment-terminals': `/api/${API_VERSION}/payment-terminals`,
mercadopago: `/api/${API_VERSION}/mercadopago`,
clip: `/api/${API_VERSION}/clip`,
},
});
});
// Construction Module Routes
app.use(`/api/${API_VERSION}/proyectos`, proyectoController);
app.use(`/api/${API_VERSION}/fraccionamientos`, fraccionamientoController);
// Auth y Users Module Routes - Se inicializan después de la conexión a BD
let authController: ReturnType<typeof createAuthController>;
let usersController: ReturnType<typeof createUsersController>;
/**
* 404 Handler
*/
app.use((req, res) => {
res.status(404).json({
error: 'Not Found',
message: `Cannot ${req.method} ${req.path}`,
});
});
/**
* Error Handler
*/
app.use((err: Error, _req: express.Request, res: express.Response, _next: express.NextFunction) => {
console.error('Error:', err);
res.status(500).json({
error: 'Internal Server Error',
message: process.env.NODE_ENV === 'development' ? err.message : 'Something went wrong',
});
});
/**
* Inicializar Base de Datos y Servidor
*/
async function bootstrap() {
try {
// Conectar a base de datos
console.log('🔌 Conectando a base de datos...');
await AppDataSource.initialize();
console.log('✅ Base de datos conectada');
// Inicializar Auth Controller (requiere DataSource)
authController = createAuthController(AppDataSource);
app.use(`/api/${API_VERSION}/auth`, authController);
console.log('🔐 Auth module inicializado');
// Inicializar Users Controller (requiere DataSource)
usersController = createUsersController(AppDataSource);
app.use(`/api/${API_VERSION}/users`, usersController);
console.log('👥 Users module inicializado');
// Inicializar Construction Controllers (requieren DataSource para auth)
const etapaController = createEtapaController(AppDataSource);
app.use(`/api/${API_VERSION}/etapas`, etapaController);
const manzanaController = createManzanaController(AppDataSource);
app.use(`/api/${API_VERSION}/manzanas`, manzanaController);
const loteController = createLoteController(AppDataSource);
app.use(`/api/${API_VERSION}/lotes`, loteController);
const prototipoController = createPrototipoController(AppDataSource);
app.use(`/api/${API_VERSION}/prototipos`, prototipoController);
console.log('🏗️ Construction module inicializado');
// Inicializar Budgets Controllers (requieren DataSource para auth)
const conceptoController = createConceptoController(AppDataSource);
app.use(`/api/${API_VERSION}/conceptos`, conceptoController);
const presupuestoController = createPresupuestoController(AppDataSource);
app.use(`/api/${API_VERSION}/presupuestos`, presupuestoController);
console.log('💰 Budgets module inicializado');
// Inicializar Progress Controllers (requieren DataSource para auth)
const avanceObraController = createAvanceObraController(AppDataSource);
app.use(`/api/${API_VERSION}/avances`, avanceObraController);
const bitacoraObraController = createBitacoraObraController(AppDataSource);
app.use(`/api/${API_VERSION}/bitacora`, bitacoraObraController);
console.log('📊 Progress module inicializado');
// Inicializar Estimates Controllers (requieren DataSource para auth)
const estimacionController = createEstimacionController(AppDataSource);
app.use(`/api/${API_VERSION}/estimaciones`, estimacionController);
const anticipoController = createAnticipoController(AppDataSource);
app.use(`/api/${API_VERSION}/anticipos`, anticipoController);
const fondoGarantiaController = createFondoGarantiaController(AppDataSource);
app.use(`/api/${API_VERSION}/fondos-garantia`, fondoGarantiaController);
const retencionController = createRetencionController(AppDataSource);
app.use(`/api/${API_VERSION}/retenciones`, retencionController);
console.log('📝 Estimates module inicializado');
// Inicializar HR Controllers (requieren DataSource para auth)
const puestoController = createPuestoController(AppDataSource);
app.use(`/api/${API_VERSION}/puestos`, puestoController);
const employeeController = createEmployeeController(AppDataSource);
app.use(`/api/${API_VERSION}/empleados`, employeeController);
console.log('👷 HR module inicializado');
// Inicializar HSE Controllers (requieren DataSource para auth)
const capacitacionController = createCapacitacionController(AppDataSource);
app.use(`/api/${API_VERSION}/capacitaciones`, capacitacionController);
const incidenteController = createIncidenteController(AppDataSource);
app.use(`/api/${API_VERSION}/incidentes`, incidenteController);
console.log('🦺 HSE module inicializado');
// Inicializar Inventory Controllers (requieren DataSource para auth)
const requisicionController = createRequisicionController(AppDataSource);
app.use(`/api/${API_VERSION}/requisiciones`, requisicionController);
const consumoObraController = createConsumoObraController(AppDataSource);
app.use(`/api/${API_VERSION}/consumos`, consumoObraController);
console.log('📦 Inventory module inicializado');
// Inicializar Purchase Controllers (requieren DataSource para auth)
const comparativoController = createComparativoController(AppDataSource);
app.use(`/api/${API_VERSION}/comparativos`, comparativoController);
console.log('🛒 Purchase module inicializado');
// Inicializar Infonavit Controllers (requieren DataSource para auth)
const derechohabienteController = createDerechohabienteController(AppDataSource);
app.use(`/api/${API_VERSION}/derechohabientes`, derechohabienteController);
const asignacionController = createAsignacionController(AppDataSource);
app.use(`/api/${API_VERSION}/asignaciones`, asignacionController);
console.log('🏠 Infonavit module inicializado');
// Inicializar Quality Controllers (requieren DataSource para auth)
const inspectionController = createInspectionController(AppDataSource);
app.use(`/api/${API_VERSION}/inspections`, inspectionController);
const ticketController = createTicketController(AppDataSource);
app.use(`/api/${API_VERSION}/tickets`, ticketController);
console.log('✅ Quality module inicializado');
// Inicializar Contracts Controllers (requieren DataSource para auth)
const contractController = createContractController(AppDataSource);
app.use(`/api/${API_VERSION}/contracts`, contractController);
const subcontractorController = createSubcontractorController(AppDataSource);
app.use(`/api/${API_VERSION}/subcontractors`, subcontractorController);
console.log('📄 Contracts module inicializado');
// Inicializar Reports Controllers (requieren DataSource para auth)
const reportController = createReportController(AppDataSource);
app.use(`/api/${API_VERSION}/reports`, reportController);
const dashboardController = createDashboardController(AppDataSource);
app.use(`/api/${API_VERSION}/dashboards`, dashboardController);
const kpiController = createKpiController(AppDataSource);
app.use(`/api/${API_VERSION}/kpis`, kpiController);
console.log('📈 Reports module inicializado');
// Inicializar Admin Controllers (requieren DataSource para auth)
const costCenterController = createCostCenterController(AppDataSource);
app.use(`/api/${API_VERSION}/cost-centers`, costCenterController);
const auditLogController = createAuditLogController(AppDataSource);
app.use(`/api/${API_VERSION}/audit-logs`, auditLogController);
const systemSettingController = createSystemSettingController(AppDataSource);
app.use(`/api/${API_VERSION}/settings`, systemSettingController);
const backupController = createBackupController(AppDataSource);
app.use(`/api/${API_VERSION}/backups`, backupController);
console.log('⚙️ Admin module inicializado');
// Inicializar Bidding Controllers (requieren DataSource para auth)
const opportunityController = createOpportunityController(AppDataSource);
app.use(`/api/${API_VERSION}/opportunities`, opportunityController);
const bidController = createBidController(AppDataSource);
app.use(`/api/${API_VERSION}/bids`, bidController);
const bidBudgetController = createBidBudgetController(AppDataSource);
app.use(`/api/${API_VERSION}/bid-budgets`, bidBudgetController);
const bidAnalyticsController = createBidAnalyticsController(AppDataSource);
app.use(`/api/${API_VERSION}/bid-analytics`, bidAnalyticsController);
console.log('📋 Bidding module inicializado');
// Inicializar Finance Controllers (requieren DataSource para auth)
const accountingController = createAccountingController(AppDataSource);
app.use(`/api/${API_VERSION}/accounting`, accountingController);
const apController = createAPController(AppDataSource);
app.use(`/api/${API_VERSION}/accounts-payable`, apController);
const arController = createARController(AppDataSource);
app.use(`/api/${API_VERSION}/accounts-receivable`, arController);
const cashFlowController = createCashFlowController(AppDataSource);
app.use(`/api/${API_VERSION}/cash-flow`, cashFlowController);
const bankReconciliationController = createBankReconciliationController(AppDataSource);
app.use(`/api/${API_VERSION}/bank-reconciliation`, bankReconciliationController);
const financialReportsController = createReportsController(AppDataSource);
app.use(`/api/${API_VERSION}/financial-reports`, financialReportsController);
console.log('💵 Finance module inicializado');
// Inicializar Payment Terminals Module
const paymentTerminals = new PaymentTerminalsModule({ dataSource: AppDataSource });
app.use(`/api/${API_VERSION}`, paymentTerminals.router);
app.use('/webhooks', paymentTerminals.webhookRouter);
console.log('💳 Payment Terminals module inicializado');
// Iniciar servidor
app.listen(PORT, () => {
console.log('🚀 Servidor iniciado');
console.log(`📍 URL: http://localhost:${PORT}`);
console.log(`📍 API: http://localhost:${PORT}/api/${API_VERSION}`);
console.log(`📍 Health: http://localhost:${PORT}/health`);
console.log(`🌍 Entorno: ${process.env.NODE_ENV || 'development'}`);
});
} catch (error) {
console.error('❌ Error al iniciar servidor:', error);
process.exit(1);
}
}
// Iniciar aplicación
bootstrap();
export default app;