# Gas Stations Feature - Deployment Checklist

## Overview

Complete deployment checklist for the Gas Stations feature. This document covers configuration, secrets, database migrations, and validation steps required for production deployment.

## Pre-Deployment Checklist

### 1. Google Maps API Configuration

- [ ] Google Cloud project created
- [ ] Billing enabled on Google Cloud project
- [ ] Places API enabled
- [ ] Maps JavaScript API enabled (for frontend)
- [ ] API key created
- [ ] API key restricted by IP (backend)
- [ ] API key restricted by domain (frontend, if separate key)
- [ ] API key restricted to required APIs only
- [ ] Quota limits configured (prevent unexpected costs)
- [ ] Billing alerts configured ($50, $100 thresholds)
- [ ] API key tested in development environment

**Verification**:
```bash
# Test API key works
curl "https://maps.googleapis.com/maps/api/place/nearbysearch/json?location=37.7749,-122.4194&radius=5000&type=gas_station&key=YOUR_API_KEY"
```

**Documentation**: See `/backend/src/features/stations/docs/GOOGLE-MAPS-SETUP.md`

### 2. Secrets Configuration

#### Backend Secret

- [ ] Secret file created: `./secrets/app/google-maps-api-key.txt`
- [ ] Secret contains valid API key (no extra whitespace/newlines)
- [ ] File permissions set correctly (`chmod 644`)
- [ ] Docker volume mount configured in `docker-compose.yml`:
  ```yaml
  mvp-backend:
    volumes:
      - ./secrets/app/google-maps-api-key.txt:/run/secrets/google-maps-api-key:ro
  ```
- [ ] Environment variable set: `SECRETS_DIR=/run/secrets`

**Verification**:
```bash
# Check secret file exists locally
cat ./secrets/app/google-maps-api-key.txt

# Check secret mounted in backend container
docker compose exec mvp-backend cat /run/secrets/google-maps-api-key
```

#### Frontend Secret

- [ ] Same secret file used (or separate key if using domain restrictions)
- [ ] Docker volume mount configured in `docker-compose.yml`:
  ```yaml
  mvp-frontend:
    volumes:
      - ./secrets/app/google-maps-api-key.txt:/run/secrets/google-maps-api-key:ro
  ```
- [ ] Environment variable set: `SECRETS_DIR=/run/secrets`
- [ ] Entrypoint script configured to generate config.js

**Verification**:
```bash
# Check config.js generated
docker compose exec mvp-frontend cat /usr/share/nginx/html/config.js
# Should output: window.CONFIG = { googleMapsApiKey: "AIza..." }

# Check in browser console
# Open https://motovaultpro.com
# Run: console.log(window.CONFIG)
```

### 3. Database Migrations

- [ ] PostgreSQL database accessible
- [ ] Database connection string configured
- [ ] All migrations files present in `backend/src/features/stations/migrations/`
- [ ] Migrations not run yet (will run during deployment)

**Migration Files**:
1. `001_create_stations_tables.sql` - Creates station_cache and saved_stations tables
2. `002_add_indexes.sql` - Adds performance indexes

**Verification** (before running migrations):
```bash
# Check tables don't exist yet
docker compose exec postgres psql -U postgres -d motovaultpro -c "\dt station*"
# Should return "Did not find any relations"
```

### 4. Redis Cache

- [ ] Redis service running
- [ ] Backend can connect to Redis
- [ ] Connection string configured: `redis://redis:6379`

**Verification**:
```bash
# Check Redis is running
docker compose exec redis redis-cli ping
# Should return: PONG

# Check backend can connect
docker compose logs mvp-backend | grep -i redis
# Should show successful connection
```

### 5. Code Quality

- [ ] All linters passing: `npm run lint`
- [ ] All type checks passing: `npm run type-check`
- [ ] All tests passing: `npm test -- features/stations`
- [ ] No console.log statements in production code
- [ ] No commented-out code
- [ ] No TODO comments for critical functionality

**Verification**:
```bash
cd backend
npm run lint
npm run type-check
npm test -- features/stations

cd ../frontend
npm run lint
npm run type-check
npm test -- stations
```

### 6. Dependencies

- [ ] All npm packages installed
- [ ] No security vulnerabilities: `npm audit`
- [ ] Package versions match package-lock.json
- [ ] Docker images built successfully

**Verification**:
```bash
cd backend
npm audit --production
npm ci  # Clean install

cd ../frontend
npm audit --production
npm ci

# Build containers
make rebuild
```

## Deployment Steps

### Step 1: Backup Existing System

```bash
# Backup database
docker compose exec postgres pg_dump -U postgres motovaultpro > backup_$(date +%Y%m%d_%H%M%S).sql

# Backup secrets (if rotating)
cp ./secrets/app/google-maps-api-key.txt ./secrets/app/google-maps-api-key.txt.bak

# Backup docker volumes (if any)
docker compose down
tar -czf volumes_backup_$(date +%Y%m%d_%H%M%S).tar.gz /var/lib/docker/volumes/
```

### Step 2: Stop Services

```bash
# Graceful shutdown
docker compose down

# Verify all containers stopped
docker compose ps
```

### Step 3: Update Code

```bash
# Pull latest code
git fetch origin
git checkout main
git pull origin main

# Verify correct branch and commit
git log -1
git status
```

### Step 4: Install Dependencies

```bash
# Backend dependencies
cd backend
npm ci
cd ..

# Frontend dependencies
cd frontend
npm ci
cd ..
```

### Step 5: Run Database Migrations

```bash
# Start database (if not already running)
docker compose up -d postgres

# Wait for database to be ready
sleep 5

# Run migrations
docker compose exec mvp-backend npm run migrate

# Verify migrations ran successfully
docker compose exec postgres psql -U postgres -d motovaultpro -c "\dt station*"
# Should show: station_cache, saved_stations
```

**Expected Output**:
```
              List of relations
 Schema |      Name       | Type  |  Owner
--------+-----------------+-------+----------
 public | station_cache   | table | postgres
 public | saved_stations  | table | postgres
```

### Step 6: Configure Secrets

```bash
# Ensure secrets directory exists
mkdir -p ./secrets/app

# Add Google Maps API key (if not already present)
echo "YOUR_GOOGLE_MAPS_API_KEY" > ./secrets/app/google-maps-api-key.txt

# Set correct permissions
chmod 644 ./secrets/app/google-maps-api-key.txt

# Verify secret file
cat ./secrets/app/google-maps-api-key.txt
```

### Step 7: Build and Start Services

```bash
# Build images
make rebuild

# Start services
docker compose up -d

# Monitor startup logs
docker compose logs -f
```

**Watch for**:
- Backend: "Server listening on port 3001"
- Frontend: "[Config] Generated /usr/share/nginx/html/config.js"
- Database: "database system is ready to accept connections"
- Redis: "Ready to accept connections"

### Step 8: Verify Services Started

```bash
# Check all containers running
docker compose ps
# All should show "Up" status

# Check backend health
curl -s https://motovaultpro.com/api/health | jq
# Should return: {"status":"ok","features":["stations",...]}

# Check frontend loads
curl -s https://motovaultpro.com | grep "MotoVaultPro"
# Should return HTML with app name
```

## Post-Deployment Validation

### 1. Health Checks

Run comprehensive health checks to verify deployment:

**Backend Health**:
```bash
# Overall health check
curl https://motovaultpro.com/api/health

# Stations feature health (implicit in API availability)
curl -H "Authorization: Bearer $TEST_TOKEN" \
  https://motovaultpro.com/api/stations/saved
```

**Frontend Health**:
```bash
# Check frontend loads
curl -I https://motovaultpro.com
# Should return: 200 OK

# Check config.js loads
curl https://motovaultpro.com/config.js
# Should return: window.CONFIG = {...}
```

**Database Health**:
```bash
# Check tables exist
docker compose exec postgres psql -U postgres -d motovaultpro \
  -c "SELECT COUNT(*) FROM station_cache;"

docker compose exec postgres psql -U postgres -d motovaultpro \
  -c "SELECT COUNT(*) FROM saved_stations;"
```

**Redis Health**:
```bash
# Check Redis connection
docker compose exec redis redis-cli ping
# Should return: PONG

# Check keys (should be empty initially)
docker compose exec redis redis-cli KEYS "station:*"
```

### 2. API Endpoint Testing

Test all stations API endpoints with actual JWT:

**Get JWT Token**:
```bash
# Authenticate via Auth0 to get token
# Or use test token from Auth0 dashboard
export TOKEN="eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9..."
```

**Test Search Endpoint**:
```bash
curl -X POST https://motovaultpro.com/api/stations/search \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "latitude": 37.7749,
    "longitude": -122.4194,
    "radius": 5000
  }' | jq
```

**Expected Response**:
```json
{
  "stations": [
    {
      "placeId": "ChIJ...",
      "name": "Shell Gas Station",
      "address": "123 Main St, San Francisco, CA",
      "latitude": 37.7750,
      "longitude": -122.4195,
      "rating": 4.2,
      "distance": 150
    }
  ],
  "searchLocation": {
    "latitude": 37.7749,
    "longitude": -122.4194
  },
  "searchRadius": 5000,
  "timestamp": "2025-01-15T10:30:00.000Z"
}
```

**Test Save Endpoint**:
```bash
# First search to populate cache
PLACE_ID=$(curl -X POST https://motovaultpro.com/api/stations/search \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"latitude": 37.7749, "longitude": -122.4194}' | \
  jq -r '.stations[0].placeId')

# Then save station
curl -X POST https://motovaultpro.com/api/stations/save \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d "{
    \"placeId\": \"$PLACE_ID\",
    \"nickname\": \"Test Station\",
    \"isFavorite\": true
  }" | jq
```

**Test Get Saved Endpoint**:
```bash
curl -X GET https://motovaultpro.com/api/stations/saved \
  -H "Authorization: Bearer $TOKEN" | jq
```

**Test Delete Endpoint**:
```bash
curl -X DELETE https://motovaultpro.com/api/stations/saved/$PLACE_ID \
  -H "Authorization: Bearer $TOKEN"
# Should return 204 No Content
```

### 3. Frontend Testing

**Browser Testing**:
1. Open https://motovaultpro.com in browser
2. Navigate to Stations feature
3. Click "Use Current Location" (grant permission)
4. Verify search completes and stations display
5. Click on map marker, verify details shown
6. Save a station, verify it appears in Saved tab
7. Test on mobile device (responsive layout)

**Console Checks**:
```javascript
// Check runtime config loaded
console.log(window.CONFIG);
// Should show: { googleMapsApiKey: "AIza..." }

// Check no errors in console
// Should be clean, no red errors
```

### 4. User Data Isolation Verification

Verify users can only access their own data:

```bash
# User 1 saves a station
USER1_TOKEN="..."
PLACE_ID=$(curl -X POST https://motovaultpro.com/api/stations/search \
  -H "Authorization: Bearer $USER1_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"latitude": 37.7749, "longitude": -122.4194}' | \
  jq -r '.stations[0].placeId')

curl -X POST https://motovaultpro.com/api/stations/save \
  -H "Authorization: Bearer $USER1_TOKEN" \
  -H "Content-Type: application/json" \
  -d "{\"placeId\": \"$PLACE_ID\"}"

# User 2 should NOT see User 1's saved station
USER2_TOKEN="..."
curl -X GET https://motovaultpro.com/api/stations/saved \
  -H "Authorization: Bearer $USER2_TOKEN" | jq
# Should return: [] (empty array)
```

### 5. Performance Validation

Test response times meet requirements:

```bash
# Search endpoint (should be < 1500ms)
time curl -X POST https://motovaultpro.com/api/stations/search \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"latitude": 37.7749, "longitude": -122.4194}'

# Saved stations endpoint (should be < 100ms)
time curl -X GET https://motovaultpro.com/api/stations/saved \
  -H "Authorization: Bearer $TOKEN"
```

**Expected Response Times**:
- Search: 500-1500ms (includes Google API call)
- Save: 50-100ms
- Get Saved: 50-100ms
- Delete: 50-100ms

### 6. Monitoring Setup

**Container Logs**:
```bash
# Monitor all logs
docker compose logs -f

# Monitor backend only
docker compose logs -f mvp-backend

# Search for errors
docker compose logs | grep -i error
docker compose logs | grep -i warning
```

**Google Maps API Usage**:
1. Go to Google Cloud Console
2. Navigate to APIs & Services > Dashboard
3. View Places API usage
4. Verify requests are being logged

**Database Monitoring**:
```bash
# Check station cache size
docker compose exec postgres psql -U postgres -d motovaultpro \
  -c "SELECT COUNT(*) as cache_count FROM station_cache;"

# Check saved stations count
docker compose exec postgres psql -U postgres -d motovaultpro \
  -c "SELECT COUNT(*) as saved_count FROM saved_stations;"
```

## Rollback Procedure

If issues arise during deployment, follow this rollback procedure:

### Immediate Rollback

```bash
# Stop containers
docker compose down

# Restore previous code
git checkout <PREVIOUS_COMMIT_HASH>

# Restore secrets backup (if changed)
cp ./secrets/app/google-maps-api-key.txt.bak ./secrets/app/google-maps-api-key.txt

# Rollback database migrations
docker compose exec postgres psql -U postgres -d motovaultpro < backup_YYYYMMDD_HHMMSS.sql

# Restart services
docker compose up -d

# Verify rollback successful
curl https://motovaultpro.com/api/health
```

### Partial Rollback (Disable Feature)

If only stations feature needs to be disabled:

```bash
# Remove stations routes from backend
# Edit backend/src/app.ts to comment out stations routes

# Rebuild backend
docker compose up -d --build mvp-backend

# Verify other features still work
curl https://motovaultpro.com/api/health
```

### Database Rollback Only

If only database changes need to be reverted:

```bash
# Drop stations tables
docker compose exec postgres psql -U postgres -d motovaultpro <<EOF
DROP TABLE IF EXISTS saved_stations;
DROP TABLE IF EXISTS station_cache;
EOF

# Verify tables removed
docker compose exec postgres psql -U postgres -d motovaultpro -c "\dt station*"
# Should return: Did not find any relations
```

## Troubleshooting

### Common Issues

**Issue**: Backend can't read Google Maps API key

**Symptoms**:
- Logs show "Google Maps API key not found"
- Search endpoint returns 502 error

**Solutions**:
```bash
# Check secret file exists
docker compose exec mvp-backend cat /run/secrets/google-maps-api-key

# Check mount in docker-compose.yml
grep -A5 "mvp-backend:" docker-compose.yml | grep "google-maps"

# Restart backend
docker compose restart mvp-backend
```

**Issue**: Frontend config.js not generated

**Symptoms**:
- Browser console shows "window.CONFIG is undefined"
- Map doesn't load

**Solutions**:
```bash
# Check entrypoint script runs
docker compose logs mvp-frontend | grep -i config

# Check config.js exists
docker compose exec mvp-frontend cat /usr/share/nginx/html/config.js

# Restart frontend
docker compose restart mvp-frontend
```

**Issue**: Database migrations fail

**Symptoms**:
- Migrations error during deployment
- Tables don't exist

**Solutions**:
```bash
# Check database connection
docker compose exec postgres psql -U postgres -l

# Run migrations manually
docker compose exec mvp-backend npm run migrate

# Check migration logs
docker compose logs mvp-backend | grep -i migration
```

**Issue**: Search returns no results

**Symptoms**:
- Search completes but returns empty array
- No errors in logs

**Solutions**:
1. Verify location is correct (valid lat/lng)
2. Try larger radius (50km instead of 5km)
3. Check Google Maps API quota not exceeded
4. Verify circuit breaker not open

**Issue**: High Google Maps API costs

**Symptoms**:
- Billing alert triggered
- Unexpected charges

**Solutions**:
1. Check usage in Google Cloud Console
2. Review quota limits
3. Implement rate limiting (if not already)
4. Reduce search radius
5. Increase cache TTL (currently 24h)

## Production Monitoring

### Daily Checks

- [ ] Check container health: `docker compose ps`
- [ ] Review error logs: `docker compose logs | grep -i error`
- [ ] Verify API responding: `curl https://motovaultpro.com/api/health`

### Weekly Checks

- [ ] Review Google Maps API usage
- [ ] Check database size: `SELECT pg_size_pretty(pg_database_size('motovaultpro'));`
- [ ] Review saved stations count
- [ ] Check for any user-reported issues

### Monthly Checks

- [ ] Review Google Maps API costs
- [ ] Rotate API keys (if policy requires)
- [ ] Update dependencies: `npm audit`
- [ ] Review and archive old logs

## Support Contacts

**Google Maps API Issues**:
- Google Cloud Support: https://cloud.google.com/support

**Infrastructure Issues**:
- Review container logs: `docker compose logs`
- Check database connectivity
- Verify Redis connectivity

**Application Issues**:
- Review backend logs
- Check frontend browser console
- Test API endpoints with curl

## References

- Architecture: `/backend/src/features/stations/docs/ARCHITECTURE.md`
- API Documentation: `/backend/src/features/stations/docs/API.md`
- Testing Guide: `/backend/src/features/stations/docs/TESTING.md`
- Google Maps Setup: `/backend/src/features/stations/docs/GOOGLE-MAPS-SETUP.md`
- Database Migrations: `/backend/src/features/stations/docs/deployment/DATABASE-MIGRATIONS.md`
- Secrets Verification: `/backend/src/features/stations/docs/deployment/SECRETS-VERIFICATION.md`
- Health Checks: `/backend/src/features/stations/docs/deployment/HEALTH-CHECKS.md`
- Production Readiness: `/backend/src/features/stations/docs/deployment/PRODUCTION-READINESS.md`
