feat(notifications): apply backend refresh schedule to native plugin

Update refreshNotifications to POST /notifications/refresh and map returned
nextNotifications timestamps to clockTime schedules, upserting them via the
DailyNotification schedule APIs (with deterministic IDs) after refreshing native
fetcher credentials.
This commit is contained in:
Jose Olarte III
2026-05-06 16:17:50 +08:00
parent 35a1b92559
commit 7c8ef284c2

View File

@@ -13,6 +13,7 @@
import { Capacitor } from "@capacitor/core";
import type { PushNotificationSchema } from "@capacitor/push-notifications";
import { ScheduleKind } from "@timesafari/daily-notification-plugin";
import { DailyNotification } from "@/plugins/DailyNotificationPlugin";
import { REMINDER_ID_DAILY_REMINDER } from "./reminderIds";
import { configureNativeFetcherIfReady } from "./nativeFetcherConfig";
@@ -553,7 +554,74 @@ export async function refreshNotifications(): Promise<void> {
if (!Capacitor.isNativePlatform()) {
return;
}
await configureNativeFetcherIfReady();
try {
const res = await fetch("/notifications/refresh", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
platform: Capacitor.getPlatform(),
testMode: true,
}),
});
if (!res.ok) {
logger.warn("[NativeNotificationService] refreshNotifications failed", {
status: res.status,
statusText: res.statusText,
});
return;
}
const data: unknown = await res.json();
const nextNotifications = (data as { nextNotifications?: unknown })
?.nextNotifications;
// Keep existing behavior: ensure background worker credentials are current.
await configureNativeFetcherIfReady();
if (!Array.isArray(nextNotifications)) {
return;
}
// Apply backend schedule to the native scheduler as recurring notifications.
// The plugin's schedule API is cron/clockTime-based (recurring), so we map
// the backend timestamps to clockTime (HH:mm) schedules.
await Promise.all(
nextNotifications.map(async (n) => {
const timestamp = (n as { timestamp?: unknown })?.timestamp;
if (typeof timestamp !== "number" || !Number.isFinite(timestamp)) {
return;
}
const dt = new Date(timestamp);
const hh = dt.getHours().toString().padStart(2, "0");
const mm = dt.getMinutes().toString().padStart(2, "0");
const clockTime = `${hh}:${mm}`;
const id = `backend-${timestamp}`;
const existing = await DailyNotification.getSchedule(id);
if (existing) {
await DailyNotification.updateSchedule(id, {
clockTime,
enabled: true,
});
} else {
// DailyNotification plugin typings currently omit `id` on CreateScheduleInput,
// but runtime supports deterministic IDs for schedule reconciliation.
await DailyNotification.createSchedule({
id,
kind: ScheduleKind.NOTIFY,
clockTime,
enabled: true,
} as unknown as never);
}
}),
);
} catch (err) {
logger.error("[NativeNotificationService] Refresh failed", err);
}
}
/**