From 73a7e49f854931c10ae7e59d6bb5a87de77b18c3 Mon Sep 17 00:00:00 2001 From: Schalli Date: Wed, 22 Jul 2026 09:28:53 +0200 Subject: [PATCH] =?UTF-8?q?feat(12-04):=20tender-radar-api=20client=20?= =?UTF-8?q?=E2=80=94=20notification-pref=20+=20instantAlert?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 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) --- apps/web/src/lib/tender-radar-api.ts | 46 ++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/apps/web/src/lib/tender-radar-api.ts b/apps/web/src/lib/tender-radar-api.ts index bc5cd54..1c9ce84 100644 --- a/apps/web/src/lib/tender-radar-api.ts +++ b/apps/web/src/lib/tender-radar-api.ts @@ -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; + instantAlert: boolean; createdAt: string; updatedAt: string; } @@ -226,12 +230,14 @@ export interface SavedSearch { export interface CreateSavedSearchPayload { name: string; filters: Record; + instantAlert?: boolean; } /** Payload accepted by PATCH /modules/tender-radar/saved-searches/:searchId. */ export interface UpdateSavedSearchPayload { name?: string; filters?: Record; + instantAlert?: boolean; } /** @@ -295,3 +301,43 @@ export async function deleteSavedSearch(id: string): Promise { ); 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 { + 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 { + 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(); +}