## Documentation System - Create complete documentation hub at /dashboard/docs with: - Getting Started guide with quick setup and troubleshooting - Hook Setup Guide with platform-specific configurations - API Reference with all endpoints and examples - FAQ with searchable questions and categories - Add responsive design with interactive features - Update navigation in base template ## Tool Call Tracking - Add ToolCall model for tracking Claude Code tool usage - Create /api/tool-calls endpoints for recording and analytics - Add tool_call hook type with auto-session detection - Include tool calls in project statistics and recalculation - Track tool names, parameters, execution time, and success rates ## Project Enhancements - Add project timeline and statistics pages (fix 404 errors) - Create recalculation script for fixing zero statistics - Update project stats to include tool call counts - Enhance session model with tool call relationships ## Infrastructure - Switch from requirements.txt to pyproject.toml/uv.lock - Add data import functionality for claude.json files - Update database connection to include all new models - Add comprehensive API documentation 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
122 lines
4.4 KiB
Python
122 lines
4.4 KiB
Python
"""
|
|
Dashboard web interface routes.
|
|
"""
|
|
|
|
from fastapi import APIRouter, Request, Depends
|
|
from fastapi.templating import Jinja2Templates
|
|
from fastapi.responses import HTMLResponse
|
|
from sqlalchemy.ext.asyncio import AsyncSession
|
|
|
|
from app.database.connection import get_db
|
|
|
|
dashboard_router = APIRouter()
|
|
templates = Jinja2Templates(directory="app/dashboard/templates")
|
|
|
|
|
|
@dashboard_router.get("/dashboard", response_class=HTMLResponse)
|
|
async def dashboard_home(request: Request, db: AsyncSession = Depends(get_db)):
|
|
"""Main dashboard page."""
|
|
return templates.TemplateResponse("dashboard.html", {
|
|
"request": request,
|
|
"title": "Claude Code Project Tracker"
|
|
})
|
|
|
|
|
|
@dashboard_router.get("/dashboard/projects", response_class=HTMLResponse)
|
|
async def dashboard_projects(request: Request, db: AsyncSession = Depends(get_db)):
|
|
"""Projects overview page."""
|
|
return templates.TemplateResponse("projects.html", {
|
|
"request": request,
|
|
"title": "Projects - Claude Code Tracker"
|
|
})
|
|
|
|
|
|
@dashboard_router.get("/dashboard/analytics", response_class=HTMLResponse)
|
|
async def dashboard_analytics(request: Request, db: AsyncSession = Depends(get_db)):
|
|
"""Analytics and insights page."""
|
|
return templates.TemplateResponse("analytics.html", {
|
|
"request": request,
|
|
"title": "Analytics - Claude Code Tracker"
|
|
})
|
|
|
|
|
|
@dashboard_router.get("/dashboard/conversations", response_class=HTMLResponse)
|
|
async def dashboard_conversations(request: Request, db: AsyncSession = Depends(get_db)):
|
|
"""Conversation search and history page."""
|
|
return templates.TemplateResponse("conversations.html", {
|
|
"request": request,
|
|
"title": "Conversations - Claude Code Tracker"
|
|
})
|
|
|
|
|
|
@dashboard_router.get("/dashboard/import", response_class=HTMLResponse)
|
|
async def dashboard_import(request: Request, db: AsyncSession = Depends(get_db)):
|
|
"""Data import page."""
|
|
return templates.TemplateResponse("import.html", {
|
|
"request": request,
|
|
"title": "Import Data - Claude Code Tracker"
|
|
})
|
|
|
|
|
|
@dashboard_router.get("/dashboard/projects/{project_id}/timeline", response_class=HTMLResponse)
|
|
async def dashboard_project_timeline(request: Request, project_id: int, db: AsyncSession = Depends(get_db)):
|
|
"""Project timeline page."""
|
|
return templates.TemplateResponse("project_timeline.html", {
|
|
"request": request,
|
|
"title": f"Timeline - Project {project_id}",
|
|
"project_id": project_id
|
|
})
|
|
|
|
|
|
@dashboard_router.get("/dashboard/projects/{project_id}/stats", response_class=HTMLResponse)
|
|
async def dashboard_project_stats(request: Request, project_id: int, db: AsyncSession = Depends(get_db)):
|
|
"""Project statistics page."""
|
|
return templates.TemplateResponse("project_stats.html", {
|
|
"request": request,
|
|
"title": f"Statistics - Project {project_id}",
|
|
"project_id": project_id
|
|
})
|
|
|
|
|
|
@dashboard_router.get("/dashboard/docs", response_class=HTMLResponse)
|
|
async def dashboard_docs(request: Request, db: AsyncSession = Depends(get_db)):
|
|
"""Documentation overview page."""
|
|
return templates.TemplateResponse("docs/index.html", {
|
|
"request": request,
|
|
"title": "Documentation - Claude Code Tracker"
|
|
})
|
|
|
|
|
|
@dashboard_router.get("/dashboard/docs/{section}", response_class=HTMLResponse)
|
|
async def dashboard_docs_section(request: Request, section: str, db: AsyncSession = Depends(get_db)):
|
|
"""Documentation section pages."""
|
|
# Map section names to templates and titles
|
|
sections = {
|
|
"getting-started": {
|
|
"template": "docs/getting-started.html",
|
|
"title": "Getting Started - Claude Code Tracker"
|
|
},
|
|
"hook-setup": {
|
|
"template": "docs/hook-setup.html",
|
|
"title": "Hook Setup Guide - Claude Code Tracker"
|
|
},
|
|
"api-reference": {
|
|
"template": "docs/api-reference.html",
|
|
"title": "API Reference - Claude Code Tracker"
|
|
},
|
|
"faq": {
|
|
"template": "docs/faq.html",
|
|
"title": "FAQ - Claude Code Tracker"
|
|
}
|
|
}
|
|
|
|
if section not in sections:
|
|
from fastapi import HTTPException
|
|
raise HTTPException(status_code=404, detail=f"Documentation section '{section}' not found")
|
|
|
|
section_info = sections[section]
|
|
return templates.TemplateResponse(section_info["template"], {
|
|
"request": request,
|
|
"title": section_info["title"],
|
|
"section": section
|
|
}) |