import { NextRequest, NextResponse } from 'next/server'; import { getApiUrl } from '@/lib/utils/api-url'; /** * Complete Chronological History * Returns ALL project data in a single chronological timeline * Optimized for AI consumption - no truncation, no summaries */ export async function GET( request: NextRequest, { params }: { params: Promise<{ projectId: string }> } ) { try { const { projectId } = await params; // Load all three data sources const [contextRes, gitRes, activityRes, timelineRes] = await Promise.all([ fetch(getApiUrl(`/api/projects/${projectId}/context`, request)), fetch(getApiUrl(`/api/projects/${projectId}/git-history`, request)), fetch(getApiUrl(`/api/projects/${projectId}/activity`, request)), fetch(getApiUrl(`/api/projects/${projectId}/timeline`, request)) ]); const context = contextRes.ok ? await contextRes.json() : null; const git = gitRes.ok ? await gitRes.json() : null; const activity = activityRes.ok ? await activityRes.json() : null; const timeline = timelineRes.ok ? await timelineRes.json() : null; // Build complete chronological event stream const events: any[] = []; // Add all Git commits as events if (git?.commits) { for (const commit of git.commits) { events.push({ type: 'git_commit', timestamp: new Date(commit.date).toISOString(), date: commit.date.split(' ')[0], data: { hash: commit.hash, author: commit.author, message: commit.message, filesChanged: commit.filesChanged, insertions: commit.insertions, deletions: commit.deletions } }); } } // Add all extension sessions as events if (activity?.sessions) { for (const session of activity.sessions) { events.push({ type: 'extension_session', timestamp: session.startTime, date: new Date(session.startTime).toISOString().split('T')[0], data: { id: session.id, startTime: session.startTime, endTime: session.endTime, duration: session.duration, filesModified: session.filesModified, conversationSummary: session.conversationSummary?.substring(0, 200), conversationSnippets: (session.conversation || []).slice(0, 5).map((msg: any) => ({ role: msg.role, message: msg.message?.substring(0, 100), timestamp: msg.timestamp })) } }); } } // Add Cursor conversations (from recent conversations in context) if (context?.activity?.recentConversations) { for (const conv of context.activity.recentConversations) { events.push({ type: 'cursor_conversation', timestamp: conv.createdAt, date: new Date(conv.createdAt).toISOString().split('T')[0], data: { id: conv.id, name: conv.name, createdAt: conv.createdAt, messageCount: conv.recentMessages?.length || 0, recentMessages: conv.recentMessages?.map((msg: any) => ({ type: msg.type, text: msg.text?.substring(0, 150), createdAt: msg.createdAt })) } }); } } // Sort everything chronologically events.sort((a, b) => new Date(a.timestamp).getTime() - new Date(b.timestamp).getTime() ); // Group by date for easier consumption const eventsByDate: Record = {}; for (const event of events) { if (!eventsByDate[event.date]) { eventsByDate[event.date] = []; } eventsByDate[event.date].push(event); } // Build response const completeHistory = { project: { id: projectId, name: context?.project?.name, vision: context?.project?.vision, githubRepo: context?.project?.githubRepo }, summary: { totalEvents: events.length, dateRange: { earliest: events[0]?.date, latest: events[events.length - 1]?.date, totalDays: Object.keys(eventsByDate).length }, breakdown: { gitCommits: events.filter(e => e.type === 'git_commit').length, extensionSessions: events.filter(e => e.type === 'extension_session').length, cursorConversations: events.filter(e => e.type === 'cursor_conversation').length } }, chronologicalEvents: events, eventsByDate: Object.keys(eventsByDate) .sort() .map(date => ({ date, dayOfWeek: new Date(date).toLocaleDateString('en-US', { weekday: 'long' }), eventCount: eventsByDate[date].length, events: eventsByDate[date] })), metadata: { generatedAt: new Date().toISOString(), dataComplete: true, includesFullHistory: true } }; return NextResponse.json(completeHistory); } catch (error) { console.error('Error generating complete history:', error); return NextResponse.json( { error: 'Failed to generate complete history', details: error instanceof Error ? error.message : String(error) }, { status: 500 } ); } }