# Developer Setup Guide - B2B Flight Ticketing Platform

This guide walks you through setting up the B2B Flight Ticketing Platform for local development, including common issues you might encounter and their solutions.

## Table of Contents

1. [Prerequisites](#prerequisites)
2. [Initial Setup](#initial-setup)
3. [Building the Application](#building-the-application)
4. [Starting Infrastructure Services](#starting-infrastructure-services)
5. [Common Issues and Fixes](#common-issues-and-fixes)
6. [Starting the Application](#starting-the-application)
7. [Verification](#verification)
8. [Development Workflow](#development-workflow)

## Prerequisites

Before you begin, ensure you have the following installed:

### Required Software

- **Java 17 or higher**
  ```bash
  java -version
  # Should show: openjdk version "17.x.x" or higher
  ```

- **Maven 3.8+**
  ```bash
  mvn -version
  # Should show: Apache Maven 3.8.x or higher
  ```

- **Docker Desktop** (or Docker Engine + Docker Compose)
  ```bash
  docker --version
  docker-compose --version
  ```

- **Git**
  ```bash
  git --version
  ```

### Optional but Recommended

- **IntelliJ IDEA** or **VS Code** with Java extensions
- **Postman** or **Insomnia** for API testing
- **DBeaver** or **pgAdmin** for database management

## Initial Setup

### 1. Clone the Repository

```bash
git clone <repository-url>
cd b2b-flight-platform
```

### 2. Configure Environment Variables

Create a `.env` file from the template:

```bash
cp .env.example .env
```

Edit `.env` and add your credentials:

```bash
# Required: Amadeus API credentials
AMADEUS_API_KEY=your_amadeus_api_key_here
AMADEUS_API_SECRET=your_amadeus_api_secret_here

# Required: Encryption key (generate using the command below)
ENCRYPTION_SECRET_KEY=your_base64_encoded_key_here
```

### 3. Generate Encryption Key

You need to generate a secure encryption key for sensitive data:

```bash
# Option 1: Using Maven (after building the project)
mvn exec:java -Dexec.mainClass="com.flightticket.util.EncryptionUtil" -Dexec.args="generateKey"

# Option 2: Generate manually (use any Base64 encoded 256-bit key)
# For now, you can use a placeholder and generate it after building
```

**Note**: You can start without the encryption key for initial setup, but you'll need it before running the application.

## Building the Application

### 1. Build the Project

```bash
mvn clean install
```

**Expected Output**:
```
[INFO] BUILD SUCCESS
[INFO] Total time: XX.XXX s
```

### 2. Build Docker Image

```bash
docker build -t b2b-flight-platform:latest .
```

**Common Issue #1: Alpine Image Not Found**

**Error**:
```
failed to solve: maven:3.9-eclipse-temurin-17-alpine: failed to resolve
```

**Cause**: Alpine-based Maven images may not be available or have connectivity issues.

**Fix**: The Dockerfile has been updated to use standard (non-Alpine) images:
- Build: `maven:3.9-eclipse-temurin-17`
- Runtime: `eclipse-temurin:17-jre`

**Verification**:
```bash
docker images | grep b2b-flight-platform
# Should show: b2b-flight-platform   latest   <image-id>   <time>   735MB
```

## Starting Infrastructure Services

### 1. Start PostgreSQL, Redis, and RabbitMQ

```bash
docker-compose up -d postgres redis rabbitmq
```

**Expected Output**:
```
[+] Running 4/4
 ✔ Network amedeus_flight-network  Created
 ✔ Container b2b-flight-postgres   Started
 ✔ Container b2b-flight-redis      Started
 ✔ Container b2b-flight-rabbitmq   Started
```

### 2. Verify Services are Running

```bash
docker-compose ps
```

**Expected Output**:
```
NAME                  STATUS
b2b-flight-postgres   Up (healthy)
b2b-flight-redis      Up (healthy)
b2b-flight-rabbitmq   Up (healthy)
```

### 3. Verify Databases Were Created

```bash
docker-compose exec postgres psql -U flight_user -c "\l"
```

**Expected Output**: You should see both databases:
- `flight_platform` ✓
- `keycloak` ✓

**Common Issue #2: Keycloak Database Missing**

**Error** (when starting Keycloak):
```
FATAL: database "keycloak" does not exist
```

**Cause**: PostgreSQL was only configured to create one database (`flight_platform`), but Keycloak needs its own database.

**Fix Applied**: 
1. Created `scripts/init-databases.sh` to initialize multiple databases
2. Updated `docker-compose.yml` to mount the initialization script
3. The script automatically creates both `flight_platform` and `keycloak` databases

**If you encounter this issue**:

```bash
# Stop and remove all containers and volumes
docker-compose down -v

# Start fresh (the init script will create both databases)
docker-compose up -d postgres redis rabbitmq

# Wait 10 seconds for initialization
sleep 10

# Verify both databases exist
docker-compose exec postgres psql -U flight_user -c "\l"
```

### 4. Start Keycloak

```bash
docker-compose up -d keycloak
```

**Wait for Keycloak to start** (takes about 30-60 seconds):

```bash
# Watch the logs
docker-compose logs -f keycloak

# Look for this message:
# "Keycloak 23.0.7 on JVM started in X.XXXs. Listening on: http://0.0.0.0:8080"
```

**Verify Keycloak is accessible**:
```bash
curl http://localhost:8080
# Should return HTML content
```

### 5. Check All Services Status

```bash
docker-compose ps
```

**Expected Output**:
```
NAME                  STATUS
b2b-flight-postgres   Up (healthy)
b2b-flight-redis      Up (healthy)
b2b-flight-rabbitmq   Up (healthy)
b2b-flight-keycloak   Up (healthy or starting)
```

## Common Issues and Fixes

### Issue #1: Docker Build Fails with Alpine Image Error

**Error**:
```
failed to solve: maven:3.9-eclipse-temurin-17-alpine: failed
```

**Solution**: Already fixed in the Dockerfile. Uses standard images instead of Alpine.

### Issue #2: Keycloak Database Does Not Exist

**Error**:
```
FATAL: database "keycloak" does not exist
```

**Solution**:
```bash
# Remove all containers and volumes
docker-compose down -v

# Start fresh - the init script will create both databases
docker-compose up -d postgres redis rabbitmq

# Wait for PostgreSQL to initialize
sleep 10

# Verify databases
docker-compose exec postgres psql -U flight_user -c "\l"

# Start Keycloak
docker-compose up -d keycloak
```

### Issue #3: Port Already in Use

**Error**:
```
Error: bind: address already in use
```

**Solution**:

**Option 1**: Stop the conflicting service
```bash
# Find what's using the port (example: 8080)
lsof -i :8080

# Kill the process
kill -9 <PID>
```

**Option 2**: Change the port in `docker-compose.yml`
```yaml
ports:
  - "8082:8080"  # Change 8080 to 8082 (or any available port)
```

### Issue #4: Docker Compose Version Warning

**Warning**:
```
the attribute `version` is obsolete
```

**Solution**: Already fixed. The `version: '3.8'` line has been removed from `docker-compose.yml`.

### Issue #5: Permission Denied on init-databases.sh

**Error**:
```
permission denied: ./scripts/init-databases.sh
```

**Solution**:
```bash
chmod +x scripts/init-databases.sh
```

### Issue #6: Application Fails with Missing system_configurations Table

**Error**:
```
Schema-validation: missing table [system_configurations]
```

**Cause**: The system_configurations table was not included in the initial database migrations.

**Fix Applied**: Created V4 migration file to add the system_configurations table.

**If you encounter this issue**:
```bash
# The migration will run automatically on next startup
# Or run manually:
docker-compose exec app java -jar app.jar --spring.flyway.migrate=true
```

### Issue #7: Redis Connection Refused (localhost:6379)

**Error**:
```
Unable to connect to localhost/<unresolved>:6379
Connection refused
```

**Cause**: Spring Boot environment variable binding requires specific naming format for nested properties.

**Fix Applied**: Changed environment variables from `SPRING_REDIS_HOST` to `SPRING_DATA_REDIS_HOST` in docker-compose.yml.

**Solution**: Already fixed in docker-compose.yml. The correct format is:
```yaml
environment:
  SPRING_DATA_REDIS_HOST: redis
  SPRING_DATA_REDIS_PORT: 6379
```

### Issue #8: Application Logs Directory Missing

**Error**:
```
FileNotFoundException: logs/b2b-flight-platform.log (No such file or directory)
```

**Cause**: The Docker container didn't have the /app/logs directory created.

**Fix Applied**: Updated Dockerfile to create the logs directory with proper permissions.

**Solution**: Already fixed in Dockerfile:
```dockerfile
RUN mkdir -p /app/logs && chown -R spring:spring /app/logs
```

## Starting the Application

### Option 1: Run with Maven (Development)

```bash
mvn spring-boot:run
```

**Or with a specific profile**:
```bash
mvn spring-boot:run -Dspring-boot.run.profiles=dev
```

### Option 2: Run the JAR directly

```bash
java -jar target/b2b-flight-platform-1.0.0-SNAPSHOT.jar
```

### Option 3: Run with Docker Compose

```bash
docker-compose up -d app
```

**Watch the application logs**:
```bash
docker-compose logs -f app
```

**Look for**:
```
Started B2BFlightPlatformApplication in X.XXX seconds
```

## Verification

### 1. Check Application Health

```bash
curl http://localhost:8081/actuator/health
```

**Expected Response**:
```json
{
  "status": "UP",
  "components": {
    "db": {"status": "UP"},
    "redis": {"status": "UP"}
  }
}
```

### 2. Access Swagger UI

Open in browser: http://localhost:8081/swagger-ui.html

You should see the API documentation with all endpoints.

### 3. Access Keycloak Admin Console

Open in browser: http://localhost:8080

**Login credentials**:
- Username: `admin`
- Password: `admin`

### 4. Access RabbitMQ Management

Open in browser: http://localhost:15672

**Login credentials**:
- Username: `flight_user`
- Password: `flight_pass`

### 5. Test Database Connection

```bash
# Connect to flight_platform database
docker-compose exec postgres psql -U flight_user -d flight_platform

# List tables (should show Flyway migrations and application tables)
\dt

# Exit
\q
```

## Development Workflow

### Daily Development Routine

1. **Start infrastructure services** (if not already running):
   ```bash
   docker-compose up -d postgres redis rabbitmq keycloak
   ```

2. **Run the application** (choose one):
   ```bash
   # Option A: Maven (hot reload with spring-boot-devtools)
   mvn spring-boot:run
   
   # Option B: IDE (IntelliJ/VS Code)
   # Run the main class: com.flightticket.B2BFlightPlatformApplication
   ```

3. **Make code changes** - the application will auto-reload (if using devtools)

4. **Run tests**:
   ```bash
   # All tests
   mvn test
   
   # Specific test
   mvn test -Dtest=UserManagementServiceTest
   
   # Integration tests
   mvn verify -P integration-tests
   ```

5. **Check code coverage**:
   ```bash
   mvn test jacoco:report
   # Open: target/site/jacoco/index.html
   ```

### Stopping Services

**Stop application only** (keep infrastructure running):
```bash
# If running with Maven: Ctrl+C
# If running with Docker:
docker-compose stop app
```

**Stop all services**:
```bash
docker-compose down
```

**Stop and remove volumes** (clean slate):
```bash
docker-compose down -v
```

### Viewing Logs

```bash
# All services
docker-compose logs -f

# Specific service
docker-compose logs -f app
docker-compose logs -f postgres
docker-compose logs -f keycloak

# Last 100 lines
docker-compose logs --tail=100 app
```

### Database Management

**Access PostgreSQL**:
```bash
docker-compose exec postgres psql -U flight_user -d flight_platform
```

**Common PostgreSQL commands**:
```sql
-- List databases
\l

-- Connect to database
\c flight_platform

-- List tables
\dt

-- Describe table
\d users

-- Query data
SELECT * FROM users LIMIT 10;

-- Exit
\q
```

**Run Flyway migrations manually**:
```bash
mvn flyway:migrate
```

**Reset database** (careful - deletes all data):
```bash
mvn flyway:clean
mvn flyway:migrate
```

### Debugging

**Enable debug logging**:

Edit `src/main/resources/application-dev.yml`:
```yaml
logging:
  level:
    com.flightticket: DEBUG
    org.springframework.security: DEBUG
```

**Debug with IDE**:
1. Set breakpoints in your code
2. Run in debug mode from your IDE
3. The application will pause at breakpoints

**Remote debugging** (if running in Docker):

Add to `docker-compose.yml` app service:
```yaml
environment:
  JAVA_OPTS: "-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:5005"
ports:
  - "5005:5005"
```

Then connect your IDE debugger to `localhost:5005`.

## Troubleshooting Quick Reference

| Issue | Quick Fix |
|-------|-----------|
| Port in use | `lsof -i :8080` then `kill -9 <PID>` |
| Database connection failed | `docker-compose restart postgres` |
| Keycloak won't start | `docker-compose down -v && docker-compose up -d` |
| Application won't start | Check logs: `docker-compose logs app` |
| Tests failing | `mvn clean test` |
| Build failing | `mvn clean install -U` |
| Docker build slow | Use `docker build --no-cache` |
| Out of memory | Increase Docker memory in Docker Desktop settings |

## Next Steps

1. **Configure Keycloak**: See [Keycloak Configuration](DEPLOYMENT.md#keycloak-configuration)
2. **Set up Amadeus API**: See [Amadeus API Setup](DEPLOYMENT.md#amadeus-api-setup)
3. **Create test data**: Use the API or SQL scripts
4. **Explore API**: Use Swagger UI at http://localhost:8081/swagger-ui.html
5. **Read documentation**:
   - [API Documentation](API_DOCUMENTATION.md)
   - [Deployment Guide](DEPLOYMENT.md)
   - [Resilience Patterns](RESILIENCE_PATTERNS.md)

## Getting Help

- **Check logs**: `docker-compose logs -f`
- **Check health**: `curl http://localhost:8081/actuator/health`
- **Review documentation**: See `docs/` directory
- **Common issues**: See [Troubleshooting](#troubleshooting-quick-reference)

## Summary of Fixes Applied

This guide includes fixes for common issues encountered during setup:

1. ✅ **Docker Alpine Image Issue**: Updated Dockerfile to use standard images
2. ✅ **Keycloak Database Missing**: Created init script to create both databases
3. ✅ **Docker Compose Version Warning**: Removed obsolete version attribute
4. ✅ **Health Check Configuration**: Simplified Keycloak health check and fixed app health check to use curl
5. ✅ **Missing Logs Directory**: Updated Dockerfile to create /app/logs directory with proper permissions
6. ✅ **Missing system_configurations Table**: Created V4 migration to add system_configurations table
7. ✅ **Redis Connection Issue**: Fixed environment variable names (SPRING_DATA_REDIS_HOST instead of SPRING_REDIS_HOST)

All these fixes are already applied in the codebase, so you should have a smooth setup experience!
