Spaces:
Configuration error
Configuration error
File size: 3,700 Bytes
bcce530 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 | import { NextRequest, NextResponse } from "next/server"
import { prisma } from "@/lib/prisma"
// POST - Record extension analytics
export async function POST(request: NextRequest) {
try {
const body = await request.json()
const {
userId,
deviceId,
action,
platform,
platforms,
promptId,
promptTitle,
promptText,
metadata
} = body
if (!deviceId || !action) {
return NextResponse.json(
{ error: "deviceId and action are required" },
{ status: 400 }
)
}
const analytics = await prisma.extensionAnalytics.create({
data: {
userId: userId || null,
deviceId,
action,
platform: platform || "unknown",
platforms: platforms || [],
promptId: promptId || null,
promptTitle: promptTitle || null,
promptText: promptText || null,
source: "extension",
metadata: metadata || null,
},
})
return NextResponse.json({ success: true, id: analytics.id })
} catch (error) {
console.error("Extension analytics error:", error)
return NextResponse.json(
{ error: "Failed to record analytics" },
{ status: 500 }
)
}
}
// GET - Fetch extension analytics for a user/device
export async function GET(request: NextRequest) {
try {
const { searchParams } = new URL(request.url)
const userId = searchParams.get("userId")
const deviceId = searchParams.get("deviceId")
const limit = parseInt(searchParams.get("limit") || "50")
if (!userId && !deviceId) {
return NextResponse.json(
{ error: "userId or deviceId required" },
{ status: 400 }
)
}
const where: { userId?: string; deviceId?: string } = {}
if (userId) where.userId = userId
if (deviceId) where.deviceId = deviceId
// Get recent activity
const recentActivity = await prisma.extensionAnalytics.findMany({
where,
orderBy: { createdAt: "desc" },
take: limit,
})
// Get aggregated stats
const stats = await prisma.extensionAnalytics.groupBy({
by: ["action"],
where,
_count: { action: true },
})
const platformStats = await prisma.extensionAnalytics.groupBy({
by: ["platform"],
where,
_count: { platform: true },
})
// Get daily usage for last 30 days
const thirtyDaysAgo = new Date()
thirtyDaysAgo.setDate(thirtyDaysAgo.getDate() - 30)
// Use Prisma's safe query approach
const dailyUsage = await prisma.extensionAnalytics.groupBy({
by: ['createdAt'],
where: {
...where,
createdAt: { gte: thirtyDaysAgo },
},
_count: { id: true },
}).then(results => {
// Group by date (day only)
const dateMap = new Map<string, number>()
results.forEach(r => {
const dateStr = r.createdAt.toISOString().split('T')[0]
dateMap.set(dateStr, (dateMap.get(dateStr) || 0) + r._count.id)
})
return Array.from(dateMap.entries()).map(([date, count]) => ({ date, count }))
}).catch(() => [])
return NextResponse.json({
recentActivity,
stats: stats.map((s: { action: string; _count: { action: number } }) => ({
action: s.action,
count: s._count.action
})),
platformStats: platformStats.map((s: { platform: string; _count: { platform: number } }) => ({
platform: s.platform,
count: s._count.platform
})),
dailyUsage,
})
} catch (error) {
console.error("Extension analytics fetch error:", error)
return NextResponse.json(
{ error: "Failed to fetch analytics" },
{ status: 500 }
)
}
}
|