Prmbr/src/app/api/users/sync/route.ts
2025-08-27 07:15:16 +08:00

138 lines
4.2 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { NextResponse } from 'next/server'
import { prisma } from '@/lib/prisma'
import { createServerSupabaseClient } from '@/lib/supabase-server'
import { addCredit } from '@/lib/services/credit'
// POST /api/users/sync - 同步Supabase用户到Prisma数据库
export async function POST() {
try {
const supabase = await createServerSupabaseClient()
const { data: { user: supabaseUser }, error: authError } = await supabase.auth.getUser()
if (authError || !supabaseUser) {
return NextResponse.json({ error: 'Unauthorized' }, { status: 401 })
}
// 先检查用户是否存在
let user = await prisma.user.findUnique({
where: { id: supabaseUser.id }
})
let isNewUser = false
if (user) {
// 用户已存在,更新信息
user = await prisma.user.update({
where: { id: supabaseUser.id },
data: {
email: supabaseUser.email!,
username: supabaseUser.user_metadata?.username || supabaseUser.user_metadata?.full_name || null,
avatar: supabaseUser.user_metadata?.avatar_url || null,
bio: supabaseUser.user_metadata?.bio || null,
language: supabaseUser.user_metadata?.language || 'en',
updatedAt: new Date()
}
})
} else {
// 用户不存在,需要创建
try {
user = await prisma.user.create({
data: {
id: supabaseUser.id,
email: supabaseUser.email!,
username: supabaseUser.user_metadata?.username || supabaseUser.user_metadata?.full_name || null,
avatar: supabaseUser.user_metadata?.avatar_url || null,
bio: supabaseUser.user_metadata?.bio || null,
language: supabaseUser.user_metadata?.language || 'en',
subscriptionPlanId: 'free'
}
})
isNewUser = true
} catch (createError: unknown) {
// 如果是唯一约束错误,可能是并发创建导致的
const prismaError = createError as { code?: string }
if (prismaError.code === 'P2002') {
console.warn(`Concurrent user creation detected for ${supabaseUser.id}, fetching existing user`)
user = await prisma.user.findUnique({
where: { id: supabaseUser.id }
})
if (!user) {
throw createError // 如果还是找不到用户,重新抛出错误
}
} else {
throw createError
}
}
}
// isNewUser 变量已经在上面定义了
if (isNewUser) {
// 为新用户添加系统赠送的5USD信用额度1个月后过期
const expiresAt = new Date()
expiresAt.setMonth(expiresAt.getMonth() + 1)
try {
await addCredit(
user.id,
5.0,
'system_gift',
'系统赠送 - 新用户礼包',
expiresAt
)
console.log(`Added welcome credit for new user: ${user.id}`)
} catch (creditError) {
console.error('Failed to add welcome credit:', creditError)
// 不影响用户创建流程
}
return NextResponse.json({
message: 'User created successfully',
user
}, { status: 201 })
} else {
return NextResponse.json({
message: 'User updated successfully',
user
})
}
} catch (error) {
console.error('Error syncing user:', error)
return NextResponse.json(
{ error: 'Failed to sync user' },
{ status: 500 }
)
}
}
// GET /api/users/sync - 获取当前用户信息
export async function GET() {
try {
const supabase = await createServerSupabaseClient()
const { data: { user: supabaseUser }, error: authError } = await supabase.auth.getUser()
if (authError || !supabaseUser) {
return NextResponse.json({ error: 'Unauthorized' }, { status: 401 })
}
// 从Prisma数据库获取用户信息
const user = await prisma.user.findUnique({
where: { id: supabaseUser.id }
})
if (!user) {
return NextResponse.json({ error: 'User not found in database' }, { status: 404 })
}
return NextResponse.json({ user })
} catch (error) {
console.error('Error fetching user:', error)
return NextResponse.json(
{ error: 'Failed to fetch user' },
{ status: 500 }
)
}
}