Feature: nutrition module (keto macros + intermittent fasting + electrolytes)
Backend:
- models/nutrition.py: NutritionGoal, Fast, ElectrolyteLog tables
- schemas/nutrition.py: Pydantic schemas for new endpoints
- routers/nutrition.py: /api/nutrition/{today,goals,fasts,electrolytes}
- main.py: register router + migration for new tables + seed keto point rules
Frontend:
- pages/Nutrition.jsx: macro bars, fast timer, eating window, electrolyte quick-add
- App.jsx: /nutrition route + Keto nav tab
- api.js: nutrition endpoints
Points schema for fasts (tier-based partial credit):
16:8=25, 18:6=40, 20:4=60, 24h=200, 36h=350, 48h=500, 72h=1000
Defaults tuned for Scot: 135kg M 44yo strict keto, 12:00-20:00 window,
Asia/Bangkok timezone, 2400/2600 cal rest/training, 20g net carb cap.
This commit is contained in:
parent
9a306bc250
commit
5dd5d39ca6
8 changed files with 818 additions and 6 deletions
|
|
@ -63,7 +63,7 @@ async def lifespan(app: FastAPI):
|
|||
logger.info("Fitness Rewards backend shutting down")
|
||||
|
||||
|
||||
app = FastAPI(title="Fitness Rewards", version="0.2.0", lifespan=lifespan)
|
||||
app = FastAPI(title="Fitness Rewards", version="0.3.0", lifespan=lifespan)
|
||||
|
||||
app.add_middleware(
|
||||
CORSMiddleware,
|
||||
|
|
@ -83,6 +83,7 @@ from app.routers.integrations import router as integrations_router
|
|||
from app.routers.programs import router as programs_router
|
||||
from app.routers.catalog import router as catalog_router
|
||||
from app.routers.support import router as support_router
|
||||
from app.routers.nutrition import router as nutrition_router
|
||||
|
||||
app.include_router(auth_router)
|
||||
app.include_router(onboarding_router)
|
||||
|
|
@ -94,11 +95,12 @@ app.include_router(integrations_router)
|
|||
app.include_router(catalog_router)
|
||||
app.include_router(support_router)
|
||||
app.include_router(programs_router)
|
||||
app.include_router(nutrition_router)
|
||||
|
||||
|
||||
@app.get("/api/health")
|
||||
async def health():
|
||||
return {"status": "ok", "version": "0.2.0"}
|
||||
return {"status": "ok", "version": "0.3.0"}
|
||||
|
||||
|
||||
|
||||
|
|
@ -134,6 +136,27 @@ async def run_migrations():
|
|||
END $$;
|
||||
"""))
|
||||
|
||||
# v3: Seed keto point rules (fast_completed, keto_day, meal_logged)
|
||||
await conn.execute(text("""
|
||||
DO $$ BEGIN
|
||||
INSERT INTO point_rules (id, user_id, category, points, unit, is_active)
|
||||
SELECT gen_random_uuid(), u.id, 'fast_completed', 200, 'per_event', TRUE
|
||||
FROM users u
|
||||
WHERE NOT EXISTS (
|
||||
SELECT 1 FROM point_rules pr
|
||||
WHERE pr.user_id = u.id AND pr.category = 'fast_completed'
|
||||
);
|
||||
INSERT INTO point_rules (id, user_id, category, points, unit, is_active)
|
||||
SELECT gen_random_uuid(), u.id, 'keto_compliant_day', 100, 'per_event', TRUE
|
||||
FROM users u
|
||||
WHERE NOT EXISTS (
|
||||
SELECT 1 FROM point_rules pr
|
||||
WHERE pr.user_id = u.id AND pr.category = 'keto_compliant_day'
|
||||
);
|
||||
EXCEPTION WHEN undefined_table THEN NULL;
|
||||
END $$;
|
||||
"""))
|
||||
|
||||
|
||||
async def seed_resources():
|
||||
"""Seed the resource library with curated fitness programs."""
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue