# Gravl Staging Integration Testing Report **Date:** 2026-03-06 **Environment:** Kubernetes (k3s) - gravl-staging namespace **Ingress:** Traefik on localhost:9080 **Test Run By:** Automated E2E Test Suite (Task 3) --- ## Executive Summary | Category | Status | Pass/Fail | |----------|--------|-----------| | API Health | ✅ Healthy | 1/1 | | Database Connectivity | ✅ Connected | 1/1 | | Authentication Flow | ✅ Working | 3/3 | | Exercise Endpoints | ✅ Working | 4/4 | | Program Endpoints | ✅ Working | 3/3 | | Progression Logic | ✅ Working | 1/1 | | Frontend | ⚠️ nginx config issue | 0/1 | | Prometheus Metrics | ❌ Route conflict | 0/1 | **Overall: 13/15 tests passing (87%)** --- ## Detailed Test Results ### 1. Health Check ✅ ```bash GET /api/health ``` **Response:** ```json { "status": "healthy", "uptime": 233, "timestamp": "2026-03-06T02:35:55.289Z", "database": { "connected": true, "responseTime": "1ms" } } ``` **Result:** PASS - Backend healthy, database connected with 1ms response time. --- ### 2. Authentication Tests ✅ #### 2.1 User Registration ```bash POST /api/auth/register Content-Type: application/json {"email":"e2e-test-xxx@gravl.io","password":"TestPass123!","name":"E2E Test User"} ``` **Response:** ```json { "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...", "user": { "id": 1, "email": "e2e-test-xxx@gravl.io" } } ``` **Result:** PASS - JWT token returned, user created. #### 2.2 User Login ```bash POST /api/auth/login Content-Type: application/json {"email":"e2e-test-xxx@gravl.io","password":"TestPass123!"} ``` **Response:** ```json { "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...", "user": { "id": 1, "email": "e2e-test-xxx@gravl.io", "gender": null, "age": null, "onboarding_complete": false, ... } } ``` **Result:** PASS - Token and full user profile returned. #### 2.3 Invalid Login (Negative Test) ```bash POST /api/auth/login {"email":"e2e-test-xxx@gravl.io","password":"WrongPassword"} ``` **Response:** ```json { "error": "Invalid credentials" } ``` **Result:** PASS - Correct error handling for wrong credentials. --- ### 3. Exercise Endpoints ✅ #### 3.1 List Exercises ```bash GET /api/exercises ``` **Response:** Array of 18 exercises **Result:** PASS #### 3.2 Exercise Alternatives ```bash GET /api/exercises/1/alternatives ``` **Response:** ```json [ { "id": 3, "name": "Incline Dumbbell Press", "muscle_group": "Chest", "description": "Incline dumbbell press for upper chest" } ] ``` **Result:** PASS - Returns exercises with same muscle group. #### 3.3 Day Exercises ```bash GET /api/days/1/exercises ``` **Response:** Array with Push A exercises (Bench Press, Overhead Press, etc.) **Result:** PASS #### 3.4 Last Workout for Exercise ```bash GET /api/exercises/1/last-workout ``` **Response:** `[]` (no previous workouts logged) **Result:** PASS - Empty array for new user. --- ### 4. Program Endpoints ✅ #### 4.1 List Programs ```bash GET /api/programs ``` **Response:** ```json [ { "id": 1, "name": "Push/Pull/Legs", "description": "Classic 6-day PPL split for strength and hypertrophy. 6-week progressive program.", "weeks": 6 } ] ``` **Result:** PASS #### 4.2 Get Program Details ```bash GET /api/programs/1 ``` **Result:** PASS - Returns full program with name and description. #### 4.3 Today's Workout ```bash GET /api/today/1 ``` **Response:** Full PPL program structure with 6 days, each containing 5-6 exercises with sets/reps. **Result:** PASS - Complete program structure returned. --- ### 5. Progression Logic ✅ ```bash GET /api/progression/1 ``` **Response:** ```json { "suggestedWeight": 20, "reason": "No previous data - start light" } ``` **Result:** PASS - Intelligent starting weight suggestion for new users. --- ### 6. Frontend ⚠️ ISSUE ```bash GET / ``` **Response:** 500 Internal Server Error **Root Cause:** nginx configuration has rewrite loop when redirecting to index.html **Log:** ``` [error] rewrite or internal redirection cycle while internally redirecting to "/index.html" ``` **Status:** Health probe passes (`/health` → 200), but root path fails. **Fix Required:** Update nginx.conf in frontend Dockerfile or ConfigMap. --- ### 7. Prometheus Metrics ❌ ISSUE ```bash GET /metrics ``` **Response:** 500 Internal Server Error (same nginx loop issue) **Note:** The `/metrics` endpoint is defined in backend but the request routes through frontend nginx first. **Fix:** Either: 1. Route `/metrics` to backend in Ingress 2. Fix nginx config to not redirect all paths --- ## Database Schema Verification All required tables exist: - ✅ users - ✅ programs - ✅ program_days - ✅ exercises - ✅ program_exercises - ✅ workout_logs - ✅ custom_workouts - ✅ custom_workout_exercises --- ## Issues Found ### Critical (0) None ### High (1) 1. **Frontend nginx rewrite loop** - Root path returns 500. Needs nginx.conf fix. ### Medium (1) 1. **Metrics endpoint inaccessible** - /metrics routes through frontend instead of backend. ### Low (0) None --- ## Recommendations 1. **Fix frontend nginx.conf** ```nginx location / { try_files $uri $uri/ /index.html; } ``` Should ensure index.html exists or handle SPA routing correctly. 2. **Add backend metrics route to Ingress** ```yaml - path: /metrics pathType: Prefix backend: service: name: gravl-backend port: number: 3000 ``` 3. **Consider adding /api/exercises/:id endpoint** - Currently only list and alternatives exist. --- ## Test Environment Details | Component | Status | Version/Notes | |-----------|--------|---------------| | PostgreSQL | Running | PVC backed, 1ms response | | Backend | Running | v2-staging image | | Frontend | Running | nginx loop issue | | Ingress | Working | Traefik, localhost:9080 | | K8s Namespace | gravl-staging | All 3 pods healthy | --- ## Conclusion **The core API functionality is working correctly.** Authentication, exercises, programs, and progression logic all function as expected. The frontend nginx configuration issue is a deployment bug, not an application bug. Once fixed, the frontend should serve the SPA correctly. **Recommended next step:** Fix nginx.conf and redeploy frontend before production release. --- *Report generated: 2026-03-06T03:38:00+01:00*