erp-core-backend-v2/src/app.integration.ts
rckrdmrd 3ce5c6ad17 Migración desde erp-core/backend - Estándar multi-repo v2
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-16 08:10:37 -06:00

504 lines
12 KiB
TypeScript

/**
* Application Integration
*
* Integrates all modules and configures the application
*/
import express, { Express, Router } from 'express';
import { DataSource } from 'typeorm';
// Import modules
import { ProfilesModule } from './modules/profiles';
import { BranchesModule } from './modules/branches';
import { BillingUsageModule } from './modules/billing-usage';
import { PaymentTerminalsModule } from './modules/payment-terminals';
// Import new business modules
import { PartnersModule } from './modules/partners';
import { ProductsModule } from './modules/products';
import { WarehousesModule } from './modules/warehouses';
import { InventoryModule } from './modules/inventory';
import { SalesModule } from './modules/sales';
import { PurchasesModule } from './modules/purchases';
import { InvoicesModule } from './modules/invoices';
import { ReportsModule } from './modules/reports';
import { DashboardModule } from './modules/dashboard';
// Import entities from all modules for TypeORM
import {
Person,
UserProfile,
ProfileTool,
ProfileModule,
UserProfileAssignment,
} from './modules/profiles/entities';
import {
Device,
BiometricCredential,
DeviceSession,
DeviceActivityLog,
} from './modules/biometrics/entities';
import {
Branch,
UserBranchAssignment,
BranchSchedule,
BranchPaymentTerminal,
} from './modules/branches/entities';
import {
MobileSession,
OfflineSyncQueue,
PushToken,
PaymentTransaction,
} from './modules/mobile/entities';
import {
SubscriptionPlan,
TenantSubscription,
UsageTracking,
Invoice as BillingInvoice,
InvoiceItem as BillingInvoiceItem,
} from './modules/billing-usage/entities';
// Import entities from new business modules
import {
Partner,
PartnerAddress,
PartnerContact,
PartnerBankAccount,
} from './modules/partners/entities';
import {
ProductCategory,
Product,
ProductPrice,
ProductSupplier,
} from './modules/products/entities';
import {
Warehouse,
WarehouseLocation,
WarehouseZone,
} from './modules/warehouses/entities';
import {
StockLevel,
StockMovement,
InventoryCount,
InventoryCountLine,
TransferOrder,
TransferOrderLine,
} from './modules/inventory/entities';
import {
Quotation,
QuotationItem,
SalesOrder,
SalesOrderItem,
} from './modules/sales/entities';
import {
PurchaseOrder,
PurchaseOrderItem,
PurchaseReceipt,
PurchaseReceiptItem,
} from './modules/purchases/entities';
import {
Invoice,
InvoiceItem,
Payment,
PaymentAllocation,
} from './modules/invoices/entities';
/**
* Get all entities for TypeORM configuration
*/
export function getAllEntities() {
return [
// Profiles
Person,
UserProfile,
ProfileTool,
ProfileModule,
UserProfileAssignment,
// Biometrics
Device,
BiometricCredential,
DeviceSession,
DeviceActivityLog,
// Branches
Branch,
UserBranchAssignment,
BranchSchedule,
BranchPaymentTerminal,
// Mobile
MobileSession,
OfflineSyncQueue,
PushToken,
PaymentTransaction,
// Billing
SubscriptionPlan,
TenantSubscription,
UsageTracking,
BillingInvoice,
BillingInvoiceItem,
// Partners
Partner,
PartnerAddress,
PartnerContact,
PartnerBankAccount,
// Products
ProductCategory,
Product,
ProductPrice,
ProductSupplier,
// Warehouses
Warehouse,
WarehouseLocation,
WarehouseZone,
// Inventory
StockLevel,
StockMovement,
InventoryCount,
InventoryCountLine,
TransferOrder,
TransferOrderLine,
// Sales
Quotation,
QuotationItem,
SalesOrder,
SalesOrderItem,
// Purchases
PurchaseOrder,
PurchaseOrderItem,
PurchaseReceipt,
PurchaseReceiptItem,
// Invoices
Invoice,
InvoiceItem,
Payment,
PaymentAllocation,
];
}
/**
* Module configuration options
*/
export interface ModuleOptions {
profiles?: {
enabled: boolean;
basePath?: string;
};
branches?: {
enabled: boolean;
basePath?: string;
};
billing?: {
enabled: boolean;
basePath?: string;
};
payments?: {
enabled: boolean;
basePath?: string;
};
partners?: {
enabled: boolean;
basePath?: string;
};
products?: {
enabled: boolean;
basePath?: string;
};
warehouses?: {
enabled: boolean;
basePath?: string;
};
inventory?: {
enabled: boolean;
basePath?: string;
};
sales?: {
enabled: boolean;
basePath?: string;
};
purchases?: {
enabled: boolean;
basePath?: string;
};
invoices?: {
enabled: boolean;
basePath?: string;
};
reports?: {
enabled: boolean;
basePath?: string;
};
dashboard?: {
enabled: boolean;
basePath?: string;
};
}
/**
* Default module options
*/
const defaultModuleOptions: ModuleOptions = {
profiles: { enabled: true, basePath: '/api' },
branches: { enabled: true, basePath: '/api' },
billing: { enabled: true, basePath: '/api' },
payments: { enabled: true, basePath: '/api' },
partners: { enabled: true, basePath: '/api' },
products: { enabled: true, basePath: '/api' },
warehouses: { enabled: true, basePath: '/api' },
inventory: { enabled: true, basePath: '/api' },
sales: { enabled: true, basePath: '/api' },
purchases: { enabled: true, basePath: '/api' },
invoices: { enabled: true, basePath: '/api' },
reports: { enabled: true, basePath: '/api' },
dashboard: { enabled: true, basePath: '/api' },
};
/**
* Initialize and integrate all modules
*/
export function initializeModules(
app: Express,
dataSource: DataSource,
options: ModuleOptions = {}
): void {
const config = { ...defaultModuleOptions, ...options };
// Initialize Profiles Module
if (config.profiles?.enabled) {
const profilesModule = new ProfilesModule({
dataSource,
basePath: config.profiles.basePath,
});
app.use(profilesModule.router);
console.log('✅ Profiles module initialized');
}
// Initialize Branches Module
if (config.branches?.enabled) {
const branchesModule = new BranchesModule({
dataSource,
basePath: config.branches.basePath,
});
app.use(branchesModule.router);
console.log('✅ Branches module initialized');
}
// Initialize Billing Module
if (config.billing?.enabled) {
const billingModule = new BillingUsageModule({
dataSource,
basePath: config.billing.basePath,
});
app.use(billingModule.router);
console.log('✅ Billing module initialized');
}
// Initialize Payment Terminals Module
if (config.payments?.enabled) {
const paymentModule = new PaymentTerminalsModule({
dataSource,
basePath: config.payments.basePath,
});
app.use(paymentModule.router);
console.log('✅ Payment Terminals module initialized');
}
// Initialize Partners Module
if (config.partners?.enabled) {
const partnersModule = new PartnersModule({
dataSource,
basePath: config.partners.basePath,
});
app.use(partnersModule.router);
console.log('✅ Partners module initialized');
}
// Initialize Products Module
if (config.products?.enabled) {
const productsModule = new ProductsModule({
dataSource,
basePath: config.products.basePath,
});
app.use(productsModule.router);
console.log('✅ Products module initialized');
}
// Initialize Warehouses Module
if (config.warehouses?.enabled) {
const warehousesModule = new WarehousesModule({
dataSource,
basePath: config.warehouses.basePath,
});
app.use(warehousesModule.router);
console.log('✅ Warehouses module initialized');
}
// Initialize Inventory Module
if (config.inventory?.enabled) {
const inventoryModule = new InventoryModule({
dataSource,
basePath: config.inventory.basePath,
});
app.use(inventoryModule.router);
console.log('✅ Inventory module initialized');
}
// Initialize Sales Module
if (config.sales?.enabled) {
const salesModule = new SalesModule({
dataSource,
basePath: config.sales.basePath,
});
app.use(salesModule.router);
console.log('✅ Sales module initialized');
}
// Initialize Purchases Module
if (config.purchases?.enabled) {
const purchasesModule = new PurchasesModule({
dataSource,
basePath: config.purchases.basePath,
});
app.use(purchasesModule.router);
console.log('✅ Purchases module initialized');
}
// Initialize Invoices Module
if (config.invoices?.enabled) {
const invoicesModule = new InvoicesModule({
dataSource,
basePath: config.invoices.basePath,
});
app.use(invoicesModule.router);
console.log('✅ Invoices module initialized');
}
// Initialize Reports Module
if (config.reports?.enabled) {
const reportsModule = new ReportsModule({
dataSource,
basePath: config.reports.basePath,
});
app.use(reportsModule.router);
console.log('✅ Reports module initialized');
}
// Initialize Dashboard Module
if (config.dashboard?.enabled) {
const dashboardModule = new DashboardModule({
dataSource,
basePath: config.dashboard.basePath,
});
app.use(dashboardModule.router);
console.log('✅ Dashboard module initialized');
}
}
/**
* Create TypeORM DataSource configuration
*/
export function createDataSourceConfig(options: {
host: string;
port: number;
username: string;
password: string;
database: string;
ssl?: boolean;
logging?: boolean;
}) {
return {
type: 'postgres' as const,
host: options.host,
port: options.port,
username: options.username,
password: options.password,
database: options.database,
ssl: options.ssl ? { rejectUnauthorized: false } : false,
logging: options.logging ?? false,
entities: getAllEntities(),
synchronize: false, // Use migrations instead
migrations: ['src/migrations/*.ts'],
};
}
/**
* Example application setup
*/
export async function createApplication(dataSourceConfig: any): Promise<Express> {
// Create Express app
const app = express();
// Middleware
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
// CORS middleware (configure for production)
app.use((req, res, next) => {
res.header('Access-Control-Allow-Origin', '*');
res.header('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, PATCH, OPTIONS');
res.header('Access-Control-Allow-Headers', 'Content-Type, Authorization, X-Tenant-ID');
if (req.method === 'OPTIONS') {
res.sendStatus(200);
return;
}
next();
});
// Initialize database
const dataSource = new DataSource(dataSourceConfig);
await dataSource.initialize();
console.log('✅ Database connected');
// Initialize all modules
initializeModules(app, dataSource);
// Health check endpoint
app.get('/health', (req, res) => {
res.json({
status: 'healthy',
timestamp: new Date().toISOString(),
modules: {
profiles: true,
branches: true,
billing: true,
payments: true,
partners: true,
products: true,
warehouses: true,
inventory: true,
sales: true,
purchases: true,
invoices: true,
reports: true,
dashboard: true,
},
});
});
// Error handling middleware
app.use((err: any, req: express.Request, res: express.Response, next: express.NextFunction) => {
console.error('Error:', err);
res.status(err.status || 500).json({
error: err.message || 'Internal Server Error',
code: err.code || 'INTERNAL_ERROR',
});
});
return app;
}
export default {
getAllEntities,
initializeModules,
createDataSourceConfig,
createApplication,
};