# Google Maps API Setup Guide

## Overview

Complete guide for setting up Google Maps API for the Gas Stations feature. This includes API key creation, required API enablement, quota management, cost estimation, and security best practices.

## Prerequisites

- Google Cloud account
- Billing enabled on Google Cloud project
- Admin access to Google Cloud Console

## Step-by-Step Setup

### 1. Create Google Cloud Project

1. Navigate to [Google Cloud Console](https://console.cloud.google.com/)
2. Click **Select a project** > **New Project**
3. Enter project details:
   - **Project Name**: "MotoVaultPro" (or your preferred name)
   - **Organization**: Select your organization (if applicable)
   - **Location**: Choose appropriate folder
4. Click **Create**
5. Wait for project creation (usually 10-30 seconds)

### 2. Enable Billing

Google Maps APIs require billing to be enabled, even for free tier usage.

1. Navigate to **Billing** in the left sidebar
2. Click **Link a billing account**
3. Select existing billing account or create new one
4. Follow prompts to add payment method
5. Confirm billing is linked to your project

**Note**: You receive $200 free credit per month. Most usage stays within free tier.

### 3. Enable Required APIs

The Gas Stations feature requires two Google Maps APIs:

#### Enable Places API

1. Navigate to **APIs & Services** > **Library**
2. Search for "Places API"
3. Click **Places API** (not "Places API (New)")
4. Click **Enable**
5. Wait for enablement (usually instant)

#### Enable Maps JavaScript API

1. Navigate to **APIs & Services** > **Library**
2. Search for "Maps JavaScript API"
3. Click **Maps JavaScript API**
4. Click **Enable**
5. Wait for enablement (usually instant)

**Why both APIs?**
- **Places API**: Backend searches for nearby gas stations
- **Maps JavaScript API**: Frontend displays interactive map

### 4. Create API Key

1. Navigate to **APIs & Services** > **Credentials**
2. Click **+ CREATE CREDENTIALS** > **API key**
3. API key is created (format: `AIzaSyD...`)
4. **Immediately restrict the key** (next step)

**DO NOT USE UNRESTRICTED KEY IN PRODUCTION**

### 5. Restrict API Key (Critical Security Step)

#### Application Restrictions

**For Backend Key** (used by Node.js server):

1. Click on the newly created API key
2. Under **Application restrictions**:
   - Select **IP addresses**
   - Add your server's IP addresses:
     ```
     10.0.0.5/32    # Docker container IP
     YOUR_SERVER_IP  # Production server IP
     ```
3. Click **Save**

**For Frontend Key** (if using separate key):

1. Create a second API key following step 4
2. Under **Application restrictions**:
   - Select **HTTP referrers (web sites)**
   - Add allowed domains:
     ```
     https://motovaultpro.com/*
     https://motovaultpro.com/*  # Development only
     ```
3. Click **Save**

#### API Restrictions

Limit the key to only required APIs:

1. Under **API restrictions**:
   - Select **Restrict key**
   - Check **Places API**
   - Check **Maps JavaScript API** (if frontend key)
2. Click **Save**

**Important**: Frontend and backend can share one key, or use separate keys for finer control.

### 6. Copy API Key

1. Copy the API key value (starts with `AIzaSy...`)
2. Store securely (next section)

**Never commit API key to version control!**

## Storing the API Key

### Development (Local)

```bash
# Create secrets directory
mkdir -p ./secrets/app

# Add API key to secrets file
echo "AIzaSyYourActualKeyHere" > ./secrets/app/google-maps-api-key.txt

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

### Production (Docker Swarm)

```bash
# Create Docker secret
echo "AIzaSyYourActualKeyHere" | docker secret create google-maps-api-key -

# Verify secret created
docker secret ls
```

### Production (Kubernetes)

```bash
# Create Kubernetes secret
kubectl create secret generic google-maps-api-key \
  --from-literal=api-key=AIzaSyYourActualKeyHere

# Verify secret created
kubectl get secrets
```

**Update deployment manifest**:
```yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: motovaultpro-backend
spec:
  template:
    spec:
      containers:
      - name: backend
        volumeMounts:
        - name: google-maps-key
          mountPath: /run/secrets/google-maps-api-key
          subPath: google-maps-api-key
          readOnly: true
      volumes:
      - name: google-maps-key
        secret:
          secretName: google-maps-api-key
          items:
          - key: api-key
            path: google-maps-api-key
```

## Quota Management

### Free Tier Limits

Google provides $200 free credit per month, which translates to:

| API | Free Tier (per month) | Cost After Free Tier |
|-----|----------------------|---------------------|
| Places Nearby Search | 40,000 requests | $5 per 1,000 requests |
| Place Details | ~11,000 requests | $17 per 1,000 requests |
| Maps JavaScript API | 28,000 loads | $7 per 1,000 loads |

**Important**: Costs are approximate and subject to change. Check [Google Maps Platform Pricing](https://developers.google.com/maps/billing/gmp-billing) for current rates.

### Setting Quotas

Prevent unexpected costs by setting quota limits:

1. Navigate to **APIs & Services** > **Enabled APIs & services**
2. Click **Places API**
3. Click **Quotas** tab
4. Click **Edit Quotas** (pencil icon)
5. Set daily limits:
   - **Queries per day**: 1000 (adjust based on usage)
   - **Queries per 100 seconds per user**: 100
6. Click **Save**

Repeat for Maps JavaScript API if needed.

### Monitoring Usage

Track API usage to avoid surprises:

1. Navigate to **APIs & Services** > **Dashboard**
2. View usage graphs for each API
3. Set up alerts:
   - Click **Quotas** tab
   - Click **Create Alert** (bell icon)
   - Configure alert thresholds (e.g., 80% of quota)
   - Add email notification

## Cost Estimation

### Typical Usage Patterns

**Assumptions**:
- 100 active users per day
- Each user performs 3 searches per day
- Each search triggers 1 Places Nearby Search call
- 10% of searches result in saved stations (no additional cost)

**Calculation**:
```
Daily API calls: 100 users × 3 searches = 300 calls
Monthly API calls: 300 calls × 30 days = 9,000 calls

Cost:
- First 40,000 calls: FREE ($200 credit covers this)
- Total monthly cost: $0
```

**High Usage Scenario**:
- 1,000 active users per day
- 5 searches per user per day
- 150,000 calls per month

**Cost**:
```
Monthly API calls: 150,000 calls
Free tier: 40,000 calls
Billable calls: 110,000 calls

Cost:
- 110 batches × $5 = $550 per month
```

### Cost Optimization Strategies

1. **Cache Aggressively**: Store search results for 24 hours (already implemented)
2. **Limit Search Radius**: Default 5km instead of 50km reduces result size
3. **Paginate Results**: Only load details for visible stations
4. **Use Place IDs**: Cheaper than repeated searches
5. **Monitor Abuse**: Implement rate limiting per user

## Security Best Practices

### Key Restrictions

- Always restrict keys by IP (backend) or domain (frontend)
- Never use same key for development and production
- Rotate keys quarterly or after team member departures
- Use separate keys for different environments

### Environment Isolation

```bash
# Development
secrets/app/google-maps-api-key.txt  → Development key (restricted to motovaultpro.com)

# Production
Kubernetes secret                     → Production key (restricted to production IPs)
```

### Monitoring for Abuse

1. Set up billing alerts:
   - Navigate to **Billing** > **Budgets & alerts**
   - Click **Create Budget**
   - Set budget amount (e.g., $50)
   - Set alert thresholds (50%, 90%, 100%)
   - Add email notifications

2. Review usage regularly:
   - Check **APIs & Services** > **Dashboard** weekly
   - Look for unusual spikes
   - Investigate unexpected usage patterns

3. Implement application-level rate limiting:
   ```typescript
   // Example: Limit user to 10 searches per hour
   const rateLimiter = rateLimit({
     windowMs: 60 * 60 * 1000, // 1 hour
     max: 10, // 10 requests per window
     keyGenerator: (request) => request.user.sub // Per user
   });

   app.post('/api/stations/search', rateLimiter, searchHandler);
   ```

### Key Rotation

Rotate API keys periodically:

1. Create new API key (follow steps above)
2. Update secret in deployment:
   ```bash
   # Update Docker secret
   echo "NEW_KEY_HERE" > ./secrets/app/google-maps-api-key.txt
   docker compose restart mvp-backend mvp-frontend

   # Update Kubernetes secret
   kubectl delete secret google-maps-api-key
   kubectl create secret generic google-maps-api-key \
     --from-literal=api-key=NEW_KEY_HERE
   kubectl rollout restart deployment/motovaultpro-backend
   ```
3. Verify new key works
4. Delete old key from Google Cloud Console

## Troubleshooting

### "API Key Invalid" Error

**Symptom**: 400 error with message "The provided API key is invalid"

**Solutions**:
1. Verify key is correctly copied (no extra spaces/newlines)
2. Check secret file exists:
   ```bash
   docker compose exec mvp-backend cat /run/secrets/google-maps-api-key
   ```
3. Verify APIs are enabled in Google Cloud Console
4. Wait 5 minutes after creating key (propagation delay)

### "API Key Not Authorized" Error

**Symptom**: 403 error with message "This API project is not authorized"

**Solutions**:
1. Verify IP restriction includes server IP
2. Check API restrictions allow Places API
3. Verify billing is enabled
4. Remove restrictions temporarily to test (then re-add)

### "Quota Exceeded" Error

**Symptom**: 429 error with message "You have exceeded your quota"

**Solutions**:
1. Check usage in Google Cloud Console
2. Increase quota limit (if within budget)
3. Review caching strategy (24-hour TTL implemented)
4. Implement rate limiting per user

### "Daily Limit Exceeded" Error

**Symptom**: Requests fail after certain number of calls

**Solutions**:
1. Check quota settings in Google Cloud Console
2. Increase daily limit
3. Review application for excessive API calls
4. Implement exponential backoff on failures

### Key Not Loading in Container

**Symptom**: Container logs show "Google Maps API key not found"

**Solutions**:
1. Verify secret file exists:
   ```bash
   ls -la ./secrets/app/
   ```
2. Check Docker volume mount in docker-compose.yml:
   ```yaml
   volumes:
     - ./secrets/app/google-maps-api-key.txt:/run/secrets/google-maps-api-key:ro
   ```
3. Verify file permissions (must be readable):
   ```bash
   chmod 644 ./secrets/app/google-maps-api-key.txt
   ```
4. Restart containers:
   ```bash
   docker compose restart mvp-backend mvp-frontend
   ```

### High Unexpected Costs

**Symptom**: Billing alert for unexpected API usage

**Solutions**:
1. Review API usage in Google Cloud Console
2. Check for infinite loops in code
3. Verify caching is working (check Redis/PostgreSQL)
4. Look for bot traffic or abuse
5. Implement stricter rate limiting
6. Reduce search radius or result count

## Verification Checklist

After setup, verify everything works:

- [ ] Google Cloud project created
- [ ] Billing enabled
- [ ] Places API enabled
- [ ] Maps JavaScript API enabled (if using frontend map)
- [ ] API key created
- [ ] Key restricted by IP/domain
- [ ] Key restricted to required APIs
- [ ] Key stored in secrets file
- [ ] Quota limits configured
- [ ] Billing alerts configured
- [ ] Key tested in development:
  ```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}'
  ```
- [ ] No errors in container logs
- [ ] Search returns results
- [ ] Usage appears in Google Cloud Console

## Cost Monitoring Dashboard

Create a cost monitoring routine:

**Weekly Review**:
1. Check API usage dashboard
2. Verify costs are within budget
3. Review for unusual patterns

**Monthly Review**:
1. Analyze usage trends
2. Optimize expensive queries
3. Adjust quotas if needed
4. Review and adjust budget alerts

**Quarterly Review**:
1. Rotate API keys
2. Review user growth vs. API costs
3. Evaluate alternative pricing tiers
4. Update cost projections

## Additional Resources

- [Google Maps Platform Documentation](https://developers.google.com/maps/documentation)
- [Places API Documentation](https://developers.google.com/maps/documentation/places/web-service/overview)
- [Pricing Calculator](https://cloud.google.com/maps-platform/pricing)
- [Best Practices Guide](https://developers.google.com/maps/documentation/places/web-service/best-practices)
- [API Key Best Practices](https://developers.google.com/maps/api-security-best-practices)

## Support

For issues with:
- **Google Cloud billing**: Contact Google Cloud Support
- **API setup**: Review this guide and Google documentation
- **MotoVaultPro integration**: Check container logs and application documentation

## 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`
- Feature README: `/backend/src/features/stations/README.md`
- Runtime Config: `/frontend/docs/RUNTIME-CONFIG.md`
