diff options
Diffstat (limited to 'app/api/tracking/page-duration')
| -rw-r--r-- | app/api/tracking/page-duration/route.ts | 56 |
1 files changed, 56 insertions, 0 deletions
diff --git a/app/api/tracking/page-duration/route.ts b/app/api/tracking/page-duration/route.ts new file mode 100644 index 00000000..861a52cc --- /dev/null +++ b/app/api/tracking/page-duration/route.ts @@ -0,0 +1,56 @@ +import { NextRequest, NextResponse } from 'next/server' +import { getServerSession } from 'next-auth' +import db from '@/db/db' +import { pageVisits } from '@/db/schema' +import { and, eq, desc, gte } from 'drizzle-orm' +import { authOptions } from '../../auth/[...nextauth]/route' + +// 타입 변환 헬퍼 +function ensureNumber(value: string | number): number { + return typeof value === 'string' ? parseInt(value, 10) : value + } + + export async function POST(request: NextRequest) { + try { + const session = await getServerSession(authOptions) + const { route, duration, timestamp } = await request.json() + + // 세션이 있는 경우에만 체류 시간 업데이트 + if (session?.user?.id) { + // string ID를 number로 변환 + const numericUserId = ensureNumber(session.user.id) + + // 최근 5분 내의 해당 라우트 방문 기록을 찾아서 체류 시간 업데이트 + const fiveMinutesAgo = new Date(Date.now() - 5 * 60 * 1000) + + // 방법 1: 서브쿼리를 사용해서 가장 최근 레코드의 ID를 찾아서 업데이트 + const latestVisitSubquery = db + .select({ id: pageVisits.id }) + .from(pageVisits) + .where( + and( + eq(pageVisits.userId, numericUserId), // ✅ 이제 타입 매칭 + eq(pageVisits.route, route), + gte(pageVisits.visitedAt, fiveMinutesAgo) + ) + ) + .orderBy(desc(pageVisits.visitedAt)) + .limit(1) + + // 서브쿼리 결과를 사용해서 업데이트 + const latestVisit = await latestVisitSubquery + + if (latestVisit.length > 0) { + await db + .update(pageVisits) + .set({ duration }) + .where(eq(pageVisits.id, latestVisit[0].id)) + } + } + + return NextResponse.json({ success: true }) + } catch (error) { + console.error('Page duration tracking API error:', error) + return NextResponse.json({ success: false }, { status: 200 }) + } + }
\ No newline at end of file |
