""" Mitai Jinkendo API - Main Application FastAPI backend with modular router structure. """ import os from pathlib import Path from fastapi import FastAPI from fastapi.middleware.cors import CORSMiddleware from slowapi import Limiter, _rate_limit_exceeded_handler from slowapi.util import get_remote_address from slowapi.errors import RateLimitExceeded from db import init_db # Import routers from routers import auth, profiles, weight, circumference, caliper from routers import activity, nutrition, photos, insights, prompts from routers import admin, stats, exportdata, importdata from routers import subscription, coupons, features, tiers_mgmt, tier_limits from routers import user_restrictions, access_grants, training_types, admin_training_types from routers import admin_activity_mappings, sleep, rest_days from routers import vitals_baseline, blood_pressure # v9d Phase 2d Refactored from routers import evaluation # v9d/v9e Training Type Profiles (#15) from routers import goals, focus_areas # v9e/v9g Goal System v2.0 (Dynamic Focus Areas) from routers import goal_types, goal_progress, training_phases, fitness_tests # v9h Goal System (Split routers) from routers import charts # Phase 0c Multi-Layer Architecture # ── App Configuration ───────────────────────────────────────────────────────── DATA_DIR = Path(os.getenv("DATA_DIR", "./data")) PHOTOS_DIR = Path(os.getenv("PHOTOS_DIR", "./photos")) DATA_DIR.mkdir(parents=True, exist_ok=True) PHOTOS_DIR.mkdir(parents=True, exist_ok=True) app = FastAPI(title="Mitai Jinkendo API", version="3.0.0") # Rate limiting limiter = Limiter(key_func=get_remote_address) app.state.limiter = limiter app.add_exception_handler(RateLimitExceeded, _rate_limit_exceeded_handler) # CORS app.add_middleware( CORSMiddleware, allow_origins=os.getenv("ALLOWED_ORIGINS", "*").split(","), allow_credentials=True, allow_methods=["GET","POST","PUT","DELETE","OPTIONS"], allow_headers=["*"], ) # ── Startup Event ───────────────────────────────────────────────────────────── @app.on_event("startup") async def startup_event(): """Run database initialization on startup.""" try: init_db() except Exception as e: print(f"⚠️ init_db() failed (non-fatal): {e}") # Don't crash on startup - can be created manually # Apply v9c migration if needed try: from apply_v9c_migration import apply_migration apply_migration() except Exception as e: print(f"⚠️ v9c migration failed (non-fatal): {e}") # ── Register Routers ────────────────────────────────────────────────────────── app.include_router(auth.router) # /api/auth/* app.include_router(profiles.router) # /api/profiles/*, /api/profile app.include_router(weight.router) # /api/weight/* app.include_router(circumference.router) # /api/circumferences/* app.include_router(caliper.router) # /api/caliper/* app.include_router(activity.router) # /api/activity/* app.include_router(nutrition.router) # /api/nutrition/* app.include_router(photos.router) # /api/photos/* app.include_router(insights.router) # /api/insights/*, /api/ai/* app.include_router(prompts.router) # /api/prompts/* app.include_router(admin.router) # /api/admin/* app.include_router(stats.router) # /api/stats app.include_router(exportdata.router) # /api/export/* app.include_router(importdata.router) # /api/import/* # v9c Subscription System app.include_router(subscription.router) # /api/subscription/* app.include_router(coupons.router) # /api/coupons/* app.include_router(features.router) # /api/features (admin) app.include_router(tiers_mgmt.router) # /api/tiers (admin) app.include_router(tier_limits.router) # /api/tier-limits (admin) app.include_router(user_restrictions.router) # /api/user-restrictions (admin) app.include_router(access_grants.router) # /api/access-grants (admin) # v9d Training Types & Sleep Module & Rest Days & Vitals app.include_router(training_types.router) # /api/training-types/* app.include_router(admin_training_types.router) # /api/admin/training-types/* app.include_router(admin_activity_mappings.router) # /api/admin/activity-mappings/* app.include_router(sleep.router) # /api/sleep/* (v9d Phase 2b) app.include_router(rest_days.router) # /api/rest-days/* (v9d Phase 2a) app.include_router(vitals_baseline.router) # /api/vitals/baseline/* (v9d Phase 2d Refactored) app.include_router(blood_pressure.router) # /api/blood-pressure/* (v9d Phase 2d Refactored) app.include_router(evaluation.router) # /api/evaluation/* (v9d/v9e Training Profiles #15) app.include_router(goals.router) # /api/goals/* (v9h Goal System Core CRUD + Focus Areas) app.include_router(goal_types.router) # /api/goals/goal-types/* (v9h Goal Type Definitions) app.include_router(goal_progress.router) # /api/goals/{goal_id}/progress/* (v9h Progress Tracking) app.include_router(training_phases.router) # /api/goals/phases/* (v9h Training Phases) app.include_router(fitness_tests.router) # /api/goals/tests/* (v9h Fitness Tests) app.include_router(focus_areas.router) # /api/focus-areas/* (v9g Focus Area System v2.0 - Dynamic) # Phase 0c Multi-Layer Architecture app.include_router(charts.router) # /api/charts/* (Phase 0c Charts API) # ── Health Check ────────────────────────────────────────────────────────────── @app.get("/") def root(): """API health check.""" return {"status": "ok", "service": "mitai-jinkendo", "version": "v9c-dev"}