A RESTful API implementation of the Amadeus Points of Interest service using Node.js, Express, Sequelize, and SQLite.
Current Status: Phase 8 Complete - Documentation & Configuration! β π
The API is fully functional with complete documentation and Swagger UI!
- β RESTful API endpoints for Points of Interest
- β SQLite database with Sequelize ORM
- β MVC architecture pattern (Model-View-Controller)
- β Comprehensive validation with custom error classes
- β Error handling with Amadeus-compliant error codes
- β Security middleware (Helmet, CORS)
- β Request logging with Morgan
- β
Swagger UI documentation at
/api-docs - β Health check endpoint
- β Graceful shutdown handling
- β Geospatial search with Haversine distance calculation
- β Pagination with HATEOAS links
- β Category filtering support
- Runtime: Node.js
- Framework: Express.js v5
- ORM: Sequelize v6
- Database: SQLite3
- Testing: Jest + Supertest
- Code Quality: ESLint + Prettier
- Development: Nodemon
- Node.js 16+
- npm 8+
- Clone the repository:
git clone <repository-url>
cd TravelinAPI- Install dependencies:
npm install- Set up environment variables:
cp .env.example .env
# Edit .env with your configuration if needed- Run database migrations:
npx sequelize-cli db:migrate
npx sequelize-cli db:seed:all- Docker installed (v20.10 or higher)
- Docker Compose installed (v2.0 or higher)
docker-compose up -d apiThe API will be available at http://localhost:3000
docker-compose --profile dev up -d api-devThe dev API will be available at http://localhost:3001
docker-compose logs -f apidocker-compose downdocker-compose up -d --build# Build the image
docker build -t travelinapi:latest .
# Run a single container
docker run -p 3000:3000 \
-e NODE_ENV=development \
-v $(pwd)/data:/app/data \
travelinapi:latest
# Execute commands inside the container
docker-compose exec api npm run test
docker-compose exec api npx sequelize-cli db:migrate
# Clean up everything
docker-compose down -v # Removes volumes tooThe SQLite database is persisted in a Docker volume. To reset the database:
# Remove the volume
docker-compose down -v
# Restart (will create fresh database with migrations)
docker-compose up -dnpm run devnpm start# Run all tests
npm test
# Run tests in watch mode
npm run test:watch
# Run tests with coverage
npm run test:coverage# Lint code
npm run lint
# Format code
npm run formatGET /healthReturns server health status, timestamp, and uptime.
Swagger UI available at: http://localhost:3000/api-docs
Interactive API documentation with "Try it out" functionality for all endpoints.
GET /v1/reference-data/locations/poisQuery Parameters:
latitude(required): Center point latitude (-90 to 90)longitude(required): Center point longitude (-180 to 180)radius(optional): Search radius in km (0-20, default: 1)categories(optional): Filter by categories (comma-separated)page[limit](optional): Results per page (1-100, default: 10)page[offset](optional): Number of results to skip (default: 0)
Example:
curl "http://localhost:3000/v1/reference-data/locations/pois?latitude=41.397158&longitude=2.160873&radius=1"Response:
{
"data": [
{
"id": "9CB40CB5D0",
"self": {
"href": "http://localhost:3000/v1/reference-data/locations/pois/9CB40CB5D0",
"methods": ["GET"]
},
"type": "location",
"subType": "POINT_OF_INTEREST",
"name": "Casa BatllΓ³",
"geoCode": {
"latitude": 41.39165,
"longitude": 2.164772
},
"category": "SIGHTS",
"rank": 5,
"tags": ["sightseeing", "museum", "landmark"]
}
],
"meta": {
"count": 10,
"links": {
"self": "...",
"first": "...",
"last": "...",
"next": "...",
"up": "..."
}
}
}GET /v1/reference-data/locations/pois/by-squareQuery Parameters:
north(required): North boundary latitudesouth(required): South boundary latitudeeast(required): East boundary longitudewest(required): West boundary longitudecategories(optional): Filter by categoriespage[limit](optional): Results per pagepage[offset](optional): Number of results to skip
Example:
curl "http://localhost:3000/v1/reference-data/locations/pois/by-square?north=41.40&south=41.38&east=2.17&west=2.15"GET /v1/reference-data/locations/pois/:poisIdExample:
curl "http://localhost:3000/v1/reference-data/locations/pois/9CB40CB5D0"Valid Categories:
SIGHTS- Tourist attractions, landmarksBEACH_PARK- Beaches and parksHISTORICAL- Historical sitesNIGHTLIFE- Bars, clubsRESTAURANT- Restaurants and cafesSHOPPING- Shopping venues
TravelinAPI/
βββ src/
β βββ config/
β β βββ database.js # Sequelize database configuration
β β βββ sequelize.js # Sequelize instance & connection
β β βββ index.js # Centralized app configuration
β βββ controllers/
β β βββ PoiController.js # POI endpoint handlers
β βββ middleware/
β β βββ validation.js # Input validation middleware
β β βββ errorHandler.js # Global error handler
β βββ models/
β β βββ index.js # Model exports
β β βββ PointOfInterest.js # POI model with validations
β βββ routes/
β β βββ index.js # Main router with Swagger UI
β β βββ poi.routes.js # POI routes
β βββ services/
β β βββ PoiService.js # Business logic & database queries
β βββ utils/
β β βββ errors.js # Custom error classes
β β βββ geospatial.js # Haversine & geospatial calculations
β β βββ responseFormatter.js # Response formatting utilities
β βββ app.js # Express app setup
β βββ server.js # Server entry point
βββ migrations/
β βββ *-create-points-of-interest.js
βββ seeders/
β βββ *-demo-barcelona-pois.js
βββ spec/
β βββ PointOfInterest.json # Swagger 2.0 specification
βββ tests/ # Test files (Phase 7)
βββ .env # Environment variables (gitignored)
βββ .env.example # Environment template
βββ package.json # Dependencies & scripts
βββ README.md # This file
All environment variables are documented in .env.example. Copy it to .env and adjust as needed.
| Variable | Description | Default | Required |
|---|---|---|---|
NODE_ENV |
Environment (development/production/test) | development | No |
PORT |
Server port | 3000 | No |
BASE_URL |
Base URL for API responses | http://localhost:3000 | No |
DB_STORAGE |
SQLite database file path | ./database.sqlite | No |
DB_LOGGING |
Enable database query logging | true | No |
CORS_ORIGIN |
CORS allowed origins | * | No |
LOG_LEVEL |
Logging level (debug, info, warn, error) | debug (dev) / info (prod) | No |
The testing framework (Jest + Supertest) is configured and ready. Tests will be implemented in Phase 7.
npm test # Run all tests
npm run test:watch # Run tests in watch mode
npm run test:coverage # Run tests with coverage reportThe API follows the Amadeus Points of Interest specification located in spec/PointOfInterest.json (Swagger 2.0 format).
- All changes should follow the MVC pattern
- Run linting before commits:
npm run lint - Format code:
npm run format - Write tests for new features
- Update documentation as needed
- Phase 1: Project Setup & Infrastructure β
- Phase 2: Database Schema & Models β
- Phase 3: Core Business Logic (Services) β
- Phase 4: Controllers (MVC Pattern) β
- Phase 5: Validation & Middleware β
- Phase 6: Routes β
- Phase 7: Testing (Skipped)
- Phase 8: Documentation & Configuration β
- Phase 9: Polish & Production Readiness
- Phase 10: Final QA & Deployment Prep
See Tasks.md for detailed task breakdown and progress tracking.
- Check if port 3000 is already in use
- Verify all dependencies are installed:
npm install - Check
.envfile exists and has correct values
- Ensure SQLite3 is properly installed:
npm install sqlite3 - Check DB_STORAGE path in
.env - Run migrations:
npx sequelize-cli db:migrate - Seed data:
npx sequelize-cli db:seed:all
- Ensure database is seeded:
npx sequelize-cli db:seed:all - Check coordinates are within Barcelona area (lat: ~41.39, lon: ~2.16)
- Increase search radius parameter
- Ensure server is running:
npm run dev - Access directly:
http://localhost:3000/api-docs - Check console for errors
ISC
See Tasks.md for current development tasks and priorities.
Last Updated: October 15, 2025
Version: 1.0.0
Phase: 8 (Documentation Complete!)
# 1. Install dependencies
npm install
# 2. Set up environment
cp .env.example .env
# 3. Run migrations & seed data
npx sequelize-cli db:migrate
npx sequelize-cli db:seed:all
# 4. Start server
npm run dev
# 5. Open Swagger UI
open http://localhost:3000/api-docs
# 6. Test API
curl "http://localhost:3000/v1/reference-data/locations/pois?latitude=41.397158&longitude=2.160873&radius=1"