2025-10-16 12:42:25 +02:00

94 lines
2.8 KiB
TypeScript

// /src/app/api/users/route.ts
import { NextResponse } from 'next/server'
import { prisma } from '@/lib/prisma'
import type { Prisma } from '@/generated/prisma' // ggf. '@prisma/client' verwenden, falls das dein Pfad ist
export const dynamic = 'force-dynamic'
type ApiUser = {
id: string
name: string
avatar?: string
steamId?: string
country?: string
rating?: number
team?: { id: string; name: string } | null
}
export async function GET(req: Request) {
try {
const { searchParams } = new URL(req.url)
const q = (searchParams.get('q') ?? '').trim()
const limit = Math.min(2000, Math.max(1, Number(searchParams.get('limit') ?? 1000)))
// Select separat halten → saubere Typinferenz inkl. Relation 'team'
const select = {
steamId: true,
name: true,
avatar: true,
location: true,
premierRank: true,
faceitNickname: true,
faceitAvatar: true,
faceitCountry: true,
team: { select: { id: true, name: true } },
} as const
// Basisfilter: lastActiveAt != null ODER (timeZone != null UND != '')
const activeOrTzFilter: Prisma.UserWhereInput = {
OR: [
{ lastActiveAt: { not: null } },
{ AND: [{ timeZone: { not: null } }, { timeZone: { not: '' } }] },
],
}
const insensitive = 'insensitive' as Prisma.QueryMode
// Optionaler Suchfilter
const searchFilter: Prisma.UserWhereInput | undefined = q
? {
OR: [
{ name: { contains: q, mode: insensitive } },
{ steamId: { contains: q, mode: insensitive } },
{ faceitNickname: { contains: q, mode: insensitive } },
{ team: { is: { name: { contains: q, mode: insensitive } } } },
],
}
: undefined
const where: Prisma.UserWhereInput = searchFilter
? { AND: [activeOrTzFilter, searchFilter] }
: activeOrTzFilter
const rows = await prisma.user.findMany({
take: limit,
where,
orderBy: [{ name: 'asc' }, { steamId: 'asc' }],
select,
})
// WICHTIG: keine Param-Typannotation hier!
const mapped: ApiUser[] = rows.map(u => ({
id: u.steamId,
name: u.name ?? u.faceitNickname ?? '—',
avatar: u.avatar ?? u.faceitAvatar ?? undefined,
steamId: u.steamId,
country: u.location ?? u.faceitCountry ?? undefined,
rating: u.premierRank ?? undefined,
team: u.team ? { id: u.team.id, name: u.team.name } : null,
}))
mapped.sort((a, b) =>
(a.name ?? '').localeCompare(b.name ?? '', 'de', { sensitivity: 'base' })
)
return NextResponse.json(
{ ok: true, users: mapped },
{ headers: { 'Cache-Control': 'no-store' } }
)
} catch (e) {
console.error('[GET /api/users] error:', e)
return NextResponse.json({ ok: false, error: 'Failed to load users' }, { status: 500 })
}
}