featur add fahrmeister

This commit is contained in:
Matthias Hochmeister
2026-02-27 21:46:50 +01:00
parent da4a56ba6b
commit dbe4f52871
17 changed files with 426 additions and 152 deletions

View File

@@ -35,6 +35,7 @@ class AuthController {
// Step 2: Get user info from Authentik
const userInfo = await authentikService.getUserInfo(tokens.access_token);
const groups = userInfo.groups ?? [];
// Step 3: Verify ID token if present
if (tokens.id_token) {
@@ -65,6 +66,8 @@ class AuthController {
profile_picture_url: userInfo.picture,
});
await userService.updateGroups(user.id, groups);
// Audit: first-ever login (user record creation)
auditService.logAudit({
user_id: user.id,
@@ -86,6 +89,7 @@ class AuthController {
});
await userService.updateLastLogin(user.id);
await userService.updateGroups(user.id, groups);
// Audit: returning user login
auditService.logAudit({
@@ -132,6 +136,7 @@ class AuthController {
userId: user.id,
email: user.email,
authentikSub: user.authentik_sub,
groups,
});
// Generate refresh token
@@ -161,6 +166,7 @@ class AuthController {
familyName: user.family_name,
profilePictureUrl: user.profile_picture_url,
isActive: user.is_active,
groups,
},
},
});

View File

@@ -29,18 +29,20 @@ const isoDate = z.string().regex(
);
const CreateFahrzeugSchema = z.object({
bezeichnung: z.string().min(1).max(100),
kurzname: z.string().max(20).optional(),
amtliches_kennzeichen: z.string().max(20).optional(),
fahrgestellnummer: z.string().max(50).optional(),
baujahr: z.number().int().min(1950).max(2100).optional(),
hersteller: z.string().max(100).optional(),
typ_schluessel: z.string().max(30).optional(),
besatzung_soll: z.string().max(10).optional(),
status: FahrzeugStatusEnum.optional(),
status_bemerkung: z.string().max(500).optional(),
standort: z.string().max(100).optional(),
bild_url: z.string().url().max(500).optional(),
bezeichnung: z.string().min(1).max(100),
kurzname: z.string().max(20).optional(),
amtliches_kennzeichen: z.string().max(20).optional(),
fahrgestellnummer: z.string().max(50).optional(),
baujahr: z.number().int().min(1950).max(2100).optional(),
hersteller: z.string().max(100).optional(),
typ_schluessel: z.string().max(30).optional(),
besatzung_soll: z.string().max(10).optional(),
status: FahrzeugStatusEnum.optional(),
status_bemerkung: z.string().max(500).optional(),
standort: z.string().max(100).optional(),
bild_url: z.string().url().max(500).optional(),
paragraph57a_faellig_am: isoDate.optional(),
naechste_wartung_am: isoDate.optional(),
});
const UpdateFahrzeugSchema = CreateFahrzeugSchema.partial();
@@ -325,6 +327,25 @@ class VehicleController {
}
}
/**
* DELETE /api/vehicles/:id
* Delete a vehicle. Requires dashboard_admin group.
*/
async deleteVehicle(req: Request, res: Response): Promise<void> {
try {
const { id } = req.params as Record<string, string>;
await vehicleService.deleteVehicle(id, getUserId(req));
res.status(200).json({ success: true, message: 'Fahrzeug gelöscht' });
} catch (error: any) {
if (error?.message === 'Vehicle not found') {
res.status(404).json({ success: false, message: 'Fahrzeug nicht gefunden' });
return;
}
logger.error('deleteVehicle error', { error, id: req.params.id });
res.status(500).json({ success: false, message: 'Fahrzeug konnte nicht gelöscht werden' });
}
}
/**
* GET /api/vehicles/:id/wartung
* Maintenance log for a vehicle.