VIBN Frontend for Coolify deployment
This commit is contained in:
84
app/api/projects/[projectId]/activity/route.ts
Normal file
84
app/api/projects/[projectId]/activity/route.ts
Normal file
@@ -0,0 +1,84 @@
|
||||
import { NextRequest, NextResponse } from 'next/server';
|
||||
import { adminDb } from '@/lib/firebase/admin';
|
||||
|
||||
export async function GET(
|
||||
request: NextRequest,
|
||||
{ params }: { params: Promise<{ projectId: string }> }
|
||||
) {
|
||||
try {
|
||||
const { projectId } = await params;
|
||||
|
||||
// Get all sessions for this project
|
||||
const sessionsSnapshot = await adminDb
|
||||
.collection('sessions')
|
||||
.where('projectId', '==', projectId)
|
||||
.get();
|
||||
|
||||
const sessions = sessionsSnapshot.docs
|
||||
.map(doc => {
|
||||
const data = doc.data();
|
||||
return {
|
||||
id: doc.id,
|
||||
startTime: data.startTime?.toDate?.() || data.startTime,
|
||||
endTime: data.endTime?.toDate?.() || data.endTime,
|
||||
duration: data.duration || 0,
|
||||
filesModified: data.filesModified || [],
|
||||
conversationSummary: data.conversationSummary || '',
|
||||
workspacePath: data.workspacePath || '',
|
||||
conversation: data.conversation || []
|
||||
};
|
||||
})
|
||||
.sort((a, b) => {
|
||||
const aTime = a.startTime ? new Date(a.startTime).getTime() : 0;
|
||||
const bTime = b.startTime ? new Date(b.startTime).getTime() : 0;
|
||||
return aTime - bTime;
|
||||
});
|
||||
|
||||
// Analyze activity
|
||||
const fileActivity: Record<string, { count: number; dates: string[] }> = {};
|
||||
const dailyActivity: Record<string, number> = {};
|
||||
|
||||
sessions.forEach(session => {
|
||||
if (!session.startTime) return;
|
||||
|
||||
const date = new Date(session.startTime).toISOString().split('T')[0];
|
||||
dailyActivity[date] = (dailyActivity[date] || 0) + 1;
|
||||
|
||||
session.filesModified.forEach((file: string) => {
|
||||
if (!fileActivity[file]) {
|
||||
fileActivity[file] = { count: 0, dates: [] };
|
||||
}
|
||||
fileActivity[file].count++;
|
||||
if (!fileActivity[file].dates.includes(date)) {
|
||||
fileActivity[file].dates.push(date);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// Get top files
|
||||
const topFiles = Object.entries(fileActivity)
|
||||
.map(([file, data]) => ({ file, ...data }))
|
||||
.sort((a, b) => b.count - a.count)
|
||||
.slice(0, 50);
|
||||
|
||||
return NextResponse.json({
|
||||
totalSessions: sessions.length,
|
||||
sessions,
|
||||
fileActivity: topFiles,
|
||||
dailyActivity: Object.entries(dailyActivity)
|
||||
.map(([date, count]) => ({ date, sessionCount: count }))
|
||||
.sort((a, b) => a.date.localeCompare(b.date))
|
||||
});
|
||||
|
||||
} catch (error) {
|
||||
console.error('Error fetching activity:', error);
|
||||
return NextResponse.json(
|
||||
{
|
||||
error: 'Failed to fetch activity',
|
||||
details: error instanceof Error ? error.message : String(error)
|
||||
},
|
||||
{ status: 500 }
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user