feat: add issue kanban/attachments/deadlines, dashboard widget DnD, and checklisten system
This commit is contained in:
383
backend/src/controllers/checklist.controller.ts
Normal file
383
backend/src/controllers/checklist.controller.ts
Normal file
@@ -0,0 +1,383 @@
|
||||
import { Request, Response } from 'express';
|
||||
import checklistService from '../services/checklist.service';
|
||||
import logger from '../utils/logger';
|
||||
|
||||
const param = (req: Request, key: string): string => req.params[key] as string;
|
||||
|
||||
class ChecklistController {
|
||||
// --- Vorlagen (Templates) ---
|
||||
|
||||
async getVorlagen(req: Request, res: Response): Promise<void> {
|
||||
try {
|
||||
const filter: { fahrzeug_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.aktiv !== undefined) {
|
||||
filter.aktiv = req.query.aktiv === 'true';
|
||||
}
|
||||
const vorlagen = await checklistService.getVorlagen(filter);
|
||||
res.status(200).json({ success: true, data: vorlagen });
|
||||
} catch (error) {
|
||||
logger.error('ChecklistController.getVorlagen error', { error });
|
||||
res.status(500).json({ success: false, message: 'Vorlagen konnten nicht geladen werden' });
|
||||
}
|
||||
}
|
||||
|
||||
async getVorlageById(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 vorlage = await checklistService.getVorlageById(id);
|
||||
if (!vorlage) {
|
||||
res.status(404).json({ success: false, message: 'Vorlage nicht gefunden' });
|
||||
return;
|
||||
}
|
||||
res.status(200).json({ success: true, data: vorlage });
|
||||
} catch (error) {
|
||||
logger.error('ChecklistController.getVorlageById error', { error });
|
||||
res.status(500).json({ success: false, message: 'Vorlage konnte nicht geladen werden' });
|
||||
}
|
||||
}
|
||||
|
||||
async createVorlage(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 vorlage = await checklistService.createVorlage(req.body);
|
||||
res.status(201).json({ success: true, data: vorlage });
|
||||
} catch (error) {
|
||||
logger.error('ChecklistController.createVorlage error', { error });
|
||||
res.status(500).json({ success: false, message: 'Vorlage konnte nicht erstellt werden' });
|
||||
}
|
||||
}
|
||||
|
||||
async updateVorlage(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 vorlage = await checklistService.updateVorlage(id, req.body);
|
||||
if (!vorlage) {
|
||||
res.status(404).json({ success: false, message: 'Vorlage nicht gefunden' });
|
||||
return;
|
||||
}
|
||||
res.status(200).json({ success: true, data: vorlage });
|
||||
} catch (error) {
|
||||
logger.error('ChecklistController.updateVorlage error', { error });
|
||||
res.status(500).json({ success: false, message: 'Vorlage konnte nicht aktualisiert werden' });
|
||||
}
|
||||
}
|
||||
|
||||
async deleteVorlage(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 vorlage = await checklistService.deleteVorlage(id);
|
||||
if (!vorlage) {
|
||||
res.status(404).json({ success: false, message: 'Vorlage nicht gefunden' });
|
||||
return;
|
||||
}
|
||||
res.status(200).json({ success: true, message: 'Vorlage gelöscht' });
|
||||
} catch (error) {
|
||||
logger.error('ChecklistController.deleteVorlage error', { error });
|
||||
res.status(500).json({ success: false, message: 'Vorlage konnte nicht gelöscht werden' });
|
||||
}
|
||||
}
|
||||
|
||||
// --- Vorlage Items ---
|
||||
|
||||
async getVorlageItems(req: Request, res: Response): Promise<void> {
|
||||
const vorlageId = parseInt(param(req, 'id'), 10);
|
||||
if (isNaN(vorlageId)) {
|
||||
res.status(400).json({ success: false, message: 'Ungültige ID' });
|
||||
return;
|
||||
}
|
||||
try {
|
||||
const items = await checklistService.getVorlageItems(vorlageId);
|
||||
res.status(200).json({ success: true, data: items });
|
||||
} catch (error) {
|
||||
logger.error('ChecklistController.getVorlageItems error', { error });
|
||||
res.status(500).json({ success: false, message: 'Items konnten nicht geladen werden' });
|
||||
}
|
||||
}
|
||||
|
||||
async addVorlageItem(req: Request, res: Response): Promise<void> {
|
||||
const vorlageId = parseInt(param(req, 'id'), 10);
|
||||
if (isNaN(vorlageId)) {
|
||||
res.status(400).json({ success: false, message: 'Ungültige ID' });
|
||||
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.addVorlageItem(vorlageId, req.body);
|
||||
res.status(201).json({ success: true, data: item });
|
||||
} catch (error) {
|
||||
logger.error('ChecklistController.addVorlageItem error', { error });
|
||||
res.status(500).json({ success: false, message: 'Item konnte nicht erstellt werden' });
|
||||
}
|
||||
}
|
||||
|
||||
async updateVorlageItem(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 item = await checklistService.updateVorlageItem(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.updateVorlageItem error', { error });
|
||||
res.status(500).json({ success: false, message: 'Item konnte nicht aktualisiert werden' });
|
||||
}
|
||||
}
|
||||
|
||||
async deleteVorlageItem(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 item = await checklistService.deleteVorlageItem(id);
|
||||
if (!item) {
|
||||
res.status(404).json({ success: false, message: 'Item nicht gefunden' });
|
||||
return;
|
||||
}
|
||||
res.status(200).json({ success: true, message: 'Item gelöscht' });
|
||||
} catch (error) {
|
||||
logger.error('ChecklistController.deleteVorlageItem error', { error });
|
||||
res.status(500).json({ success: false, message: 'Item konnte nicht gelöscht werden' });
|
||||
}
|
||||
}
|
||||
|
||||
// --- Vehicle-specific items ---
|
||||
|
||||
async getVehicleItems(req: Request, res: Response): Promise<void> {
|
||||
const fahrzeugId = param(req, 'fahrzeugId');
|
||||
if (!fahrzeugId) {
|
||||
res.status(400).json({ success: false, message: 'Fahrzeug-ID erforderlich' });
|
||||
return;
|
||||
}
|
||||
try {
|
||||
const items = await checklistService.getVehicleItems(fahrzeugId);
|
||||
res.status(200).json({ success: true, data: items });
|
||||
} catch (error) {
|
||||
logger.error('ChecklistController.getVehicleItems error', { error });
|
||||
res.status(500).json({ success: false, message: 'Items konnten nicht geladen werden' });
|
||||
}
|
||||
}
|
||||
|
||||
async addVehicleItem(req: Request, res: Response): Promise<void> {
|
||||
const fahrzeugId = param(req, 'fahrzeugId');
|
||||
if (!fahrzeugId) {
|
||||
res.status(400).json({ success: false, message: 'Fahrzeug-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.addVehicleItem(fahrzeugId, req.body);
|
||||
res.status(201).json({ success: true, data: item });
|
||||
} catch (error) {
|
||||
logger.error('ChecklistController.addVehicleItem error', { error });
|
||||
res.status(500).json({ success: false, message: 'Item konnte nicht erstellt werden' });
|
||||
}
|
||||
}
|
||||
|
||||
async updateVehicleItem(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 item = await checklistService.updateVehicleItem(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.updateVehicleItem error', { error });
|
||||
res.status(500).json({ success: false, message: 'Item konnte nicht aktualisiert werden' });
|
||||
}
|
||||
}
|
||||
|
||||
async deleteVehicleItem(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 item = await checklistService.deleteVehicleItem(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.deleteVehicleItem error', { error });
|
||||
res.status(500).json({ success: false, message: 'Item konnte nicht deaktiviert werden' });
|
||||
}
|
||||
}
|
||||
|
||||
// --- Templates for vehicle ---
|
||||
|
||||
async getTemplatesForVehicle(req: Request, res: Response): Promise<void> {
|
||||
const fahrzeugId = param(req, 'fahrzeugId');
|
||||
if (!fahrzeugId) {
|
||||
res.status(400).json({ success: false, message: 'Fahrzeug-ID erforderlich' });
|
||||
return;
|
||||
}
|
||||
try {
|
||||
const templates = await checklistService.getTemplatesForVehicle(fahrzeugId);
|
||||
res.status(200).json({ success: true, data: templates });
|
||||
} catch (error) {
|
||||
logger.error('ChecklistController.getTemplatesForVehicle error', { error });
|
||||
res.status(500).json({ success: false, message: 'Checklisten konnten nicht geladen werden' });
|
||||
}
|
||||
}
|
||||
|
||||
// --- Ausführungen (Executions) ---
|
||||
|
||||
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' });
|
||||
return;
|
||||
}
|
||||
try {
|
||||
const execution = await checklistService.startExecution(fahrzeugId, vorlageId, req.user!.id);
|
||||
res.status(201).json({ success: true, data: execution });
|
||||
} catch (error) {
|
||||
logger.error('ChecklistController.startExecution error', { error });
|
||||
res.status(500).json({ success: false, message: 'Ausführung konnte nicht gestartet werden' });
|
||||
}
|
||||
}
|
||||
|
||||
async submitExecution(req: Request, res: Response): Promise<void> {
|
||||
const id = param(req, 'id');
|
||||
if (!id) {
|
||||
res.status(400).json({ success: false, message: 'Ungültige ID' });
|
||||
return;
|
||||
}
|
||||
const { items, notizen } = req.body;
|
||||
if (!Array.isArray(items)) {
|
||||
res.status(400).json({ success: false, message: 'items muss ein Array sein' });
|
||||
return;
|
||||
}
|
||||
try {
|
||||
const execution = await checklistService.submitExecution(id, items, notizen ?? null, req.user!.id);
|
||||
res.status(200).json({ success: true, data: execution });
|
||||
} catch (error) {
|
||||
logger.error('ChecklistController.submitExecution error', { error });
|
||||
res.status(500).json({ success: false, message: 'Ausführung konnte nicht abgeschlossen werden' });
|
||||
}
|
||||
}
|
||||
|
||||
async approveExecution(req: Request, res: Response): Promise<void> {
|
||||
const id = param(req, 'id');
|
||||
if (!id) {
|
||||
res.status(400).json({ success: false, message: 'Ungültige ID' });
|
||||
return;
|
||||
}
|
||||
try {
|
||||
const execution = await checklistService.approveExecution(id, req.user!.id);
|
||||
if (!execution) {
|
||||
res.status(404).json({ success: false, message: 'Ausführung nicht gefunden oder Status ungültig' });
|
||||
return;
|
||||
}
|
||||
res.status(200).json({ success: true, data: execution });
|
||||
} catch (error) {
|
||||
logger.error('ChecklistController.approveExecution error', { error });
|
||||
res.status(500).json({ success: false, message: 'Freigabe konnte nicht erteilt werden' });
|
||||
}
|
||||
}
|
||||
|
||||
async getExecutions(req: Request, res: Response): Promise<void> {
|
||||
try {
|
||||
const filter: { fahrzeugId?: string; vorlageId?: number; status?: string } = {};
|
||||
if (req.query.fahrzeugId) filter.fahrzeugId = req.query.fahrzeugId 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);
|
||||
res.status(200).json({ success: true, data: executions });
|
||||
} catch (error) {
|
||||
logger.error('ChecklistController.getExecutions error', { error });
|
||||
res.status(500).json({ success: false, message: 'Ausführungen konnten nicht geladen werden' });
|
||||
}
|
||||
}
|
||||
|
||||
async getExecutionById(req: Request, res: Response): Promise<void> {
|
||||
const id = param(req, 'id');
|
||||
if (!id) {
|
||||
res.status(400).json({ success: false, message: 'Ungültige ID' });
|
||||
return;
|
||||
}
|
||||
try {
|
||||
const execution = await checklistService.getExecutionById(id);
|
||||
if (!execution) {
|
||||
res.status(404).json({ success: false, message: 'Ausführung nicht gefunden' });
|
||||
return;
|
||||
}
|
||||
res.status(200).json({ success: true, data: execution });
|
||||
} catch (error) {
|
||||
logger.error('ChecklistController.getExecutionById error', { error });
|
||||
res.status(500).json({ success: false, message: 'Ausführung konnte nicht geladen werden' });
|
||||
}
|
||||
}
|
||||
|
||||
// --- Fälligkeiten ---
|
||||
|
||||
async getOverdueChecklists(_req: Request, res: Response): Promise<void> {
|
||||
try {
|
||||
const overdue = await checklistService.getOverdueChecklists();
|
||||
res.status(200).json({ success: true, data: overdue });
|
||||
} catch (error) {
|
||||
logger.error('ChecklistController.getOverdueChecklists error', { error });
|
||||
res.status(500).json({ success: false, message: 'Überfällige Checklisten konnten nicht geladen werden' });
|
||||
}
|
||||
}
|
||||
|
||||
async getDueChecklists(req: Request, res: Response): Promise<void> {
|
||||
const fahrzeugId = param(req, 'fahrzeugId');
|
||||
if (!fahrzeugId) {
|
||||
res.status(400).json({ success: false, message: 'Fahrzeug-ID erforderlich' });
|
||||
return;
|
||||
}
|
||||
try {
|
||||
const due = await checklistService.getDueChecklists(fahrzeugId);
|
||||
res.status(200).json({ success: true, data: due });
|
||||
} catch (error) {
|
||||
logger.error('ChecklistController.getDueChecklists error', { error });
|
||||
res.status(500).json({ success: false, message: 'Fälligkeiten konnten nicht geladen werden' });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default new ChecklistController();
|
||||
126
backend/src/controllers/fahrzeugTyp.controller.ts
Normal file
126
backend/src/controllers/fahrzeugTyp.controller.ts
Normal file
@@ -0,0 +1,126 @@
|
||||
import { Request, Response } from 'express';
|
||||
import fahrzeugTypService from '../services/fahrzeugTyp.service';
|
||||
import logger from '../utils/logger';
|
||||
|
||||
const param = (req: Request, key: string): string => req.params[key] as string;
|
||||
|
||||
class FahrzeugTypController {
|
||||
async getAll(_req: Request, res: Response): Promise<void> {
|
||||
try {
|
||||
const types = await fahrzeugTypService.getAll();
|
||||
res.status(200).json({ success: true, data: types });
|
||||
} catch (error) {
|
||||
logger.error('FahrzeugTypController.getAll error', { error });
|
||||
res.status(500).json({ success: false, message: 'Fahrzeug-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 fahrzeugTypService.getById(id);
|
||||
if (!type) {
|
||||
res.status(404).json({ success: false, message: 'Fahrzeug-Typ nicht gefunden' });
|
||||
return;
|
||||
}
|
||||
res.status(200).json({ success: true, data: type });
|
||||
} catch (error) {
|
||||
logger.error('FahrzeugTypController.getById error', { error });
|
||||
res.status(500).json({ success: false, message: 'Fahrzeug-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 fahrzeugTypService.create(req.body);
|
||||
res.status(201).json({ success: true, data: type });
|
||||
} catch (error) {
|
||||
logger.error('FahrzeugTypController.create error', { error });
|
||||
res.status(500).json({ success: false, message: 'Fahrzeug-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 fahrzeugTypService.update(id, req.body);
|
||||
if (!type) {
|
||||
res.status(404).json({ success: false, message: 'Fahrzeug-Typ nicht gefunden' });
|
||||
return;
|
||||
}
|
||||
res.status(200).json({ success: true, data: type });
|
||||
} catch (error) {
|
||||
logger.error('FahrzeugTypController.update error', { error });
|
||||
res.status(500).json({ success: false, message: 'Fahrzeug-Typ konnte nicht aktualisiert werden' });
|
||||
}
|
||||
}
|
||||
|
||||
async delete(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 fahrzeugTypService.delete(id);
|
||||
if (!type) {
|
||||
res.status(404).json({ success: false, message: 'Fahrzeug-Typ nicht gefunden' });
|
||||
return;
|
||||
}
|
||||
res.status(200).json({ success: true, message: 'Fahrzeug-Typ gelöscht' });
|
||||
} catch (error) {
|
||||
logger.error('FahrzeugTypController.delete error', { error });
|
||||
res.status(500).json({ success: false, message: 'Fahrzeug-Typ konnte nicht gelöscht werden' });
|
||||
}
|
||||
}
|
||||
|
||||
async getTypesForVehicle(req: Request, res: Response): Promise<void> {
|
||||
const fahrzeugId = param(req, 'fahrzeugId');
|
||||
if (!fahrzeugId) {
|
||||
res.status(400).json({ success: false, message: 'Fahrzeug-ID erforderlich' });
|
||||
return;
|
||||
}
|
||||
try {
|
||||
const types = await fahrzeugTypService.getTypesForVehicle(fahrzeugId);
|
||||
res.status(200).json({ success: true, data: types });
|
||||
} catch (error) {
|
||||
logger.error('FahrzeugTypController.getTypesForVehicle error', { error });
|
||||
res.status(500).json({ success: false, message: 'Fahrzeug-Typen konnten nicht geladen werden' });
|
||||
}
|
||||
}
|
||||
|
||||
async setTypesForVehicle(req: Request, res: Response): Promise<void> {
|
||||
const fahrzeugId = param(req, 'fahrzeugId');
|
||||
if (!fahrzeugId) {
|
||||
res.status(400).json({ success: false, message: 'Fahrzeug-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 fahrzeugTypService.setTypesForVehicle(fahrzeugId, typIds);
|
||||
res.status(200).json({ success: true, data: types });
|
||||
} catch (error) {
|
||||
logger.error('FahrzeugTypController.setTypesForVehicle error', { error });
|
||||
res.status(500).json({ success: false, message: 'Fahrzeug-Typen konnten nicht gesetzt werden' });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default new FahrzeugTypController();
|
||||
@@ -175,6 +175,7 @@ class IssueController {
|
||||
titel: 'Titel geändert',
|
||||
beschreibung: 'Beschreibung geändert',
|
||||
typ_id: 'Typ geändert',
|
||||
faellig_am: 'Fälligkeitsdatum geändert',
|
||||
};
|
||||
for (const [field, label] of Object.entries(fieldLabels)) {
|
||||
if (field in updateData && updateData[field] !== existing[field]) {
|
||||
@@ -503,6 +504,67 @@ class IssueController {
|
||||
res.status(500).json({ success: false, message: 'Priorität konnte nicht deaktiviert werden' });
|
||||
}
|
||||
}
|
||||
|
||||
// --- File management ---
|
||||
|
||||
async uploadFile(req: Request, res: Response): Promise<void> {
|
||||
const issueId = parseInt(param(req, 'id'), 10);
|
||||
if (isNaN(issueId)) {
|
||||
res.status(400).json({ success: false, message: 'Ungültige Issue-ID' });
|
||||
return;
|
||||
}
|
||||
const file = req.file as Express.Multer.File | undefined;
|
||||
if (!file) {
|
||||
res.status(400).json({ success: false, message: 'Keine Datei hochgeladen' });
|
||||
return;
|
||||
}
|
||||
try {
|
||||
const fileRecord = await issueService.addFile(issueId, {
|
||||
dateiname: file.originalname,
|
||||
dateipfad: file.path,
|
||||
dateityp: file.mimetype,
|
||||
dateigroesse: file.size,
|
||||
}, req.user!.id);
|
||||
res.status(201).json({ success: true, data: fileRecord });
|
||||
} catch (error) {
|
||||
logger.error('IssueController.uploadFile error', { error });
|
||||
res.status(500).json({ success: false, message: 'Datei konnte nicht hochgeladen werden' });
|
||||
}
|
||||
}
|
||||
|
||||
async getFiles(req: Request, res: Response): Promise<void> {
|
||||
const issueId = parseInt(param(req, 'id'), 10);
|
||||
if (isNaN(issueId)) {
|
||||
res.status(400).json({ success: false, message: 'Ungültige ID' });
|
||||
return;
|
||||
}
|
||||
try {
|
||||
const files = await issueService.getFiles(issueId);
|
||||
res.status(200).json({ success: true, data: files });
|
||||
} catch (error) {
|
||||
logger.error('IssueController.getFiles error', { error });
|
||||
res.status(500).json({ success: false, message: 'Dateien konnten nicht geladen werden' });
|
||||
}
|
||||
}
|
||||
|
||||
async deleteFile(req: Request, res: Response): Promise<void> {
|
||||
const fileId = param(req, 'fileId');
|
||||
if (!fileId) {
|
||||
res.status(400).json({ success: false, message: 'Ungültige Datei-ID' });
|
||||
return;
|
||||
}
|
||||
try {
|
||||
const result = await issueService.deleteFile(fileId, req.user!.id);
|
||||
if (!result) {
|
||||
res.status(404).json({ success: false, message: 'Datei nicht gefunden' });
|
||||
return;
|
||||
}
|
||||
res.status(200).json({ success: true, message: 'Datei gelöscht' });
|
||||
} catch (error) {
|
||||
logger.error('IssueController.deleteFile error', { error });
|
||||
res.status(500).json({ success: false, message: 'Datei konnte nicht gelöscht werden' });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default new IssueController();
|
||||
|
||||
Reference in New Issue
Block a user