docs: add plugin-repo handoff section to iOS/Android New Activity parity guide

Add §6 with reference file table, Endorser contract summary aligned to
TimeSafariNativeFetcher, likely plugin touchpoints, and suggested implementation
order; renumber acceptance checklist to §7.
This commit is contained in:
Jose Olarte III
2026-04-02 17:51:51 +08:00
parent 8290943b53
commit 90e6603d52

View File

@@ -113,7 +113,48 @@ Plugin work item **§4A.3** should reflect this: document the chosen strategy (c
---
## 6. Acceptance checklist (iOS vs Android product intent)
## 6. Handoff to plugin repo (Cursor / isolated workspace)
Use this section when **daily-notification-plugin** is open **without** the TimeSafari app tree, so implementers do not depend on paths that only exist in crowd-funder-for-time-pwa.
### 6.1 Bring reference material into scope
| Source (this app repo) | Why |
|------------------------|-----|
| `android/app/src/main/java/app/timesafari/TimeSafariNativeFetcher.java` | **Canonical Endorser behavior** for New Activity: POST body, pagination, aggregation copy, prefs keys for starred IDs and `last_acked_jwt_id`. Copy or open alongside the plugin when implementing iOS fetch or `setNativeFetcher`. |
| `src/services/notifications/dualScheduleConfig.ts` | Shape the app sends to `scheduleDualNotification` (`buildDualScheduleConfig`). |
| `doc/plugin-feedback-android-dual-schedule-native-fetch-and-timing.md` | Android plugin: dual path must call native fetcher at fetch cron. |
| `doc/plugin-feedback-ios-scheduleDualNotification.md` | iOS `UNIMPLEMENTED` / PluginHeaders troubleshooting. |
In the plugin repo itself, align with **`src/definitions.ts`** (`DualScheduleConfiguration`, `configureNativeFetcher`, `updateStarredPlans`) and **INTEGRATION_GUIDE** if present.
### 6.2 HTTP / storage contract (match `TimeSafariNativeFetcher`)
Implementations on **iOS** (in-plugin Swift or host `NativeNotificationContentFetcher`) should match this **unless** product explicitly changes:
- **Method & path:** `POST` `{apiBaseUrl}/api/v2/report/plansLastUpdatedBetween` (no trailing slash mismatch on `apiBaseUrl`).
- **Headers:** `Content-Type: application/json`, `Authorization: Bearer {token}` (token from `jwtToken` or **JWT pool** selection—see Java `selectBearerTokenForRequest`: UTC day mod pool size).
- **JSON body:** `planIds` (array of strings, possibly empty), `afterId` (string; use `"0"` if none stored).
- **Starred plans:** Persist `updateStarredPlans` the same way Androids plugin + host expect: SharedPreferences name **`daily_notification_timesafari`**, key **`starredPlanIds`** (JSON array string). iOS should use **the same keys** if using `UserDefaults` / app group so behavior matches the Java fetcher and plugin docs.
- **Pagination:** After a successful response with non-empty `data`, update **`last_acked_jwt_id`** from the last rows `jwtId` (item or nested `plan.jwtId`)—see Java `updateLastAckedJwtIdFromResponse`.
- **Empty `data`:** Return **no** notification items (empty list); do not synthesize a “no updates” push from an empty result—Java returns empty `contents` when `data` is absent or empty.
- **Non-empty `data`:** One aggregated `NotificationContent`: titles **Starred Project Update** / **Starred Project Updates**, bodies use typographic quotes around first project name and **has been updated.** / **+ N more have been updated.** (see Java `parseApiResponse`).
### 6.3 Likely plugin touchpoints (names may drift—search the repo)
- **iOS:** `ios/Plugin/DailyNotificationPlugin.swift`, `DailyNotificationScheduleHelper.swift`, background fetch / UN notification paths; add **`updateStarredPlans`** to `pluginMethods` and persistence.
- **Android:** `DailyNotificationPlugin.kt`, `FetchWorker` / `DailyNotificationFetchWorker`, `ScheduleHelper`—per dual-schedule feedback doc.
### 6.4 Suggested order inside the plugin repo
1. **Android dual path** + native fetcher at fetch cron (fixes real device behavior for existing host).
2. **iOS** `updateStarredPlans` + **`plansLastUpdatedBetween`** parity (or **iOS `setNativeFetcher`** + thin Swift adapter).
3. **iOS** prefetch/notify **ordering** (§3.3): document and implement chained arm vs best-effort.
4. Release / tag → consuming app bumps **`@timesafari/daily-notification-plugin`**, `npx cap sync`, `pod install`.
---
## 7. Acceptance checklist (iOS vs Android product intent)
- [ ] Prefetch uses **plansLastUpdatedBetween** (or host fetcher with identical behavior), not only `offers` GET.
- [ ] **Starred plan IDs** from settings change what is queried (`updateStarredPlans` works on iOS).