# ✅ API Subdomain - COMPLETE & WORKING!

## What Changed

### Old Architecture (REMOVED)
```
Browser → Traefik → PWA nginx → API (internal proxy)
                          ↓
                    /api/ → http://api:8000/
                    /ws/  → http://api:8000/ws/
```

### New Architecture (CURRENT)
```
Browser → Traefik → API (api.echoesoftheashgame.patacuack.net:8000)
Browser → Traefik → PWA (echoesoftheashgame.patacuack.net:80)
```

## Why This Is Better

1. **Cleaner Separation**: Frontend and backend are completely separate services
2. **Better Performance**: No nginx proxy hop - direct Traefik → API
3. **Easier Debugging**: Clear separation in logs and network requests
4. **Independent Scaling**: Can scale PWA and API separately
5. **Standard Architecture**: Industry standard microservices pattern

## Verified Working ✅

### API Subdomain Tests
```bash
# Health endpoint
$ curl https://api.echoesoftheashgame.patacuack.net/health
{"status":"healthy","version":"2.0.0","locations_loaded":14,"items_loaded":42}

# Login endpoint (with wrong password)
$ curl -X POST https://api.echoesoftheashgame.patacuack.net/api/auth/login \
  -H "Content-Type: application/json" \
  -d '{"username":"test","password":"wrong"}'
{"detail":"Invalid username or password"}

# ✅ Both returning proper responses!
```

### PWA Configuration
```bash
# PWA loads correctly
$ curl -I https://echoesoftheashgame.patacuack.net
HTTP/2 200 ✅

# API URL is baked into build
$ docker exec echoes_of_the_ashes_pwa sh -c 'grep -o "api\.echoesoftheashgame\.patacuack\.net" /usr/share/nginx/html/assets/index-*.js'
api.echoesoftheashgame.patacuack.net ✅
```

### nginx Configuration
```bash
# No more /api/ or /ws/ proxy routes
$ docker exec echoes_of_the_ashes_pwa cat /etc/nginx/conf.d/default.conf | grep location
    location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ {
    location /sw.js {
    location /workbox-*.js {
    location /manifest.webmanifest {
    location / {

# ✅ Only static file serving!
```

## API Endpoint Reference

### Base URLs
- **API**: `https://api.echoesoftheashgame.patacuack.net`
- **PWA**: `https://echoesoftheashgame.patacuack.net`

### REST Endpoints (all have /api prefix)
```
POST   https://api.echoesoftheashgame.patacuack.net/api/auth/register
POST   https://api.echoesoftheashgame.patacuack.net/api/auth/login
GET    https://api.echoesoftheashgame.patacuack.net/api/auth/me
GET    https://api.echoesoftheashgame.patacuack.net/api/game/state
GET    https://api.echoesoftheashgame.patacuack.net/api/game/profile
POST   https://api.echoesoftheashgame.patacuack.net/api/game/move
POST   https://api.echoesoftheashgame.patacuack.net/api/game/interact
... etc
```

### WebSocket Endpoint (no /api prefix)
```
wss://api.echoesoftheashgame.patacuack.net/ws/game/{token}
```

## PWA Configuration

### Environment Variable
```typescript
// pwa/src/services/api.ts
const API_URL = import.meta.env.VITE_API_URL || (
  import.meta.env.PROD 
    ? 'https://api.echoesoftheashgame.patacuack.net/api'  // ← /api suffix for REST
    : 'http://localhost:8000/api'
)
```

### WebSocket Configuration
```typescript
// pwa/src/hooks/useGameWebSocket.ts
const API_BASE = import.meta.env.VITE_API_URL || (
  import.meta.env.PROD 
    ? 'https://api.echoesoftheashgame.patacuack.net'  // ← no /api for WebSocket
    : 'http://localhost:8000'
);
const wsBase = API_BASE.replace(/\/api$/, '').replace(/^http/, 'ws');
// Results in: wss://api.echoesoftheashgame.patacuack.net/ws/game/{token}
```

## Docker Configuration

### docker-compose.yml
```yaml
echoes_of_the_ashes_api:
  networks:
    - default_docker
    - traefik  # ← Now exposed via Traefik!
  labels:
    - traefik.enable=true
    - traefik.http.routers.echoesoftheashapi.rule=Host(`api.echoesoftheashgame.patacuack.net`)
    - traefik.http.services.echoesoftheashapi.loadbalancer.server.port=8000

echoes_of_the_ashes_pwa:
  build:
    args:
      VITE_API_URL: https://api.echoesoftheashgame.patacuack.net/api  # ← Baked into build
  networks:
    - default_docker
    - traefik
```

### Dockerfile.pwa
```dockerfile
ARG VITE_API_URL=https://api.echoesoftheashgame.patacuack.net/api
ENV VITE_API_URL=$VITE_API_URL
```

### nginx.conf
```nginx
# REMOVED:
# location /api/ { proxy_pass http://api:8000/; }
# location /ws/ { proxy_pass http://api:8000/ws/; }

# NOW ONLY:
location / {
    try_files $uri $uri/ /index.html;
}
```

## DNS Configuration

**Required DNS Records:**
```
A    api.echoesoftheashgame.patacuack.net  →  <your-server-ip>
A    echoesoftheashgame.patacuack.net      →  <your-server-ip>
```

**TLS Certificates:**
- Both subdomains get Let's Encrypt certificates from Traefik
- Auto-renewal configured
- Both use certResolver=production

## Testing Checklist ✅

- [x] API health endpoint returns 200
- [x] API login endpoint returns proper error for invalid credentials
- [x] PWA loads and serves static files
- [x] API URL is embedded in PWA build (not runtime fallback)
- [x] nginx config simplified (no proxy routes)
- [x] Both domains have valid TLS certificates
- [x] WebSocket endpoint exists (returns 404 for invalid token as expected)
- [x] Traefik routes both services correctly

## What to Test in Browser

1. **Open PWA**: https://echoesoftheashgame.patacuack.net
2. **Check Network Tab**:
   - API calls should go to `api.echoesoftheashgame.patacuack.net/api/*`
   - WebSocket should connect to `wss://api.echoesoftheashgame.patacuack.net/ws/game/*`
3. **Login/Register**: Should work normally
4. **Game Actions**: All should work (move, combat, inventory, etc.)
5. **WebSocket**: Should connect and show real-time updates

## Troubleshooting

### If API calls fail
```bash
# Check API is running
docker compose logs echoes_of_the_ashes_api

# Test health endpoint
curl https://api.echoesoftheashgame.patacuack.net/health

# Check Traefik routing
docker compose logs | grep api.echoesoftheashgame
```

### If WebSocket fails
```bash
# Check logs for WebSocket connections
docker compose logs echoes_of_the_ashes_api | grep -i websocket

# Verify token is valid (login to get fresh token)
# Old tokens won't work after rebuild
```

### If PWA loads but can't connect to API
```bash
# Verify API URL is in build
docker exec echoes_of_the_ashes_pwa sh -c 'grep -o "api\.echoesoftheashgame\.patacuack\.net" /usr/share/nginx/html/assets/index-*.js'

# If not found, rebuild PWA
docker compose build echoes_of_the_ashes_pwa
docker compose up -d echoes_of_the_ashes_pwa
```

## Summary

✅ **API subdomain deployed and working**  
✅ **PWA simplified (static files only)**  
✅ **Direct Traefik routing (no nginx proxy)**  
✅ **Both services have valid TLS**  
✅ **Configuration verified in build**  

**The architecture is now cleaner, faster, and easier to maintain!** 🚀

---

**Note:** Users need to **logout and login again** after this deployment to get fresh JWT tokens. Old tokens from the previous architecture won't work because the issuer URL changed.
