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>
This commit is contained in:
parent
166247bf70
commit
bec1606c86
27 changed files with 6150 additions and 32 deletions
109
recalculate_project_stats.py
Normal file
109
recalculate_project_stats.py
Normal file
|
|
@ -0,0 +1,109 @@
|
|||
#!/usr/bin/env python3
|
||||
"""
|
||||
Script to recalculate project statistics from imported sessions and conversations.
|
||||
Run this after importing data to fix zero statistics on the projects page.
|
||||
"""
|
||||
|
||||
import asyncio
|
||||
from sqlalchemy import select, func
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
from app.database.connection import engine, async_session_maker
|
||||
from app.models.project import Project
|
||||
from app.models.session import Session
|
||||
from app.models.conversation import Conversation
|
||||
from app.models.activity import Activity
|
||||
from app.models.tool_call import ToolCall
|
||||
|
||||
async def recalculate_project_stats():
|
||||
"""Recalculate statistics for all projects based on imported data."""
|
||||
|
||||
async with async_session_maker() as db:
|
||||
try:
|
||||
# Get all projects
|
||||
result = await db.execute(select(Project))
|
||||
projects = result.scalars().all()
|
||||
|
||||
print(f"Found {len(projects)} projects to recalculate")
|
||||
|
||||
for project in projects:
|
||||
print(f"\nRecalculating stats for project: {project.name}")
|
||||
|
||||
# Get all sessions for this project
|
||||
session_result = await db.execute(
|
||||
select(Session).where(Session.project_id == project.id)
|
||||
)
|
||||
sessions = session_result.scalars().all()
|
||||
session_ids = [s.id for s in sessions] if sessions else []
|
||||
|
||||
# Calculate session-based statistics
|
||||
total_sessions = len(sessions)
|
||||
total_time_minutes = sum(
|
||||
s.calculated_duration_minutes or 0 for s in sessions
|
||||
)
|
||||
|
||||
# Find last session time
|
||||
last_session_time = None
|
||||
if sessions:
|
||||
last_session_time = max(s.start_time for s in sessions)
|
||||
|
||||
# Calculate activity-based statistics
|
||||
files_modified_count = 0
|
||||
lines_changed_count = 0
|
||||
tool_calls_count = 0
|
||||
|
||||
if session_ids:
|
||||
activity_result = await db.execute(
|
||||
select(Activity).where(Activity.session_id.in_(session_ids))
|
||||
)
|
||||
activities = activity_result.scalars().all()
|
||||
|
||||
# Count unique files modified
|
||||
unique_files = set()
|
||||
total_lines_changed = 0
|
||||
|
||||
for activity in activities:
|
||||
if activity.file_path:
|
||||
unique_files.add(activity.file_path)
|
||||
if activity.total_lines_changed:
|
||||
total_lines_changed += activity.total_lines_changed
|
||||
|
||||
files_modified_count = len(unique_files)
|
||||
lines_changed_count = total_lines_changed
|
||||
|
||||
# Count tool calls
|
||||
session_ids_str = [str(sid) for sid in session_ids]
|
||||
tool_calls_result = await db.execute(
|
||||
select(ToolCall).where(ToolCall.session_id.in_(session_ids_str))
|
||||
)
|
||||
tool_calls = tool_calls_result.scalars().all()
|
||||
tool_calls_count = len(tool_calls)
|
||||
|
||||
# Update project statistics
|
||||
project.total_sessions = total_sessions
|
||||
project.total_time_minutes = total_time_minutes
|
||||
project.files_modified_count = files_modified_count
|
||||
project.lines_changed_count = lines_changed_count
|
||||
project.tool_calls_count = tool_calls_count
|
||||
if last_session_time:
|
||||
project.last_session = last_session_time
|
||||
|
||||
print(f" Sessions: {total_sessions}")
|
||||
print(f" Time: {total_time_minutes} minutes")
|
||||
print(f" Files: {files_modified_count}")
|
||||
print(f" Lines: {lines_changed_count}")
|
||||
print(f" Tool calls: {tool_calls_count}")
|
||||
print(f" Last session: {last_session_time}")
|
||||
|
||||
# Commit all changes
|
||||
await db.commit()
|
||||
print(f"\nSuccessfully recalculated statistics for {len(projects)} projects")
|
||||
|
||||
except Exception as e:
|
||||
await db.rollback()
|
||||
print(f"Error recalculating project stats: {e}")
|
||||
raise
|
||||
finally:
|
||||
await engine.dispose()
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(recalculate_project_stats())
|
||||
Loading…
Add table
Add a link
Reference in a new issue