- Add rules_engine.py with quantitative rules for all 8 workout types - Add quality gate retry loop in generate_single_workout() - Expand calibrate_structure_rules to all 120 combinations (8 types × 5 goals × 3 sections) - Wire WeeklySplitPattern DB records into _pick_weekly_split() - Enforce movement patterns from WorkoutStructureRule in exercise selection - Add straight-set strength support (single main lift, 4-6 rounds) - Add modality consistency check for duration-dominant workout types - Add InjuryStep component to onboarding and preferences - Add sibling exercise exclusion in regenerate and preview_day endpoints - Display generator warnings on dashboard - Expand fix_rep_durations, fix_exercise_flags, fix_movement_pattern_typo - Add audit_exercise_data and check_rules_drift management commands - Add Next.js frontend with dashboard, onboarding, preferences, history pages - Add generator app with ML-powered workout generation pipeline - 96 new tests across 7 test modules Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
35 lines
1.0 KiB
Python
35 lines
1.0 KiB
Python
# Generated by Django 5.1.4 on 2026-02-21 05:06
|
|
|
|
from django.db import migrations
|
|
|
|
|
|
def deduplicate_exercise_muscles(apps, schema_editor):
|
|
"""Remove duplicate ExerciseMuscle rows before adding unique constraint."""
|
|
ExerciseMuscle = apps.get_model('muscle', 'ExerciseMuscle')
|
|
seen = set()
|
|
to_delete = []
|
|
for em in ExerciseMuscle.objects.all().order_by('id'):
|
|
key = (em.exercise_id, em.muscle_id)
|
|
if key in seen:
|
|
to_delete.append(em.id)
|
|
else:
|
|
seen.add(key)
|
|
if to_delete:
|
|
ExerciseMuscle.objects.filter(id__in=to_delete).delete()
|
|
|
|
|
|
class Migration(migrations.Migration):
|
|
|
|
dependencies = [
|
|
('exercise', '0010_alter_exercise_complexity_rating_and_more'),
|
|
('muscle', '0002_exercisemuscle'),
|
|
]
|
|
|
|
operations = [
|
|
migrations.RunPython(deduplicate_exercise_muscles, migrations.RunPython.noop),
|
|
migrations.AlterUniqueTogether(
|
|
name='exercisemuscle',
|
|
unique_together={('exercise', 'muscle')},
|
|
),
|
|
]
|