- Add Next.js rewrites to proxy API calls through same origin (fixes login/media on werkout.treytartt.com) - Fix mediaUrl() in DayCard and ExerciseRow to use relative paths in production - Add proxyTimeout for long-running workout generation endpoints - Add CSRF trusted origin for treytartt.com - Split docker-compose into production (Unraid) and dev configs - Show display_name and descriptions on workout type cards - Generator: rules engine improvements, movement enforcement, exercise selector updates - Add new test files for rules drift, workout research generation Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
122 lines
3.4 KiB
Python
122 lines
3.4 KiB
Python
from django.core.management import call_command
|
|
from django.db import migrations
|
|
|
|
|
|
WORKOUT_TYPE_CALIBRATION = {
|
|
'functional_strength_training': {
|
|
'typical_rest_between_sets': 60,
|
|
'typical_intensity': 'medium',
|
|
'rep_range_min': 8,
|
|
'rep_range_max': 15,
|
|
'round_range_min': 3,
|
|
'round_range_max': 4,
|
|
'duration_bias': 0.15,
|
|
'superset_size_min': 2,
|
|
'superset_size_max': 4,
|
|
},
|
|
'traditional_strength_training': {
|
|
'typical_rest_between_sets': 120,
|
|
'typical_intensity': 'high',
|
|
'rep_range_min': 4,
|
|
'rep_range_max': 8,
|
|
'round_range_min': 3,
|
|
'round_range_max': 5,
|
|
'duration_bias': 0.1,
|
|
'superset_size_min': 1,
|
|
'superset_size_max': 3,
|
|
},
|
|
'high_intensity_interval_training': {
|
|
'typical_rest_between_sets': 30,
|
|
'typical_intensity': 'high',
|
|
'rep_range_min': 10,
|
|
'rep_range_max': 20,
|
|
'round_range_min': 3,
|
|
'round_range_max': 5,
|
|
'duration_bias': 0.7,
|
|
'superset_size_min': 3,
|
|
'superset_size_max': 6,
|
|
},
|
|
'cross_training': {
|
|
'typical_rest_between_sets': 45,
|
|
'typical_intensity': 'high',
|
|
'rep_range_min': 8,
|
|
'rep_range_max': 15,
|
|
'round_range_min': 3,
|
|
'round_range_max': 5,
|
|
'duration_bias': 0.4,
|
|
'superset_size_min': 3,
|
|
'superset_size_max': 5,
|
|
},
|
|
'core_training': {
|
|
'typical_rest_between_sets': 30,
|
|
'typical_intensity': 'medium',
|
|
'rep_range_min': 10,
|
|
'rep_range_max': 20,
|
|
'round_range_min': 2,
|
|
'round_range_max': 4,
|
|
'duration_bias': 0.5,
|
|
'superset_size_min': 3,
|
|
'superset_size_max': 5,
|
|
},
|
|
'flexibility': {
|
|
'typical_rest_between_sets': 15,
|
|
'typical_intensity': 'low',
|
|
'rep_range_min': 1,
|
|
'rep_range_max': 5,
|
|
'round_range_min': 1,
|
|
'round_range_max': 2,
|
|
'duration_bias': 0.9,
|
|
'superset_size_min': 3,
|
|
'superset_size_max': 6,
|
|
},
|
|
'cardio': {
|
|
'typical_rest_between_sets': 30,
|
|
'typical_intensity': 'medium',
|
|
'rep_range_min': 1,
|
|
'rep_range_max': 1,
|
|
'round_range_min': 1,
|
|
'round_range_max': 3,
|
|
'duration_bias': 1.0,
|
|
'superset_size_min': 1,
|
|
'superset_size_max': 3,
|
|
},
|
|
'hypertrophy': {
|
|
'typical_rest_between_sets': 90,
|
|
'typical_intensity': 'high',
|
|
'rep_range_min': 8,
|
|
'rep_range_max': 15,
|
|
'round_range_min': 3,
|
|
'round_range_max': 4,
|
|
'duration_bias': 0.2,
|
|
'superset_size_min': 2,
|
|
'superset_size_max': 4,
|
|
},
|
|
}
|
|
|
|
|
|
def apply_calibration(apps, schema_editor):
|
|
WorkoutType = apps.get_model('generator', 'WorkoutType')
|
|
|
|
for type_name, fields in WORKOUT_TYPE_CALIBRATION.items():
|
|
defaults = dict(fields)
|
|
defaults.setdefault('display_name', type_name.replace('_', ' ').title())
|
|
defaults.setdefault('description', '')
|
|
WorkoutType.objects.update_or_create(name=type_name, defaults=defaults)
|
|
|
|
call_command('calibrate_structure_rules')
|
|
|
|
|
|
def noop_reverse(apps, schema_editor):
|
|
pass
|
|
|
|
|
|
class Migration(migrations.Migration):
|
|
|
|
dependencies = [
|
|
('generator', '0006_calibrate_workout_types_and_structure_rules'),
|
|
]
|
|
|
|
operations = [
|
|
migrations.RunPython(apply_calibration, noop_reverse),
|
|
]
|