System Architecture
Overview
Talbino is built as a modern, scalable marketplace platform with native mobile apps and a web presence.
Stack Decision: Laravel + PostgreSQL
Backend: Laravel 11 (PHP)
Why Laravel over Node.js:
- Speed to MVP: Laravel's batteries-included approach (auth, queues, events, admin panel) saves 2-3 weeks vs building from scratch
- Real-time ready: Laravel Echo + Soketi for chat and notifications (proven, minimal config)
- Admin tooling: Filament v3 gives production-ready admin panel in days
- Queue system: Built-in job queues for push notifications, email, background tasks
- Egypt talent pool: Strong PHP/Laravel community in Cairo for future hiring
- Cost efficiency: Single container deployment vs microservices complexity
- Mature ecosystem: Packages for OTP, file storage, localization
Technology Stack:
| Component | Technology | Purpose |
|---|---|---|
| Backend Framework | Laravel 11 | API + business logic |
| Database | PostgreSQL 15 | Primary data store |
| Cache/Queue | Redis 7 | Sessions, cache, job queue |
| Real-time | Laravel Echo + Soketi | WebSocket for chat |
| Storage | AWS S3 | File uploads (avatars, future media) |
| Admin Panel | Filament v3 | Admin dashboard |
| Search | PostgreSQL Full-Text | MVP search (Meilisearch Phase 2) |
| SMS | Twilio | OTP delivery |
| Push Notifications | FCM (Firebase) | iOS/Android/Flutter push |
Frontend Applications
| App | Technology | Purpose |
|---|---|---|
| Buyer iOS | Swift + SwiftUI | Native iOS buyer experience |
| Buyer Android | Kotlin + Jetpack Compose | Native Android buyer experience |
| Seller App | Flutter (Dart) | Cross-platform seller app |
| Web App | Next.js 14 (App Router) | Marketing + optional buyer web + admin |
High-Level Architecture
┌─────────────────────────────────────────────────────────────┐
│ CLIENT LAYER │
├──────────────┬──────────────┬──────────────┬────────────────┤
│ iOS App │ Android App │ Flutter App │ Next.js Web │
│ (SwiftUI) │ (Compose) │ (Seller) │ (Marketing) │
└──────┬───────┴──────┬───────┴──────┬───────┴────────┬───────┘
│ │ │ │
└──────────────┴──────────────┴────────────────┘
│
▼
┌──────────────────────────────────────────┐
│ AWS Application Load Balancer │
└──────────────────┬───────────────────────┘
│
┌──────────────────▼───────────────────────┐
│ Laravel API (ECS Fargate) │
│ ┌────────────────────────────────────┐ │
│ │ REST API Endpoints │ │
│ │ - Auth (OTP) │ │
│ │ - Requests, Offers, Deals │ │
│ │ - Chat, Notifications │ │
│ │ - Admin │ │
│ └────────────────────────────────────┘ │
│ ┌────────────────────────────────────┐ │
│ │ WebSocket Server (Soketi) │ │
│ │ - Real-time chat │ │
│ │ - Presence channels │ │
│ └────────────────────────────────────┘ │
│ ┌────────────────────────────────────┐ │
│ │ Queue Workers │ │
│ │ - Push notifications │ │
│ │ - Email jobs │ │
│ │ - Analytics events │ │
│ └────────────────────────────────────┘ │
└──────────────┬───────────────────────────┘
│
┌──────────────┼───────────────────────────┐
│ │ │
▼ ▼ ▼
┌─────────────┐ ┌──────────┐ ┌──────────────┐
│ PostgreSQL │ │ Redis │ │ AWS S3 │
│ (RDS) │ │(ElastiCache)│ │ (Storage) │
└─────────────┘ └──────────┘ └──────────────┘
│
▼
┌─────────────┐
│ Backups │
│ (S3) │
└─────────────┘
External Services:
├── Twilio (SMS/OTP)
├── Firebase Cloud Messaging (Push)
└── CloudWatch (Logging/Monitoring)
Service Modules
1. Authentication Service
Responsibilities:
- Phone number + OTP registration/login
- JWT token generation and validation
- Device token management
- Session management
Key Components:
AuthController: OTP request/verify endpointsOtpService: Generate, validate, rate-limit OTPsDeviceTokenService: Store/update push tokens
2. Request Service
Responsibilities:
- Create, read, update buy requests
- Request lifecycle management
- Request filtering and search
Key Components:
RequestController: CRUD endpointsRequestService: Business logicRequestPolicy: Authorization rules
3. Offer Service
Responsibilities:
- Create, read, withdraw offers
- Offer validation (price range, seller status)
- Offer acceptance logic
Key Components:
OfferController: CRUD endpointsOfferService: Business logic + validationOfferAcceptanceService: Transaction handling
4. Deal Service
Responsibilities:
- Deal creation (on offer acceptance)
- Deal status management (completed/cancelled)
- Deal history
Key Components:
DealController: Status update endpointsDealService: Business logicDealCompletionService: Rating trigger
5. Chat Service
Responsibilities:
- 1:1 conversations per offer
- Real-time message delivery
- Message history and read receipts
Key Components:
ChatController: REST endpoints for historyChatWebSocketHandler: Real-time messagingConversationService: Conversation management
6. Notification Service
Responsibilities:
- Push notification delivery
- Notification templates
- Device token management
Key Components:
NotificationService: Send push via FCMNotificationJob: Queue-based deliveryNotificationTemplates: Message templates
7. Rating Service
Responsibilities:
- Create ratings
- Update seller rating aggregates
- Rating validation (one per deal)
Key Components:
RatingController: Create rating endpointRatingService: Business logicSellerRatingAggregator: Update averages
8. Report Service
Responsibilities:
- Create reports
- Report moderation workflow
- Admin actions (warn/suspend)
Key Components:
ReportController: Create/list endpointsReportService: Business logicModerationService: Admin actions
9. Admin Service
Responsibilities:
- Seller approval workflow
- Content moderation
- Marketplace analytics
- System configuration
Key Components:
- Filament Admin Panel
SellerApprovalResource: Approve/reject sellersReportResource: Review reportsAnalyticsDashboard: KPI widgets
Data Flow Examples
Example 1: Buyer Posts Request
1. iOS App → POST /api/v1/requests
2. RequestController validates input
3. RequestService creates request (status=active)
4. Event: RequestCreated dispatched
5. Analytics listener logs event
6. Response: 201 Created with request data
7. iOS App shows success + navigates to request detail
Example 2: Seller Makes Offer
1. Flutter App → POST /api/v1/offers
2. OfferController validates:
- Request exists and status=active
- Seller profile exists and status=approved
- Price within budget range
3. OfferService creates offer (status=pending)
4. Request.offer_count incremented
5. Event: OfferCreated dispatched
6. NotificationJob queued → Push to buyer
7. Response: 201 Created with offer data
8. Buyer receives push <5s
Example 3: Chat Message
1. iOS App → WebSocket: send message
2. ChatWebSocketHandler receives message
3. ChatService creates message record
4. WebSocket broadcasts to recipient (if online)
5. If recipient offline → NotificationJob queued
6. Push notification sent via FCM
7. Recipient receives message in real-time or via push
Example 4: Accept Offer (Transaction)
1. iOS App → POST /api/v1/offers/`{id}`/accept
2. OfferAcceptanceService starts DB transaction:
a. Create deal (status=accepted)
b. Update accepted offer (status=accepted)
c. Update other offers (status=rejected)
d. Update request (status=closed)
3. Transaction commits (atomic)
4. Events dispatched:
- OfferAccepted
- DealCreated
- RequestClosed
5. NotificationJobs queued for all parties
6. Response: 200 OK with deal data
7. All parties receive push notifications
Deployment Architecture (AWS)
Production Environment
┌────────────────────────────────────────────────────────┐
│ AWS Cloud (eu-central-1) │
│ │
│ ┌────────────────────────────────────────────────┐ │
│ │ CloudFront CDN │ │
│ │ - Static assets (Next.js) │ │
│ │ - Image optimization │ │
│ └────────────────┬───────────────────────────────┘ │
│ │ │
│ ┌────────────────▼───────────────────────────────┐ │
│ │ Application Load Balancer │ │
│ │ - SSL termination │ │
│ │ - Health checks │ │
│ └────────────────┬───────────────────────────────┘ │
│ │ │
│ ┌────────────────▼───────────────────────────────┐ │
│ │ ECS Fargate Cluster │ │
│ │ ┌──────────────────────────────────────────┐ │ │
│ │ │ Laravel API (2+ tasks) │ │ │
│ │ │ - Auto-scaling (CPU/Memory) │ │ │
│ │ │ - Rolling deployments │ │ │
│ │ └──────────────────────────────────────────┘ │ │
│ │ ┌──────────────────────────────────────────┐ │ │
│ │ │ Queue Workers (1+ tasks) │ │ │
│ │ │ - Process notification jobs │ │ │
│ │ └──────────────────────────────────────────┘ │ │
│ └────────────────────────────────────────────────┘ │
│ │
│ ┌─────────────────────────────────────────────────┐ │
│ │ RDS PostgreSQL (Multi-AZ) │ │
│ │ - db.t3.medium (MVP) │ │
│ │ - Automated backups │ │
│ │ - Read replica (Phase 2) │ │
│ └─────────────────────────────────────────────────┘ │
│ │
│ ┌─────────────────────────────────────────────────┐ │
│ │ ElastiCache Redis (Cluster mode) │ │
│ │ - cache.t3.micro (MVP) │ │
│ │ - Multi-AZ replication │ │
│ └─────────────────────────────────────────────────┘ │
│ │
│ ┌─────────────────────────────────────────────────┐ │
│ │ S3 Buckets │ │
│ │ - talbino-assets-prod (public) │ │
│ │ - talbino-backups-prod (private) │ │
│ └─────────────────────────────────────────────────┘ │
│ │
│ ┌─────────────────────────────────────────────────┐ │
│ │ CloudWatch │ │
│ │ - Application logs │ │
│ │ - Metrics & alarms │ │
│ │ - Dashboard │ │
│ └─────────────────────────────────────────────────┘ │
└────────────────────────────────────────────────────────┘
Cost Estimate (MVP - First 3 Months)
| Service | Configuration | Monthly Cost |
|---|---|---|
| ECS Fargate | 2 API tasks (0.5 vCPU, 1GB) + 1 worker | $50 |
| RDS PostgreSQL | db.t3.medium Multi-AZ | $120 |
| ElastiCache Redis | cache.t3.micro | $25 |
| ALB | Standard load balancer | $25 |
| S3 + CloudFront | 100GB storage + 1TB transfer | $30 |
| CloudWatch | Logs + metrics | $20 |
| Total AWS | ~$270/month | |
| Twilio SMS | 5K OTPs/month | $40 |
| Firebase (FCM) | Free tier | $0 |
| Domain + SSL | Route53 + ACM | $5 |
| Grand Total | ~$315/month |
Scaling Headroom: Budget allows 10x scale ($3K/month) before optimization needed.
Security Architecture
Authentication Flow
1. User enters phone number
2. API generates 6-digit OTP
3. OTP hashed (bcrypt) and stored in auth_otps table
4. SMS sent via Twilio
5. User enters OTP
6. API validates OTP (max 3 attempts, 10min expiry)
7. JWT token issued (24h expiry)
8. Refresh token issued (30d expiry)
9. Device token stored for push notifications
Authorization Rules
| Endpoint | Buyer | Seller | Admin |
|---|---|---|---|
| POST /requests | ✅ | ✅ | ✅ |
| POST /offers | ❌ | ✅ (if approved) | ✅ |
POST /offers/{id}/accept | ✅ (own request) | ❌ | ✅ |
| GET /admin/* | ❌ | ❌ | ✅ |
| POST /seller-profiles | ✅ | ✅ | ✅ |
Data Protection
- At Rest: RDS encryption enabled
- In Transit: TLS 1.3 for all API calls
- Secrets: AWS Secrets Manager for credentials
- PII: Phone numbers hashed in logs
- GDPR: User data export/deletion endpoints (Phase 2)
Scalability Considerations
Current Capacity (MVP)
- Concurrent users: 1,000
- Requests/second: 100
- Database connections: 50
- WebSocket connections: 500
Scaling Strategy (Phase 2)
- Horizontal scaling: Add ECS tasks (auto-scaling)
- Database: Add read replicas for queries
- Cache: Increase Redis cluster size
- CDN: CloudFront for API responses (GET only)
- Search: Migrate to Meilisearch for advanced filters
Performance Targets
- API response time: p95 < 200ms
- Database queries: p95 < 50ms
- WebSocket latency: p95 < 100ms
- Push delivery: p95 < 5s
Monitoring & Observability
Metrics to Track
- Request rate: Requests/offers/deals per minute
- Error rate: 4xx/5xx responses per endpoint
- Latency: p50, p95, p99 response times
- Queue depth: Pending notification jobs
- WebSocket: Active connections, message rate
Alerts
- API error rate > 5% (5min window)
- Database CPU > 80% (5min window)
- Queue depth > 1000 jobs
- Disk space > 85%
- SSL certificate expiry < 30 days
Logging Strategy
- Application logs: JSON format to CloudWatch
- Access logs: ALB logs to S3
- Audit logs: Admin actions logged separately
- Retention: 30 days hot, 1 year cold (S3)