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:
kkfluous
2026-04-16 23:43:21 +08:00
parent 31716c6547
commit 3ef0d4edfa
12 changed files with 614 additions and 33 deletions

View File

@@ -119,6 +119,8 @@ export function generateSuggestions(
predictedAfterSwap,
canQualifyAfterSwap,
isSameRegion: inv.region === vehicle.region,
notificationId: null,
notificationStatus: null,
};
})
.sort((a, b) => {
@@ -188,6 +190,8 @@ export function generateSuggestions(
predictedAfterSwap,
canQualifyAfterSwap,
isSameRegion: inv.region === vehicle.region,
notificationId: null,
notificationStatus: null,
};
})
// Only keep candidates that can actually qualify at this customer —