27 KiB
EDR Platform - Ethio-Djibouti Railway Passenger API
Enterprise-grade NestJS REST API for the Ethio-Djibouti Railway passenger booking and management platform. Built with TypeScript, PostgreSQL, and Prisma ORM.
🚀 Features
🆕 NEW: Age-Based Pricing, Verifayda 2.0 & Multi-Currency
Age-Based Pricing
- ADULT (≥5 years): Pay 100% of base fare
- CHILD (<5 years): First child travels FREE, subsequent children pay 100%
- Automatic age calculation from date of birth
- Example: 2 adults + 3 children = 4× base fare (first child free)
Verifayda 2.0 Integration
- Real-time Ethiopian national ID verification
- Retrieves passenger data from government database
- National IDs NOT stored (policy compliant)
- Non-Ethiopians use passport (no verification required)
- Booking fails if verification unsuccessful
Multi-Currency Support
- Transaction Currency: ETB (Ethiopian Birr)
- Display Currencies: ETB, DJF (Djiboutian Franc), USD (US Dollar)
- Real-time exchange rate conversion
- Prices shown in user's preferred currency
- Exchange rates: ETB→DJF=3.25, ETB→USD=0.018
Core Modules
- Authentication & Authorization - Dual authentication system:
- Passenger Auth: JWT-based auth with OTP verification, password reset, account lockout
- Corporate IAM: Integration with @tria-plc corporate identity system for back-office operations (agents, supervisors, admins)
- Role-based access control (RBAC) with granular permissions
- Age-Based Pricing - Smart passenger categorization:
- ADULT (≥5 years): Full fare
- CHILD (<5 years): First child free, subsequent children full fare
- Automatic age calculation from date of birth
- Verifayda 2.0 Integration - Ethiopian national ID verification:
- Real-time verification via government API
- Retrieves passenger data (name, DOB, nationality)
- National IDs NOT stored (policy compliant)
- Non-Ethiopians use passport (no verification)
- Multi-Currency Support - Display prices in multiple currencies:
- ETB (Ethiopian Birr) - Transaction currency
- DJF (Djiboutian Franc) - Display option
- USD (US Dollar) - Display option
- Real-time exchange rate conversion
- Booking Management - Complete booking lifecycle:
- Guest Booking: Book without login, optional account creation
- Saved Passengers: Store passenger details for quick rebooking
- Modification, cancellation, refunds, and fare breakdown
- Multi-segment journey support
- Payment Integration - Multi-provider support (Telebirr, CBE Birr, eBirr, Card, Wallet) with webhook handling
- Seat Management - Real-time seat inventory:
- Seat holds with 5-minute expiry
- Seat releases and blocking with coach/class management
- Segment-based seat availability (partial journey bookings)
- Auto-assign seats with contiguous algorithm
- CSV import/export for seat configurations
- Ticketing - QR code and barcode generation, PDF tickets, gate validation with audit logs
- Agent Operations - Counter booking, shift management, commission tracking, and reconciliation
- Passenger Services - Profile management, traveler profiles, saved routes, and preferences
- Loyalty Program - Points accumulation, tier management (Bronze/Silver/Gold/Platinum), and rewards
- Wallet System - Balance management, top-up, transaction ledger
- Live Tracking - Real-time trip status, location updates, delay notifications, crowd signals
- Notifications - Multi-channel (Email, SMS, Push) with templating engine
- Support System - FAQ management, live chat conversations
- Reports & Analytics - Revenue reports, occupancy analytics, agent sales tracking
- Route Management - Route configuration, stops, fare rules, baggage allowance
Technical Features
- Security - Password hashing (bcrypt), JWT tokens, rate limiting, audit logging
- Validation - Request validation with class-validator, DTO transformation
- Documentation - Auto-generated Swagger/OpenAPI docs at
/api-docs - Error Handling - Global exception filters with standardized error responses
- Database - PostgreSQL with Prisma ORM, migrations, and comprehensive seeding
- Scheduling - Cron jobs for automated tasks (seat release, report generation)
- Event System - Event-driven architecture with @nestjs/event-emitter
📋 Prerequisites
- Node.js >= 20.x
- pnpm >= 9.x (
npm install -g pnpm) - PostgreSQL >= 15.x
- Git
🛠️ Installation & Setup
1. Clone Repository
git clone <repository-url>
cd edr-platform
2. Install Dependencies
pnpm install
3. Environment Configuration
# Copy environment template
cp apps/edr-passenger-api/.env.example apps/edr-passenger-api/.env
# Edit .env file with your configuration
Required Environment Variables
| Variable | Description | Example |
|---|---|---|
NODE_ENV |
Environment mode | development |
PORT |
HTTP server port | 4000 |
DATABASE_URL |
PostgreSQL connection string | postgresql://user:pass@localhost:5432/edr_passenger |
JWT_SECRET |
JWT signing secret (change in production) | your-secret-key |
JWT_EXPIRES_IN |
JWT token expiry | 7d |
PORTAL_URL |
Web app CORS origin | http://localhost:3000 |
BACK_OFFICE_URL |
Admin portal CORS origin | http://localhost:3001 |
SENDGRID_API_KEY |
SendGrid API key (optional) | SG.xxx |
SENDGRID_FROM_EMAIL |
Email sender address | noreply@edr-platform.com |
Verifayda 2.0 Configuration (Ethiopian National ID Verification)
| Variable | Description | Example |
|---|---|---|
VERIFAYDA_ENABLED |
Enable Verifayda integration | true or false |
VERIFAYDA_API_URL |
Verifayda API endpoint | https://api.verifayda.gov.et/v2 |
VERIFAYDA_API_KEY |
API key for Verifayda service | your-verifayda-api-key |
Note: When VERIFAYDA_ENABLED=false, verification is skipped (development mode only).
Corporate IAM Configuration (Back-office Authentication)
| Variable | Description | Example |
|---|---|---|
IAM_ENABLED |
Enable corporate IAM integration | true or false |
IAM_API_URL |
Corporate IAM API endpoint | https://iam.tria-plc.com/api |
IAM_API_KEY |
API key for IAM service | your-iam-api-key |
Note: When IAM_ENABLED=false, IAM-protected routes allow access without validation (development mode only).
Optional: Payment Provider Configuration
# Telebirr Configuration
TELEBIRR_BASE_URL=https://api.telebirr.com
TELEBIRR_MERCHANT_CODE=your-merchant-code
TELEBIRR_APP_SECRET=your-app-secret
# ... see .env.example for complete list
4. Database Setup
Start PostgreSQL
# Using Docker (recommended)
docker run --name edr-postgres \
-e POSTGRES_USER=edr \
-e POSTGRES_PASSWORD=edr_secret \
-e POSTGRES_DB=edr_passenger \
-p 5432:5432 \
-d postgres:15
# Or use your local PostgreSQL installation
Generate Prisma Client
pnpm --filter @edr/passenger-api run prisma:generate
Run Migrations
pnpm --filter @edr/passenger-api run prisma:migrate:dev
Seed Database
pnpm --filter @edr/passenger-api run prisma:seed
Seed Data Includes:
- 21 Stations (Complete Ethiopian-Djibouti Railway with country codes)
- 1 Route with 21 stops and fare rules
- 2 Train services with 4 trips
- 360 seats across 12 coaches (Economy Regular, Economy Bed, VIP Bed classes)
- 3 User accounts (Admin, Passenger, Agent)
- Fare rules for ADULT and CHILD passenger categories
- Currency exchange rates (ETB, DJF, USD)
- Baggage allowance rules
- Notification templates
- Promotions and FAQ content
- Menu items and station crowd signals
- Fraud detection rules
- Saved passenger profiles for testing
5. Start Development Server
pnpm --filter @edr/passenger-api run dev
API Server: http://localhost:4000
Swagger Docs: http://localhost:4000/api-docs
🔑 Default Credentials
After seeding, use these credentials to test the API:
| Role | Password | Description | |
|---|---|---|---|
| Admin | admin@edr-platform.com |
admin123 |
Full system access, reports, agent management |
| Passenger | kelemu@email.com |
password123 |
Regular user with loyalty (Silver) and wallet |
| Agent | agent@edr-platform.com |
agent123 |
Counter booking agent with commission tracking |
📚 API Documentation
Swagger UI
Interactive API documentation available at: http://localhost:4000/api-docs
Authentication Methods
The API uses two authentication schemes:
1. JWT Authentication (Passenger-facing)
- Used for: Passenger bookings, profile management, wallet, loyalty
- Header:
Authorization: Bearer <jwt-token> - Obtain token:
POST /auth/loginwith passenger credentials - Swagger Security:
JWT-auth
2. IAM Authentication (Back-office)
- Used for: Agent operations, fraud detection, reports, admin functions
- Header:
Authorization: Bearer <iam-token> - Obtain token: From corporate IAM system (https://iam.tria-plc.com)
- Swagger Security:
IAM-auth - Roles: AGENT, SUPERVISOR, ADMIN, STAFF
API Endpoints Overview
| Module | Base Path | Auth Type | Description |
|---|---|---|---|
| Auth | /auth |
Public/JWT | Register, login, OTP verification, password reset |
| Passengers | /passengers |
Public/JWT | Verifayda verification, international registration, profiles |
| Search | /search |
Public | Trip search, availability, fare quotes |
| Stations | /stations |
Public/JWT | Station directory and information |
| Seats | /seats |
JWT/IAM | Seat maps, holds, releases, blocking |
| Bookings | /bookings |
Public/JWT | Guest booking, create, modify, cancel bookings |
| Payments | /payments |
JWT/Public | Payment initiation, webhooks, refunds |
| Tickets | /tickets |
JWT/IAM | Ticket generation, QR/barcode, validation |
| Notifications | /notifications |
JWT | In-app notifications, preferences |
| Loyalty | /loyalty |
JWT | Points, tiers, rewards redemption |
| Wallet | /wallet |
JWT | Balance, top-up, transaction history |
| Promotions | /promos |
Public/JWT | Active promotions, promo code validation |
| Live Tracking | /live |
Public/JWT | Real-time trip status, crowd signals |
| Support | /support |
Public/JWT | FAQ, chat conversations |
| Dashboard | /dashboard |
JWT | Home screen aggregated data |
| Routes | /routes |
JWT/IAM | Reusable route templates with ordered stops |
| Schedules | /schedules |
JWT/IAM | Trip schedules, fare rules, status updates |
| Fleet | /fleet |
JWT/IAM | Train services, coaches, seat configurations |
| Seat Classes | /seat-classes or /classes |
Public/JWT/IAM | Seat class management and configuration |
| Segment Seats | /segments/seats |
Public/JWT | Segment-based seat availability and booking |
| Agents | /agents |
IAM | Agent booking, shifts, commissions, reconciliation |
| Fraud Detection | /fraud |
IAM | Fraud alerts, rules management, user blocking |
| Reports | /reports |
IAM | Revenue, occupancy, agent sales analytics |
Example API Calls
1. Register Passenger
POST /auth/register
Content-Type: application/json
{
"email": "user@example.com",
"phone": "+251911234567",
"fullName": "John Doe",
"password": "SecurePass123"
}
2. Login (Passenger)
POST /auth/login
Content-Type: application/json
{
"email": "user@example.com",
"password": "SecurePass123"
}
# Response includes JWT token
{
"accessToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"user": { "id": "uuid", "role": "PASSENGER" }
}
3. Verify Ethiopian National ID (Verifayda)
POST /passengers/verify-fayda
Content-Type: application/json
{
"nationalId": "ET123456789"
}
# Response with verified passenger data
{
"verified": true,
"passengerData": {
"fullName": "Abebe Kebede",
"dateOfBirth": "1985-03-15T00:00:00.000Z",
"gender": "Male",
"nationality": "Ethiopian"
}
}
4. Universal Passenger Registration (NEW)
# Guest Ethiopian with Fayda verification
POST /passengers/register
Content-Type: application/json
{
"passengerName": "Abebe Kebede",
"dateOfBirth": "1985-03-15",
"nationalId": "ET123456789",
"phone": "+251911234567",
"deviceId": "device-uuid-123"
}
# Logged-in user with JWT token
POST /passengers/register
Authorization: Bearer <jwt-token>
Content-Type: application/json
{
"passengerName": "Abebe Kebede",
"dateOfBirth": "1985-03-15",
"nationalId": "ET123456789",
"phone": "+251911234567"
}
# International passenger (passport)
POST /passengers/register
Content-Type: application/json
{
"passengerName": "John Smith",
"dateOfBirth": "1990-07-20",
"passportNumber": "P1234567",
"passportCountry": "Kenya",
"nationality": "Kenyan",
"phone": "+254712345678",
"email": "john@example.com",
"deviceId": "device-uuid-123"
}
5. Get User Profile (NEW)
GET /auth/profile
Authorization: Bearer <jwt-token>
# Response includes user, passenger, loyalty, and wallet details
{
"id": "uuid",
"email": "user@example.com",
"phone": "+251911234567",
"fullName": "John Doe",
"role": "PASSENGER",
"nationality": "Ethiopian",
"faydaVerified": true,
"faydaVerifiedAt": "2024-01-15T10:30:00.000Z",
"passenger": {
"id": "uuid",
"loyalty": {
"tier": "SILVER",
"pointsBalance": 1500,
"lifetimePoints": 3000
},
"wallet": {
"balanceMinor": 50000,
"currency": "ETB"
}
}
}
6. Search Trips
POST /search
Content-Type: application/json
{
"originStationId": "uuid",
"destinationStationId": "uuid",
"date": "2026-06-15",
"adultCount": 2,
"childCount": 1
}
7. Get Fare Quote
POST /search/fare-quote
Content-Type: application/json
{
"tripId": "uuid",
"serviceClass": "ECONOMY_REGULAR",
"adultCount": 2,
"childCount": 1,
"displayCurrency": "USD"
}
# Response includes age-based pricing breakdown
{
"baseFareMinor": 35000,
"adultCount": 2,
"adultFareMinor": 70000,
"childCount": 1,
"freeChildrenCount": 1,
"paidChildrenCount": 0,
"childFareMinor": 0,
"totalMinor": 73500,
"currency": "ETB",
"displayCurrency": "USD",
"displayTotalMinor": 1323
}
8. Guest Booking (No Login Required)
POST /bookings/guest
Content-Type: application/json
{
"tripId": "uuid",
"holdId": "uuid",
"serviceClass": "ECONOMY_REGULAR",
"displayCurrency": "ETB",
"passengers": [
{
"seatId": "uuid",
"passengerName": "Abebe Kebede",
"dateOfBirth": "1985-03-15",
"idDocumentType": "NATIONAL_ID",
"idDocumentNumber": "ET123456789"
}
],
"createAccount": false,
"savePassengerDetails": true,
"deviceId": "device-uuid"
}
9. Agent Booking (IAM Auth)
POST /agents/bookings
Authorization: Bearer <iam-token>
Content-Type: application/json
{
"tripId": "uuid",
"seats": [...],
"paymentMethod": "CASH",
"cashReceived": 50000
}
🏗️ Project Structure
apps/edr-passenger-api/
├── prisma/
│ ├── schema.prisma # Database schema (40+ models)
│ ├── seed.ts # Comprehensive seed script
│ └── migrations/ # Database migrations
├── src/
│ ├── common/ # Shared utilities
│ │ ├── filters/ # Exception filters
│ │ ├── interceptors/ # Response interceptors
│ │ ├── pipes/ # Validation pipes
│ │ ├── i18n/ # Internationalization
│ │ ├── jwt.guard.ts # JWT authentication guard (passengers)
│ │ ├── jwt.strategy.ts # Passport JWT strategy
│ │ ├── iam-adapter.ts # Corporate IAM guard (back-office)
│ │ ├── iam.module.ts # IAM module
│ │ ├── roles.guard.ts # RBAC authorization guard
│ │ ├── roles.decorator.ts # Roles decorator
│ │ ├── prisma.service.ts # Prisma client service
│ │ └── prisma.module.ts # Prisma module
│ ├── config/ # Configuration files
│ │ ├── app.config.ts # App configuration
│ │ ├── database.config.ts # Database configuration
│ │ └── telebirr.config.ts # Payment provider config
│ ├── modules/ # Feature modules
│ │ ├── auth/ # Authentication & authorization (JWT)
│ │ ├── agents/ # Agent operations (IAM-protected)
│ │ ├── bookings/ # Booking management (JWT)
│ │ ├── currency/ # Currency conversion service
│ │ ├── dashboard/ # Dashboard aggregations (JWT)
│ │ ├── fleet/ # Train fleet management (JWT/IAM)
│ │ ├── fraud/ # Fraud detection (IAM-protected)
│ │ ├── live/ # Live tracking (JWT)
│ │ ├── loyalty/ # Loyalty program (JWT)
│ │ ├── notifications/ # Notification system (JWT)
│ │ ├── passengers/ # Passenger management (JWT)
│ │ ├── payments/ # Payment processing (JWT/Webhooks)
│ │ ├── promos/ # Promotions (JWT)
│ │ ├── reports/ # Reports & analytics (IAM-protected)
│ │ ├── schedules/ # Trip schedules (JWT/IAM)
│ │ ├── search/ # Trip search (JWT)
│ │ ├── seats/ # Seat management (JWT/IAM)
│ │ ├── segments/ # Journey segments (JWT)
│ │ ├── stations/ # Station management (JWT)
│ │ ├── support/ # Customer support (JWT)
│ │ ├── tickets/ # Ticketing (JWT/IAM)
│ │ ├── verifayda/ # Verifayda 2.0 integration
│ │ └── wallet/ # Wallet system (JWT)
│ ├── app.module.ts # Root application module
│ └── main.ts # Application entry point
├── test/ # E2E tests
├── .env.example # Environment template
├── Dockerfile # Docker configuration
├── nest-cli.json # NestJS CLI configuration
├── package.json # Dependencies & scripts
├── tsconfig.json # TypeScript configuration
└── tsconfig.build.json # Build configuration
🗄️ Database Schema
Key Models (40+ total)
Core Entities:
User,Session,Passenger,AgentStation,Route,RouteStop,RouteFareRuleTrainService,Trip,TripStopTime,Coach,SeatBooking,BookingSeat,TicketPaymentIntent,PaymentRefund,PaymentWebhookEvent
Enhanced Features:
OtpCode,PasswordResetToken(Auth)AgentBooking,AgentShift,AgentCommission(Agents)BookingModification,BookingCancellation(Booking lifecycle)GateValidationLog(Ticket validation)BaggageAllowance,BaggageBooking(Baggage)LoyaltyAccount,LoyaltyLedgerEntry,LoyaltyRewardWalletAccount,WalletLedgerEntryNotification,NotificationTemplateAuditLog,OperationalReportSeatBlock,SeatHoldCurrencyExchangeRate(Multi-currency)VerifaydaVerification(National ID verification)SavedPassengerProfile(Guest booking)SeatClass(Seat class configuration)JourneySegment(Multi-segment journeys)
🔧 Available Scripts
# Development
pnpm --filter @edr/passenger-api run dev # Start with hot-reload
# Build
pnpm --filter @edr/passenger-api run build # Compile TypeScript
# Production
pnpm --filter @edr/passenger-api run start # Run compiled code
# Testing
pnpm --filter @edr/passenger-api run test # Unit tests
pnpm --filter @edr/passenger-api run test:e2e # E2E tests
# Code Quality
pnpm --filter @edr/passenger-api run lint # ESLint
pnpm --filter @edr/passenger-api run type-check # TypeScript check
# Database
pnpm --filter @edr/passenger-api run prisma:generate # Generate Prisma client
pnpm --filter @edr/passenger-api run prisma:migrate:dev # Run migrations (local dev)
pnpm --filter @edr/passenger-api run prisma:seed # Seed database
🐳 Docker Deployment
All six apps build from Dockerfiles: each API has its own (apps/edr-freight-api/Dockerfile, apps/edr-passenger-api/Dockerfile); Vite frontends share infrastructure/docker/Dockerfile.web and are served with nginx. APIs run on Node 22.
Prerequisites
- Docker with BuildKit enabled
- A local
.npmrcwith GitHub Packages auth for@tria-plc/*(required for freight API and web images) - External Postgres for each API (compose does not include databases)
- Copy
apps/edr-freight-api/.env.example→.envandapps/edr-passenger-api/.env.example→.envwith real connection strings
Build and run (all apps)
# From monorepo root
DOCKER_BUILDKIT=1 pnpm docker:build
pnpm docker:up
Or without pnpm scripts:
DOCKER_BUILDKIT=1 docker compose build
docker compose up -d
| Service | URL (default) |
|---|---|
| Freight API | http://localhost:3001 |
| Passenger API | http://localhost:4000 |
| Freight portal | http://localhost:5173 |
| Freight backoffice | http://localhost:5183 |
| Passenger portal | http://localhost:5174 |
| Passenger backoffice | http://localhost:5184 |
Build a single service
docker compose build freight-api
docker compose build passenger-portal
Freight images mount .npmrc as a BuildKit secret during pnpm install. Passenger web images do not require private packages.
VITE_API_URL (frontends)
API URLs are baked in at image build time (import.meta.env.VITE_API_URL). Defaults in docker-compose.yaml use http://localhost:3001/api (freight) and http://localhost:4000 (passenger) for local smoke tests. Override build args for production, e.g.:
docker compose build freight-portal \
--build-arg VITE_API_URL=https://freight-api.example.com/api
Migrations
- Freight API: TypeORM migrations are not run on container startup — apply them separately before deploy.
- Passenger API: On each container start, the entrypoint runs
npm run prisma:migrateandnpm run prisma:seed(samepackage.jsonscripts aspnpm run) before starting the server. EnsureDATABASE_URLin.envpoints at a reachable Postgres instance.
For local development, use pnpm --filter @edr/passenger-api run prisma:migrate:dev instead of prisma:migrate.
GitHub Actions (self-hosted runner)
Two workflows deploy independently on push to main, develop, or staging:
| Workflow | Services | Server env root |
|---|---|---|
.github/workflows/deploy-freight.yml |
freight-api, freight-portal, freight-backoffice | /home/user/environmen/edr-freight/<branch>/ |
.github/workflows/deploy-passenger.yml |
passenger-api, passenger-portal, passenger-backoffice | /home/user/environmen/edr-passenger/<branch>/ |
On the runner, place env files before the first deploy (example for branch main):
/home/user/environmen/edr-freight/main/
freight-api.env
freight-portal.env # optional runtime env for Vite/nginx
freight-backoffice.env
freight-web.build.env # exports FREIGHT_VITE_API_URL=...
/home/user/environmen/edr-passenger/main/
passenger-api.env
passenger-portal.env
passenger-backoffice.env
passenger-web.build.env # exports PASSENGER_VITE_API_URL=...
Example freight-web.build.env:
export FREIGHT_VITE_API_URL=https://freight-api.example.com/api
The workflow copies *.env into each app directory, creates .npmrc from the NPM_TOKEN repository secret, then runs docker compose build and docker compose up -d for that stack.
🔒 Security Best Practices
- Environment Variables - Never commit
.envfiles. Use secrets management in production. - JWT Secret - Use strong, randomly generated secrets (min 32 characters).
- Password Hashing - Bcrypt with salt rounds (default: 10).
- Rate Limiting - Implement rate limiting for auth endpoints.
- CORS - Configure allowed origins in production.
- HTTPS - Always use HTTPS in production.
- Database - Use connection pooling and prepared statements (Prisma handles this).
- Audit Logging - All sensitive operations are logged in
AuditLogtable. - Dual Authentication - Passenger routes use JWT, back-office routes use corporate IAM.
- IAM Integration - Corporate IAM validates tokens against centralized identity service.
- Role-Based Access - Granular permissions enforced via IAM roles (AGENT, SUPERVISOR, ADMIN).
- Token Validation - IAM tokens validated in real-time with 5-second timeout.
📊 Monitoring & Logging
- Application Logs - NestJS built-in logger
- Database Queries - Prisma query logging (enable in development)
- Audit Trail - All user actions logged in
AuditLogtable - Error Tracking - Global exception filters with detailed error responses
🧪 Testing
# Unit tests
pnpm --filter @edr/passenger-api run test
# E2E tests
pnpm --filter @edr/passenger-api run test:e2e
# Test coverage
pnpm --filter @edr/passenger-api run test:cov
🚀 Production Deployment
Pre-deployment Checklist
- Update environment variables (JWT_SECRET, DATABASE_URL, etc.)
- Configure IAM integration (IAM_ENABLED=true, IAM_API_URL, IAM_API_KEY)
- Configure Verifayda integration (VERIFAYDA_ENABLED=true, VERIFAYDA_API_KEY)
- Set up currency exchange rate sync (external API)
- Set NODE_ENV=production
- Configure CORS origins (PORTAL_URL, BACK_OFFICE_URL)
- Set up SSL/TLS certificates
- Configure database connection pooling
- Set up monitoring and logging
- Configure backup strategy
- Test payment provider integrations
- Verify IAM token validation endpoint
- Test Verifayda verification with real national IDs
- Verify currency conversion accuracy
- Test age-based pricing calculations
- Review security settings and audit logs
- Test both JWT and IAM authentication flows
Deployment Steps
# 1. Build application
pnpm --filter @edr/passenger-api run build
# 2. Run migrations
pnpm --filter @edr/passenger-api run prisma:migrate
# 3. Start production server
NODE_ENV=production pnpm --filter @edr/passenger-api run start:prod
🤝 Contributing
- Fork the repository
- Create feature branch (
git checkout -b feature/amazing-feature) - Commit changes (
git commit -m 'Add amazing feature') - Push to branch (
git push origin feature/amazing-feature) - Open Pull Request
📝 License
This project is proprietary and confidential.
📧 Support
For technical support or questions:
- Email: support@edr-platform.com
- Documentation: http://localhost:4000/api-docs
Built with ❤️ for Ethio-Djibouti Railway