5.2 KiB
5.2 KiB
External Integrations
Analysis Date: 2026-02-15
APIs & External Services
None - No external third-party APIs currently integrated.
Data Storage
Databases:
- PostgreSQL (Primary)
- Connection via
pgclient library (8.11.3) - Environment variables:
DB_HOST- Default:postgres(Docker service name)DB_PORT- Default:5432DB_USER- Default:postgresDB_PASSWORD- Required secretDB_NAME- Default:gravl
- ORM/Client:
pg(node-postgres) - Direct SQL queries, no ORM - Initialization:
db/init.sql- Schema and seed data - Tables: users, programs, program_days, exercises, program_exercises, workout_logs, user_measurements, user_strength
- Connection via
File Storage:
- Local filesystem only - No external file storage service
- Static assets served by Nginx from built frontend
dist/directory
Caching:
- None detected - No Redis, Memcached, or other caching layer
Authentication & Identity
Auth Provider:
- Custom JWT-based authentication
- Implementation:
backend/src/index.js(lines 22-29, 35-68) - Token generation:
jsonwebtoken9.0.2 - Password hashing:
bcryptjs2.4.3 - Secret:
JWT_SECRETenvironment variable (default:gravl-secret-key-change-in-production) - Token expiration: 30 days
- Implementation:
Auth Flow:
- Frontend
AuthContext(frontend/src/context/AuthContext.jsx) manages user state - User registers or logs in via
/api/auth/registeror/api/auth/login - Backend verifies credentials, generates JWT token
- Frontend stores token in
localStorageastoken - Subsequent requests include
Authorization: Bearer {token}header - Backend
authMiddlewarevalidates token on protected routes - User profile fetched on app load via
/api/user/profile
Protected Routes:
/api/user/profile- GET/PUT (requires auth)/api/user/measurements- GET/POST (requires auth)/api/user/strength- GET/POST (requires auth)/api/logs- GET/POST (no auth check in code - potential security gap)/api/progression/:programExerciseId- GET (no auth check - potential security gap)
Public Routes:
/api/health- Health check endpoint/api/auth/register- User registration/api/auth/login- User login/api/programs- List all programs/api/programs/:id- Get program details/api/days/:dayId/exercises- Get exercises for a day/api/today/:programId- Get workout for day
Frontend-Backend Communication
API Base URL:
- Hardcoded as
/apiinfrontend/src/context/AuthContext.jsx(line 2) - Development: Proxied by Vite to
http://localhost:3001 - Production: Proxied by Nginx to
http://gravl-backend:3001
CORS:
- Enabled on backend via
corsmiddleware 2.8.5 app.use(cors())inbackend/src/index.js(line 19)
HTTP Methods:
- POST
/api/auth/register- Register user - POST
/api/auth/login- Login user - GET
/api/user/profile- Get user profile - PUT
/api/user/profile- Update user profile - POST
/api/user/measurements- Add measurements - GET
/api/user/measurements- Get measurement history - POST
/api/user/strength- Add strength record - GET
/api/user/strength- Get strength history - GET
/api/programs- List programs - GET
/api/programs/:id- Get program with days and exercises - GET
/api/days/:dayId/exercises- Get exercises for day - GET/POST
/api/logs- Get/create workout logs - GET
/api/logs/last/:programExerciseId- Get last workout for exercise - GET
/api/progression/:programExerciseId- Calculate suggested weight
Request/Response Format:
- Content-Type:
application/json - Token: Passed in
Authorization: Bearer {token}header - Response: JSON objects
Monitoring & Observability
Error Tracking:
- None detected - No Sentry, LogRocket, or similar
Logs:
- Backend:
console.error()for errors (lines 48, 65, 98, 115, 133, 147, 165, 179, 190, 228, 246, 276, 294, 327, 380, 417) - Frontend: No error tracking integrated
- Example:
console.error('Register error:', err)inbackend/src/index.js(line 48)
Database Logging:
- None detected - SQL queries not logged
Webhooks & Callbacks
Incoming:
- None detected
Outgoing:
- None detected
Environment Configuration
Required env vars for backend:
DB_HOST- PostgreSQL hostnameDB_PORT- PostgreSQL portDB_USER- Database userDB_PASSWORD- Database password (REQUIRED SECRET)DB_NAME- Database nameJWT_SECRET- JWT signing secret (REQUIRED SECRET for production)PORT- Backend port (optional, default 3001)
Secrets location:
- Docker Compose:
docker-compose.yml(lines 8-13) - WARNING: Password visible in file - Backend defaults:
backend/src/index.js(lines 9, 14-16) - Frontend: None (token stored in browser localStorage)
Traefik Integration:
- Frontend exposed via Traefik reverse proxy
- Host:
gravl.homelab.local - HTTP and HTTPS support configured
- Networks:
proxy(external),homelab(internal Docker Compose network)
Service Dependencies
Backend Dependencies:
- PostgreSQL (required)
- Traefik proxy (for production routing)
Frontend Dependencies:
- Backend API at
/api(required for all authenticated operations) - Can operate in degraded mode if API is unavailable
Integration audit: 2026-02-15