From 1df47f17c497d071b4dc679b0dc7837f92f1bc41 Mon Sep 17 00:00:00 2001 From: Jose Olarte III Date: Mon, 16 Mar 2026 21:16:10 +0800 Subject: [PATCH] docs: add plugin-repo alignment section to New Activity lay-of-the-land Document how daily-notification-plugin aligns with app usage (APIs, dual vs single schedules, native fetcher, exact alarm). Note attention items: cancelDailyReminder argument shape, INTEGRATION_GUIDE scope, and iOS use of app-provided id for scheduleDailyNotification. --- ...tification-new-activity-lay-of-the-land.md | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/doc/notification-new-activity-lay-of-the-land.md b/doc/notification-new-activity-lay-of-the-land.md index 2d68c9f3..985d133a 100644 --- a/doc/notification-new-activity-lay-of-the-land.md +++ b/doc/notification-new-activity-lay-of-the-land.md @@ -185,3 +185,30 @@ Use this section to verify the New Activity flow end-to-end on a physical device - **No starred plans:** Enable New Activity with no starred projects; confirm no crash and a sensible fallback message in the notification. - **JWT / API errors:** After leaving the app in background for a long time, the JWT may expire. Re-opening Account (or app) may re-run `configureNativeFetcherIfReady`; document or test whether a new notification still gets valid content or shows fallback. - **Daily Reminder and New Activity both on:** With the fix, turning off only New Activity should not affect the Daily Reminder notification (they use different plugin APIs; Option B must not cancel the single reminder if the user still has Daily Reminder on). + +--- + +## 8. Plugin Repo Alignment and Attention Items + +Comparison with the **daily-notification-plugin** repo (e.g. `daily-notification-plugin_test` or gitea `master`) to confirm our documentation and usage line up, and to flag anything that needs attention for the New Activity feature. + +### 8.1 What lines up + +- **API surface:** Plugin `definitions.ts` exposes `configureNativeFetcher({ apiBaseUrl, activeDid, jwtToken })`, `scheduleDualNotification(config)`, `cancelDualSchedule()`, `updateStarredPlans({ planIds })`, `scheduleDailyNotification(options)`, and `cancelDailyReminder(reminderId)`. Our app uses these as described in this doc; `buildDualScheduleConfig` produces a `DualScheduleConfiguration` that matches the plugin’s `ContentFetchConfig` / `UserNotificationConfig` / `relationship` shape (cron schedules, title/body, `callbacks: {}`, `fallbackBehavior: "show_default"`, etc.). +- **Native fetcher:** Plugin is designed for a host-supplied JWT via `configureNativeFetcher` and a native fetcher implementation (e.g. Android `TimeSafariNativeFetcher`). Our `nativeFetcherConfig.ts` and Android `TimeSafariNativeFetcher.java` follow that model; prefetch runs in the plugin’s background workers and uses the configured credentials. +- **Dual vs single:** The plugin clearly separates: + - **Single daily path:** `scheduleDailyNotification(options)` (with `id` on Android) and `cancelDailyReminder(reminderId)` (iOS uses `reminder_` for the static-reminder path). + - **Dual path:** `scheduleDualNotification(config)` and `cancelDualSchedule()`. + So our analysis that “two schedules” are created when the dialog schedules the single reminder and AccountViewView schedules the dual is consistent with the plugin. +- **Exact alarm:** The plugin’s Android implementation does **not** require exact alarm: it proceeds with scheduling using inexact/windowed alarms when exact is not granted. The plugin’s `INTEGRATION_GUIDE.md` still shows `SCHEDULE_EXACT_ALARM` in the manifest example; this app has chosen to disable exact alarm, and the plugin supports that. No doc change needed beyond what we already state in section 7. + +### 8.2 Attention items + +- **`cancelDailyReminder` signature:** In the plugin’s `definitions.ts`, `cancelDailyReminder(reminderId: string)`. The app calls it with an object: `cancelDailyReminder({ reminderId })`. On iOS the plugin uses `call.getString("reminderId")`, so the object form works. If the plugin’s TypeScript definition is ever used for strict typing, prefer updating the plugin to accept `{ reminderId: string }` or document that the bridge accepts an object with a `reminderId` key. +- **Plugin INTEGRATION_GUIDE vs this app:** The guide describes generic polling, dual scheduling, and optional `SCHEDULE_EXACT_ALARM`. This app uses the dual-schedule + native-fetcher path only (no generic polling), and does not use exact alarm. When onboarding or debugging, treat the guide as the full plugin feature set; our flow is the “legacy dual scheduling” + native fetcher part plus `updateStarredPlans` and `configureNativeFetcher`. +- **iOS `scheduleDailyNotification` and stable `id`:** On **Android**, the plugin uses `options.getString("id")` as the stable `scheduleId` for “one per day” semantics and cleanup. On **iOS**, the implementation in the repo was observed to build notification content with an internally generated id (e.g. `daily_`) and not obviously use the app-provided `id` from the call. If the app ever relies on a stable id on iOS for the single reminder (e.g. to cancel or replace only that reminder), it’s worth confirming in the plugin’s iOS code whether the call’s `id` is read and used; if not, consider requesting or contributing a change so iOS also uses the app-provided id for consistency with Android. +- **Dual schedule and content fetch:** The plugin’s dual schedule runs the content-fetch job on its cron and then the user notification at the configured time; our config uses a 5-minute gap and `relationship.contentTimeout` / `fallbackBehavior: "show_default"`. The native fetcher is invoked by the plugin’s background layer when the content-fetch schedule fires; we don’t rely on JS `callbacks` in the config (we pass `callbacks: {}`). That matches the “native fetcher does the work” design. + +### 8.3 Summary + +The plugin repo aligns with how we use it for New Activity (dual schedule + native fetcher, no generic polling, exact alarm optional). The main follow-ups are: (1) clarify or align `cancelDailyReminder` argument shape in the plugin if needed for typing/tooling, and (2) confirm on iOS whether `scheduleDailyNotification` uses the app-provided `id` for stable single-reminder semantics.