# Cloudflare Integration Setup

This guide explains how to configure Cloudflare DNS automation for AMSOIL dealer landing pages.

> **Scope:** this covers **dealer-subdomain DNS automation** in the 4 apex zones (`myamsoil.com`, `myamsoil.ca`, `shopamsoil.com`, `shopamsoil.ca`). It does **not** cover custom (dealer-owned) domains — those use certbot / Let's Encrypt, **not** Cloudflare for SaaS. See [`CUSTOM_DOMAINS.md`](./CUSTOM_DOMAINS.md).

## Prerequisites

- Cloudflare account with administrative access
- Domain configured and active in Cloudflare (e.g., `myamsoil.com`)
- API token permissions enabled
- Server IP address (public IP of production or development server)

## Architecture Overview

When a dealer publishes their landing page:

1. Application creates an A record in Cloudflare pointing the subdomain to the server IP
2. ISR revalidation generates static content for the subdomain
3. DNS propagates (typically within seconds)
4. Subdomain becomes immediately accessible (e.g., `bobsoil.myamsoil.com`)

## Getting Cloudflare Credentials

### Step 1: Create API Token

1. Log into [Cloudflare Dashboard](https://dash.cloudflare.com)
2. Navigate to **Account Home → API Tokens** (left sidebar)
3. Click **Create Token** button
4. Use the **Edit zone DNS** template or create a custom token with these permissions:
   - **Zone** → **DNS** → **Edit**
   - **Zone** → **Zone** → **Read**
5. Set the scope to your specific zone (e.g., `myamsoil.com`)
6. Set TTL as needed (recommended: No TTL or 90 days)
7. Click **Continue to summary** → **Create Token**
8. Copy the token immediately (you won't see it again)

**Example permissions:**

```
✓ Zone.DNS.Edit
✓ Zone.Zone.Read
- Scoped to: myamsoil.com zone
```

### Step 2: Get Your Zone ID

1. In Cloudflare Dashboard, select your domain (e.g., `myamsoil.com`)
2. Right sidebar shows **Zone ID** (looks like: `a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6`)
3. Copy this value

### Step 3: Get Your Server IP Address

Get your server's public IP address:

```bash
# On the server:
curl https://api.ipify.org

# Or from your cloud provider (AWS, Google Cloud, DigitalOcean, etc.)
```

### Step 4: Configure Environment Variables

Add these to `.env.local` (development) or production secrets:

```bash
# Cloudflare API credentials
CLOUDFLARE_API_TOKEN=your_api_token_here
CLOUDFLARE_ZONE_ID=your_zone_id_here
SERVER_IP_ADDRESS=your_server_ip_here
```

**Important:** Never commit these credentials to version control.

## Verification

### Verify credentials are working:

1. Start the development server:

   ```bash
   npm run dev
   ```

2. Check server startup logs for:

   ```
   ✓ Cloudflare integration initialized
   ```

3. Test by publishing a dealer:
   - Navigate to dashboard
   - Click publish on a dealer
   - Should see success response with subdomain

### Verify DNS record in Cloudflare:

1. Log into Cloudflare Dashboard
2. Select your zone (e.g., `myamsoil.com`)
3. Navigate to **DNS** section
4. Look for the new A record with subdomain and your server IP
5. Verify status shows **Proxied** (orange cloud icon)

## Environment-Specific Setup

### Development Setup

```bash
# Create .env.local (git-ignored)
CLOUDFLARE_API_TOKEN=test_token_from_cloudflare
CLOUDFLARE_ZONE_ID=your_zone_id
SERVER_IP_ADDRESS=your_local_machine_ip_or_ngrok_url
NEXTAUTH_URL=http://localhost:3000
```

Note: If testing locally with ngrok or similar:

```bash
# Use ngrok's forwarding IP
SERVER_IP_ADDRESS=$(curl -s http://localhost:4040/api/tunnels | jq -r '.tunnels[0].public_url' | sed 's/https:\/\///g' | sed 's/:.*//')
```

### Production Setup

- Use production Cloudflare credentials
- Use production server IP address
- Store credentials in production secret manager (AWS Secrets, Google Secret Manager, etc.)
- Never hardcode credentials in deployment scripts

## Troubleshooting

### "Missing Cloudflare environment variables"

**Error:** Endpoint returns this error when trying to publish

**Causes:**

- `.env.local` not created or missing variable
- Variable name spelled incorrectly
- Server hasn't been restarted after adding env variables

**Fix:**

```bash
# Check variables are set
echo $CLOUDFLARE_API_TOKEN
echo $CLOUDFLARE_ZONE_ID
echo $SERVER_IP_ADDRESS

# If empty, verify .env.local exists and reload shell
source ~/.bashrc  # or ~/.zshrc
```

### "Cloudflare API error: Invalid token"

**Error:** Token validation fails

**Causes:**

- Token is incorrect or expired
- Token doesn't have DNS.Edit permission
- Token scope doesn't include your zone

**Fix:**

1. Generate new token with correct permissions
2. Verify token works: `curl -X GET "https://api.cloudflare.com/client/v4/user/tokens/verify" -H "Authorization: Bearer YOUR_TOKEN"`
3. Update `.env.local` and restart server

### "DNS record not found for [subdomain]"

**Error:** Trying to republish and record lookup fails

**Causes:**

- DNS record was manually deleted from Cloudflare
- Zone ID is incorrect
- API token doesn't have permission to list records

**Fix:**

- Verify zone ID in Cloudflare dashboard matches `.env.local`
- Check API token permissions include Zone.Zone.Read
- Manual republish will create a new record

### DNS record created but subdomain not accessible

**Causes:**

- DNS propagation delay (up to 60 seconds, usually <5 seconds)
- Server not running or not responding on SERVER_IP_ADDRESS
- Firewall blocking port 80/443
- Wrong IP address in SERVER_IP_ADDRESS variable

**Fix:**

```bash
# Wait 30-60 seconds
sleep 30

# Check DNS resolution
nslookup testdealer.myamsoil.com
# or
dig testdealer.myamsoil.com

# Check server is accessible
curl -I http://SERVER_IP_ADDRESS
```

## API Rate Limiting

Cloudflare API has rate limits:

- **Enterprise**: 1200 requests per hour
- **Pro/Business**: 1200 requests per hour
- **Free**: 1200 requests per hour

Current implementation:

- Creates 1 DNS record per publish (first publish only)
- No rate limit concerns for normal usage

## Security Considerations

1. **Token Scope**: Limit token to specific zone, not account-wide
2. **Token Permissions**: Use only required permissions (DNS.Edit, Zone.Read)
3. **Rotation**: Rotate tokens periodically (every 90 days recommended)
4. **Monitoring**: Enable audit logs in Cloudflare to monitor API usage
5. **Secrets Management**: Use environment variables or secret managers, never hardcode

## References

- [Cloudflare API Tokens](https://developers.cloudflare.com/api/tokens/)
- [Cloudflare API Documentation](https://developers.cloudflare.com/api/)
- [DNS Records API](https://developers.cloudflare.com/api/operations/dns-records-get)
