add now features
This commit is contained in:
99
backend/src/models/atemschutz.model.ts
Normal file
99
backend/src/models/atemschutz.model.ts
Normal file
@@ -0,0 +1,99 @@
|
||||
// =============================================================================
|
||||
// Atemschutz (Breathing Apparatus) — Domain Model
|
||||
// =============================================================================
|
||||
|
||||
import { z } from 'zod';
|
||||
|
||||
// ── Enums ───────────────────────────────────────────────────────────────────
|
||||
|
||||
export const UNTERSUCHUNG_ERGEBNIS_VALUES = ['tauglich', 'bedingt_tauglich', 'nicht_tauglich'] as const;
|
||||
export type UntersuchungErgebnis = typeof UNTERSUCHUNG_ERGEBNIS_VALUES[number];
|
||||
|
||||
// ── Core DB Row ─────────────────────────────────────────────────────────────
|
||||
|
||||
export interface AtemschutzTraeger {
|
||||
id: string;
|
||||
user_id: string;
|
||||
atemschutz_lehrgang: boolean;
|
||||
lehrgang_datum: Date | null;
|
||||
untersuchung_datum: Date | null;
|
||||
untersuchung_gueltig_bis: Date | null;
|
||||
untersuchung_ergebnis: UntersuchungErgebnis | null;
|
||||
leistungstest_datum: Date | null;
|
||||
leistungstest_gueltig_bis: Date | null;
|
||||
leistungstest_bestanden: boolean | null;
|
||||
bemerkung: string | null;
|
||||
created_at: Date;
|
||||
updated_at: Date;
|
||||
}
|
||||
|
||||
// ── View Row (extended with user info + computed fields) ────────────────────
|
||||
|
||||
export interface AtemschutzUebersicht extends AtemschutzTraeger {
|
||||
user_name: string | null;
|
||||
user_given_name: string | null;
|
||||
user_family_name: string | null;
|
||||
user_email: string;
|
||||
mitglied_status: string | null;
|
||||
dienstgrad: string | null;
|
||||
untersuchung_gueltig: boolean;
|
||||
untersuchung_tage_rest: number | null;
|
||||
leistungstest_gueltig: boolean;
|
||||
leistungstest_tage_rest: number | null;
|
||||
einsatzbereit: boolean;
|
||||
}
|
||||
|
||||
// ── Dashboard KPI ───────────────────────────────────────────────────────────
|
||||
|
||||
export interface AtemschutzStats {
|
||||
total: number; // total tracked members
|
||||
mitLehrgang: number; // have completed course
|
||||
untersuchungGueltig: number; // valid medical exam
|
||||
untersuchungAbgelaufen: number; // expired medical exam
|
||||
untersuchungBaldFaellig: number; // expires within 90 days
|
||||
leistungstestGueltig: number; // valid performance test
|
||||
leistungstestAbgelaufen: number; // expired performance test
|
||||
leistungstestBaldFaellig: number; // expires within 30 days
|
||||
einsatzbereit: number; // fully qualified
|
||||
}
|
||||
|
||||
// ── Zod Validation Schemas ──────────────────────────────────────────────────
|
||||
|
||||
const uuidString = z.string().regex(
|
||||
/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i,
|
||||
'Ungültige UUID'
|
||||
);
|
||||
|
||||
const isoDate = z.string().regex(
|
||||
/^\d{4}-(0[1-9]|1[0-2])-(0[1-9]|[12]\d|3[01])$/,
|
||||
'Erwartet ISO-Datum im Format YYYY-MM-DD'
|
||||
);
|
||||
|
||||
export const CreateAtemschutzSchema = z.object({
|
||||
user_id: uuidString,
|
||||
atemschutz_lehrgang: z.boolean().default(false),
|
||||
lehrgang_datum: isoDate.optional(),
|
||||
untersuchung_datum: isoDate.optional(),
|
||||
untersuchung_gueltig_bis: isoDate.optional(),
|
||||
untersuchung_ergebnis: z.enum(UNTERSUCHUNG_ERGEBNIS_VALUES).optional(),
|
||||
leistungstest_datum: isoDate.optional(),
|
||||
leistungstest_gueltig_bis: isoDate.optional(),
|
||||
leistungstest_bestanden: z.boolean().optional(),
|
||||
bemerkung: z.string().max(2000).optional(),
|
||||
});
|
||||
|
||||
export type CreateAtemschutzData = z.infer<typeof CreateAtemschutzSchema>;
|
||||
|
||||
export const UpdateAtemschutzSchema = z.object({
|
||||
atemschutz_lehrgang: z.boolean().optional(),
|
||||
lehrgang_datum: isoDate.nullable().optional(),
|
||||
untersuchung_datum: isoDate.nullable().optional(),
|
||||
untersuchung_gueltig_bis: isoDate.nullable().optional(),
|
||||
untersuchung_ergebnis: z.enum(UNTERSUCHUNG_ERGEBNIS_VALUES).nullable().optional(),
|
||||
leistungstest_datum: isoDate.nullable().optional(),
|
||||
leistungstest_gueltig_bis: isoDate.nullable().optional(),
|
||||
leistungstest_bestanden: z.boolean().nullable().optional(),
|
||||
bemerkung: z.string().max(2000).nullable().optional(),
|
||||
});
|
||||
|
||||
export type UpdateAtemschutzData = z.infer<typeof UpdateAtemschutzSchema>;
|
||||
Reference in New Issue
Block a user