add features
This commit is contained in:
@@ -74,7 +74,7 @@ class IncidentController {
|
||||
// -------------------------------------------------------------------------
|
||||
async getIncident(req: AuthenticatedRequest, res: Response): Promise<void> {
|
||||
try {
|
||||
const { id } = req.params;
|
||||
const { id } = req.params as Record<string, string>;
|
||||
const incident = await incidentService.getIncidentById(id);
|
||||
|
||||
if (!incident) {
|
||||
@@ -147,7 +147,7 @@ class IncidentController {
|
||||
return;
|
||||
}
|
||||
|
||||
const { id } = req.params;
|
||||
const { id } = req.params as Record<string, string>;
|
||||
const parseResult = UpdateEinsatzSchema.safeParse(req.body);
|
||||
if (!parseResult.success) {
|
||||
res.status(400).json({
|
||||
@@ -181,7 +181,7 @@ class IncidentController {
|
||||
return;
|
||||
}
|
||||
|
||||
const { id } = req.params;
|
||||
const { id } = req.params as Record<string, string>;
|
||||
await incidentService.deleteIncident(id, req.user.id);
|
||||
|
||||
res.status(200).json({ success: true, message: 'Einsatz archiviert' });
|
||||
@@ -200,7 +200,7 @@ class IncidentController {
|
||||
// -------------------------------------------------------------------------
|
||||
async assignPersonnel(req: AuthenticatedRequest, res: Response): Promise<void> {
|
||||
try {
|
||||
const { id } = req.params;
|
||||
const { id } = req.params as Record<string, string>;
|
||||
|
||||
const parseResult = AssignPersonnelSchema.safeParse(req.body);
|
||||
if (!parseResult.success) {
|
||||
@@ -226,7 +226,7 @@ class IncidentController {
|
||||
// -------------------------------------------------------------------------
|
||||
async removePersonnel(req: AuthenticatedRequest, res: Response): Promise<void> {
|
||||
try {
|
||||
const { id, userId } = req.params;
|
||||
const { id, userId } = req.params as Record<string, string>;
|
||||
await incidentService.removePersonnel(id, userId);
|
||||
|
||||
res.status(200).json({ success: true, message: 'Person entfernt' });
|
||||
@@ -245,7 +245,7 @@ class IncidentController {
|
||||
// -------------------------------------------------------------------------
|
||||
async assignVehicle(req: AuthenticatedRequest, res: Response): Promise<void> {
|
||||
try {
|
||||
const { id } = req.params;
|
||||
const { id } = req.params as Record<string, string>;
|
||||
|
||||
const parseResult = AssignVehicleSchema.safeParse(req.body);
|
||||
if (!parseResult.success) {
|
||||
@@ -271,7 +271,7 @@ class IncidentController {
|
||||
// -------------------------------------------------------------------------
|
||||
async removeVehicle(req: AuthenticatedRequest, res: Response): Promise<void> {
|
||||
try {
|
||||
const { id, fahrzeugId } = req.params;
|
||||
const { id, fahrzeugId } = req.params as Record<string, string>;
|
||||
await incidentService.removeVehicle(id, fahrzeugId);
|
||||
|
||||
res.status(200).json({ success: true, message: 'Fahrzeug entfernt' });
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import { Request, Response } from 'express';
|
||||
import memberService from '../services/member.service';
|
||||
import logger from '../utils/logger';
|
||||
import { AppError } from '../middleware/error.middleware';
|
||||
import {
|
||||
CreateMemberProfileSchema,
|
||||
UpdateMemberProfileSchema,
|
||||
@@ -79,7 +78,7 @@ class MemberController {
|
||||
* Returns aggregate member counts for each status.
|
||||
* Must be registered BEFORE /:userId to avoid route collision.
|
||||
*/
|
||||
async getMemberStats(req: Request, res: Response): Promise<void> {
|
||||
async getMemberStats(_req: Request, res: Response): Promise<void> {
|
||||
try {
|
||||
const stats = await memberService.getMemberStats();
|
||||
res.status(200).json({ success: true, data: stats });
|
||||
@@ -100,9 +99,7 @@ class MemberController {
|
||||
*/
|
||||
async getMemberById(req: Request, res: Response): Promise<void> {
|
||||
try {
|
||||
const { userId } = req.params;
|
||||
const requestorId = req.user!.id;
|
||||
const requestorRole = getRole(req);
|
||||
const { userId } = req.params as Record<string, string>;
|
||||
const ownProfile = isOwnProfile(req, userId);
|
||||
|
||||
const member = await memberService.getMemberById(userId);
|
||||
@@ -151,7 +148,7 @@ class MemberController {
|
||||
*/
|
||||
async createMemberProfile(req: Request, res: Response): Promise<void> {
|
||||
try {
|
||||
const { userId } = req.params;
|
||||
const { userId } = req.params as Record<string, string>;
|
||||
|
||||
const parseResult = CreateMemberProfileSchema.safeParse(req.body);
|
||||
if (!parseResult.success) {
|
||||
@@ -187,7 +184,7 @@ class MemberController {
|
||||
*/
|
||||
async updateMember(req: Request, res: Response): Promise<void> {
|
||||
try {
|
||||
const { userId } = req.params;
|
||||
const { userId } = req.params as Record<string, string>;
|
||||
const updaterId = req.user!.id;
|
||||
const ownProfile = isOwnProfile(req, userId);
|
||||
|
||||
|
||||
@@ -176,7 +176,7 @@ class TrainingController {
|
||||
// -------------------------------------------------------------------------
|
||||
getById = async (req: Request, res: Response): Promise<void> => {
|
||||
try {
|
||||
const { id } = req.params;
|
||||
const { id } = req.params as Record<string, string>;
|
||||
const userId = req.user?.id;
|
||||
|
||||
// Determine if the requester may see the full attendee list
|
||||
@@ -229,7 +229,7 @@ class TrainingController {
|
||||
// -------------------------------------------------------------------------
|
||||
updateEvent = async (req: Request, res: Response): Promise<void> => {
|
||||
try {
|
||||
const { id } = req.params;
|
||||
const { id } = req.params as Record<string, string>;
|
||||
const parsed = UpdateUebungSchema.safeParse(req.body);
|
||||
|
||||
if (!parsed.success) {
|
||||
@@ -258,7 +258,7 @@ class TrainingController {
|
||||
// -------------------------------------------------------------------------
|
||||
cancelEvent = async (req: Request, res: Response): Promise<void> => {
|
||||
try {
|
||||
const { id } = req.params;
|
||||
const { id } = req.params as Record<string, string>;
|
||||
const parsed = CancelEventSchema.safeParse(req.body);
|
||||
|
||||
if (!parsed.success) {
|
||||
@@ -287,7 +287,7 @@ class TrainingController {
|
||||
// -------------------------------------------------------------------------
|
||||
updateRsvp = async (req: Request, res: Response): Promise<void> => {
|
||||
try {
|
||||
const { id: uebungId } = req.params;
|
||||
const { id: uebungId } = req.params as Record<string, string>;
|
||||
const userId = req.user!.id;
|
||||
const parsed = UpdateRsvpSchema.safeParse(req.body);
|
||||
|
||||
@@ -319,7 +319,7 @@ class TrainingController {
|
||||
// -------------------------------------------------------------------------
|
||||
markAttendance = async (req: Request, res: Response): Promise<void> => {
|
||||
try {
|
||||
const { id: uebungId } = req.params;
|
||||
const { id: uebungId } = req.params as Record<string, string>;
|
||||
const parsed = MarkAttendanceSchema.safeParse(req.body);
|
||||
|
||||
if (!parsed.success) {
|
||||
|
||||
@@ -85,7 +85,7 @@ class VehicleController {
|
||||
* GET /api/vehicles
|
||||
* Fleet overview list with per-vehicle inspection badge data.
|
||||
*/
|
||||
async listVehicles(req: Request, res: Response): Promise<void> {
|
||||
async listVehicles(_req: Request, res: Response): Promise<void> {
|
||||
try {
|
||||
const vehicles = await vehicleService.getAllVehicles();
|
||||
res.status(200).json({ success: true, data: vehicles });
|
||||
@@ -99,7 +99,7 @@ class VehicleController {
|
||||
* GET /api/vehicles/stats
|
||||
* Aggregated KPI counts for the dashboard strip.
|
||||
*/
|
||||
async getStats(req: Request, res: Response): Promise<void> {
|
||||
async getStats(_req: Request, res: Response): Promise<void> {
|
||||
try {
|
||||
const stats = await vehicleService.getVehicleStats();
|
||||
res.status(200).json({ success: true, data: stats });
|
||||
@@ -140,7 +140,7 @@ class VehicleController {
|
||||
*/
|
||||
async getVehicle(req: Request, res: Response): Promise<void> {
|
||||
try {
|
||||
const { id } = req.params;
|
||||
const { id } = req.params as Record<string, string>;
|
||||
const vehicle = await vehicleService.getVehicleById(id);
|
||||
|
||||
if (!vehicle) {
|
||||
@@ -185,7 +185,7 @@ class VehicleController {
|
||||
*/
|
||||
async updateVehicle(req: Request, res: Response): Promise<void> {
|
||||
try {
|
||||
const { id } = req.params;
|
||||
const { id } = req.params as Record<string, string>;
|
||||
const parsed = UpdateFahrzeugSchema.safeParse(req.body);
|
||||
if (!parsed.success) {
|
||||
res.status(400).json({
|
||||
@@ -219,7 +219,7 @@ class VehicleController {
|
||||
*/
|
||||
async updateVehicleStatus(req: Request, res: Response): Promise<void> {
|
||||
try {
|
||||
const { id } = req.params;
|
||||
const { id } = req.params as Record<string, string>;
|
||||
const parsed = UpdateStatusSchema.safeParse(req.body);
|
||||
|
||||
if (!parsed.success) {
|
||||
@@ -262,7 +262,7 @@ class VehicleController {
|
||||
*/
|
||||
async addPruefung(req: Request, res: Response): Promise<void> {
|
||||
try {
|
||||
const { id } = req.params;
|
||||
const { id } = req.params as Record<string, string>;
|
||||
const parsed = CreatePruefungSchema.safeParse(req.body);
|
||||
|
||||
if (!parsed.success) {
|
||||
@@ -288,7 +288,7 @@ class VehicleController {
|
||||
*/
|
||||
async getPruefungen(req: Request, res: Response): Promise<void> {
|
||||
try {
|
||||
const { id } = req.params;
|
||||
const { id } = req.params as Record<string, string>;
|
||||
const pruefungen = await vehicleService.getPruefungenForVehicle(id);
|
||||
res.status(200).json({ success: true, data: pruefungen });
|
||||
} catch (error) {
|
||||
@@ -305,7 +305,7 @@ class VehicleController {
|
||||
*/
|
||||
async addWartung(req: Request, res: Response): Promise<void> {
|
||||
try {
|
||||
const { id } = req.params;
|
||||
const { id } = req.params as Record<string, string>;
|
||||
const parsed = CreateWartungslogSchema.safeParse(req.body);
|
||||
|
||||
if (!parsed.success) {
|
||||
@@ -331,7 +331,7 @@ class VehicleController {
|
||||
*/
|
||||
async getWartung(req: Request, res: Response): Promise<void> {
|
||||
try {
|
||||
const { id } = req.params;
|
||||
const { id } = req.params as Record<string, string>;
|
||||
const entries = await vehicleService.getWartungslogForVehicle(id);
|
||||
res.status(200).json({ success: true, data: entries });
|
||||
} catch (error) {
|
||||
|
||||
@@ -132,9 +132,9 @@ export function auditMiddleware(
|
||||
// Resource ID: prefer controller override, then route param, then body id.
|
||||
const resourceId =
|
||||
res.locals.auditResourceId ??
|
||||
req.params.id ??
|
||||
(req.params as Record<string, string>).id ??
|
||||
(body !== null && typeof body === 'object'
|
||||
? (body as Record<string, unknown>)?.data?.id as string | undefined
|
||||
? ((body as Record<string, unknown>)?.data as Record<string, unknown>)?.id as string | undefined
|
||||
: undefined) ??
|
||||
null;
|
||||
|
||||
|
||||
@@ -100,7 +100,7 @@ router.get(
|
||||
res.status(400).json({
|
||||
success: false,
|
||||
message: 'Invalid query parameters',
|
||||
errors: error.errors,
|
||||
errors: error.issues,
|
||||
});
|
||||
return;
|
||||
}
|
||||
@@ -152,7 +152,7 @@ router.get(
|
||||
res.status(400).json({
|
||||
success: false,
|
||||
message: 'Invalid query parameters',
|
||||
errors: error.errors,
|
||||
errors: error.issues,
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -28,21 +28,6 @@ const router = Router();
|
||||
|
||||
type AppRole = 'admin' | 'kommandant' | 'mitglied';
|
||||
|
||||
// Extend the Express Request type to include role
|
||||
declare global {
|
||||
namespace Express {
|
||||
interface Request {
|
||||
user?: {
|
||||
id: string;
|
||||
email: string;
|
||||
authentikSub: string;
|
||||
role?: AppRole;
|
||||
groups?: string[];
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolves the AppRole from Authentik groups attached to the JWT.
|
||||
* Mutates req.user.role so downstream controllers can read it directly.
|
||||
@@ -53,9 +38,9 @@ const resolveRole = (req: Request, _res: Response, next: NextFunction): void =>
|
||||
if (groups.includes('feuerwehr-admin')) {
|
||||
req.user.role = 'admin';
|
||||
} else if (groups.includes('feuerwehr-kommandant')) {
|
||||
req.user.role = 'kommandant';
|
||||
req.user.role = 'kommandant' as any;
|
||||
} else {
|
||||
req.user.role = 'mitglied';
|
||||
req.user.role = 'mitglied' as any;
|
||||
}
|
||||
logger.debug('resolveRole', { userId: req.user.id, role: req.user.role });
|
||||
}
|
||||
|
||||
@@ -375,7 +375,7 @@ class MemberService {
|
||||
await this.updateDienstgrad(userId, dienstgrad, updatedBy, dienstgrad_seit, client);
|
||||
} else if (dienstgrad_seit !== undefined) {
|
||||
// dienstgrad_seit can be updated independently
|
||||
rest.dienstgrad_seit = dienstgrad_seit;
|
||||
(rest as any).dienstgrad_seit = dienstgrad_seit;
|
||||
}
|
||||
|
||||
// Build dynamic SET clause for remaining fields
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import { Server as SocketIOServer } from 'socket.io';
|
||||
import pool from '../config/database';
|
||||
import logger from '../utils/logger';
|
||||
import {
|
||||
@@ -282,7 +281,7 @@ class VehicleService {
|
||||
status: FahrzeugStatus,
|
||||
bemerkung: string,
|
||||
updatedBy: string,
|
||||
io?: SocketIOServer
|
||||
io?: any
|
||||
): Promise<void> {
|
||||
try {
|
||||
// Fetch old status for Socket.IO payload and logging
|
||||
|
||||
Reference in New Issue
Block a user