Refactored the whole app based on the requirements shared

This commit is contained in:
Stephanos A
2026-05-21 08:48:28 +03:00
parent 2dc3da9e74
commit 51bc906792
84 changed files with 6880 additions and 12659 deletions

584
README.md
View File

@@ -1,141 +1,513 @@
# EDR Passenger API
# EDR Platform - Ethio-Djibouti Railway Passenger API
NestJS REST API for the Ethio-Djibouti Railway passenger platform. Handles booking lifecycle, seat inventory, payments (Telebirr, CBE Birr, eBirr, Card, Wallet), loyalty, live tracking, notifications, and support.
Enterprise-grade NestJS REST API for the Ethio-Djibouti Railway passenger booking and management platform. Built with TypeScript, PostgreSQL, and Prisma ORM.
## Tech Stack
## 🚀 Features
- **Runtime**: Node.js 20, TypeScript
- **Framework**: NestJS 11
- **Database**: PostgreSQL via Prisma ORM
- **Auth**: JWT (Passport)
- **Docs**: Swagger / OpenAPI (`/api-docs`)
- **Package manager**: pnpm 9
### 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
- **Booking Management** - Complete booking lifecycle with modification, cancellation, refunds, and fare breakdown
- **Payment Integration** - Multi-provider support (Telebirr, CBE Birr, eBirr, Card, Wallet) with webhook handling
- **Seat Management** - Real-time seat inventory, holds, releases, and blocking with coach/class management
- **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
## Prerequisites
### 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
- Node.js >= 20
- pnpm >= 9 (`npm i -g pnpm`)
- PostgreSQL 15+
## 📋 Prerequisites
## Quick Start
- **Node.js** >= 20.x
- **pnpm** >= 9.x (`npm install -g pnpm`)
- **PostgreSQL** >= 15.x
- **Git**
## 🛠️ Installation & Setup
### 1. Clone Repository
```bash
# 1. Install dependencies (from monorepo root)
pnpm install
git clone <repository-url>
cd edr-platform
```
# 2. Copy and fill environment variables
### 2. Install Dependencies
```bash
pnpm install
```
### 3. Environment Configuration
```bash
# Copy environment template
cp apps/edr-passenger-api/.env.example apps/edr-passenger-api/.env
# 3. Generate Prisma client
# 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` |
| `FRONTEND_URL` | Web app CORS origin | `http://localhost:3000` |
| `PORTAL_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` |
#### 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
```bash
# 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
```bash
# 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
```bash
pnpm --filter @edr/passenger-api run prisma:generate
```
# 4. Run database migrations
#### Run Migrations
```bash
pnpm --filter @edr/passenger-api run prisma:migrate
```
# 5. Seed the database
#### Seed Database
```bash
pnpm --filter @edr/passenger-api run prisma:seed
```
# 6. Start in development mode
**Seed Data Includes:**
- 5 Stations (Addis Ababa, Adama, Awash, Dire Dawa, Djibouti)
- 1 Route with 5 stops and fare rules
- 2 Train services with 2 trips
- 360 seats across 6 coaches (Economy, Bed, VIP classes)
- 3 User accounts (Admin, Passenger, Agent)
- Baggage allowance rules
- Notification templates
- Promotions and FAQ content
- Menu items and station crowd signals
### 5. Start Development Server
```bash
pnpm --filter @edr/passenger-api run dev
```
API runs at **http://localhost:4000**
Swagger UI at **http://localhost:4000/api-docs**
**API Server:** http://localhost:4000
**Swagger Docs:** http://localhost:4000/api-docs
## Environment Variables
## 🔑 Default Credentials
| Variable | Description | Default |
| --------------------- | ------------------------------------ | -------------------------------- |
| `PORT` | HTTP port | `4000` |
| `DATABASE_URL` | PostgreSQL connection string | — |
| `JWT_SECRET` | JWT signing secret | — |
| `JWT_EXPIRES_IN` | JWT expiry | `7d` |
| `FRONTEND_URL` | Allowed CORS origin (web app) | `http://localhost:3000` |
| `PORTAL_URL` | Allowed CORS origin (portal) | `http://localhost:3001` |
| `SENDGRID_API_KEY` | SendGrid key for email notifications | _(optional — logs if absent)_ |
| `SENDGRID_FROM_EMAIL` | Sender email address | `noreply@edr-platform.com` |
After seeding, use these credentials to test the API:
## API Modules
| Role | Email | 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 |
| Tag | Base path | Description |
| -------------- | ----------------- | ---------------------------------------- |
| Auth | `/auth` | Register, login, JWT |
| Stations | `/stations` | Station directory |
| Fleet | `/fleet` | Train services, coaches, seat batches |
| Schedule | `/schedule` | Trips, fare rules, status updates |
| Search | `/search` | Trip search, fare quotes |
| Seats | `/seats` | Seat maps, holds, releases |
| Booking | `/bookings` | Create, retrieve, cancel bookings |
| Payment | `/payments` | Initiate payment, refunds, methods |
| Tickets | `/tickets` | QR ticket generation and validation |
| Passenger | `/passengers` | Profiles, traveler profiles, saved routes|
| Notifications | `/notifications` | In-app notifications |
| Loyalty | `/loyalty` | Points, tiers, rewards |
| Wallet | `/wallet` | Balance, top-up, ledger |
| Promotions | `/promos` | Active promos, promo code validation |
| Live Tracking | `/live` | Real-time trip status, crowd signals |
| Support | `/support` | FAQ, chat conversations |
| Dashboard | `/dashboard` | Home screen aggregate |
## 📚 API Documentation
## Seed Credentials
### Swagger UI
Interactive API documentation available at: **http://localhost:4000/api-docs**
After running `prisma:seed`:
### Authentication Methods
| Role | Email | Password |
| --------- | ------------------------ | ------------- |
| Passenger | `kelemu@email.com` | `password123` |
| Admin | `admin@edr-platform.com` | `admin123` |
The API uses two authentication schemes:
## Docker
#### 1. JWT Authentication (Passenger-facing)
- **Used for**: Passenger bookings, profile management, wallet, loyalty
- **Header**: `Authorization: Bearer <jwt-token>`
- **Obtain token**: `POST /auth/login` with 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 |
| **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 |
| **Stations** | `/stations` | JWT | Station directory and information |
| **Fleet** | `/fleet` | JWT/IAM | Train services, coaches, seat configurations |
| **Schedules** | `/schedules` | JWT/IAM | Trip schedules, fare rules, status updates |
| **Search** | `/search` | JWT | Trip search, availability, fare quotes |
| **Seats** | `/seats` | JWT/IAM | Seat maps, holds, releases, blocking |
| **Bookings** | `/bookings` | JWT | Create, modify, cancel bookings |
| **Payments** | `/payments` | JWT/Public | Payment initiation, webhooks, refunds |
| **Tickets** | `/tickets` | JWT/IAM | Ticket generation, QR/barcode, validation |
| **Passengers** | `/passengers` | JWT | Profile management, traveler profiles |
| **Notifications** | `/notifications` | JWT | In-app notifications, preferences |
| **Loyalty** | `/loyalty` | JWT | Points, tiers, rewards redemption |
| **Wallet** | `/wallet` | JWT | Balance, top-up, transaction history |
| **Promotions** | `/promos` | JWT | Active promotions, promo code validation |
| **Live Tracking** | `/live` | JWT | Real-time trip status, crowd signals |
| **Support** | `/support` | JWT | FAQ, chat conversations |
| **Dashboard** | `/dashboard` | JWT | Home screen aggregated data |
### Example API Calls
#### 1. Register Passenger
```bash
POST /auth/register
Content-Type: application/json
{
"email": "user@example.com",
"phone": "+251911234567",
"fullName": "John Doe",
"password": "SecurePass123"
}
```
#### 2. Login (Passenger)
```bash
POST /auth/login
Content-Type: application/json
{
"email": "user@example.com",
"password": "SecurePass123"
}
# Response includes JWT token
{
"accessToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"user": { "id": "uuid", "role": "PASSENGER" }
}
```
#### 2b. Agent Booking (IAM Auth)
```bash
POST /agents/bookings
Authorization: Bearer <iam-token>
Content-Type: application/json
{
"tripId": "uuid",
"seats": [...],
"paymentMethod": "CASH",
"cashReceived": 50000
}
```
#### 3. Search Trips
```bash
GET /search/trips?originStationId={id}&destinationStationId={id}&date=2026-06-15
Authorization: Bearer {token}
```
#### 4. Create Booking
```bash
POST /bookings
Authorization: Bearer {token}
Content-Type: application/json
{
"tripId": "uuid",
"seats": [
{
"seatId": "uuid",
"passengerName": "John Doe",
"idDocumentType": "PASSPORT",
"idDocumentNumber": "ET123456"
}
]
}
```
## 🏗️ 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)
│ │ ├── 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)
│ │ └── 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`, `Agent`
- `Station`, `Route`, `RouteStop`, `RouteFareRule`
- `TrainService`, `Trip`, `TripStopTime`, `Coach`, `Seat`
- `Booking`, `BookingSeat`, `Ticket`
- `PaymentIntent`, `PaymentRefund`, `PaymentWebhookEvent`
**Enhanced Features:**
- `OtpCode`, `PasswordResetToken` (Auth)
- `AgentBooking`, `AgentShift`, `AgentCommission` (Agents)
- `BookingModification`, `BookingCancellation` (Booking lifecycle)
- `GateValidationLog` (Ticket validation)
- `BaggageAllowance`, `BaggageBooking` (Baggage)
- `LoyaltyAccount`, `LoyaltyLedgerEntry`, `LoyaltyReward`
- `WalletAccount`, `WalletLedgerEntry`
- `Notification`, `NotificationTemplate`
- `AuditLog`, `OperationalReport`
- `SeatBlock`, `SeatHold`
## 🔧 Available Scripts
```bash
# Build image (run from monorepo root)
# 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 # Run migrations
pnpm --filter @edr/passenger-api run prisma:seed # Seed database
```
## 🐳 Docker Deployment
### Build Image
```bash
# From monorepo root
docker build -f apps/edr-passenger-api/Dockerfile -t edr-passenger-api .
# Run
docker run -p 4000:4000 --env-file apps/edr-passenger-api/.env edr-passenger-api
```
## Scripts
| Command | Description |
| ---------------------- | ------------------------------ |
| `pnpm dev` | Start with hot-reload |
| `pnpm build` | Compile to `dist/` |
| `pnpm start` | Run compiled output |
| `pnpm test` | Run unit tests |
| `pnpm lint` | ESLint |
| `pnpm type-check` | TypeScript type check |
| `pnpm prisma:generate` | Regenerate Prisma client |
| `pnpm prisma:migrate` | Run pending migrations |
| `pnpm prisma:seed` | Seed the database |
## Project Structure
### Run Container
```bash
docker run -d \
--name edr-api \
-p 4000:4000 \
--env-file apps/edr-passenger-api/.env \
edr-passenger-api
```
src/
├── common/ # PrismaService, JwtGuard, JwtStrategy, filters, interceptors
├── config/ # app.config.ts, database.config.ts
└── modules/
├── auth/
├── stations/
├── fleet/
├── schedules/
├── search/
├── seats/
├── bookings/
├── payments/
├── tickets/
├── passengers/
├── notifications/
├── loyalty/
├── wallet/
├── promos/
├── live/
├── support/
└── dashboard/
prisma/
├── schema.prisma
├── seed.ts
└── migrations/
### Docker Compose (Recommended)
```yaml
version: '3.8'
services:
postgres:
image: postgres:15
environment:
POSTGRES_USER: edr
POSTGRES_PASSWORD: edr_secret
POSTGRES_DB: edr_passenger
ports:
- "5432:5432"
volumes:
- postgres_data:/var/lib/postgresql/data
api:
build:
context: .
dockerfile: apps/edr-passenger-api/Dockerfile
ports:
- "4000:4000"
environment:
DATABASE_URL: postgresql://edr:edr_secret@postgres:5432/edr_passenger
JWT_SECRET: your-secret-key
PORT: 4000
depends_on:
- postgres
volumes:
postgres_data:
```
## 🔒 Security Best Practices
1. **Environment Variables** - Never commit `.env` files. Use secrets management in production.
2. **JWT Secret** - Use strong, randomly generated secrets (min 32 characters).
3. **Password Hashing** - Bcrypt with salt rounds (default: 10).
4. **Rate Limiting** - Implement rate limiting for auth endpoints.
5. **CORS** - Configure allowed origins in production.
6. **HTTPS** - Always use HTTPS in production.
7. **Database** - Use connection pooling and prepared statements (Prisma handles this).
8. **Audit Logging** - All sensitive operations are logged in `AuditLog` table.
9. **Dual Authentication** - Passenger routes use JWT, back-office routes use corporate IAM.
10. **IAM Integration** - Corporate IAM validates tokens against centralized identity service.
11. **Role-Based Access** - Granular permissions enforced via IAM roles (AGENT, SUPERVISOR, ADMIN).
12. **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 `AuditLog` table
- **Error Tracking** - Global exception filters with detailed error responses
## 🧪 Testing
```bash
# 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)
- [ ] Set NODE_ENV=production
- [ ] Configure CORS origins (FRONTEND_URL, PORTAL_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
- [ ] Review security settings and audit logs
- [ ] Test both JWT and IAM authentication flows
### Deployment Steps
```bash
# 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
1. Fork the repository
2. Create feature branch (`git checkout -b feature/amazing-feature`)
3. Commit changes (`git commit -m 'Add amazing feature'`)
4. Push to branch (`git push origin feature/amazing-feature`)
5. 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**