127 lines
4.0 KiB
TypeScript
127 lines
4.0 KiB
TypeScript
// /src/app/api/team/transfer-leader/route.ts
|
|
import { prisma } from '@/app/lib/prisma'
|
|
import { NextResponse, type NextRequest } from 'next/server'
|
|
import { sendServerSSEMessage } from '@/app/lib/sse-server-client'
|
|
|
|
export const dynamic = 'force-dynamic'
|
|
|
|
export async function POST(req: NextRequest) {
|
|
try {
|
|
const { teamId, newLeaderSteamId } = await req.json()
|
|
|
|
if (!teamId || !newLeaderSteamId) {
|
|
return NextResponse.json({ message: 'Fehlende Parameter' }, { status: 400 })
|
|
}
|
|
|
|
const team = await prisma.team.findUnique({
|
|
where: { id: teamId },
|
|
select: { id: true, name: true, leaderId: true, activePlayers: true, inactivePlayers: true },
|
|
})
|
|
if (!team) {
|
|
return NextResponse.json({ message: 'Team nicht gefunden.' }, { status: 404 })
|
|
}
|
|
|
|
const allPlayerIds = Array.from(new Set([
|
|
...(team.activePlayers ?? []),
|
|
...(team.inactivePlayers ?? []),
|
|
team.leaderId, // alter Leader (kann null sein)
|
|
].filter(Boolean) as string[]))
|
|
|
|
// Neuer Leader muss Mitglied sein
|
|
if (!allPlayerIds.includes(newLeaderSteamId)) {
|
|
return NextResponse.json({ message: 'Neuer Leader ist kein Teammitglied.' }, { status: 400 })
|
|
}
|
|
|
|
// Leader setzen
|
|
await prisma.team.update({
|
|
where: { id: teamId },
|
|
data : { leaderId: newLeaderSteamId },
|
|
})
|
|
|
|
// Namen neuer Leader
|
|
const newLeader = await prisma.user.findUnique({
|
|
where : { steamId: newLeaderSteamId },
|
|
select: { name: true },
|
|
})
|
|
|
|
const textForOthers =
|
|
`${newLeader?.name ?? 'Ein Spieler'} ist jetzt Teamleader von "${team.name}".`
|
|
|
|
// 1) Notification an neuen Leader (sichtbar + live)
|
|
const leaderNote = await prisma.notification.create({
|
|
data: {
|
|
steamId : newLeaderSteamId,
|
|
title : 'Beförderung',
|
|
message : `Du bist jetzt Teamleader von "${team.name}".`,
|
|
actionType: 'team-leader-self',
|
|
actionData: teamId,
|
|
},
|
|
})
|
|
await sendServerSSEMessage({
|
|
type : 'notification',
|
|
targetUserIds: [newLeaderSteamId],
|
|
message : leaderNote.message,
|
|
id : leaderNote.id,
|
|
actionType : leaderNote.actionType ?? undefined,
|
|
actionData : leaderNote.actionData ?? undefined,
|
|
createdAt : leaderNote.createdAt.toISOString(),
|
|
})
|
|
|
|
// 2) Info an alle anderen (sichtbar + live)
|
|
const others = allPlayerIds.filter(id => id !== newLeaderSteamId)
|
|
if (others.length) {
|
|
const notes = await Promise.all(
|
|
others.map(steamId =>
|
|
prisma.notification.create({
|
|
data: {
|
|
steamId,
|
|
title: 'Neuer Teamleader',
|
|
message: textForOthers,
|
|
actionType: 'team-leader-changed',
|
|
actionData: newLeaderSteamId,
|
|
},
|
|
})
|
|
)
|
|
)
|
|
|
|
await Promise.all(
|
|
notes.map(n =>
|
|
sendServerSSEMessage({
|
|
type: 'notification',
|
|
targetUserIds: [n.steamId],
|
|
message: n.message,
|
|
id: n.id,
|
|
actionType: n.actionType ?? undefined,
|
|
actionData: n.actionData ?? undefined,
|
|
createdAt: n.createdAt.toISOString(),
|
|
})
|
|
)
|
|
)
|
|
|
|
// zusätzliches Team-Event (für SSEHandler → soft reload)
|
|
await sendServerSSEMessage({
|
|
type: 'team-leader-changed',
|
|
targetUserIds: others,
|
|
teamId,
|
|
message: textForOthers,
|
|
actionData: newLeaderSteamId,
|
|
})
|
|
}
|
|
|
|
// 3) Zielgerichtetes “team-updated” an ALLE (inkl. neuem Leader)
|
|
const reloadTargets = Array.from(new Set([...allPlayerIds, newLeaderSteamId]))
|
|
if (reloadTargets.length) {
|
|
await sendServerSSEMessage({
|
|
type: 'team-updated',
|
|
targetUserIds: reloadTargets,
|
|
teamId,
|
|
})
|
|
}
|
|
|
|
return NextResponse.json({ message: 'Leader erfolgreich übertragen.' })
|
|
} catch (error) {
|
|
console.error('Fehler beim Leaderwechsel:', error)
|
|
return NextResponse.json({ message: 'Serverfehler beim Leaderwechsel.' }, { status: 500 })
|
|
}
|
|
}
|