import { NextRequest, NextResponse } from 'next/server' import { prisma } from '@/lib/db' import { getSession, isAdmin } from '@/lib/auth' import { getProjectWithTenantCheck } from '@/lib/tenant' import QRCode from 'qrcode' // Helper: create a rapport record and return JSON response async function createRapport(projectId: string, data: any, tenantId: string, userId: string, req: NextRequest) { // Einsatz-Nummer: one unique number per project (not per rapport) const existingRapport = await (prisma as any).rapport.findFirst({ where: { projectId }, orderBy: { createdAt: 'asc' }, select: { reportNumber: true }, }) let reportNumber: string if (existingRapport?.reportNumber) { reportNumber = existingRapport.reportNumber } else { const year = new Date().getFullYear() const prefix = `${year}-` const lastRapport = await (prisma as any).rapport.findFirst({ where: { tenantId, reportNumber: { startsWith: prefix } }, orderBy: { reportNumber: 'desc' }, select: { reportNumber: true }, }) let nextNum = 1 if (lastRapport?.reportNumber) { const lastNum = parseInt(lastRapport.reportNumber.split('-')[1]) if (!isNaN(lastNum)) nextNum = lastNum + 1 } reportNumber = `${prefix}${String(nextNum).padStart(4, '0')}` } data.reportNumber = reportNumber const rapport = await (prisma as any).rapport.create({ data: { reportNumber, data, projectId, tenantId, createdById: userId }, }) // Generate QR code const baseUrl = process.env.NEXTAUTH_URL || req.headers.get('origin') || `${req.headers.get('x-forwarded-proto') || 'https'}://${req.headers.get('host')}` || 'http://localhost:3000' const rapportUrl = `${baseUrl}/rapport/${rapport.token}` let qrCodeDataUri = '' try { qrCodeDataUri = await QRCode.toDataURL(rapportUrl, { width: 200, margin: 1, color: { dark: '#1a1a1a', light: '#ffffff' } }) } catch (e) { console.warn('QR code generation failed:', e) } if (qrCodeDataUri) { data.qrCodeUrl = qrCodeDataUri await (prisma as any).rapport.update({ where: { id: rapport.id }, data: { data } }) } return NextResponse.json({ id: rapport.id, reportNumber: rapport.reportNumber, token: rapport.token, qrCodeUrl: qrCodeDataUri, }) } // GET: List rapports for a project export async function GET(req: NextRequest) { try { const user = await getSession() if (!user) return NextResponse.json({ error: 'Nicht autorisiert' }, { status: 401 }) const { searchParams } = new URL(req.url) const projectId = searchParams.get('projectId') if (!projectId) { return NextResponse.json({ error: 'projectId erforderlich' }, { status: 400 }) } // Mandanten-Isolation: nur Rapporte von Projekten des eigenen Tenants const project = await getProjectWithTenantCheck(projectId, user) if (!project) { return NextResponse.json({ error: 'Projekt nicht gefunden' }, { status: 404 }) } const rapports = await (prisma as any).rapport.findMany({ where: { projectId }, orderBy: { createdAt: 'desc' }, select: { id: true, reportNumber: true, token: true, generatedAt: true, createdAt: true, createdBy: { select: { name: true } }, }, }) return NextResponse.json({ rapports }) } catch (error) { console.error('Error fetching rapports:', error) return NextResponse.json({ error: 'Serverfehler' }, { status: 500 }) } } // POST: Create a new rapport export async function POST(req: NextRequest) { try { const user = await getSession() if (!user) return NextResponse.json({ error: 'Nicht autorisiert' }, { status: 401 }) if (user.role === 'VIEWER') return NextResponse.json({ error: 'Keine Berechtigung' }, { status: 403 }) let body: any try { body = await req.json() } catch (parseErr: any) { console.error('[Rapport] Body parse error:', parseErr?.message) return NextResponse.json({ error: 'Request zu gross oder ungültig: ' + (parseErr?.message || 'Body konnte nicht gelesen werden') }, { status: 400 }) } const { projectId, data } = body || {} if (!projectId || !data) { console.error('[Rapport] Missing fields — projectId:', !!projectId, 'data:', !!data, 'body keys:', Object.keys(body || {})) return NextResponse.json({ error: `Felder fehlen (projectId=${!!projectId}, data=${!!data})` }, { status: 400 }) } // Mandanten-Isolation: Rapport nur für ein Projekt des eigenen Tenants anlegen const project = await getProjectWithTenantCheck(projectId, user) if (!project) { return NextResponse.json({ error: 'Projekt nicht gefunden' }, { status: 404 }) } let tenantId = project?.tenantId || user.tenantId || null if (!tenantId) { const membership = await (prisma as any).tenantMembership.findFirst({ where: { userId: user.id }, select: { tenantId: true }, }) tenantId = membership?.tenantId || null } console.log('[Rapport] Creating rapport — project:', projectId, 'tenant:', tenantId || '(none)') return await createRapport(projectId, data, tenantId, user.id, req) } catch (error: any) { console.error('[Rapport] Error:', error?.message || error) if (error?.code === 'P2002') { return NextResponse.json({ error: 'Rapportnummer existiert bereits' }, { status: 409 }) } return NextResponse.json({ error: error?.message || 'Serverfehler' }, { status: 500 }) } }