feat(12-04): tender-radar-api client — notification-pref + instantAlert

- fetchNotificationPref/saveNotificationPref for GET/PUT
  /modules/tender-radar/notification-pref (NOTIFY-01)
- SavedSearch/Create/UpdateSavedSearchPayload now carry instantAlert
  (NOTIFY-02, D-04)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-07-22 09:28:53 +02:00
parent 9e7ba5353d
commit 73a7e49f85
+46
View File
@@ -213,11 +213,15 @@ export async function setTriage(
* deadlineFrom/To, openOnly, valueMin/Max, includeNullValue, sort, favOnly)
* — see SavedSearchBar.tsx's serialize/deserialize helpers for the
* round-trip contract.
*
* `instantAlert` (Plan 12-04, NOTIFY-02, D-04): per-profile Sofort-Alert
* toggle, default false — set via createSavedSearch/updateSavedSearch.
*/
export interface SavedSearch {
id: string;
name: string;
filters: Record<string, unknown>;
instantAlert: boolean;
createdAt: string;
updatedAt: string;
}
@@ -226,12 +230,14 @@ export interface SavedSearch {
export interface CreateSavedSearchPayload {
name: string;
filters: Record<string, unknown>;
instantAlert?: boolean;
}
/** Payload accepted by PATCH /modules/tender-radar/saved-searches/:searchId. */
export interface UpdateSavedSearchPayload {
name?: string;
filters?: Record<string, unknown>;
instantAlert?: boolean;
}
/**
@@ -295,3 +301,43 @@ export async function deleteSavedSearch(id: string): Promise<void> {
);
if (!res.ok) throw new Error('Failed to delete saved search');
}
/**
* This user's digest interval preference (Plan 12-04, NOTIFY-01, D-01/D-03).
* Per-user, NOT per-profile — the backend derives userId from the auth
* cookie, this client never sends a userId.
*/
export interface NotificationPref {
digestInterval: 'daily' | 'weekly' | 'off';
}
/**
* Fetch this user's digest interval preference. Defaults to 'daily' on the
* backend when no row exists yet (D-01) — this client just relays whatever
* the backend returns.
* GET /modules/tender-radar/notification-pref
*/
export async function fetchNotificationPref(): Promise<NotificationPref> {
const res = await fetch(`${API_URL}/modules/tender-radar/notification-pref`, {
credentials: 'include',
});
if (!res.ok) throw new Error('Failed to fetch notification preference');
return res.json();
}
/**
* Save this user's digest interval preference.
* PUT /modules/tender-radar/notification-pref
*/
export async function saveNotificationPref(
digestInterval: NotificationPref['digestInterval'],
): Promise<NotificationPref> {
const res = await fetch(`${API_URL}/modules/tender-radar/notification-pref`, {
method: 'PUT',
headers: { 'Content-Type': 'application/json' },
credentials: 'include',
body: JSON.stringify({ digestInterval }),
});
if (!res.ok) throw new Error('Failed to save notification preference');
return res.json();
}