diff --git a/.planning/research/00-index.md b/.planning/research/00-index.md index d6b252a..97c53fc 100644 --- a/.planning/research/00-index.md +++ b/.planning/research/00-index.md @@ -14,6 +14,7 @@ Research sammanställd 2026-02-15 via Exa AI Search. | [06-ai-coaching.md](06-ai-coaching.md) | AI-coaching trends, conversational UI | | [07-recommendations.md](07-recommendations.md) | Konkreta rekommendationer för Gravl | | [08-sources.md](08-sources.md) | Alla källor och länkar | +| [09-exercise-databases.md](09-exercise-databases.md) | Övningsdatabaser, APIs, media, substitution | ## Key Takeaways diff --git a/.planning/research/09-exercise-databases.md b/.planning/research/09-exercise-databases.md new file mode 100644 index 0000000..40fcc94 --- /dev/null +++ b/.planning/research/09-exercise-databases.md @@ -0,0 +1,437 @@ +# Övningsdatabaser & APIs — Research för Gravl + +## Sammanfattning + +Det finns flera högkvalitativa, **gratis och open source** övningsdatabaser tillgängliga. De bästa alternativen är: + +| Databas | Övningar | Media | Licens | API | +|---------|----------|-------|--------|-----| +| **ExerciseDB** | 1,300-11,000 | GIF | Open Source | ✅ REST | +| **wger** | 800+ | Bilder | AGPL | ✅ REST | +| **free-exercise-db** | 800+ | Bilder | Public Domain | JSON | +| **MusclesWorked** | 856 | — | Commercial | ✅ REST + MCP | +| **API Ninjas** | 3,000+ | — | Freemium | ✅ REST | + +**Rekommendation:** Kombinera **ExerciseDB** (GIF-demos, omfattande) med **wger** (open source, self-hosted möjligt). + +--- + +## Top Picks + +### 1. ExerciseDB API (Rekommenderat) + +**URL:** https://exercisedb.dev / https://github.com/cyberboyanmol/exercisedb-api + +**Styrkor:** +- 1,300+ övningar (v1) eller 11,000+ (v2) +- GIF-demonstrationer för varje övning +- Detaljerad metadata +- Open source (self-hostable) +- Aktiv utveckling + +**Data per övning:** +```json +{ + "id": "0001", + "name": "3/4 sit-up", + "target": "abs", + "bodyPart": "waist", + "equipment": "body weight", + "gifUrl": "https://...", + "secondaryMuscles": ["hip flexors"], + "instructions": [ + "Lie flat on your back with your knees bent...", + "Place your hands behind your head...", + "..." + ] +} +``` + +**Endpoints:** +``` +GET /exercises - Alla övningar +GET /exercises/bodyPart/{part} - Filter på kroppsdel +GET /exercises/equipment/{equip} - Filter på utrustning +GET /exercises/target/{muscle} - Filter på målmuskel +GET /exercises/{id} - Specifik övning +``` + +**Bodyparts:** +- back, cardio, chest, lower arms, lower legs +- neck, shoulders, upper arms, upper legs, waist + +**Equipment:** +- assisted, band, barbell, body weight, bosu ball +- cable, dumbbell, elliptical machine, ez barbell +- hammer, kettlebell, leverage machine, medicine ball +- olympic barbell, resistance band, roller, rope +- skierg machine, sled machine, smith machine +- stability ball, stationary bike, stepmill machine +- tire, trap bar, upper body ergometer, weighted +- wheel roller + +--- + +### 2. wger (Open Source, Self-Hosted) + +**URL:** https://wger.de / https://github.com/wger-project/wger + +**Styrkor:** +- Helt open source (AGPL) +- Self-hosted möjligt (Docker) +- 800+ övningar +- Stöd för flera språk (inkl. svenska möjligt) +- Workout manager ingår +- Nutrition tracking ingår +- REST API + +**Data per övning:** +```json +{ + "id": 9, + "uuid": "1b020b3a-3732-4c7e-92fd-a0cec90ed69b", + "category": 10, + "muscles": [1, 2], + "muscles_secondary": [3], + "equipment": [10], + "license": 2, + "license_author": "wger.de" +} +``` + +**API Endpoints:** +``` +GET /api/v2/exercise/ - Lista övningar +GET /api/v2/muscle/ - Lista muskler +GET /api/v2/equipment/ - Lista utrustning +GET /api/v2/exerciseimage/ - Övningsbilder +GET /api/v2/exercisevideo/ - Övningsvideor +``` + +**Self-hosting:** +```bash +git clone https://github.com/wger-project/wger +cd wger +docker compose up -d +``` + +--- + +### 3. free-exercise-db (Public Domain) + +**URL:** https://github.com/yuhonas/free-exercise-db + +**Styrkor:** +- 800+ övningar +- Public Domain (Unlicense) — inga restriktioner +- Ren JSON-data +- Bilder inkluderade +- Sökbar frontend: https://yuhonas.github.io/free-exercise-db/ + +**Data format:** +```json +{ + "name": "Barbell Bench Press", + "force": "push", + "level": "intermediate", + "mechanic": "compound", + "equipment": "barbell", + "primaryMuscles": ["chest"], + "secondaryMuscles": ["shoulders", "triceps"], + "instructions": ["..."], + "category": "strength", + "images": ["Barbell-Bench-Press/0.jpg", "Barbell-Bench-Press/1.jpg"] +} +``` + +**GitHub stats:** 1,100+ stars, aktivt community + +--- + +### 4. MusclesWorked API + +**URL:** https://musclesworked.com + +**Styrkor:** +- 856 övningar, 63 muskler, 7,310+ mappings +- REST API + MCP server (för AI-agenter) +- Detaljerad muskel-mapping + +**Begränsningar:** +- Kommersiell (API key krävs) +- Ingen media (bilder/video) + +**Endpoints:** +``` +GET /api/v1/exercises +GET /api/v1/muscles +GET /api/v1/exercise/{id}/muscles +``` + +--- + +### 5. API Ninjas Exercises + +**URL:** https://api-ninjas.com/api/exercises + +**Styrkor:** +- 3,000+ övningar +- Enkel att använda +- Filter på namn, typ, muskel, svårighetsgrad + +**Begränsningar:** +- Freemium (gratis tier har limits) +- Ingen media + +**Endpoint:** +``` +GET https://api.api-ninjas.com/v1/exercises?muscle=biceps&difficulty=beginner +``` + +--- + +## Exercise Substitution (Alternativa övningar) + +### Problemet + +> "The bench is taken, what do I do instead?" + +Användare vill kunna byta övning till en som tränar samma muskelgrupp. + +### Lösningar + +#### 1. Muskelgrupp-baserad substitution + +```python +def get_alternatives(exercise_id): + exercise = get_exercise(exercise_id) + target_muscle = exercise.target + + alternatives = db.query(""" + SELECT * FROM exercises + WHERE target = %s + AND id != %s + ORDER BY popularity DESC + LIMIT 5 + """, [target_muscle, exercise_id]) + + return alternatives +``` + +#### 2. Utrustnings-baserad substitution + +```python +def get_alternatives_for_equipment(exercise_id, available_equipment): + exercise = get_exercise(exercise_id) + target_muscle = exercise.target + + alternatives = db.query(""" + SELECT * FROM exercises + WHERE target = %s + AND equipment = ANY(%s) + AND id != %s + """, [target_muscle, available_equipment, exercise_id]) + + return alternatives +``` + +#### 3. Sweat App-approach + +Sweat har built-in substitution: +- Samma muskelgrupp +- Liknande rörelse-pattern (push/pull/hinge) +- Utrustning användaren har + +#### 4. Tonal's Movement Replacements + +280+ movement substitutes kategoriserade efter: +- Target muscle +- Movement pattern +- Equipment required +- Difficulty level + +### Substitution-data + +**Fitness Volt Substitute Finder:** +https://fitnessvolt.com/substitute-exercises/ + +Manuellt kurerad lista av alternativ för varje övning. + +--- + +## Video/GIF Sources + +### Gratis/Open Source + +| Källa | Format | Kvalitet | Licens | +|-------|--------|----------|--------| +| ExerciseDB | GIF | Bra | Open | +| wger | Video/Bild | Varierar | AGPL | +| free-exercise-db | Bild | Bra | Public Domain | + +### Kommersiella + +| Källa | Format | Övningar | Pris | +|-------|--------|----------|------| +| Gym Visual | GIF/Video | 1000+ | $$ | +| Central Athlete | Video | 2,800+ | $$$ | +| Exercise.com | Video | Omfattande | $$$ | +| JEFIT | GIF | 1,400+ | I appen | + +### Skapa egna + +**GIPHY:** Sök "exercise" för community-uploads (osäker licens) + +**AI-genererade:** Modeller som kan generera exercise-demos utvecklas, men kvaliteten är ännu inte där. + +--- + +## Datastruktur för Gravl + +### Rekommenderad schema + +```sql +CREATE TABLE exercises ( + id SERIAL PRIMARY KEY, + external_id VARCHAR(50), -- ID från extern källa + source VARCHAR(50), -- 'exercisedb', 'wger', 'custom' + + -- Basic info + name VARCHAR(255) NOT NULL, + name_sv VARCHAR(255), -- Svenskt namn + description TEXT, + instructions TEXT[], + + -- Categorization + body_part VARCHAR(50), -- 'chest', 'back', etc. + target_muscle VARCHAR(50), -- Primary muscle + secondary_muscles VARCHAR(50)[], -- Secondary muscles + equipment VARCHAR(50), + + -- Metadata + difficulty VARCHAR(20), -- 'beginner', 'intermediate', 'advanced' + force_type VARCHAR(20), -- 'push', 'pull', 'static' + mechanic VARCHAR(20), -- 'compound', 'isolation' + + -- Media + gif_url VARCHAR(500), + image_urls TEXT[], + video_url VARCHAR(500), + + -- Gravl-specific + is_active BOOLEAN DEFAULT true, + popularity_score INT DEFAULT 0, + created_at TIMESTAMPTZ DEFAULT NOW(), + updated_at TIMESTAMPTZ DEFAULT NOW() +); + +CREATE TABLE exercise_alternatives ( + exercise_id INT REFERENCES exercises(id), + alternative_id INT REFERENCES exercises(id), + similarity_score DECIMAL(3,2), -- 0.0 - 1.0 + reason VARCHAR(100), -- 'same_muscle', 'same_equipment', etc. + PRIMARY KEY (exercise_id, alternative_id) +); + +-- Index för snabb lookup +CREATE INDEX idx_exercises_target ON exercises(target_muscle); +CREATE INDEX idx_exercises_equipment ON exercises(equipment); +CREATE INDEX idx_exercises_body_part ON exercises(body_part); +``` + +### Import-script + +```python +import requests +import json + +def import_exercisedb(): + """Import exercises from ExerciseDB API""" + + response = requests.get("https://exercisedb.p.rapidapi.com/exercises", + headers={"X-RapidAPI-Key": API_KEY}) + + exercises = response.json() + + for ex in exercises: + db.execute(""" + INSERT INTO exercises ( + external_id, source, name, body_part, + target_muscle, equipment, gif_url, instructions + ) VALUES (%s, %s, %s, %s, %s, %s, %s, %s) + ON CONFLICT (external_id, source) DO UPDATE + SET gif_url = EXCLUDED.gif_url, + updated_at = NOW() + """, [ + ex['id'], 'exercisedb', ex['name'], ex['bodyPart'], + ex['target'], ex['equipment'], ex['gifUrl'], + ex.get('instructions', []) + ]) +``` + +--- + +## Rekommendationer för Gravl + +### Phase 1: MVP + +1. **Använd ExerciseDB** som primär källa + - 1,300+ övningar med GIF + - Gratis, open source + - Bra API + +2. **Importera till lokal databas** + - Cache för performance + - Möjlighet att lägga till custom övningar + - Offline-stöd + +3. **Basic substitution** + - Samma target muscle = alternativ + - Visa 3-5 alternativ per övning + +### Phase 2: Enhanced + +1. **Lägg till svenska namn** + - Manuellt eller via översättning + - Community contributions + +2. **Smarter substitution** + - Equipment-aware + - Difficulty-matching + - Movement pattern-matching + +3. **Custom exercises** + - Användare kan lägga till egna + - Upload egen GIF/video + +### Phase 3: Advanced + +1. **AI-driven substitution** + - "Axeln gör ont" → undvik overhead press + - "Bänken upptagen" → DB press istället + +2. **Video tutorials** + - Licens commercial content + - Eller skapa egna + +3. **Form analysis** + - Pose estimation + - Jämför mot ideal form + +--- + +## Licens-sammanfattning + +| Källa | Kan använda kommersiellt | Attribution krävs | +|-------|-------------------------|-------------------| +| ExerciseDB (open) | ✅ | Rekommenderas | +| wger | ✅ (AGPL) | Ja, och dela ändringar | +| free-exercise-db | ✅ (Unlicense) | Nej | +| API Ninjas | ⚠️ Check terms | Ja | +| MusclesWorked | 💰 Betala | Enligt avtal | + +**Säkraste valet:** free-exercise-db (Public Domain) + ExerciseDB (Open Source) + +--- + +*Källa: GitHub, ExerciseDB, wger, Reddit, Exa AI Search — 2023-2026*