System Architecture
MayTravel is an AI-powered travel planning assistant built with a modern three-tier architecture. The system combines a React frontend, Node.js/Express backend, and PostgreSQL database with Google Gemini AI integration for intelligent itinerary generation.High-Level Architecture
Component Architecture
Backend Structure
The backend follows a Model-View-Controller (MVC) pattern organized by feature domains:Layer Responsibilities
Controllers (backend/src/components/*/controller/)
- Handle HTTP requests and responses
- Parse request parameters and body
- Invoke service layer methods
- Return appropriate HTTP status codes
- Error handling and user feedback
TripsController.mjs:48-56
Services (backend/src/components/*/service/)
- Implement business logic
- Transform and aggregate data
- Coordinate between multiple models
- Data formatting and simplification
TripsService.mjs:25-46 transforms database results into simplified trip objects with nested stops.
Models (backend/src/components/*/model/)
- Direct database interaction using PostgreSQL client
- Execute SQL queries with parameterized statements
- Perform CRUD operations
- Return raw database results
TripsModel.mjs:30-33 uses complex JOIN queries to fetch trip details with stops and POI information.
Technology Stack
Frontend
- Framework: React
- Purpose: Single-page application for user interface
- Location:
frontend/src/
Backend
- Runtime: Node.js
- Framework: Express 5.2.1
- Language: JavaScript (ES Modules)
- Architecture: RESTful API
- Port: 3000
Database
- DBMS: PostgreSQL
- Version: Compatible with pg 8.16.3
- Extensions: PostGIS for geospatial data
- Connection:
pgclient library
AI & External Services
- AI Model: Google Gemini (with RAG)
- Geolocation: Google Maps Platform
- Integration: REST API calls from backend
API Design
RESTful Endpoints
The API follows REST principles with resource-based routing:Users
GET /users- List all usersGET /users/:id- Get user by IDPOST /users- Create new userPUT /users/:id- Update userDELETE /users/:id- Delete userPOST /auth/login- User authenticationPOST /auth/register- User registrationGET /users/:id/interests- Get user interestsPOST /users/:id/interests- Add interests to userGET /users/:id/trips- Get user’s trips
Trips
GET /trips- List all tripsGET /trips/:id- Get trip details with stopsPOST /users/:id/trips- Create new tripDELETE /trips/:id- Delete trip
Points of Interest (POIs)
GET /pois- List all POIsPOST /pois- Create new POIPATCH /pois/:id- Update POIDELETE /pois/:id- Delete POI
Stops
POST /stops- Create stop in trip itinerary
Interests
GET /interests- List all interestsPOST /interests- Create new interestPUT /interests/:id- Update interestDELETE /interests/:id- Delete interest
backend/src/configs/routing.mjs:1-65 for complete route definitions.
Data Flow
Typical Request Flow
- Client Request: Frontend sends HTTP request to Express API
- Routing: Express router matches URL pattern and method
- Middleware: Request passes through validation/authentication middleware
- Controller: Controller parses request and extracts parameters
- Service: Service layer applies business logic and coordinates data
- Model: Model executes SQL query against PostgreSQL
- Database: PostgreSQL processes query and returns results
- Response Chain: Data flows back through Model → Service → Controller
- JSON Response: Controller sends formatted JSON response to client
Example: Fetching a Trip with Stops
Security Considerations
Database Security
- Parameterized Queries: All SQL queries use parameterized statements (
$1,$2) to prevent SQL injection - Input Sanitization: User inputs are sanitized (e.g.,
.toLowerCase()for usernames/emails)
UsersModel.mjs:15-18
Authentication
- Basic username/email and password authentication
- JWT token placeholder for future implementation (
UsersController.mjs:82) - Role-based access control support (user roles stored in database)
Scalability & Flexibility
Why This Architecture?
- Separation of Concerns: MVC pattern isolates responsibilities
- Modularity: Feature-based organization allows independent development
- Testability: Each layer can be unit tested independently
- Maintainability: Clear structure makes codebase easy to navigate
- Extensibility: New features can be added as new components
PostgreSQL Flexibility
The choice of PostgreSQL provides:- Schema Flexibility: Can handle dynamic fields from AI responses
- JSON Support: Can store semi-structured itinerary data if needed
- Geospatial Support: PostGIS for location-based features
- Data Integrity: Foreign keys and constraints maintain relationships
- ACID Compliance: Reliable transaction handling
Performance Considerations
Database Connection
- Single persistent PostgreSQL client connection (
backend/src/databases/postgres-db/maytraveldb.mjs:12) - Async/await for non-blocking database operations
- Note: All database operations must use
awaitkeyword
Query Optimization
- Efficient JOINs to minimize round trips
- Parameterized queries for prepared statement caching
- Geospatial indexing with PostGIS for location queries
Future Architecture Enhancements
Planned Improvements
- JWT Implementation: Complete token-based authentication system
- Connection Pooling: Replace single client with pg.Pool for better concurrency
- Caching Layer: Redis for frequently accessed data
- API Gateway: Centralized request handling and rate limiting
- Microservices: Potential split of AI integration into separate service
- WebSockets: Real-time trip updates and notifications
- CDN Integration: Frontend asset delivery optimization
Related Documentation
- Database Architecture - Detailed schema and data model
- AI Integration - Google Gemini and RAG implementation