add features

This commit is contained in:
Matthias Hochmeister
2026-02-27 19:50:14 +01:00
parent c5e8337a69
commit 620bacc6b5
46 changed files with 14095 additions and 1 deletions

View File

@@ -0,0 +1,269 @@
// =============================================================================
// Vehicle Fleet Management — Domain Model
// =============================================================================
// ── Enums ─────────────────────────────────────────────────────────────────────
/**
* Operational status of a vehicle.
* These values are the CHECK constraint values in the database.
*/
export enum FahrzeugStatus {
Einsatzbereit = 'einsatzbereit',
AusserDienstWartung = 'ausser_dienst_wartung',
AusserDienstSchaden = 'ausser_dienst_schaden',
InLehrgang = 'in_lehrgang',
}
/** Human-readable German labels for each status value */
export const FahrzeugStatusLabel: Record<FahrzeugStatus, string> = {
[FahrzeugStatus.Einsatzbereit]: 'Einsatzbereit',
[FahrzeugStatus.AusserDienstWartung]: 'Außer Dienst (Wartung)',
[FahrzeugStatus.AusserDienstSchaden]: 'Außer Dienst (Schaden)',
[FahrzeugStatus.InLehrgang]: 'In Lehrgang',
};
/**
* Types of vehicle inspections (Prüfungsarten).
* These values are the CHECK constraint values in the database.
*/
export enum PruefungArt {
HU = 'HU', // Hauptuntersuchung (TÜV) — 24-month interval
AU = 'AU', // Abgasuntersuchung — 12-month interval
UVV = 'UVV', // Unfallverhütungsvorschrift BGV D29 — 12-month
Leiter = 'Leiter', // Leiternprüfung (DLK only) — 12-month
Kran = 'Kran', // Kranprüfung — 12-month
Seilwinde = 'Seilwinde', // Seilwindenprüfung — 12-month
Sonstiges = 'Sonstiges',
}
/** Human-readable German labels for each PruefungArt */
export const PruefungArtLabel: Record<PruefungArt, string> = {
[PruefungArt.HU]: 'Hauptuntersuchung (TÜV)',
[PruefungArt.AU]: 'Abgasuntersuchung',
[PruefungArt.UVV]: 'UVV-Prüfung (BGV D29)',
[PruefungArt.Leiter]: 'Leiternprüfung (DLK)',
[PruefungArt.Kran]: 'Kranprüfung',
[PruefungArt.Seilwinde]: 'Seilwindenprüfung',
[PruefungArt.Sonstiges]: 'Sonstige Prüfung',
};
/**
* Standard inspection intervals in months, keyed by PruefungArt.
* Used by vehicle.service.ts to auto-calculate naechste_faelligkeit.
*/
export const PruefungIntervalMonths: Partial<Record<PruefungArt, number>> = {
[PruefungArt.HU]: 24,
[PruefungArt.AU]: 12,
[PruefungArt.UVV]: 12,
[PruefungArt.Leiter]: 12,
[PruefungArt.Kran]: 12,
[PruefungArt.Seilwinde]: 12,
// Sonstiges: no standard interval — must be set manually
};
/** Inspection result values */
export type PruefungErgebnis =
| 'bestanden'
| 'bestanden_mit_maengeln'
| 'nicht_bestanden'
| 'ausstehend';
/** Maintenance log entry types */
export type WartungslogArt =
| 'Inspektion'
| 'Reparatur'
| 'Kraftstoff'
| 'Reifenwechsel'
| 'Hauptuntersuchung'
| 'Reinigung'
| 'Sonstiges';
// ── Core Entities ─────────────────────────────────────────────────────────────
/** Raw database row from the `fahrzeuge` table */
export interface Fahrzeug {
id: string; // UUID
bezeichnung: string; // e.g. "LF 20/16"
kurzname: string | null;
amtliches_kennzeichen: string | null;
fahrgestellnummer: string | null;
baujahr: number | null;
hersteller: string | null;
typ_schluessel: string | null;
besatzung_soll: string | null; // e.g. "1/8"
status: FahrzeugStatus;
status_bemerkung: string | null;
standort: string;
bild_url: string | null;
created_at: Date;
updated_at: Date;
}
/** Raw database row from `fahrzeug_pruefungen` */
export interface FahrzeugPruefung {
id: string; // UUID
fahrzeug_id: string; // UUID FK
pruefung_art: PruefungArt;
faellig_am: Date; // The hard legal deadline
durchgefuehrt_am: Date | null;
ergebnis: PruefungErgebnis | null;
naechste_faelligkeit: Date | null;
pruefende_stelle: string | null;
kosten: number | null;
dokument_url: string | null;
bemerkung: string | null;
erfasst_von: string | null; // UUID FK users
created_at: Date;
}
/** Raw database row from `fahrzeug_wartungslog` */
export interface FahrzeugWartungslog {
id: string; // UUID
fahrzeug_id: string; // UUID FK
datum: Date;
art: WartungslogArt | null;
beschreibung: string;
km_stand: number | null;
kraftstoff_liter: number | null;
kosten: number | null;
externe_werkstatt: string | null;
erfasst_von: string | null; // UUID FK users
created_at: Date;
}
// ── Inspection Status per Type ────────────────────────────────────────────────
/** Status of a single inspection type for a vehicle */
export interface PruefungStatus {
pruefung_id: string | null;
faellig_am: Date | null;
tage_bis_faelligkeit: number | null; // negative = overdue
ergebnis: PruefungErgebnis | null;
}
/**
* Vehicle with its per-type inspection status.
* Comes from the `fahrzeuge_mit_pruefstatus` view.
*/
export interface FahrzeugWithPruefstatus extends Fahrzeug {
pruefstatus: {
hu: PruefungStatus;
au: PruefungStatus;
uvv: PruefungStatus;
leiter: PruefungStatus;
};
/** Minimum tage_bis_faelligkeit across all inspections (negative = any overdue) */
naechste_pruefung_tage: number | null;
/** Full inspection history, ordered by faellig_am DESC */
pruefungen: FahrzeugPruefung[];
/** Maintenance log entries, ordered by datum DESC */
wartungslog: FahrzeugWartungslog[];
}
// ── List Item (Grid / Card view) ──────────────────────────────────────────────
/**
* Lightweight type used in the vehicle fleet overview grid.
* Includes only the fields needed to render a card plus inspection badges.
*/
export interface FahrzeugListItem {
id: string;
bezeichnung: string;
kurzname: string | null;
amtliches_kennzeichen: string | null;
baujahr: number | null;
hersteller: string | null;
besatzung_soll: string | null;
status: FahrzeugStatus;
status_bemerkung: string | null;
bild_url: string | null;
hu_faellig_am: Date | null;
hu_tage_bis_faelligkeit: number | null;
au_faellig_am: Date | null;
au_tage_bis_faelligkeit: number | null;
uvv_faellig_am: Date | null;
uvv_tage_bis_faelligkeit: number | null;
leiter_faellig_am: Date | null;
leiter_tage_bis_faelligkeit: number | null;
naechste_pruefung_tage: number | null;
}
// ── Dashboard KPI ─────────────────────────────────────────────────────────────
/** Aggregated vehicle stats for the dashboard KPI strip */
export interface VehicleStats {
total: number;
einsatzbereit: number;
ausserDienst: number; // wartung + schaden combined
inLehrgang: number;
inspectionsDue: number; // vehicles with any inspection due within 30 days
inspectionsOverdue: number; // vehicles with any inspection already overdue
}
// ── Inspection Alert ──────────────────────────────────────────────────────────
/** Single alert item for the dashboard InspectionAlerts component */
export interface InspectionAlert {
fahrzeugId: string;
bezeichnung: string;
kurzname: string | null;
pruefungId: string;
pruefungArt: PruefungArt;
faelligAm: Date;
tage: number; // negative = already overdue
}
// ── Create / Update DTOs ──────────────────────────────────────────────────────
export interface CreateFahrzeugData {
bezeichnung: string;
kurzname?: string;
amtliches_kennzeichen?: string;
fahrgestellnummer?: string;
baujahr?: number;
hersteller?: string;
typ_schluessel?: string;
besatzung_soll?: string;
status?: FahrzeugStatus;
status_bemerkung?: string;
standort?: string;
bild_url?: string;
}
export interface UpdateFahrzeugData {
bezeichnung?: string;
kurzname?: string | null;
amtliches_kennzeichen?: string | null;
fahrgestellnummer?: string | null;
baujahr?: number | null;
hersteller?: string | null;
typ_schluessel?: string | null;
besatzung_soll?: string | null;
status?: FahrzeugStatus;
status_bemerkung?: string | null;
standort?: string;
bild_url?: string | null;
}
export interface CreatePruefungData {
pruefung_art: PruefungArt;
faellig_am: string; // ISO date string 'YYYY-MM-DD'
durchgefuehrt_am?: string; // ISO date string, optional
ergebnis?: PruefungErgebnis;
pruefende_stelle?: string;
kosten?: number;
dokument_url?: string;
bemerkung?: string;
// naechste_faelligkeit is auto-calculated by the service — not accepted from client
}
export interface CreateWartungslogData {
datum: string; // ISO date string 'YYYY-MM-DD'
art?: WartungslogArt;
beschreibung: string;
km_stand?: number;
kraftstoff_liter?: number;
kosten?: number;
externe_werkstatt?: string;
}