smart tdee

This commit is contained in:
2026-06-16 04:38:23 +00:00
parent f2e98942ff
commit a3f01cd850
56 changed files with 2519 additions and 591 deletions
+116
View File
@@ -0,0 +1,116 @@
import unittest
from unittest.mock import patch
from sqlalchemy import create_engine, text
from sqlalchemy.orm import sessionmaker
from app.db.base import Base
from app.db.models import FitnessProfile, User
from app.fitness.calculators import compute_targets
class TdeeBackfillTests(unittest.TestCase):
def setUp(self) -> None:
self.engine = create_engine("sqlite:///:memory:")
Base.metadata.create_all(self.engine)
with self.engine.begin() as conn:
conn.execute(
text(
"CREATE TABLE IF NOT EXISTS _schema_migrations ("
"name TEXT PRIMARY KEY, "
"applied_at DATETIME DEFAULT CURRENT_TIMESTAMP)"
)
)
def _insert_legacy_profile(self) -> None:
Session = sessionmaker(bind=self.engine)
with Session() as db:
user = User(username="tester", api_token_hash="x")
db.add(user)
db.flush()
db.add(
FitnessProfile(
user_id=user.id,
sex="male",
age=30,
height_cm=180,
weight_kg=86,
goal="maintain",
activity_level="active",
calorie_target=3200,
protein_g=155,
fat_g=89,
carbs_g=400,
water_l=3.0,
neat_base_kcal=None,
)
)
db.commit()
def test_backfill_recalculates_stored_targets(self) -> None:
from app.db import migrate_fitness
self._insert_legacy_profile()
with patch.object(migrate_fitness, "engine", self.engine):
updated = migrate_fitness.backfill_tdee_targets(force=True)
self.assertEqual(updated, 1)
Session = sessionmaker(bind=self.engine)
with Session() as db:
row = db.query(FitnessProfile).one()
expected = compute_targets(
{
"sex": row.sex,
"age": row.age,
"height_cm": row.height_cm,
"weight_kg": row.weight_kg,
"goal": row.goal,
"neat_base_kcal": 200,
}
)
self.assertEqual(row.neat_base_kcal, 200.0)
self.assertEqual(row.calorie_target, expected["calorie_target"])
self.assertEqual(row.protein_g, expected["protein_g"])
self.assertLess(row.calorie_target, 3200)
def test_backfill_runs_once(self) -> None:
from app.db import migrate_fitness
self._insert_legacy_profile()
with patch.object(migrate_fitness, "engine", self.engine):
first = migrate_fitness.backfill_tdee_targets(force=True)
second = migrate_fitness.backfill_tdee_targets()
self.assertEqual(first, 1)
self.assertEqual(second, 0)
def test_macros_backfill_updates_bju_only(self) -> None:
from app.db import migrate_fitness
from app.fitness.calculators import macro_targets
self._insert_legacy_profile()
with patch.object(migrate_fitness, "engine", self.engine):
migrate_fitness.backfill_tdee_targets(force=True)
Session = sessionmaker(bind=self.engine)
with Session() as db:
row = db.query(FitnessProfile).one()
calorie_before = row.calorie_target
row.protein_g = 999
db.commit()
updated = migrate_fitness.backfill_macros_gkg(force=True)
self.assertEqual(updated, 1)
with Session() as db:
row = db.query(FitnessProfile).one()
expected = macro_targets(calorie_before, row.weight_kg, row.goal)
self.assertEqual(row.calorie_target, calorie_before)
self.assertEqual(row.protein_g, expected["protein_g"])
self.assertEqual(row.fat_g, expected["fat_g"])
self.assertEqual(row.carbs_g, expected["carbs_g"])
if __name__ == "__main__":
unittest.main()