This commit is contained in:
Timo Knuth
2026-02-27 15:19:24 +01:00
parent b7f8221095
commit 253c3c1c6d
134 changed files with 11188 additions and 1871 deletions

View File

@@ -0,0 +1,72 @@
import { NextRequest, NextResponse } from 'next/server'
import { prisma } from '@innungsapp/shared'
import { sendInviteEmail } from '@/lib/email'
import { auth } from '@/lib/auth'
export async function POST(req: NextRequest, { params }: { params: Promise<{ slug: string }> }) {
const { slug } = await params
const body = await req.json().catch(() => null)
if (!body?.name || !body?.email) {
return NextResponse.json({ error: 'Name und E-Mail sind erforderlich.' }, { status: 400 })
}
const name: string = String(body.name).trim()
const email: string = String(body.email).trim().toLowerCase()
const org = await prisma.organization.findUnique({
where: { slug },
select: { id: true, name: true },
})
if (!org) {
return NextResponse.json({ error: 'Organisation nicht gefunden.' }, { status: 404 })
}
// Check if email already registered in this org
const existing = await prisma.member.findFirst({
where: { orgId: org.id, email },
})
if (existing) {
// Still send invite so user can log in — don't reveal whether they exist
await sendInviteEmail({
to: email,
memberName: existing.name,
orgName: org.name,
apiUrl: process.env.BETTER_AUTH_URL!,
})
return NextResponse.json({ success: true })
}
// Create member record
await prisma.member.create({
data: {
name,
email,
orgId: org.id,
betrieb: '-',
sparte: '-',
ort: '-',
status: 'aktiv',
},
})
// Create auth user (may already exist)
try {
await auth.api.createUser({
body: { name, email, role: 'user', password: undefined },
})
} catch {
// User may already exist in auth system
}
await sendInviteEmail({
to: email,
memberName: name,
orgName: org.name,
apiUrl: process.env.BETTER_AUTH_URL!,
})
return NextResponse.json({ success: true })
}

View File

@@ -0,0 +1,82 @@
import { NextRequest, NextResponse } from 'next/server'
import { prisma } from '@innungsapp/shared'
export async function POST(req: NextRequest, { params }: { params: Promise<{ slug: string }> }) {
const { slug } = await params
const body = await req.json().catch(() => null)
if (!body?.email) {
return NextResponse.json({ error: 'E-Mail ist erforderlich.' }, { status: 400 })
}
const email: string = String(body.email).trim().toLowerCase()
const name: string = String(body.name ?? '').trim() || email.split('@')[0]
const org = await prisma.organization.findUnique({
where: { slug },
select: { id: true },
})
if (!org) {
return NextResponse.json({ error: 'Organisation nicht gefunden.' }, { status: 404 })
}
// Look up the auth user that better-auth just created
const authUser = await prisma.user.findUnique({
where: { email },
select: { id: true },
})
if (!authUser) {
return NextResponse.json({ error: 'Benutzer nicht gefunden. Bitte zuerst registrieren.' }, { status: 400 })
}
// Idempotent: skip if member already exists (linked to this user)
const existingMember = await prisma.member.findFirst({
where: { orgId: org.id, userId: authUser.id },
})
if (!existingMember) {
// Member may exist without userId (created by admin before user registered)
const unlinkedMember = await prisma.member.findFirst({
where: { orgId: org.id, email, userId: null },
})
if (unlinkedMember) {
await prisma.member.update({
where: { id: unlinkedMember.id },
data: { userId: authUser.id },
})
} else {
await prisma.member.create({
data: {
name,
email,
orgId: org.id,
userId: authUser.id,
betrieb: '-',
sparte: '-',
ort: '-',
status: 'aktiv',
},
})
}
}
// Idempotent: skip if role already exists
const existingRole = await prisma.userRole.findFirst({
where: { userId: authUser.id, orgId: org.id },
})
if (!existingRole) {
await prisma.userRole.create({
data: {
userId: authUser.id,
orgId: org.id,
role: 'member',
},
})
}
return NextResponse.json({ success: true })
}