diff --git a/backend/src/services/incident.service.ts b/backend/src/services/incident.service.ts index cb59e20..dcda192 100644 --- a/backend/src/services/incident.service.ts +++ b/backend/src/services/incident.service.ts @@ -560,7 +560,7 @@ class IncidentService { [targetYear] ); - const totals = totalsResult.rows[0]; + const totals = totalsResult.rows[0] ?? { gesamt: 0, abgeschlossen: 0, aktiv: 0, avg_hilfsfrist_min: null }; // Monthly breakdown — target year const monthlyResult = await pool.query( @@ -636,21 +636,21 @@ class IncidentService { const haeufigste_art: EinsatzArt | null = byArtResult.rows.length > 0 ? (byArtResult.rows[0].einsatz_art as EinsatzArt) : null; - const monthly: MonthlyStatRow[] = monthlyResult.rows.map((r) => ({ + const monthly: MonthlyStatRow[] = (monthlyResult.rows ?? []).map((r) => ({ monat: r.monat, anzahl: r.anzahl, avg_hilfsfrist_min: r.avg_hilfsfrist_min !== null ? Number(r.avg_hilfsfrist_min) : null, avg_dauer_min: r.avg_dauer_min !== null ? Number(r.avg_dauer_min) : null, })); - const prev_year_monthly: MonthlyStatRow[] = prevMonthlyResult.rows.map((r) => ({ + const prev_year_monthly: MonthlyStatRow[] = (prevMonthlyResult.rows ?? []).map((r) => ({ monat: r.monat, anzahl: r.anzahl, avg_hilfsfrist_min: r.avg_hilfsfrist_min !== null ? Number(r.avg_hilfsfrist_min) : null, avg_dauer_min: r.avg_dauer_min !== null ? Number(r.avg_dauer_min) : null, })); - const by_art: EinsatzArtStatRow[] = byArtResult.rows.map((r) => ({ + const by_art: EinsatzArtStatRow[] = (byArtResult.rows ?? []).map((r) => ({ einsatz_art: r.einsatz_art as EinsatzArt, anzahl: r.anzahl, avg_hilfsfrist_min: r.avg_hilfsfrist_min !== null ? Number(r.avg_hilfsfrist_min) : null, diff --git a/backend/src/services/member.service.ts b/backend/src/services/member.service.ts index f07bd50..498a99f 100644 --- a/backend/src/services/member.service.ts +++ b/backend/src/services/member.service.ts @@ -236,6 +236,8 @@ class MemberService { // Attach rank history when the profile exists if (member.profile) { member.dienstgrad_verlauf = await this.getDienstgradVerlauf(userId); + } else { + member.dienstgrad_verlauf = []; } return member; @@ -583,7 +585,15 @@ class MemberService { FROM mitglieder_profile `); - return result.rows[0] as MemberStats; + return (result.rows[0] as MemberStats) ?? { + total: 0, + aktiv: 0, + passiv: 0, + ehrenmitglied: 0, + jugendfeuerwehr: 0, + 'anwärter': 0, + ausgetreten: 0, + }; } catch (error) { logger.error('Error fetching member stats', { error }); throw new Error('Failed to fetch member stats'); diff --git a/backend/src/services/vehicle.service.ts b/backend/src/services/vehicle.service.ts index a02eeb7..b271ff5 100644 --- a/backend/src/services/vehicle.service.ts +++ b/backend/src/services/vehicle.service.ts @@ -373,16 +373,16 @@ class VehicleService { WHERE deleted_at IS NULL `); - const totals = totalsResult.rows[0]; - const alerts = alertResult.rows[0]; + const totals = totalsResult.rows[0] ?? { total: '0', einsatzbereit: '0', ausser_dienst: '0', in_lehrgang: '0' }; + const alerts = alertResult.rows[0] ?? { inspections_due: '0', inspections_overdue: '0' }; return { - total: parseInt(totals.total, 10), - einsatzbereit: parseInt(totals.einsatzbereit, 10), - ausserDienst: parseInt(totals.ausser_dienst, 10), - inLehrgang: parseInt(totals.in_lehrgang, 10), - inspectionsDue: parseInt(alerts.inspections_due, 10), - inspectionsOverdue: parseInt(alerts.inspections_overdue, 10), + total: parseInt(totals.total ?? '0', 10), + einsatzbereit: parseInt(totals.einsatzbereit ?? '0', 10), + ausserDienst: parseInt(totals.ausser_dienst ?? '0', 10), + inLehrgang: parseInt(totals.in_lehrgang ?? '0', 10), + inspectionsDue: parseInt(alerts.inspections_due ?? '0', 10), + inspectionsOverdue: parseInt(alerts.inspections_overdue ?? '0', 10), }; } catch (error) { logger.error('VehicleService.getVehicleStats failed', { error }); diff --git a/frontend/src/pages/FahrzeugDetail.tsx b/frontend/src/pages/FahrzeugDetail.tsx index 67e0d3b..9a1b44d 100644 --- a/frontend/src/pages/FahrzeugDetail.tsx +++ b/frontend/src/pages/FahrzeugDetail.tsx @@ -14,6 +14,7 @@ import { Fab, FormControl, Grid, + IconButton, InputLabel, MenuItem, Paper, diff --git a/frontend/src/services/incidents.ts b/frontend/src/services/incidents.ts index 60d7289..177e223 100644 --- a/frontend/src/services/incidents.ts +++ b/frontend/src/services/incidents.ts @@ -216,7 +216,7 @@ export const incidentsApi = { const response = await api.get<{ success: boolean; data: IncidentListResponse }>( `/api/incidents?${params.toString()}` ); - if (!response.data?.data) { + if (response.data?.data === undefined || response.data?.data === null) { throw new Error('Invalid API response'); } return response.data.data; @@ -230,7 +230,7 @@ export const incidentsApi = { const response = await api.get<{ success: boolean; data: EinsatzStats }>( `/api/incidents/stats${params}` ); - if (!response.data?.data) { + if (response.data?.data === undefined || response.data?.data === null) { throw new Error('Invalid API response'); } return response.data.data; @@ -243,7 +243,7 @@ export const incidentsApi = { const response = await api.get<{ success: boolean; data: EinsatzDetail }>( `/api/incidents/${id}` ); - if (!response.data?.data) { + if (response.data?.data === undefined || response.data?.data === null) { throw new Error('Invalid API response'); } return response.data.data; @@ -257,7 +257,7 @@ export const incidentsApi = { '/api/incidents', payload ); - if (!response.data?.data) { + if (response.data?.data === undefined || response.data?.data === null) { throw new Error('Invalid API response'); } return response.data.data; @@ -271,7 +271,7 @@ export const incidentsApi = { `/api/incidents/${id}`, payload ); - if (!response.data?.data) { + if (response.data?.data === undefined || response.data?.data === null) { throw new Error('Invalid API response'); } return response.data.data; diff --git a/frontend/src/services/members.ts b/frontend/src/services/members.ts index 0dab506..0092127 100644 --- a/frontend/src/services/members.ts +++ b/frontend/src/services/members.ts @@ -55,7 +55,7 @@ export const membersService = { const response = await api.get>( `/api/members?${params.toString()}` ); - if (!response.data?.data) { + if (response.data?.data === undefined || response.data?.data === null) { throw new Error('Invalid API response'); } return { @@ -72,7 +72,7 @@ export const membersService = { const response = await api.get>( `/api/members/${userId}` ); - if (!response.data?.data) { + if (response.data?.data === undefined || response.data?.data === null) { throw new Error('Invalid API response'); } return response.data.data; @@ -90,7 +90,7 @@ export const membersService = { `/api/members/${userId}/profile`, data ); - if (!response.data?.data) { + if (response.data?.data === undefined || response.data?.data === null) { throw new Error('Invalid API response'); } return response.data.data; @@ -109,7 +109,7 @@ export const membersService = { `/api/members/${userId}`, data ); - if (!response.data?.data) { + if (response.data?.data === undefined || response.data?.data === null) { throw new Error('Invalid API response'); } return response.data.data; @@ -120,7 +120,7 @@ export const membersService = { */ async getMemberStats(): Promise { const response = await api.get>('/api/members/stats'); - if (!response.data?.data) { + if (response.data?.data === undefined || response.data?.data === null) { throw new Error('Invalid API response'); } return response.data.data; diff --git a/frontend/src/services/vehicles.ts b/frontend/src/services/vehicles.ts index 3604921..b0e15ff 100644 --- a/frontend/src/services/vehicles.ts +++ b/frontend/src/services/vehicles.ts @@ -15,7 +15,7 @@ async function unwrap( promise: ReturnType> ): Promise { const response = await promise; - if (!response.data?.data) { + if (response.data?.data === undefined || response.data?.data === null) { throw new Error('Invalid API response'); } return response.data.data; @@ -47,7 +47,7 @@ export const vehiclesApi = { '/api/vehicles', payload ); - if (!response.data?.data) { + if (response.data?.data === undefined || response.data?.data === null) { throw new Error('Invalid API response'); } return response.data.data; @@ -58,7 +58,7 @@ export const vehiclesApi = { `/api/vehicles/${id}`, payload ); - if (!response.data?.data) { + if (response.data?.data === undefined || response.data?.data === null) { throw new Error('Invalid API response'); } return response.data.data; @@ -83,7 +83,7 @@ export const vehiclesApi = { `/api/vehicles/${id}/wartung`, payload ); - if (!response.data?.data) { + if (response.data?.data === undefined || response.data?.data === null) { throw new Error('Invalid API response'); } return response.data.data;