import 'reflect-metadata'; import { NestFactory } from '@nestjs/core'; import { ValidationPipe } from '@nestjs/common'; import { DocumentBuilder, SwaggerModule } from '@nestjs/swagger'; import { AppModule } from './app.module'; import { HttpExceptionFilter } from './common/filters/http-exception.filter'; import { ResponseTransformInterceptor } from './common/interceptors/response-transform.interceptor'; import { SessionActivityInterceptor } from './common/interceptors/session-activity.interceptor'; async function bootstrap() { const app = await NestFactory.create(AppModule); app.enableCors({ origin: [ process.env.FRONTEND_URL ?? 'http://localhost:3000', process.env.PORTAL_URL ?? 'http://localhost:3001', ], }); app.useGlobalFilters(new HttpExceptionFilter()); app.useGlobalInterceptors( new ResponseTransformInterceptor(), app.get(SessionActivityInterceptor), ); app.useGlobalPipes(new ValidationPipe({ whitelist: true, transform: true })); const config = new DocumentBuilder() .setTitle('EDR Passenger API') .setDescription( `# Ethio-Djibouti Railway Passenger Booking API ## Overview Enterprise-grade REST API for the Ethio-Djibouti Railway passenger booking and management platform. Built with NestJS, TypeScript, PostgreSQL, and Prisma ORM. ## Authentication ### Passenger Authentication (JWT-auth) Used for passenger-facing endpoints. Obtain token via \`POST /auth/login\`. **Usage:** Add header \`Authorization: Bearer \` ### Back-office Authentication (IAM-auth) Used for agent, fraud, and reporting endpoints. Requires corporate IAM token. **Usage:** Add header \`Authorization: Bearer \` ## Key Features ### 🎫 Booking Lifecycle - Search trips with real-time availability - Create bookings with seat selection - Modify bookings (seat changes, passenger updates) - Cancel bookings with automatic refunds - Multi-segment journey support ### 💳 Payment Integration - **Telebirr** - Ethiopia's leading mobile money - **CBE Birr** - Commercial Bank of Ethiopia - **eBirr** - Electronic payment gateway - **Card** - International card payments - **Wallet** - Internal wallet system ### 🪑 Seat Management - Real-time seat availability - Seat holds (15-minute expiry) - Auto-assign seats with contiguous algorithm - Seat blocking for maintenance - Coach-level seat maps ### 🎟️ Ticketing - QR code and barcode generation - PDF ticket generation - Gate validation with audit logs - Offline validation support ### 🏆 Loyalty Program - 4 tiers: Bronze, Silver, Gold, Platinum - Points accumulation on trips - Reward redemption - Tier-based benefits ### 💰 Wallet System - Top-up via payment methods - Pay with wallet balance - Transaction ledger - Refund to wallet ### 📍 Live Tracking - Real-time trip status - Location updates - Delay notifications - Station crowd signals ### 🔒 Fraud Detection - Velocity checks (multiple bookings) - High-value transaction monitoring - Failed payment pattern detection - Automatic user blocking ### 🌍 Internationalization - Multi-language support (English, Amharic, French, Oromo) - Locale-based responses - Currency formatting ### 👨‍💼 Agent Operations - Counter booking - Shift management - Commission tracking - Cash reconciliation ## Rate Limiting - Auth endpoints: 5 requests/minute - General endpoints: 100 requests/minute - Webhook endpoints: No limit ## Error Handling All errors follow standard format: \`\`\`json { "statusCode": 400, "message": "Validation failed", "error": "Bad Request", "timestamp": "2026-05-20T14:30:00.000Z", "path": "/bookings" } \`\`\` ## Pagination List endpoints support pagination: - \`limit\`: Number of items (default: 20, max: 100) - \`offset\`: Skip items (default: 0) ## Webhooks Payment providers send notifications to: - \`POST /payments/webhooks/telebirr\` - \`POST /payments/webhooks/cbe-birr\` - \`POST /payments/webhooks/ebirr\` - \`POST /payments/webhooks/card\` ## Support - **Email:** support@edr-platform.com - **Documentation:** https://docs.edr-platform.com - **Status Page:** https://status.edr-platform.com `, ) .setVersion('1.0.0') .addBearerAuth( { type: 'http', scheme: 'bearer', bearerFormat: 'JWT', in: 'header', description: 'JWT token for passenger authentication. Obtain via POST /auth/login' }, 'JWT-auth' ) .addBearerAuth( { type: 'http', scheme: 'bearer', bearerFormat: 'JWT', in: 'header', description: 'Corporate IAM token for back-office operations (agents, fraud, reports)' }, 'IAM-auth' ) .addTag('Auth', '🔐 Registration, login, OTP verification, password reset') .addTag('Agents', '👨‍💼 Agent booking, shifts, commissions, reconciliation') .addTag('Booking', '🎫 Booking lifecycle, modification, cancellation, refunds') .addTag('Dashboard', '📊 Home dashboard aggregated data') .addTag('Fleet', '🚂 Train services, coaches, seat configurations') .addTag('Fraud Detection', '🔒 Fraud detection, risk scoring, user blocking') .addTag('Live Tracking', '📍 Real-time trip status, location updates, crowd signals') .addTag('Loyalty', '🏆 Points accumulation, tier management, rewards redemption') .addTag('Notifications', '🔔 Push, email, SMS notifications, preferences') .addTag('Passenger', '👤 Profiles, traveler profiles, saved routes, preferences') .addTag('Payment', '💳 Payment intents, status queries, refunds') .addTag('Payment Webhooks', '🔗 Payment provider callback endpoints') .addTag('Promotions', '🎁 Promo codes, campaigns, discount validation') .addTag('Reports', '📈 Revenue reports, occupancy analytics, agent sales') .addTag('Schedule', '🗓️ Trip schedules, fare rules, status updates') .addTag('Search', '🔍 Trip search, availability, fare quotes') .addTag('Seats', '🪑 Seat maps, holds, releases, blocking, auto-assign') .addTag('Segment-based Seats', '🎯 Segment-based seat availability and booking') .addTag('Stations', '🚉 Station directory, information, crowd signals') .addTag('Support', '💬 FAQ management, live chat conversations') .addTag('Tickets', '🎟️ QR/barcode generation, PDF tickets, gate validation') .addTag('Wallet', '💰 Wallet balance, top-up, transaction ledger') .addServer('http://localhost:4000', 'Local Development') .addServer('https://api-staging.edr-platform.com', 'Staging Environment') .addServer('https://api.edr-platform.com', 'Production') .build(); const document = SwaggerModule.createDocument(app, config); SwaggerModule.setup('api-docs', app, document, { customSiteTitle: 'EDR Passenger API Documentation', customfavIcon: 'https://edr-platform.com/favicon.ico', customCss: ` .swagger-ui .topbar { display: none } .swagger-ui .info { margin: 20px 0 } .swagger-ui .info .title { font-size: 36px; font-weight: bold } .swagger-ui .scheme-container { background: #fafafa; padding: 15px; border-radius: 4px } `, swaggerOptions: { persistAuthorization: true, docExpansion: 'none', filter: true, tagsSorter: 'alpha', operationsSorter: 'alpha', displayRequestDuration: true, tryItOutEnabled: true, syntaxHighlight: { activate: true, theme: 'monokai' } }, }); const port = process.env.PORT ?? 4000; await app.listen(port); console.log(`🚀 EDR Passenger API running on port ${port}`); console.log(`📚 Swagger: http://localhost:${port}/api-docs`); } bootstrap();