from __future__ import annotations from pathlib import Path from fastapi import APIRouter, Depends, Request from fastapi.responses import HTMLResponse from fastapi.templating import Jinja2Templates from app.api.tasks import get_task_repository from app.storage import JsonFileTaskRepository, StoredTask router = APIRouter(tags=["stats"]) templates = Jinja2Templates(directory=str(Path(__file__).resolve().parents[2] / "templates")) def get_task_status(task: StoredTask) -> str: if task.done_at is not None: return "done" if task.started_at is not None: return "in_progress" return "backlog" def format_dt(value: object) -> str: if value is None: return "—" return str(value) def format_duration(task: StoredTask) -> str: if task.started_at is None or task.done_at is None: return "—" delta = task.done_at - task.started_at total_seconds = int(delta.total_seconds()) hours, remainder = divmod(total_seconds, 3600) minutes, seconds = divmod(remainder, 60) return f"{hours}h {minutes}m {seconds}s" def serialize_task(task: StoredTask) -> dict[str, str]: return { "id": str(task.id), "title": task.title, "status": get_task_status(task), "created_at": task.created_at.isoformat(), "started_at": task.started_at.isoformat() if task.started_at is not None else "", "done_at": task.done_at.isoformat() if task.done_at is not None else "", "cycle_time": format_duration(task), } @router.get("/stats", response_class=HTMLResponse) def stats_page( request: Request, repo: JsonFileTaskRepository = Depends(get_task_repository), ) -> HTMLResponse: tasks = repo.list_tasks() backlog_tasks = [serialize_task(task) for task in tasks if get_task_status(task) == "backlog"] in_progress_tasks = [serialize_task(task) for task in tasks if get_task_status(task) == "in_progress"] done_tasks = [serialize_task(task) for task in tasks if get_task_status(task) == "done"] selected_task = None if tasks: selected_task = serialize_task(tasks[0]) return templates.TemplateResponse( request=request, name="stats.html", context={ "selected_task": selected_task, "backlog_tasks": backlog_tasks, "in_progress_tasks": in_progress_tasks, "done_tasks": done_tasks, }, )