# ✅ 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 → A echoesoftheashgame.patacuack.net → ``` **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.