feat: vehicle/equipment type system, equipment checklist support, and checklist overview redesign
This commit is contained in:
130
backend/src/controllers/ausruestungTyp.controller.ts
Normal file
130
backend/src/controllers/ausruestungTyp.controller.ts
Normal file
@@ -0,0 +1,130 @@
|
||||
import { Request, Response } from 'express';
|
||||
import ausruestungTypService from '../services/ausruestungTyp.service';
|
||||
import logger from '../utils/logger';
|
||||
|
||||
const param = (req: Request, key: string): string => req.params[key] as string;
|
||||
|
||||
class AusruestungTypController {
|
||||
async getAll(_req: Request, res: Response): Promise<void> {
|
||||
try {
|
||||
const types = await ausruestungTypService.getAll();
|
||||
res.status(200).json({ success: true, data: types });
|
||||
} catch (error) {
|
||||
logger.error('AusruestungTypController.getAll error', { error });
|
||||
res.status(500).json({ success: false, message: 'Ausrüstungs-Typen konnten nicht geladen werden' });
|
||||
}
|
||||
}
|
||||
|
||||
async getById(req: Request, res: Response): Promise<void> {
|
||||
const id = parseInt(param(req, 'id'), 10);
|
||||
if (isNaN(id)) {
|
||||
res.status(400).json({ success: false, message: 'Ungültige ID' });
|
||||
return;
|
||||
}
|
||||
try {
|
||||
const type = await ausruestungTypService.getById(id);
|
||||
if (!type) {
|
||||
res.status(404).json({ success: false, message: 'Ausrüstungs-Typ nicht gefunden' });
|
||||
return;
|
||||
}
|
||||
res.status(200).json({ success: true, data: type });
|
||||
} catch (error) {
|
||||
logger.error('AusruestungTypController.getById error', { error });
|
||||
res.status(500).json({ success: false, message: 'Ausrüstungs-Typ konnte nicht geladen werden' });
|
||||
}
|
||||
}
|
||||
|
||||
async create(req: Request, res: Response): Promise<void> {
|
||||
const { name } = req.body;
|
||||
if (!name || typeof name !== 'string' || name.trim().length === 0) {
|
||||
res.status(400).json({ success: false, message: 'Name ist erforderlich' });
|
||||
return;
|
||||
}
|
||||
try {
|
||||
const type = await ausruestungTypService.create(req.body);
|
||||
res.status(201).json({ success: true, data: type });
|
||||
} catch (error) {
|
||||
logger.error('AusruestungTypController.create error', { error });
|
||||
res.status(500).json({ success: false, message: 'Ausrüstungs-Typ konnte nicht erstellt werden' });
|
||||
}
|
||||
}
|
||||
|
||||
async update(req: Request, res: Response): Promise<void> {
|
||||
const id = parseInt(param(req, 'id'), 10);
|
||||
if (isNaN(id)) {
|
||||
res.status(400).json({ success: false, message: 'Ungültige ID' });
|
||||
return;
|
||||
}
|
||||
try {
|
||||
const type = await ausruestungTypService.update(id, req.body);
|
||||
if (!type) {
|
||||
res.status(404).json({ success: false, message: 'Ausrüstungs-Typ nicht gefunden' });
|
||||
return;
|
||||
}
|
||||
res.status(200).json({ success: true, data: type });
|
||||
} catch (error) {
|
||||
logger.error('AusruestungTypController.update error', { error });
|
||||
res.status(500).json({ success: false, message: 'Ausrüstungs-Typ konnte nicht aktualisiert werden' });
|
||||
}
|
||||
}
|
||||
|
||||
async deleteTyp(req: Request, res: Response): Promise<void> {
|
||||
const id = parseInt(param(req, 'id'), 10);
|
||||
if (isNaN(id)) {
|
||||
res.status(400).json({ success: false, message: 'Ungültige ID' });
|
||||
return;
|
||||
}
|
||||
try {
|
||||
const type = await ausruestungTypService.delete(id);
|
||||
if (!type) {
|
||||
res.status(404).json({ success: false, message: 'Ausrüstungs-Typ nicht gefunden' });
|
||||
return;
|
||||
}
|
||||
res.status(200).json({ success: true, message: 'Ausrüstungs-Typ gelöscht' });
|
||||
} catch (error: any) {
|
||||
if (error.message === 'Typ wird noch von Ausrüstung verwendet') {
|
||||
res.status(409).json({ success: false, message: error.message });
|
||||
return;
|
||||
}
|
||||
logger.error('AusruestungTypController.deleteTyp error', { error });
|
||||
res.status(500).json({ success: false, message: 'Ausrüstungs-Typ konnte nicht gelöscht werden' });
|
||||
}
|
||||
}
|
||||
|
||||
async getTypesForEquipment(req: Request, res: Response): Promise<void> {
|
||||
const ausruestungId = param(req, 'ausruestungId');
|
||||
if (!ausruestungId) {
|
||||
res.status(400).json({ success: false, message: 'Ausrüstungs-ID erforderlich' });
|
||||
return;
|
||||
}
|
||||
try {
|
||||
const types = await ausruestungTypService.getTypesForEquipment(ausruestungId);
|
||||
res.status(200).json({ success: true, data: types });
|
||||
} catch (error) {
|
||||
logger.error('AusruestungTypController.getTypesForEquipment error', { error });
|
||||
res.status(500).json({ success: false, message: 'Ausrüstungs-Typen konnten nicht geladen werden' });
|
||||
}
|
||||
}
|
||||
|
||||
async setTypesForEquipment(req: Request, res: Response): Promise<void> {
|
||||
const ausruestungId = param(req, 'ausruestungId');
|
||||
if (!ausruestungId) {
|
||||
res.status(400).json({ success: false, message: 'Ausrüstungs-ID erforderlich' });
|
||||
return;
|
||||
}
|
||||
const { typIds } = req.body;
|
||||
if (!Array.isArray(typIds)) {
|
||||
res.status(400).json({ success: false, message: 'typIds muss ein Array sein' });
|
||||
return;
|
||||
}
|
||||
try {
|
||||
const types = await ausruestungTypService.setTypesForEquipment(ausruestungId, typIds);
|
||||
res.status(200).json({ success: true, data: types });
|
||||
} catch (error) {
|
||||
logger.error('AusruestungTypController.setTypesForEquipment error', { error });
|
||||
res.status(500).json({ success: false, message: 'Ausrüstungs-Typen konnten nicht gesetzt werden' });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default new AusruestungTypController();
|
||||
@@ -5,14 +5,29 @@ import logger from '../utils/logger';
|
||||
const param = (req: Request, key: string): string => req.params[key] as string;
|
||||
|
||||
class ChecklistController {
|
||||
// --- Overview ---
|
||||
|
||||
async getOverviewItems(_req: Request, res: Response): Promise<void> {
|
||||
try {
|
||||
const data = await checklistService.getOverviewItems();
|
||||
res.status(200).json({ success: true, data });
|
||||
} catch (error) {
|
||||
logger.error('ChecklistController.getOverviewItems error', { error });
|
||||
res.status(500).json({ success: false, message: 'Übersichtsdaten konnten nicht geladen werden' });
|
||||
}
|
||||
}
|
||||
|
||||
// --- Vorlagen (Templates) ---
|
||||
|
||||
async getVorlagen(req: Request, res: Response): Promise<void> {
|
||||
try {
|
||||
const filter: { fahrzeug_typ_id?: number; aktiv?: boolean } = {};
|
||||
const filter: { fahrzeug_typ_id?: number; ausruestung_typ_id?: number; aktiv?: boolean } = {};
|
||||
if (req.query.fahrzeug_typ_id) {
|
||||
filter.fahrzeug_typ_id = parseInt(req.query.fahrzeug_typ_id as string, 10);
|
||||
}
|
||||
if (req.query.ausruestung_typ_id) {
|
||||
filter.ausruestung_typ_id = parseInt(req.query.ausruestung_typ_id as string, 10);
|
||||
}
|
||||
if (req.query.aktiv !== undefined) {
|
||||
filter.aktiv = req.query.aktiv === 'true';
|
||||
}
|
||||
@@ -263,16 +278,108 @@ class ChecklistController {
|
||||
}
|
||||
}
|
||||
|
||||
// --- Ausführungen (Executions) ---
|
||||
// --- Templates for equipment ---
|
||||
|
||||
async startExecution(req: Request, res: Response): Promise<void> {
|
||||
const { fahrzeugId, vorlageId } = req.body;
|
||||
if (!fahrzeugId || !vorlageId) {
|
||||
res.status(400).json({ success: false, message: 'fahrzeugId und vorlageId sind erforderlich' });
|
||||
async getTemplatesForEquipment(req: Request, res: Response): Promise<void> {
|
||||
const ausruestungId = param(req, 'ausruestungId');
|
||||
if (!ausruestungId) {
|
||||
res.status(400).json({ success: false, message: 'Ausrüstungs-ID erforderlich' });
|
||||
return;
|
||||
}
|
||||
try {
|
||||
const execution = await checklistService.startExecution(fahrzeugId, vorlageId, req.user!.id);
|
||||
const templates = await checklistService.getTemplatesForEquipment(ausruestungId);
|
||||
res.status(200).json({ success: true, data: templates });
|
||||
} catch (error) {
|
||||
logger.error('ChecklistController.getTemplatesForEquipment error', { error });
|
||||
res.status(500).json({ success: false, message: 'Checklisten konnten nicht geladen werden' });
|
||||
}
|
||||
}
|
||||
|
||||
// --- Equipment-specific items ---
|
||||
|
||||
async getEquipmentItems(req: Request, res: Response): Promise<void> {
|
||||
const ausruestungId = param(req, 'ausruestungId');
|
||||
if (!ausruestungId) {
|
||||
res.status(400).json({ success: false, message: 'Ausrüstungs-ID erforderlich' });
|
||||
return;
|
||||
}
|
||||
try {
|
||||
const items = await checklistService.getEquipmentItems(ausruestungId);
|
||||
res.status(200).json({ success: true, data: items });
|
||||
} catch (error) {
|
||||
logger.error('ChecklistController.getEquipmentItems error', { error });
|
||||
res.status(500).json({ success: false, message: 'Items konnten nicht geladen werden' });
|
||||
}
|
||||
}
|
||||
|
||||
async addEquipmentItem(req: Request, res: Response): Promise<void> {
|
||||
const ausruestungId = param(req, 'ausruestungId');
|
||||
if (!ausruestungId) {
|
||||
res.status(400).json({ success: false, message: 'Ausrüstungs-ID erforderlich' });
|
||||
return;
|
||||
}
|
||||
const { bezeichnung } = req.body;
|
||||
if (!bezeichnung || typeof bezeichnung !== 'string' || bezeichnung.trim().length === 0) {
|
||||
res.status(400).json({ success: false, message: 'Bezeichnung ist erforderlich' });
|
||||
return;
|
||||
}
|
||||
try {
|
||||
const item = await checklistService.addEquipmentItem(ausruestungId, req.body);
|
||||
res.status(201).json({ success: true, data: item });
|
||||
} catch (error) {
|
||||
logger.error('ChecklistController.addEquipmentItem error', { error });
|
||||
res.status(500).json({ success: false, message: 'Item konnte nicht erstellt werden' });
|
||||
}
|
||||
}
|
||||
|
||||
async updateEquipmentItem(req: Request, res: Response): Promise<void> {
|
||||
const id = parseInt(param(req, 'itemId'), 10);
|
||||
if (isNaN(id)) {
|
||||
res.status(400).json({ success: false, message: 'Ungültige ID' });
|
||||
return;
|
||||
}
|
||||
try {
|
||||
const item = await checklistService.updateEquipmentItem(id, req.body);
|
||||
if (!item) {
|
||||
res.status(404).json({ success: false, message: 'Item nicht gefunden' });
|
||||
return;
|
||||
}
|
||||
res.status(200).json({ success: true, data: item });
|
||||
} catch (error) {
|
||||
logger.error('ChecklistController.updateEquipmentItem error', { error });
|
||||
res.status(500).json({ success: false, message: 'Item konnte nicht aktualisiert werden' });
|
||||
}
|
||||
}
|
||||
|
||||
async deleteEquipmentItem(req: Request, res: Response): Promise<void> {
|
||||
const id = parseInt(param(req, 'itemId'), 10);
|
||||
if (isNaN(id)) {
|
||||
res.status(400).json({ success: false, message: 'Ungültige ID' });
|
||||
return;
|
||||
}
|
||||
try {
|
||||
const item = await checklistService.deleteEquipmentItem(id);
|
||||
if (!item) {
|
||||
res.status(404).json({ success: false, message: 'Item nicht gefunden' });
|
||||
return;
|
||||
}
|
||||
res.status(200).json({ success: true, message: 'Item deaktiviert' });
|
||||
} catch (error) {
|
||||
logger.error('ChecklistController.deleteEquipmentItem error', { error });
|
||||
res.status(500).json({ success: false, message: 'Item konnte nicht deaktiviert werden' });
|
||||
}
|
||||
}
|
||||
|
||||
// --- Ausführungen (Executions) ---
|
||||
|
||||
async startExecution(req: Request, res: Response): Promise<void> {
|
||||
const { fahrzeugId, ausruestungId, vorlageId } = req.body;
|
||||
if (!vorlageId || (!fahrzeugId && !ausruestungId)) {
|
||||
res.status(400).json({ success: false, message: 'vorlageId und entweder fahrzeugId oder ausruestungId sind erforderlich' });
|
||||
return;
|
||||
}
|
||||
try {
|
||||
const execution = await checklistService.startExecution(fahrzeugId || null, vorlageId, req.user!.id, ausruestungId || null);
|
||||
res.status(201).json({ success: true, data: execution });
|
||||
} catch (error) {
|
||||
logger.error('ChecklistController.startExecution error', { error });
|
||||
@@ -321,8 +428,9 @@ class ChecklistController {
|
||||
|
||||
async getExecutions(req: Request, res: Response): Promise<void> {
|
||||
try {
|
||||
const filter: { fahrzeugId?: string; vorlageId?: number; status?: string } = {};
|
||||
const filter: { fahrzeugId?: string; ausruestungId?: string; vorlageId?: number; status?: string } = {};
|
||||
if (req.query.fahrzeugId) filter.fahrzeugId = req.query.fahrzeugId as string;
|
||||
if (req.query.ausruestungId) filter.ausruestungId = req.query.ausruestungId as string;
|
||||
if (req.query.vorlageId) filter.vorlageId = parseInt(req.query.vorlageId as string, 10);
|
||||
if (req.query.status) filter.status = req.query.status as string;
|
||||
const executions = await checklistService.getExecutions(filter);
|
||||
|
||||
Reference in New Issue
Block a user