using System.Text.Json.Serialization; namespace KronaStaffTerminal.Models; public sealed class EmployeeRecord { public string Id { get; set; } = UlidGenerator.New(); public string PersonnelNumber { get; set; } = ""; public string DisplayName { get; set; } = ""; public string Position { get; set; } = ""; public string Gender { get; set; } = ""; public bool IsAdministrator { get; set; } public List Fingerprints { get; set; } = []; // Legacy single-fingerprint fields are kept for one-way migration of existing encrypted state. public int FingerprintId { get; set; } public string? FingerprintTemplate { get; set; } [JsonIgnore] public bool HasFingerprint => Fingerprints.Count > 0; [JsonIgnore] public string FingerprintStatus => Fingerprints.Count switch { 0 => "Отпечатков нет", 1 => "1 отпечаток", 2 or 3 or 4 => $"{Fingerprints.Count} отпечатка", _ => $"{Fingerprints.Count} отпечатков" }; [JsonIgnore] public string AccessStatus => IsAdministrator ? "Администратор" : "Сотрудник"; [JsonIgnore] public string GenderDisplay => string.IsNullOrWhiteSpace(Gender) ? "—" : Gender; } public sealed class FingerprintRecord { public int Id { get; set; } public string Template { get; set; } = ""; public string Label { get; set; } = ""; } public sealed class AttendanceRecord { public string Id { get; set; } = UlidGenerator.New(); public string EmployeeId { get; set; } = ""; public string EmployeeName { get; set; } = ""; public DateTimeOffset OccurredAtUtc { get; set; } public int ReaderIndex { get; set; } public string EventType { get; set; } = "Приход"; public bool NotificationDelivered { get; set; } public string? NotificationError { get; set; } [JsonIgnore] public string LocalTime => OccurredAtUtc.ToLocalTime().ToString("dd.MM.yyyy HH:mm:ss"); [JsonIgnore] public string DeliveryStatus => NotificationDelivered ? "Отправлено" : string.IsNullOrWhiteSpace(NotificationError) ? "Не настроено" : "Ошибка отправки"; } public sealed class TerminalSettings { public int ReaderIndex { get; set; } public bool StartWithWindows { get; set; } public string AdminPinSalt { get; set; } = ""; public string AdminPinHash { get; set; } = ""; public int AdminPinIterations { get; set; } = 120_000; public int DuplicateScanGuardSeconds { get; set; } = 120; public int MaximumShiftHours { get; set; } = 20; public bool ShowEmployeeNamesOnTerminal { get; set; } public bool TelegramEnabled { get; set; } public string TelegramBotToken { get; set; } = ""; public string TelegramChatId { get; set; } = ""; public bool MaxEnabled { get; set; } public string MaxBotToken { get; set; } = ""; public string MaxChatId { get; set; } = ""; } public sealed class TerminalState { public List Employees { get; set; } = []; public List Attendance { get; set; } = []; public TerminalSettings Settings { get; set; } = new(); }