Ryan Malloy bec1606c86 Add comprehensive documentation system and tool call tracking
## 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>
2025-08-11 05:58:27 -06:00

71 lines
2.8 KiB
Python

"""
Project model for tracking development projects.
"""
from datetime import datetime
from typing import Optional, List
from sqlalchemy import String, Text, Integer, DateTime, JSON
from sqlalchemy.orm import Mapped, mapped_column, relationship
from sqlalchemy.sql import func
from .base import Base, TimestampMixin
class Project(Base, TimestampMixin):
"""
Represents a development project tracked by Claude Code.
A project is typically identified by its filesystem path and may
correspond to a git repository.
"""
__tablename__ = "projects"
# Primary key
id: Mapped[int] = mapped_column(primary_key=True)
# Core project information
name: Mapped[str] = mapped_column(String(255), nullable=False)
path: Mapped[str] = mapped_column(Text, nullable=False, unique=True, index=True)
git_repo: Mapped[Optional[str]] = mapped_column(String(500), nullable=True)
languages: Mapped[Optional[List[str]]] = mapped_column(JSON, nullable=True)
# Activity tracking
last_session: Mapped[Optional[datetime]] = mapped_column(DateTime(timezone=True), nullable=True, index=True)
total_sessions: Mapped[int] = mapped_column(Integer, default=0, nullable=False)
total_time_minutes: Mapped[int] = mapped_column(Integer, default=0, nullable=False)
files_modified_count: Mapped[int] = mapped_column(Integer, default=0, nullable=False)
lines_changed_count: Mapped[int] = mapped_column(Integer, default=0, nullable=False)
tool_calls_count: Mapped[int] = mapped_column(Integer, default=0, nullable=False)
# Relationships
sessions: Mapped[List["Session"]] = relationship(
"Session",
back_populates="project",
cascade="all, delete-orphan",
order_by="Session.start_time.desc()"
)
def __repr__(self) -> str:
return f"<Project(id={self.id}, name='{self.name}', path='{self.path}')>"
@property
def is_git_repo(self) -> bool:
"""Check if this project is a git repository."""
return self.git_repo is not None and self.git_repo != ""
@property
def primary_language(self) -> Optional[str]:
"""Get the primary programming language for this project."""
if self.languages and len(self.languages) > 0:
return self.languages[0]
return None
def update_stats(self, session_duration_minutes: int, files_count: int, lines_count: int, tool_calls_count: int = 0) -> None:
"""Update project statistics after a session."""
self.total_sessions += 1
self.total_time_minutes += session_duration_minutes
self.files_modified_count += files_count
self.lines_changed_count += lines_count
self.tool_calls_count += tool_calls_count
self.last_session = func.now()