feat(scheduling): persist notifications, batch notify flow, dedup protection
- Add tab_scheduling_notifications table with bootstrap via ensureSchedulingTables() - Notify endpoint rewritten: dedup by (suggestion_id, candidate_plate), history list, PATCH /:id for execute/cancel lifecycle - Batch notify endpoint returns success/skipped/failed counts - Suggestions response now carries notificationId + notificationStatus per candidate (joined from active-notification map) - UI: select mode with checkboxes, floating action bar, confirmation modal listing each swap; already-notified items are dimmed and skipped - Detail view badges show sent/executed state, preventing duplicate notify Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -21,6 +21,8 @@ export interface SchedulingVehicleInfo {
|
||||
daysLeft: number;
|
||||
}
|
||||
|
||||
export type NotificationStatus = 'sent' | 'executed' | 'cancelled';
|
||||
|
||||
export interface CandidateVehicle {
|
||||
plateNumber: string;
|
||||
targetId: number | null;
|
||||
@@ -36,6 +38,41 @@ export interface CandidateVehicle {
|
||||
predictedAfterSwap: number;
|
||||
canQualifyAfterSwap: boolean;
|
||||
isSameRegion: boolean;
|
||||
notificationId: number | null;
|
||||
notificationStatus: NotificationStatus | null;
|
||||
}
|
||||
|
||||
export interface NotificationRecord {
|
||||
id: number;
|
||||
suggestionId: string;
|
||||
currentPlate: string;
|
||||
candidatePlate: string;
|
||||
operatorId: string | null;
|
||||
operatorName: string | null;
|
||||
status: NotificationStatus;
|
||||
createdAt: string;
|
||||
updatedAt: string;
|
||||
executedAt: string | null;
|
||||
notes: string | null;
|
||||
beforeMileage: number | null;
|
||||
afterMileage: number | null;
|
||||
}
|
||||
|
||||
export interface NotifyBatchRequest {
|
||||
items: NotifyRequest[];
|
||||
}
|
||||
|
||||
export interface NotifyBatchResult {
|
||||
success: number;
|
||||
skipped: number;
|
||||
failed: number;
|
||||
records: NotificationRecord[];
|
||||
}
|
||||
|
||||
export interface UpdateNotificationRequest {
|
||||
status: NotificationStatus;
|
||||
notes?: string;
|
||||
afterMileage?: number;
|
||||
}
|
||||
|
||||
export interface ReasonLine {
|
||||
|
||||
Reference in New Issue
Block a user