Commit Graph

4111 Commits

Author SHA1 Message Date
Jose Olarte III
4fb8f048cd build(ios): add GoogleService-Info.plist to Xcode resources
Also clarify the ngrok iOS guide steps for dragging the plist into the correct App folder/target.
2026-05-27 17:01:35 +08:00
Jose Olarte III
c97defef11 build(ios): add CapacitorPreferences pod for notification deviceId
Wire @capacitor/preferences into the iOS Capacitor Podfile so stable
deviceId persistence works on native builds. Refresh package-lock.json.
2026-05-25 17:06:07 +08:00
Jose Olarte III
2c0992ba8b docs(notifications): put Xcode workspace before Firebase in ngrok guide
Reorder first-time setup so Capacitor/Xcode workspace generation (section 4)
precedes Firebase and APNs steps that require Xcode. Update cross-links and
skip targets; no change to Firebase/APNs technical instructions.
2026-05-25 16:59:17 +08:00
Jose Olarte III
964cdb4509 docs(notifications): add from-scratch Firebase and APNs setup to ngrok guide
Document first-time FCM/APNs configuration (project, plist, .p8 key,
Admin credentials, Xcode capabilities) before the iOS build step, and
renumber later sections so the checklist references the new flow.
2026-05-24 17:33:01 +08:00
Jose Olarte III
656de5eba3 docs(notifications): clarify ngrok guide so backend starts once
Consolidate first-run backend setup in section 1 and reframe section 2
as verification only, so local iPhone testing does not look like two
separate startup steps.
2026-05-24 10:21:10 +08:00
Jose Olarte III
0d7586865c feat(notifications): allow auth bypass for local debug and ngrok testing
Add shouldBypassNotificationAuth() when test mode or a backend URL override
is set so register/refresh can proceed without DID/Bearer headers. Production
paths still require auth when bypass is off; log bypass vs authenticated
request modes for easier WAKEUP_PING and panel smoke testing.
2026-05-20 19:34:46 +08:00
Jose Olarte III
5bc030125a feat(notifications): defer FCM registration until auth is ready
Queue token registration when Bearer auth is unavailable at startup,
with bounded exponential backoff retries. Flush the pending token when
identity is set, the app resumes, or the native fetcher configures.
Skip refresh API calls when auth is missing and log lifecycle events
for registration wait and refresh skip.
2026-05-20 15:54:36 +08:00
Jose Olarte III
8cd8727a84 feat(notifications): authenticate register and refresh API calls
Use getHeaders(activeDid) for POST /notifications/register and
/notifications/refresh so requests include Authorization: Bearer tokens
like the rest of the app. Add notificationApiAuth helper for shared header
resolution, auth logging, and graceful handling when identity or token
is missing or the server returns 401/403.
2026-05-20 15:45:46 +08:00
Jose Olarte III
8864a2049b docs(notifications): add local iOS ngrok testing guide for wakeup service
Document Mac backend + ngrok + physical iPhone setup, debug panel overrides,
Firebase/APNs checklist, curl examples, and troubleshooting for WAKEUP_PING flows.
2026-05-18 21:22:53 +08:00
Jose Olarte III
63f5c4ecc7 feat(notifications): add structured observability for push wake and refresh flows
Introduce NotificationDebugEvents and [Notifications] console/panel logging for push
handlers, token registration, refresh timing, schedule replacement, and WAKEUP_PING.
2026-05-18 18:46:16 +08:00
Jose Olarte III
a4453c0b1b feat(dev): extend Notification Debug Panel for backend testing
Add backend URL, test mode, token re-register, refresh diagnostics, FCM token display,
and a capped event log; expose refreshNotificationsWithDiagnostics and reregisterFcmTokenNow.
2026-05-18 16:28:21 +08:00
Jose Olarte III
794b48f0d7 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.
2026-05-18 15:06:52 +08:00
Jose Olarte III
4c97c578bb fix(notifications): fall back when crypto.randomUUID is missing
If randomUUID is unavailable (older WebViews), generate a one-time ID
with Date.now + random segment, log a single DeviceId warning, and
persist it as before so registration still works.
2026-05-13 20:57:14 +08:00
Jose Olarte III
6a9f34a516 feat(notifications): persist stable deviceId for FCM registration
Add getOrCreateDeviceId() backed by Capacitor Preferences so one UUID
survives app restarts and token refreshes. Include deviceId in POST
/notifications/register alongside fcmToken, platform, and testMode.
Add @capacitor/preferences and lightweight DeviceId logs (no token/ID values).
2026-05-13 18:41:10 +08:00
Jose Olarte III
5a40075ab1 fix(dev): pending inspector stable times and refreshPending without nested busy
Expose wall-clock fire targets from the iOS NotificationInspector
(scheduled_time userInfo and predictive_<epochMs> ids) so the debug
panel is not misleading when nextTriggerDate resamples for interval
triggers. Extend TS types and show the scheduled target in the UI,
with a note when iOS nextTriggerDate diverges.

Make refreshPending a plain fetch so mock refresh, wakeup ping, flood
test, and clear notifications can refresh the pending list while an
outer withBusy guard is already active.
2026-05-11 13:50:52 +08:00
Jose Olarte III
48637ae9a8 docs(readme): document Notification Debug Panel for dev builds 2026-05-11 11:16:43 +08:00
Jose Olarte III
a55dce6f3d fix(dev): align notification debug with non-production Capacitor builds
Add includeDevToolkitRoutes (vite dev or MODE !== production) and use it
from the router, AccountViewView, and NotificationDebugView so the debug
screen matches dev-notifications registration after vite build.

Update the gated banner copy to refer to production Vite builds.
2026-05-08 20:02:34 +08:00
Jose Olarte III
d7d5e401b8 fix: dev notification debug on Capacitor and iOS compile
Register the dev-notifications route whenever the bundle is non-production
(DEV or Vite MODE !== production), matching the account screen so RouterLink
to Notification Debug does not throw after vite build.

Align AccountViewView isDev with that rule and document the coupling.

Add NotificationInspectorPlugin.swift to the App target compile sources so
AppDelegate can register the plugin.
2026-05-08 17:54:00 +08:00
Jose Olarte III
19427c2817 fix(account): avoid import.meta in AccountViewView template
Vue’s template compiler treats bindings as non-module JS, so
`import.meta.env.DEV` in `v-if` broke the Capacitor/Vite build.
Expose a readonly `isDev` from the script instead.
2026-05-08 16:34:17 +08:00
Jose Olarte III
d4ac0acd01 chore: bump @timesafari/daily-notification-plugin to 3.0.2 2026-05-08 16:31:52 +08:00
Jose Olarte III
1ef3f32b9e fix(dev): clarify Android pending inspector and harden debug entry guard
- Report UNIMPLEMENTED from Android NotificationInspector instead of empty pending
- Surface iOS-only inspector message in NotificationDebugPanel without noisy errors
- Gate Account debug link with import.meta.env.DEV and document intent
- Add architecture comments on NotificationDebugService, inspector plugin, and native exports
2026-05-07 20:40:09 +08:00
Jose Olarte III
fd0b8ce6d0 feat(dev): add notification debug panel and native pending inspector
Add a dev-only Notification Debug Panel at /dev/notifications for testing
predictive refresh and WAKEUP_PING without a backend.

- Gate route and Advanced Settings entry on import.meta.env.DEV
- NotificationDebugService drives mock refresh, flood test, clear, and
  wake simulation via existing handleCapacitorPushNotificationReceived and
  applyNotificationRefreshPayload (shared with refreshNotifications)
- Add NotificationInspector Capacitor plugin: iOS lists pending
  UNNotificationRequest identifiers and next trigger; Android stub returns
  empty pending for safe registration
2026-05-07 18:52:59 +08:00
Jose Olarte III
320e55912b fix(notifications): apply backend timestamps via scheduleNotifications API
Stop converting backend timestamps to HH:mm/recurring schedules and remove
createSchedule/updateSchedule reconciliation. After a successful refresh payload,
clear existing notifications and schedule exact timestamps via the plugin
scheduleNotifications API (with back-compat clear fallback) to prevent drift.
2026-05-06 17:56:55 +08:00
Jose Olarte III
6bbade2a29 feat(notifications): refresh on mount and resume with debounce
Trigger refreshNotifications on composable mount and document resume, using a
debounced/in-flight guarded wrapper to avoid rapid duplicate refresh calls.
Expose the debounced refresh function from useNotifications.
2026-05-06 17:11:10 +08:00
Jose Olarte III
1cd329c720 fix(notifications): clear scheduled notifications before refresh apply
Cancel all native notifications before applying the backend-provided schedule so
refreshNotifications always performs a full replacement and never leaves stale
entries behind.
2026-05-06 16:45:56 +08:00
Jose Olarte III
7c8ef284c2 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.
2026-05-06 16:17:50 +08:00
Jose Olarte III
35a1b92559 feat(notifications): refresh native fetcher on WAKEUP_PING silent push
Add refreshNotifications (configureNativeFetcherIfReady) and
handleCapacitorPushNotificationReceived for data.type WAKEUP_PING; invoke from
Capacitor pushNotificationReceived without UI.
2026-05-06 16:04:01 +08:00
Jose Olarte III
c523c14d96 feat(notifications): register FCM tokens with backend
Add registerToken POST to /notifications/register (platform, testMode).
Call it from Capacitor registration and Firebase getToken with deduped
registerRetrievedToken; expose registerToken via barrel and useNotifications
as registerFcmToken.
2026-05-06 15:40:00 +08:00
Jose Olarte III
162158066f feat(notifications): initialize Firebase Messaging and Capacitor push on native
Add firebaseMessagingClient to ensure the Firebase app is created from VITE_FIREBASE_*,
wire PushNotifications (listeners, requestPermissions, register) before token work,
and call getMessaging/getToken/onMessage when firebase/messaging is supported. Hook
startup from main.capacitor and set PushNotifications presentationOptions in
capacitor.config. Depend on firebase and @capacitor/push-notifications.
2026-05-06 15:30:46 +08:00
Jose Olarte III
1643bab18b Merge branch 'notify-api_android' into notify-api 2026-04-23 16:08:05 +08:00
Jose Olarte III
ce078862e7 chore: sync package-lock and Podfile.lock (TimesafariDailyNotificationPlugin 3.0.1) 2026-04-20 17:44:00 +08:00
Jose Olarte III
b9f19d3898 fix(notifications): set dual-schedule fallbackBehavior to skip
Avoid showing default New Activity copy when dual content is missing or
outside contentTimeout, per PLUGIN_NOTIFICATION_FIX_ANDROID.md.
2026-04-16 21:21:37 +08:00
Jose Olarte III
24957e0c6f docs(notifications): add Android plugin handout for empty-fetch dual schedule
Document PLUGIN_NOTIFICATION_FIX_ANDROID diagnosis and recommended changes in
the daily-notification-plugin repo, verified against plugin 3.0.0.
2026-04-10 21:12:11 +08:00
Jose Olarte III
954500cf9d fix(ios): static SQLCipher pods, strip system SQLite, refresh deps
- Podfile: use static frameworks; post_install/post_integrate hooks to
  avoid mixing Apple libsqlite3/SQLite headers with SQLCipher (including
  stripping aggregate Pods-App xcconfig flags for Swift explicit modules).
- Xcode: enable CLANG_ENABLE_MODULES; replace CocoaPods “Embed Pods
  Frameworks” phase with “Copy Pods Resources”; minor project file hygiene.
- Pods: SQLCipher 4.10.0, ZIPFoundation patch bump; Podfile.lock updated.
- package.json: allow patch updates for @capacitor-community/sqlite (^6.0.2);
  regenerate package-lock.json.
- Info.plist: reorder keys only (same URL scheme, background modes, BG tasks,
  notification alert style).
2026-04-09 21:46:32 +08:00
Jose Olarte III
73d595046a docs(readme): expand Setup & Building quick start for all platforms
Restructure the quick start with Web, Android, and iOS subheadings; put
each npm command in its own code block; fold the test-page step into the
Web section. Document Android (build:android:test:run + ADB, link to
BUILDING.md) and iOS (build:ios:studio + Xcode prerequisites).
2026-04-02 19:03:58 +08:00
Jose Olarte III
cf9d207895 fix(ios): make build-ios.sh work on current simulators and trim xcodebuild noise
Use generic/platform=iOS Simulator instead of a fixed device name so CLI builds
do not fail when that simulator is not installed (e.g. newer Xcode runtimes).

Pass -quiet to xcodebuild and enable SWIFT_SUPPRESS_WARNINGS plus
GCC_WARN_INHIBIT_ALL_WARNINGS for scripted builds and IPA archive/export so
terminal output stays smaller; full diagnostics remain available in Xcode.
2026-04-02 19:03:58 +08:00
Jose Olarte III
7d87a746f9 feat(ios): register Swift TimeSafariNativeFetcher for New Activity notifications
Add TimeSafariNativeFetcher (plansLastUpdatedBetween parity with Android) and
call DailyNotificationPlugin.registerNativeFetcher from AppDelegate before JS
configureNativeFetcher; broaden DailyNotificationDelivered scheduled_time types
in willPresent. Wire the new file into the App target; normalize PBX object IDs
to 24-char hex.

Document plugin ≥3 handoff (consuming-app-handoff-ios-native-fetcher-chained-dual),
refresh iOS/Android parity and notification-from-api-call file tables.
2026-04-02 19:02:48 +08:00
Jose Olarte III
90e6603d52 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.
2026-04-02 17:51:51 +08:00
Jose Olarte III
8290943b53 docs: add New Activity iOS/Android parity guide and refine follow-ups
Add doc/new-activity-notifications-ios-android-parity.md covering dual-schedule
and Endorser API parity, plugin vs app work, Android dual-path notes, prefetch
vs notify ordering on iOS (§3.3), and clarified Phase B JWT pool status on
both platforms. Link the guide from doc/notification-from-api-call.md under the
iOS checklist.
2026-04-01 20:49:02 +08:00
Jose Olarte III
8ba84888ee feat(android): improve New Activity notification copy in TimeSafariNativeFetcher
Aggregate API rows into one notification with Starred Project Update(s) titles,
plan names in typographic quotes, and "+ N more have been updated." for multiples.
Stop emitting the empty-data "No Project Updates" fallback. Sync internal docs.
2026-03-31 19:50:14 +08:00
Jose Olarte III
230dc52974 feat(notifications): sync starred plans to native plugin on star/unstar
Add syncStarredPlansToNativePlugin() and call it from AccountViewView
(schedule + initializeState) and ProjectViewView.toggleStar when New
Activity is enabled so Android prefetch uses the current starred list.

Update notification-from-api-call.md with the helper and file references.
2026-03-31 15:57:22 +08:00
Jose Olarte III
2c8aa21fa5 feat(notifications): mint JWT pool for native fetcher; log API response
- Mint BACKGROUND_JWT_POOL_SIZE (90 + 10) distinct background JWTs with
  unique jti; pass jwtTokens from nativeFetcherConfig into configureNativeFetcher.
- Android TimeSafariNativeFetcher: overload configure with jwtTokenPool;
  select bearer via epoch day mod pool size; fall back to primary jwtToken.
- Log truncated plansLastUpdatedBetween response at DEBUG for prefetch debugging.
2026-03-30 17:25:50 +08:00
Jose Olarte III
9f44a53047 feat(notifications): mint long-lived JWT for native New Activity prefetch (Phase A)
Add BACKGROUND_JWT_EXPIRY_DAYS/SECONDS and accessTokenForBackgroundNotifications
via createEndorserJwtForDid; configureNativeFetcher uses it instead of getHeaders
so WorkManager prefetch is not stuck with a 60s access token. Interactive API
calls unchanged.
2026-03-27 21:33:46 +08:00
Jose Olarte III
c9ea2e4120 docs: plan background JWT pool/expiry and plugin configureNativeFetcher handoff
Add plan-background-jwt-pool-and-expiry.md (Phase A/B, expiryDays + buffer sizing,
pool size 100). Add plugin-feedback-daily-notification-configureNativeFetcher-jwt-pool.md
for daily-notification-plugin: optional jwtTokens on configureNativeFetcher. Link plan
to plugin doc and endorser-jwt-background-prefetch-options.md.
2026-03-27 14:57:54 +08:00
Jose Olarte III
43c9b95c14 docs: add Endorser JWT options for background New Activity prefetch
Document expired-token causes, client limits, and server-side options (TTL,
scoped tokens, refresh, BFF) plus questions for Endorser maintainers.
2026-03-26 18:16:54 +08:00
Jose Olarte III
f4ee507918 fix(notifications): refresh native fetcher on resume and log API error bodies
Call configureNativeFetcherIfReady when the app becomes active so getHeaders can
supply a new JWT before the next background prefetch when users return from
background.

In TimeSafariNativeFetcher, read HttpURLConnection#getErrorStream for non-200
responses and log a capped body snippet (including on retryable errors) to
diagnose JWT_VERIFY_FAILED and other API failures.
2026-03-26 18:16:08 +08:00
Jose Olarte III
0ebad3b497 fix(android): skip sync on cap run after restore-local-plugins
`npx cap run android` runs `sync` by default, which regenerated
`capacitor.plugins.json` and removed SafeArea and SharedImage entries
after `restore-local-plugins.js` had already run. Use `--no-sync` in
`build-android.sh` (auto-run) and `auto-run.sh` so the launch step does
not overwrite the restored plugin list.
2026-03-26 15:50:35 +08:00
Jose Olarte III
aaee3bbbd2 Add plugin feedback doc for Android dual schedule native fetch and timing
Document how the daily-notification-plugin dual path uses FetchWorker mock/URL
fetch instead of NativeNotificationContentFetcher, schedules fetch immediately
rather than at contentFetch cron, and why DualScheduleHelper shows useCache=false.
Includes acceptance criteria and file pointers for maintainers fixing the plugin.
2026-03-24 22:05:30 +08:00
Jose Olarte III
d4cdee0698 Add verbose INFO logging to TimeSafariNativeFetcher for dual-notification debugging
Log configure-time starred plan count, fetchContent entry (trigger, scheduledTime,
thread), worker start, POST summary (plan count, truncated afterId), and HTTP
status at INFO so logcat shows clearly when the native fetcher runs versus
plugin-only DNP-FETCH paths.
2026-03-24 21:19:39 +08:00
Jose Olarte III
178dcec5b8 docs: expand New Activity testing (starred plans, Endorser URL)
Add an Android-focused procedure for verifying API-driven copy when a
starred plan has updates via plansLastUpdatedBetween, including expected
notification text, prefetch timing, repeatability, and logcat. Clarify
that iOS parity is documented separately and that the native fetcher uses
Account API Server URL (test Endorser is valid), not the Partner API URL.
2026-03-23 18:56:10 +08:00