Files
gravl/docs/TESTING_REPORT.md
clawd d81e403f01 Phase 06 Tier 1: Complete Backend Implementation - Recovery Tracking & Swap System
COMPLETED TASKS:
 06-01: Workout Swap System
   - Added swapped_from_id to workout_logs
   - Created workout_swaps table for history
   - POST /api/workouts/:id/swap endpoint
   - GET /api/workouts/available endpoint
   - Reversible swaps with audit trail

 06-02: Muscle Group Recovery Tracking
   - Created muscle_group_recovery table
   - Implemented calculateRecoveryScore() function
   - GET /api/recovery/muscle-groups endpoint
   - GET /api/recovery/most-recovered endpoint
   - Auto-tracking on workout log completion

 06-03: Smart Workout Recommendations
   - GET /api/recommendations/smart-workout endpoint
   - 7-day workout analysis algorithm
   - Recovery-based filtering (>30% threshold)
   - Top 3 recommendations with context
   - Context-aware reasoning messages

DATABASE CHANGES:
- Added 4 new tables: muscle_group_recovery, workout_swaps, custom_workouts, custom_workout_exercises
- Extended workout_logs with: swapped_from_id, source_type, custom_workout_id, custom_workout_exercise_id
- Created 7 new indexes for performance

IMPLEMENTATION:
- Recovery service with 4 core functions
- 2 new route handlers (recovery, smartRecommendations)
- Updated workouts router with swap endpoints
- Integrated recovery tracking into POST /api/logs
- Full error handling and logging

TESTING:
- Test file created: /backend/test/phase-06-tests.js
- Ready for E2E and staging validation

STATUS: Ready for frontend integration and production review
Branch: feature/06-phase-06
2026-03-06 20:54:03 +01:00

6.3 KiB

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

GET /api/health

Response:

{
  "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

POST /api/auth/register
Content-Type: application/json
{"email":"e2e-test-xxx@gravl.io","password":"TestPass123!","name":"E2E Test User"}

Response:

{
  "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
  "user": {
    "id": 1,
    "email": "e2e-test-xxx@gravl.io"
  }
}

Result: PASS - JWT token returned, user created.

2.2 User Login

POST /api/auth/login
Content-Type: application/json
{"email":"e2e-test-xxx@gravl.io","password":"TestPass123!"}

Response:

{
  "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)

POST /api/auth/login
{"email":"e2e-test-xxx@gravl.io","password":"WrongPassword"}

Response:

{
  "error": "Invalid credentials"
}

Result: PASS - Correct error handling for wrong credentials.


3. Exercise Endpoints

3.1 List Exercises

GET /api/exercises

Response: Array of 18 exercises
Result: PASS

3.2 Exercise Alternatives

GET /api/exercises/1/alternatives

Response:

[
  {
    "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

GET /api/days/1/exercises

Response: Array with Push A exercises (Bench Press, Overhead Press, etc.)
Result: PASS

3.4 Last Workout for Exercise

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

GET /api/programs

Response:

[
  {
    "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

GET /api/programs/1

Result: PASS - Returns full program with name and description.

4.3 Today's Workout

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

GET /api/progression/1

Response:

{
  "suggestedWeight": 20,
  "reason": "No previous data - start light"
}

Result: PASS - Intelligent starting weight suggestion for new users.


6. Frontend ⚠️ ISSUE

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

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

    location / {
      try_files $uri $uri/ /index.html;
    }
    

    Should ensure index.html exists or handle SPA routing correctly.

  2. Add backend metrics route to Ingress

    - 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