feat(notifications): add localStorage debug config for notification API base URL
Introduce NotificationDebugConfig so register/refresh use getNotificationApiBaseUrl() (APP_SERVER by default, optional LAN/ngrok override) and configurable testMode without rebuilds.
This commit is contained in:
@@ -16,6 +16,10 @@ import type { PushNotificationSchema } from "@capacitor/push-notifications";
|
||||
import { DailyNotification } from "@/plugins/DailyNotificationPlugin";
|
||||
import { REMINDER_ID_DAILY_REMINDER } from "./reminderIds";
|
||||
import { configureNativeFetcherIfReady } from "./nativeFetcherConfig";
|
||||
import {
|
||||
getNotificationApiBaseUrl,
|
||||
getTestMode,
|
||||
} from "./NotificationDebugConfig";
|
||||
|
||||
/**
|
||||
* Extended type for DailyNotification that includes the actual Swift implementation
|
||||
@@ -555,12 +559,13 @@ export async function refreshNotifications(): Promise<void> {
|
||||
}
|
||||
|
||||
try {
|
||||
const res = await fetch("/notifications/refresh", {
|
||||
const baseUrl = getNotificationApiBaseUrl();
|
||||
const res = await fetch(`${baseUrl}/notifications/refresh`, {
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/json" },
|
||||
body: JSON.stringify({
|
||||
platform: Capacitor.getPlatform(),
|
||||
testMode: true,
|
||||
testMode: getTestMode(),
|
||||
}),
|
||||
});
|
||||
|
||||
|
||||
96
src/services/notifications/NotificationDebugConfig.ts
Normal file
96
src/services/notifications/NotificationDebugConfig.ts
Normal file
@@ -0,0 +1,96 @@
|
||||
/**
|
||||
* Lightweight debug configuration for notification backend testing.
|
||||
* Persists overrides in localStorage; production defaults apply when unset.
|
||||
*/
|
||||
|
||||
import { APP_SERVER } from "@/constants/app";
|
||||
|
||||
const LOG = "[NotificationDebug]";
|
||||
const STORAGE_KEY_BACKEND_URL = "notificationDebug.backendBaseUrl";
|
||||
const STORAGE_KEY_TEST_MODE = "notificationDebug.testMode";
|
||||
|
||||
/** Trim whitespace, drop trailing slash; empty input becomes null. */
|
||||
export function normalizeNotificationBackendUrl(url: string): string | null {
|
||||
const trimmed = url.trim();
|
||||
if (!trimmed) {
|
||||
return null;
|
||||
}
|
||||
return trimmed.replace(/\/$/, "");
|
||||
}
|
||||
|
||||
function readStorage(key: string): string | null {
|
||||
if (typeof localStorage === "undefined") {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
return localStorage.getItem(key);
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
function writeStorage(key: string, value: string | null): void {
|
||||
if (typeof localStorage === "undefined") {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
if (value === null) {
|
||||
localStorage.removeItem(key);
|
||||
} else {
|
||||
localStorage.setItem(key, value);
|
||||
}
|
||||
} catch {
|
||||
// Quota / privacy mode — ignore
|
||||
}
|
||||
}
|
||||
|
||||
/** Backend URL override, or null when using the default app server. */
|
||||
export function getBackendBaseUrl(): string | null {
|
||||
const raw = readStorage(STORAGE_KEY_BACKEND_URL);
|
||||
if (raw === null) {
|
||||
return null;
|
||||
}
|
||||
return normalizeNotificationBackendUrl(raw);
|
||||
}
|
||||
|
||||
export function setBackendBaseUrl(url: string): void {
|
||||
const normalized = normalizeNotificationBackendUrl(url);
|
||||
if (normalized === null) {
|
||||
writeStorage(STORAGE_KEY_BACKEND_URL, null);
|
||||
// eslint-disable-next-line no-console
|
||||
console.log(`${LOG} backend URL cleared (using default)`);
|
||||
return;
|
||||
}
|
||||
writeStorage(STORAGE_KEY_BACKEND_URL, normalized);
|
||||
// eslint-disable-next-line no-console
|
||||
console.log(`${LOG} backend URL set to ${normalized}`);
|
||||
}
|
||||
|
||||
/**
|
||||
* When never configured via debug UI/console, matches prior hardcoded `testMode: true`.
|
||||
*/
|
||||
export function getTestMode(): boolean {
|
||||
const raw = readStorage(STORAGE_KEY_TEST_MODE);
|
||||
if (raw === null) {
|
||||
return true;
|
||||
}
|
||||
return raw === "true";
|
||||
}
|
||||
|
||||
export function setTestMode(enabled: boolean): void {
|
||||
writeStorage(STORAGE_KEY_TEST_MODE, enabled ? "true" : "false");
|
||||
// eslint-disable-next-line no-console
|
||||
console.log(`${LOG} test mode ${enabled ? "enabled" : "disabled"}`);
|
||||
}
|
||||
|
||||
/**
|
||||
* Base URL for `/notifications/*` API calls.
|
||||
* Uses debug override when set; otherwise the built-in app server (production default).
|
||||
*/
|
||||
export function getNotificationApiBaseUrl(): string {
|
||||
const override = getBackendBaseUrl();
|
||||
if (override) {
|
||||
return override;
|
||||
}
|
||||
return normalizeNotificationBackendUrl(APP_SERVER) ?? APP_SERVER;
|
||||
}
|
||||
@@ -16,6 +16,10 @@
|
||||
import { Capacitor } from "@capacitor/core";
|
||||
import { logger } from "@/utils/logger";
|
||||
import { getOrCreateDeviceId } from "./deviceId";
|
||||
import {
|
||||
getNotificationApiBaseUrl,
|
||||
getTestMode,
|
||||
} from "./NotificationDebugConfig";
|
||||
import { NativeNotificationService } from "./NativeNotificationService";
|
||||
import { WebPushNotificationService } from "./WebPushNotificationService";
|
||||
|
||||
@@ -24,14 +28,15 @@ import { WebPushNotificationService } from "./WebPushNotificationService";
|
||||
*/
|
||||
export async function registerToken(fcmToken: string): Promise<void> {
|
||||
const deviceId = await getOrCreateDeviceId();
|
||||
const res = await fetch("/notifications/register", {
|
||||
const baseUrl = getNotificationApiBaseUrl();
|
||||
const res = await fetch(`${baseUrl}/notifications/register`, {
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/json" },
|
||||
body: JSON.stringify({
|
||||
deviceId,
|
||||
fcmToken,
|
||||
platform: Capacitor.getPlatform(),
|
||||
testMode: true,
|
||||
testMode: getTestMode(),
|
||||
}),
|
||||
});
|
||||
if (!res.ok) {
|
||||
|
||||
@@ -13,6 +13,14 @@
|
||||
* ```
|
||||
*/
|
||||
|
||||
export {
|
||||
getBackendBaseUrl,
|
||||
getNotificationApiBaseUrl,
|
||||
getTestMode,
|
||||
normalizeNotificationBackendUrl,
|
||||
setBackendBaseUrl,
|
||||
setTestMode,
|
||||
} from "./NotificationDebugConfig";
|
||||
export { NotificationService, registerToken } from "./NotificationService";
|
||||
export { NativeNotificationService } from "./NativeNotificationService";
|
||||
export { WebPushNotificationService } from "./WebPushNotificationService";
|
||||
|
||||
Reference in New Issue
Block a user