Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 35 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# Docker
.docker/
docker-compose.override.yml

# Environment files
.env
.env.local
.env.development.local
.env.test.local
.env.production.local

# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*

# Database data
postgres_data/
postgres_data_dev/

# IDE
.vscode/
.idea/
*.swp
*.swo

# OS
.DS_Store
Thumbs.db

# Temporary files
tmp/
temp/
167 changes: 166 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,167 @@
# TravelAssistant
AI travel assistant

AI-powered travel assistant with FastAPI backend and Next.js frontend.

## Architecture

This project consists of three main components:

- **Backend**: FastAPI application with PostgreSQL database
- **Frontend**: Next.js application with TypeScript
- **Database**: PostgreSQL with sample travel data

## Quick Start with Docker Compose

### Prerequisites

- Docker and Docker Compose installed
- Git

### Development Setup

1. Clone the repository:
```bash
git clone <repository-url>
cd TravelAssistant
```

2. Start all services in development mode:
```bash
docker-compose -f docker-compose.dev.yml up --build
```

3. Access the application:
- Frontend: http://localhost:3000
- Backend API: http://localhost:8000
- API Documentation: http://localhost:8000/docs
- Database: localhost:5432

### Production Setup

1. Start all services in production mode:
```bash
docker-compose up --build -d
```

2. The application will be available at:
- Frontend: http://localhost:3000
- Backend: http://localhost:8000

## Development

### Backend (FastAPI)

The backend is located in the `backend/` directory and includes:

- FastAPI application with CORS support
- PostgreSQL database integration with SQLAlchemy
- Travel recommendations API endpoints
- Environment-based configuration

#### API Endpoints

- `GET /` - Root endpoint
- `GET /health` - Health check
- `GET /recommendations` - Get all travel recommendations
- `GET /recommendations/{destination}` - Get recommendation by destination
- `POST /search` - Search destinations based on criteria

#### Local Development

```bash
cd backend
pip install -r requirements.txt
uvicorn main:app --reload
```

### Frontend (Next.js)

The frontend is located in the `frontend/` directory and includes:

- Next.js 14 with App Router
- TypeScript configuration
- Styled Components for styling
- API integration with the backend
- Responsive design

#### Local Development

```bash
cd frontend
npm install
npm run dev
```

## Database

PostgreSQL database with pre-populated sample data:

- Destinations table with travel information
- Travel plans table for user itineraries
- Sample destinations: Paris, Tokyo, New York, Barcelona

## Environment Variables

### Backend (.env)
```
DATABASE_URL=postgresql://travel_user:travel_pass@db:5432/travel_assistant
API_HOST=0.0.0.0
API_PORT=8000
DEBUG=true
SECRET_KEY=your-secret-key-here
```

### Frontend (.env.local)
```
NEXT_PUBLIC_API_URL=http://localhost:8000
NODE_ENV=development
```

## Docker Services

- **db**: PostgreSQL 15 database
- **backend**: FastAPI application with uvicorn
- **frontend**: Next.js application

## Features

- 🌍 Travel destination search and recommendations
- πŸ’° Budget-based filtering
- πŸ“… Date-based planning
- 🎯 Personalized preferences
- πŸ“± Responsive web interface
- 🐳 Full Docker containerization
- πŸ”„ Hot reload in development mode

## API Documentation

When the backend is running, visit http://localhost:8000/docs for interactive API documentation powered by FastAPI's automatic OpenAPI generation.

## Contributing

1. Fork the repository
2. Create a feature branch
3. Make your changes
4. Test with Docker Compose
5. Submit a pull request

## Troubleshooting

### Common Issues

1. **Port conflicts**: Ensure ports 3000, 8000, and 5432 are available
2. **Docker build issues**: Try `docker-compose down -v` and rebuild
3. **Database connection issues**: Wait for the database health check to pass

### Logs

View logs for specific services:
```bash
docker-compose logs backend
docker-compose logs frontend
docker-compose logs db
```

## License

MIT License
32 changes: 32 additions & 0 deletions backend/.dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# Docker
*.dockerfile
.dockerignore

# OS
.DS_Store
Thumbs.db

# Logs
*.log

# Runtime data
pids
*.pid
*.seed
*.pid.lock

# Coverage directory used by tools like istanbul
coverage/

# Dependency directories
jspm_packages/

# Optional npm cache directory
.npm

# Optional eslint cache
.eslintcache

# Temporary files
tmp/
temp/
6 changes: 6 additions & 0 deletions backend/.env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# Environment variables for local development
DATABASE_URL=postgresql://travel_user:travel_pass@localhost:5432/travel_assistant
API_HOST=0.0.0.0
API_PORT=8000
DEBUG=true
SECRET_KEY=your-secret-key-here-change-in-production
43 changes: 43 additions & 0 deletions backend/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# Python
__pycache__/
*.py[cod]
*$py.class
*.so
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
*.egg-info/
.installed.cfg
*.egg

# FastAPI
.env
.env.*
!.env.example

# Database
*.db
*.sqlite3

# IDE
.vscode/
.idea/
*.swp
*.swo

# OS
.DS_Store
Thumbs.db

# Logs
*.log
30 changes: 30 additions & 0 deletions backend/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
FROM python:3.11-slim

WORKDIR /app

# Install system dependencies
RUN apt-get update && apt-get install -y \
gcc \
&& rm -rf /var/lib/apt/lists/*

# Copy requirements first for better caching
COPY requirements.txt .
RUN pip install --no-cache-dir --trusted-host pypi.org --trusted-host pypi.python.org --trusted-host files.pythonhosted.org -r requirements.txt

# Copy application code
COPY . .

# Create non-root user
RUN useradd --create-home --shell /bin/bash app \
&& chown -R app:app /app
USER app

# Expose port
EXPOSE 8000

# Health check
HEALTHCHECK --interval=30s --timeout=30s --start-period=5s --retries=3 \
CMD python -c "import requests; requests.get('http://localhost:8000/health')"

# Run with uvicorn
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]
48 changes: 48 additions & 0 deletions backend/database.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
from sqlalchemy import create_engine, Column, Integer, String, Float, DateTime, Text, JSON
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker
from datetime import datetime
import os

DATABASE_URL = os.getenv("DATABASE_URL", "postgresql://travel_user:travel_pass@db:5432/travel_assistant")

engine = create_engine(DATABASE_URL)
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)

Base = declarative_base()

class Destination(Base):
__tablename__ = "destinations"

id = Column(Integer, primary_key=True, index=True)
name = Column(String, index=True)
country = Column(String)
description = Column(Text)
estimated_cost = Column(Float)
recommended_duration = Column(String)
highlights = Column(JSON)
created_at = Column(DateTime, default=datetime.utcnow)

class TravelPlan(Base):
__tablename__ = "travel_plans"

id = Column(Integer, primary_key=True, index=True)
user_id = Column(String) # In production, this would be a foreign key
destination_id = Column(Integer) # Foreign key to destinations
start_date = Column(DateTime)
end_date = Column(DateTime)
budget = Column(Float)
preferences = Column(JSON)
status = Column(String, default="draft")
created_at = Column(DateTime, default=datetime.utcnow)

def get_db():
db = SessionLocal()
try:
yield db
finally:
db.close()

# Create tables
def create_tables():
Base.metadata.create_all(bind=engine)
Loading