Phase 2 Complete - Backend Refactoring: - Extracted all endpoints to dedicated router modules - main.py: 1878 → 75 lines (-96% reduction) - Created modular structure for maintainability Router Structure (60 endpoints total): ├── auth.py - 7 endpoints (login, logout, password reset) ├── profiles.py - 7 endpoints (CRUD + current user) ├── weight.py - 5 endpoints (tracking + stats) ├── circumference.py - 4 endpoints (body measurements) ├── caliper.py - 4 endpoints (skinfold tracking) ├── activity.py - 6 endpoints (workouts + Apple Health import) ├── nutrition.py - 4 endpoints (diet + FDDB import) ├── photos.py - 3 endpoints (progress photos) ├── insights.py - 8 endpoints (AI analysis + pipeline) ├── prompts.py - 2 endpoints (AI prompt management) ├── admin.py - 7 endpoints (user management) ├── stats.py - 1 endpoint (dashboard stats) ├── exportdata.py - 3 endpoints (CSV/JSON/ZIP export) └── importdata.py - 1 endpoint (ZIP import) Core modules maintained: - db.py: PostgreSQL connection + helpers - auth.py: Auth functions (hash, verify, sessions) - models.py: 11 Pydantic models Benefits: - Self-contained modules with clear responsibilities - Easier to navigate and modify specific features - Improved code organization and readability - 100% functional compatibility maintained - All syntax checks passed Updated CLAUDE.md with new architecture documentation. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
40 lines
1.5 KiB
Python
40 lines
1.5 KiB
Python
"""
|
|
Statistics Endpoints for Mitai Jinkendo
|
|
|
|
Dashboard statistics showing entry counts across all categories.
|
|
"""
|
|
from typing import Optional
|
|
|
|
from fastapi import APIRouter, Header, Depends
|
|
|
|
from db import get_db, get_cursor
|
|
from auth import require_auth
|
|
from routers.profiles import get_pid
|
|
|
|
router = APIRouter(prefix="/api", tags=["stats"])
|
|
|
|
|
|
@router.get("/stats")
|
|
def get_stats(x_profile_id: Optional[str]=Header(default=None), session: dict=Depends(require_auth)):
|
|
"""Get entry counts for all tracking categories."""
|
|
pid = get_pid(x_profile_id)
|
|
with get_db() as conn:
|
|
cur = get_cursor(conn)
|
|
cur.execute("SELECT COUNT(*) as count FROM weight_log WHERE profile_id=%s",(pid,))
|
|
weight_count = cur.fetchone()['count']
|
|
cur.execute("SELECT COUNT(*) as count FROM circumference_log WHERE profile_id=%s",(pid,))
|
|
circ_count = cur.fetchone()['count']
|
|
cur.execute("SELECT COUNT(*) as count FROM caliper_log WHERE profile_id=%s",(pid,))
|
|
caliper_count = cur.fetchone()['count']
|
|
cur.execute("SELECT COUNT(*) as count FROM nutrition_log WHERE profile_id=%s",(pid,))
|
|
nutrition_count = cur.fetchone()['count']
|
|
cur.execute("SELECT COUNT(*) as count FROM activity_log WHERE profile_id=%s",(pid,))
|
|
activity_count = cur.fetchone()['count']
|
|
return {
|
|
"weight_count": weight_count,
|
|
"circ_count": circ_count,
|
|
"caliper_count": caliper_count,
|
|
"nutrition_count": nutrition_count,
|
|
"activity_count": activity_count
|
|
}
|