Files
crowd-funder-for-time-pwa/doc/notification-from-api-call.md

7.0 KiB
Raw Blame History

New Activity Notification (API-Driven Daily Message)

Purpose: Integrate the daily-notification-plugins second feature—the daily, API-driven message—into the crowd-funder (TimeSafari) app. The first feature (daily static reminder) is already integrated; this document covers the plan, completed work, and remaining tasks for the API-driven flow.

References:

  • Plugin: daily-notification-plugin (INTEGRATION_GUIDE.md, definitions.ts)
  • Alignment outline: doc/daily-notification-alignment-outline.md
  • Help copy: HelpNotificationTypesView.vue (“New Activity Notifications”)

Plan Summary

The API-driven flow:

  1. Prefetch Shortly before the users chosen time, the plugin runs a background job that calls the Endorser.ch API (e.g. plansLastUpdatedBetween, and optionally offers endpoints) using credentials supplied by the app.
  2. Cache Fetched content is stored in the plugins cache.
  3. Notify At the chosen time, the user sees a notification whose title/body come from that content (or a fallback).

The app must:

  • Configure the native fetcher with apiBaseUrl, activeDid, and a JWT so the plugins background workers can call the API.
  • Implement the native fetcher (or register an implementation) so the plugin can perform the actual HTTP requests and parse responses into notification content.
  • Sync starred plan IDs to the plugin via updateStarredPlans so the fetcher knows which plans to query.
  • Expose UI to enable/disable the “New Activity” notification and choose a time, and call scheduleDualNotification / cancelDualSchedule accordingly.

Tasks Finished

  • Configure native fetcher on startup and identity

    • Added configureNativeFetcherIfReady() in src/services/notifications/nativeFetcherConfig.ts (reads activeDid and apiServer from DB, gets JWT via getHeaders(did), calls DailyNotification.configureNativeFetcher()).
    • Called from main.capacitor.ts after the 2s delay (with deep link registration).
    • Called from AccountViewView.initializeState() when on native and activeDid is set; when New Activity is enabled, also calls updateStarredPlans(settings.starredPlanHandleIds).
  • Implement real API calls in Android native fetcher

    • android/app/src/main/java/app/timesafari/TimeSafariNativeFetcher.java implements NativeNotificationContentFetcher: POST to /api/v2/report/plansLastUpdatedBetween with planIds (from SharedPreferences daily_notification_timesafari / starredPlanIds) and afterId; parses response into NotificationContent list; updates last_acked_jwt_id for pagination.
    • Registered in MainActivity.onCreate() via DailyNotificationPlugin.setNativeFetcher(new TimeSafariNativeFetcher(this)).
  • Sync starred plan IDs

    • When user enables New Activity, scheduleNewActivityDualNotification() calls DailyNotification.updateStarredPlans({ planIds: settings.starredPlanHandleIds ?? [] }).
    • When Account view loads and New Activity is on, initializeState() calls updateStarredPlans(settings.starredPlanHandleIds) so the plugin has the latest list.
  • Dual schedule config and scheduling

    • Added src/services/notifications/dualScheduleConfig.ts: timeToCron(), timeToCronFiveMinutesBefore(), buildDualScheduleConfig({ notifyTime, title?, body? }) (contentFetch 5 min before, userNotification at chosen time).
    • When user enables New Activity and picks a time, app calls DailyNotification.scheduleDualNotification({ config }) with this config.
    • When user disables New Activity, app calls DailyNotification.cancelDualSchedule().
  • UI for New Activity notification

    • Unhid the “New Activity Notification” block in AccountViewView.vue (toggle + accessibility).
    • Enable flow: time dialog → save settings → on native, scheduleNewActivityDualNotification(timeText) (configure fetcher, updateStarredPlans, scheduleDualNotification).
    • Disable flow: on native, cancelDualSchedule() then save and clear settings.
    • Added starredPlanHandleIds to AccountSettings in interfaces/accountView.ts.
  • Exports

    • src/services/notifications/index.ts exports configureNativeFetcherIfReady, buildDualScheduleConfig, timeToCron, timeToCronFiveMinutesBefore, and DualScheduleConfigInput.

Checklist of Remaining Tasks

iOS

  • Confirm iOS native fetcher / dual schedule
    Plugin exposes configureNativeFetcher on iOS. Confirm whether the plugin expects an iOS-specific native fetcher registration (similar to Androids setNativeFetcher) and, if so, register a TimeSafari fetcher implementation for iOS so API-driven notifications work on iPhone.

  • Verify dual schedule on iOS
    Test scheduleDualNotification and cancelDualSchedule on iOS; ensure content fetch and user notification fire at the expected times and that foreground/background behavior matches expectations.

Testing and hardening

  • Test full flow on Android
    Enable New Activity, set time, wait for prefetch and notification (or use a short rollover for testing). Confirm notification shows with API-derived or fallback content.

  • Test full flow on iOS
    Same as Android: enable, set time, verify prefetch and notification delivery and content.

  • Test with no starred plans
    Enable New Activity with empty starredPlanHandleIds; confirm no crash and sensible fallback (e.g. “No updates in your starred projects” or similar).

  • Test JWT expiry
    Ensure behavior when the token passed to configureNativeFetcher has expired (e.g. app in background for a long time); document or implement refresh (e.g. re-call configureNativeFetcherIfReady on foreground or when opening Account).

Optional enhancements

  • Offers endpoints
    Extend TimeSafariNativeFetcher (and any iOS fetcher) to call offers endpoints (e.g. offers, offersToPlansOwnedByMe) and merge with project-update content for richer notifications.

  • Sync starred plans on star/unstar
    When the user stars or unstars a project elsewhere in the app, call updateStarredPlans so the plugin always has the current list without requiring a visit to Account.

  • Documentation
    Add a short “New Activity notifications” section to BUILDING.md or a user-facing help page describing how the feature works and how to troubleshoot (e.g. no notification, wrong content, JWT/API errors).


File Reference

Area Files
Fetcher config src/services/notifications/nativeFetcherConfig.ts
Dual schedule config src/services/notifications/dualScheduleConfig.ts
Notification exports src/services/notifications/index.ts
Startup src/main.capacitor.ts
Account UI and flow src/views/AccountViewView.vue
Settings type src/interfaces/accountView.ts
Android native fetcher android/app/src/main/java/app/timesafari/TimeSafariNativeFetcher.java
Android registration android/app/src/main/java/app/timesafari/MainActivity.java