Files
dashboard/backend/src/controllers/personalEquipment.controller.ts

186 lines
7.4 KiB
TypeScript

import { Request, Response } from 'express';
import { z } from 'zod';
import personalEquipmentService from '../services/personalEquipment.service';
import logger from '../utils/logger';
const uuidString = z.string().regex(
/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i,
'Ungültige UUID',
);
const isoDate = z.string().regex(
/^\d{4}-(0[1-9]|1[0-2])-(0[1-9]|[12]\d|3[01])$/,
'Erwartet ISO-Datum im Format YYYY-MM-DD',
);
const ZustandEnum = z.enum(['gut', 'beschaedigt', 'abgaengig', 'verloren']);
const EigenschaftInput = z.object({
eigenschaft_id: z.number().int().positive().nullable().optional(),
name: z.string().min(1).max(200),
wert: z.string().max(500),
});
const CreateSchema = z.object({
bezeichnung: z.string().min(1).max(200),
kategorie: z.string().max(100).optional(),
artikel_id: z.number().int().positive().optional(),
user_id: uuidString.optional(),
benutzer_name: z.string().max(200).optional(),
groesse: z.string().max(50).optional(),
seriennummer: z.string().max(100).optional(),
inventarnummer: z.string().max(50).optional(),
anschaffung_datum: isoDate.optional(),
zustand: ZustandEnum.optional(),
notizen: z.string().max(2000).optional(),
eigenschaften: z.array(EigenschaftInput).optional(),
});
const UpdateSchema = z.object({
bezeichnung: z.string().min(1).max(200).optional(),
kategorie: z.string().max(100).nullable().optional(),
artikel_id: z.number().int().positive().nullable().optional(),
user_id: uuidString.nullable().optional(),
benutzer_name: z.string().max(200).nullable().optional(),
groesse: z.string().max(50).nullable().optional(),
seriennummer: z.string().max(100).nullable().optional(),
inventarnummer: z.string().max(50).nullable().optional(),
anschaffung_datum: isoDate.nullable().optional(),
zustand: ZustandEnum.optional(),
notizen: z.string().max(2000).nullable().optional(),
eigenschaften: z.array(EigenschaftInput).nullable().optional(),
});
function isValidUUID(s: string): boolean {
return /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(s);
}
class PersonalEquipmentController {
async list(req: Request, res: Response): Promise<void> {
try {
const filters: Record<string, string> = {};
if (req.query.user_id) filters.userId = String(req.query.user_id);
if (req.query.kategorie) filters.kategorie = String(req.query.kategorie);
if (req.query.zustand) filters.zustand = String(req.query.zustand);
const items = await personalEquipmentService.getAll(filters);
res.status(200).json({ success: true, data: items });
} catch (error) {
logger.error('personalEquipment.list error', { error });
res.status(500).json({ success: false, message: 'Persönliche Ausrüstung konnte nicht geladen werden' });
}
}
async getMy(req: Request, res: Response): Promise<void> {
try {
const items = await personalEquipmentService.getByUserId(req.user!.id);
res.status(200).json({ success: true, data: items });
} catch (error) {
logger.error('personalEquipment.getMy error', { error });
res.status(500).json({ success: false, message: 'Persönliche Ausrüstung konnte nicht geladen werden' });
}
}
async getByUser(req: Request, res: Response): Promise<void> {
try {
const { userId } = req.params as Record<string, string>;
if (!isValidUUID(userId)) {
res.status(400).json({ success: false, message: 'Ungültige User-ID' });
return;
}
const items = await personalEquipmentService.getByUserId(userId);
res.status(200).json({ success: true, data: items });
} catch (error) {
logger.error('personalEquipment.getByUser error', { error });
res.status(500).json({ success: false, message: 'Persönliche Ausrüstung konnte nicht geladen werden' });
}
}
async getById(req: Request, res: Response): Promise<void> {
try {
const { id } = req.params as Record<string, string>;
if (!isValidUUID(id)) {
res.status(400).json({ success: false, message: 'Ungültige ID' });
return;
}
const item = await personalEquipmentService.getById(id);
if (!item) {
res.status(404).json({ success: false, message: 'Nicht gefunden' });
return;
}
res.status(200).json({ success: true, data: item });
} catch (error) {
logger.error('personalEquipment.getById error', { error });
res.status(500).json({ success: false, message: 'Persönliche Ausrüstung konnte nicht geladen werden' });
}
}
async create(req: Request, res: Response): Promise<void> {
try {
const parsed = CreateSchema.safeParse(req.body);
if (!parsed.success) {
res.status(400).json({ success: false, message: 'Validierungsfehler', errors: parsed.error.flatten().fieldErrors });
return;
}
const item = await personalEquipmentService.create(parsed.data, req.user!.id);
res.status(201).json({ success: true, data: item });
} catch (error) {
logger.error('personalEquipment.create error', { error });
res.status(500).json({ success: false, message: 'Persönliche Ausrüstung konnte nicht erstellt werden' });
}
}
async update(req: Request, res: Response): Promise<void> {
try {
const { id } = req.params as Record<string, string>;
if (!isValidUUID(id)) {
res.status(400).json({ success: false, message: 'Ungültige ID' });
return;
}
const parsed = UpdateSchema.safeParse(req.body);
if (!parsed.success) {
res.status(400).json({ success: false, message: 'Validierungsfehler', errors: parsed.error.flatten().fieldErrors });
return;
}
if (Object.keys(parsed.data).length === 0) {
res.status(400).json({ success: false, message: 'Kein Feld zum Aktualisieren angegeben' });
return;
}
const item = await personalEquipmentService.update(id, parsed.data as any);
if (!item) {
res.status(404).json({ success: false, message: 'Nicht gefunden' });
return;
}
res.status(200).json({ success: true, data: item });
} catch (error: any) {
if (error?.message === 'No fields to update') {
res.status(400).json({ success: false, message: 'Kein Feld zum Aktualisieren angegeben' });
return;
}
logger.error('personalEquipment.update error', { error, id: req.params.id });
res.status(500).json({ success: false, message: 'Persönliche Ausrüstung konnte nicht aktualisiert werden' });
}
}
async delete(req: Request, res: Response): Promise<void> {
try {
const { id } = req.params as Record<string, string>;
if (!isValidUUID(id)) {
res.status(400).json({ success: false, message: 'Ungültige ID' });
return;
}
const deleted = await personalEquipmentService.delete(id);
if (!deleted) {
res.status(404).json({ success: false, message: 'Nicht gefunden' });
return;
}
res.status(200).json({ success: true, message: 'Persönliche Ausrüstung gelöscht' });
} catch (error) {
logger.error('personalEquipment.delete error', { error, id: req.params.id });
res.status(500).json({ success: false, message: 'Persönliche Ausrüstung konnte nicht gelöscht werden' });
}
}
}
export default new PersonalEquipmentController();