- 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>
62 lines
1.8 KiB
TypeScript
62 lines
1.8 KiB
TypeScript
import { fetchJson } from '../../auth/api-client';
|
|
import type {
|
|
SchedulingResponse,
|
|
NotifyRequest,
|
|
NotifyBatchRequest,
|
|
NotifyBatchResult,
|
|
NotificationRecord,
|
|
NotificationStatus,
|
|
UpdateNotificationRequest,
|
|
} from './types';
|
|
|
|
const BASE = '/api/scheduling';
|
|
|
|
export async function fetchSuggestions(targetId?: number): Promise<SchedulingResponse> {
|
|
const params = new URLSearchParams();
|
|
if (targetId !== undefined) params.set('targetId', String(targetId));
|
|
const qs = params.toString();
|
|
return fetchJson<SchedulingResponse>(`${BASE}/suggestions${qs ? `?${qs}` : ''}`);
|
|
}
|
|
|
|
export async function sendNotify(
|
|
body: NotifyRequest,
|
|
): Promise<{ success: boolean; message: string; record?: NotificationRecord }> {
|
|
return fetchJson(`${BASE}/notify`, {
|
|
method: 'POST',
|
|
headers: { 'Content-Type': 'application/json' },
|
|
body: JSON.stringify(body),
|
|
});
|
|
}
|
|
|
|
export async function sendNotifyBatch(
|
|
body: NotifyBatchRequest,
|
|
): Promise<{ success: boolean; message: string; result: NotifyBatchResult }> {
|
|
return fetchJson(`${BASE}/notify/batch`, {
|
|
method: 'POST',
|
|
headers: { 'Content-Type': 'application/json' },
|
|
body: JSON.stringify(body),
|
|
});
|
|
}
|
|
|
|
export async function fetchNotifications(
|
|
status?: NotificationStatus,
|
|
limit?: number,
|
|
): Promise<{ records: NotificationRecord[] }> {
|
|
const params = new URLSearchParams();
|
|
if (status) params.set('status', status);
|
|
if (limit) params.set('limit', String(limit));
|
|
const qs = params.toString();
|
|
return fetchJson(`${BASE}/notify${qs ? `?${qs}` : ''}`);
|
|
}
|
|
|
|
export async function updateNotification(
|
|
id: number,
|
|
body: UpdateNotificationRequest,
|
|
): Promise<{ success: boolean; record?: NotificationRecord; message?: string }> {
|
|
return fetchJson(`${BASE}/notify/${id}`, {
|
|
method: 'PATCH',
|
|
headers: { 'Content-Type': 'application/json' },
|
|
body: JSON.stringify(body),
|
|
});
|
|
}
|