import { Response } from 'express'; import { ApiResponse, AuthRequest } from '../types/index.js'; import { logChange } from '../services/audit.service.js'; import * as referralService from '../services/customerReferral.service.js'; // Der ganze Bereich ist rein für Mitarbeiter/Admins – Portal-Kunden dürfen // Werbe-Beziehungen weder sehen noch ändern. Defense-in-Depth: nicht nur die // UI blendet den Tab aus, der Endpoint blockt Portal-Token explizit. function blockPortal(req: AuthRequest, res: Response): boolean { if (req.user?.isCustomerPortal) { res.status(403).json({ success: false, error: 'Kein Zugriff' } as ApiResponse); return true; } return false; } export async function getReferrals(req: AuthRequest, res: Response): Promise { try { if (blockPortal(req, res)) return; const customerId = parseInt(req.params.customerId); if (Number.isNaN(customerId)) { res.status(400).json({ success: false, error: 'Ungültige Kunden-ID' } as ApiResponse); return; } const data = await referralService.getReferralsForCustomer(customerId); res.json({ success: true, data } as ApiResponse); } catch (error) { res.status(500).json({ success: false, error: 'Fehler beim Laden der Werbe-Beziehungen' } as ApiResponse); } } export async function searchCustomers(req: AuthRequest, res: Response): Promise { try { if (blockPortal(req, res)) return; const customerId = parseInt(req.params.customerId); if (Number.isNaN(customerId)) { res.status(400).json({ success: false, error: 'Ungültige Kunden-ID' } as ApiResponse); return; } const search = req.query.search; if (!search || typeof search !== 'string' || search.trim().length < 2) { res.json({ success: true, data: [] } as ApiResponse); return; } const customers = await referralService.searchCustomersForReferral(search.trim(), customerId); res.json({ success: true, data: customers } as ApiResponse); } catch (error) { res.status(500).json({ success: false, error: 'Fehler bei der Suche' } as ApiResponse); } } export async function createReferral(req: AuthRequest, res: Response): Promise { try { if (blockPortal(req, res)) return; const customerId = parseInt(req.params.customerId); if (Number.isNaN(customerId)) { res.status(400).json({ success: false, error: 'Ungültige Kunden-ID' } as ApiResponse); return; } const { direction, otherCustomerId, relationship } = req.body ?? {}; const otherId = parseInt(otherCustomerId); if (Number.isNaN(otherId)) { res.status(400).json({ success: false, error: 'Kein Kunde ausgewählt' } as ApiResponse); return; } // direction bestimmt, wer Werber und wer Geworbener ist: // 'recruitedBy' = dieser Kunde wurde vom anderen geworben (Abschnitt 1) // 'recruited' = dieser Kunde hat den anderen geworben (Abschnitt 2) let recruiterId: number; let recruitedId: number; if (direction === 'recruitedBy') { recruiterId = otherId; recruitedId = customerId; } else if (direction === 'recruited') { recruiterId = customerId; recruitedId = otherId; } else { res.status(400).json({ success: false, error: 'Ungültige Richtung' } as ApiResponse); return; } const created = await referralService.createReferral({ recruiterId, recruitedId, relationship: (relationship ?? '').toString(), createdBy: req.user?.email, }); await logChange({ req, action: 'CREATE', resourceType: 'CustomerReferral', resourceId: created.id.toString(), label: `Werbe-Beziehung angelegt: Kunde #${recruiterId} hat Kunde #${recruitedId} geworben (${created.relationship})`, customerId: recruitedId, }); res.status(201).json({ success: true, data: created } as ApiResponse); } catch (error) { const status = (error as referralService.ReferralError)?.status ?? 500; res.status(status).json({ success: false, error: error instanceof Error ? error.message : 'Fehler beim Anlegen der Werbe-Beziehung', } as ApiResponse); } } export async function deleteReferral(req: AuthRequest, res: Response): Promise { try { if (blockPortal(req, res)) return; const referralId = parseInt(req.params.referralId); if (Number.isNaN(referralId)) { res.status(400).json({ success: false, error: 'Ungültige ID' } as ApiResponse); return; } const ok = await referralService.deleteReferral(referralId); if (!ok) { res.status(404).json({ success: false, error: 'Eintrag nicht gefunden' } as ApiResponse); return; } await logChange({ req, action: 'DELETE', resourceType: 'CustomerReferral', resourceId: referralId.toString(), label: `Werbe-Beziehung #${referralId} entfernt`, }); res.json({ success: true } as ApiResponse); } catch (error) { res.status(500).json({ success: false, error: 'Fehler beim Entfernen der Werbe-Beziehung' } as ApiResponse); } }