# Changelog

All notable changes to the Daily Notification Plugin will be documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [4.0.1] - 2026-06-09

### Fixed

- **iOS**: Daily Reminders now use `daily_<reminderId>` UNNotificationCenter identifiers instead of sharing `api_<epochMillis>` with batch API notifications. `clearApiNotifications` no longer removes new daily reminders.
- **iOS**: Legacy `api_*` daily-reminder pending requests are cancelled on schedule/cancel/update; `getScheduledReminders` matches both `daily_*` and transitional legacy ids.

### Changed

- **TypeScript**: JSDoc documents separate iOS identifier families (`daily_*` vs `api_*`).

## [4.0.0] - 2026-06-09

### Changed

- **Breaking**: Public batch APIs renamed to `scheduleApiNotifications` and `clearApiNotifications`, replacing `scheduleNotifications`, `clearPredictiveNotifications`, and iOS `clearAllNotifications`. Scheduling behavior and `api_*` identifiers are unchanged.
- **TypeScript**: JSDoc updated for API terminology and `api_*` identifiers.

## [3.0.4] - 2026-06-09

### Added

- **Android**: `scheduleNotifications` batch API schedules one-shot notifications at epoch-ms timestamps using deterministic `api_<epochMillis>` schedule IDs.
- **Android**: `clearPredictiveNotifications` cancels only API-managed schedules (`api_*`) without affecting Daily Reminders, user schedules, dual schedules, or fetch jobs.

### Changed

- **Android / iOS**: Internal batch notification ID namespace renamed from `predictive_<epochMillis>` to `api_<epochMillis>`. Public Capacitor method names are unchanged; scheduling and lifecycle behavior are unchanged.
- **TypeScript**: JSDoc for `scheduleNotifications` and `clearPredictiveNotifications` updated to document `api_*` identifiers.

## [3.0.3] - 2026-05-22

### Added

- **iOS**: `getDeliveredNotifications` and `getNotificationSettings` diagnostics APIs for debug panels (bridge-safe, local notification state only).
- **iOS**: `getPendingNotifications` now includes `triggerTimestamp` and `triggerDateIso`; always resolves with serializable values.
- **TypeScript**: `PendingNotificationsResult`, `DeliveredNotificationsResult`, `NotificationCenterSettingsSnapshot`, and related definitions/web stubs.

## [3.0.2] - 2026-05-05

### Changed

- **iOS**: API notification identifiers use epoch **milliseconds** (`api_<timestamp>`). Daily reminders persist `predictiveEpochMillis` for cancel/update alignment.
- **iOS**: `clearApiNotifications` removes only **`api_*`** pending and delivered notifications (dual/org IDs unchanged).
- **iOS**: `scheduleApiNotifications` is additive only (no automatic clear); skips stale timestamps in the past.

### Added

- **iOS**: `clearApiNotifications` and `scheduleApiNotifications` batch APIs on `DailyNotification` (Capacitor).

## [3.0.1] - 2026-04-16

### Fixed

- **Android**: Dual native prefetch with an empty `NotificationContent` list no longer maps to placeholder title/body or arms the chained notify alarm for that cycle. The cache stores `skipNotification`, `DualScheduleHelper` skips display for fresh payloads (and for stale cache when `relationship.fallbackBehavior` is `skip`), and `DualScheduleFetchRecovery` still schedules the next prefetch.

### Added

- **Android**: Unit tests (`DualScheduleHelperTest`) for dual empty-cache resolution and skip payload detection.

## [3.0.0] - 2026-04-02

### Added

- **iOS**: `NativeNotificationContentFetcher` SPI, `FetchContext`, `NativeNotificationFetcherRegistry`, and `DailyNotificationPlugin.registerNativeFetcher(_:)` for host-provided fetch (parity with Android `setNativeFetcher`).
- **iOS**: `updateStarredPlans` / `getStarredPlans` plugin methods; starred IDs stored under UserDefaults key `daily_notification_timesafari.starredPlanIds` (JSON array string).
- **Android**: `DualScheduleNotifyScheduler` and `DUAL_NOTIFY_SCHEDULE_ID_KEY` to arm the dual user notification **after** prefetch completes.
- **Docs**: `doc/CONSUMING_APP_HANDOFF_IOS_NATIVE_FETCHER_AND_CHAINED_DUAL.md` for consuming apps.

### Changed

- **iOS**: `configureNativeFetcher` requires a registered native fetcher (matches Android); calls `configure` on the fetcher; background fetch prefers registered fetcher with timeout, then legacy in-plugin HTTP when no fetcher + config exists.
- **iOS**: Dual (`scheduleDualNotification`) uses **chained** scheduling: prefetch BG task only, then one-shot user notification after fetch (`armChainedDualNotificationAfterPrefetch`), with max slip before fallback copy.
- **iOS**: `NotificationContent` is `public` for host fetcher implementations.
- **Android**: Dual notify exact alarm is no longer scheduled in `ScheduleHelper.scheduleDualNotification`; it is scheduled when `FetchWorker` completes (`max(nextNotifyAt, now)`), with recovery enqueue unchanged.

### Breaking

- **iOS**: `configureNativeFetcher` rejects if `registerNativeFetcher` was not called first.

## [2.1.5] - 2026-03-25

### Changed

- **Android**: Dual (`scheduleDualNotification`) content prefetch uses **WorkManager** with **`initialDelay`** to the next `contentFetch.schedule` occurrence (not an immediate fetch at setup). After each successful dual fetch, the next prefetch is re-enqueued from persisted dual config.
- **Android**: Dual prefetch with no `contentFetch.url` invokes the registered **`NativeNotificationContentFetcher`** when present (same SPI as `DailyNotificationFetchWorker`); otherwise mock JSON is used for development.
- **Android**: `content_cache` rows include **`cacheScope`** (`dual` | `daily` | `legacy`). Dual notify resolution reads only **`dual`**; daily reminder fetches write **`daily`**, avoiding cross-feature overwrites. Database version **4** with migration from v3.

### Documentation

- **Android**: `doc/platform/android/ANDROID_DUAL_SCHEDULE_NATIVE_FETCH_AND_CACHE_SCOPE.md` (implementation plan; see repo for details).

## [2.1.4] - 2026-03-20

### Fixed

- **Android**: `scheduleDualNotification` / `parseContentFetchConfig` no longer requires `timeout`, `retryAttempts`, and `retryDelay` in `contentFetch` (optional fields per TypeScript). Omitted values defer to `FetchWorker` defaults.
- **Android**: `parseUserNotificationConfig` no longer uses strict `getBoolean` / `getString` for optional `userNotification` fields (`title`, `body`, `sound`, `vibration`, `priority`). Omitted keys no longer throw `JSONException`; native scheduling applies existing defaults (`NotifyReceiver` / `DualScheduleHelper`).

### Documentation

- **README**: Notes for omitted `contentFetch` and optional `userNotification` fields on Android.

## [1.1.6] - 2026-02-16

### Fixed

- **Android**: Alarm set after edit/reschedule now fires. Removed `existingPendingIntent.cancel()` in the "cancel existing alarm before rescheduling" path so the PendingIntent passed to `setAlarmClock` is not cancelled (only `alarmManager.cancel()` is used), fixing no-fire on some devices.

## [1.1.5] - 2026-02-16

### Fixed

- **Android**: Rollover work using a `daily_rollover_*` schedule id no longer overwrites the app's schedule row in the DB. `NotifyReceiver` post-schedule update skips the "first enabled notify" fallback when `stableScheduleId` starts with `daily_rollover_`, so the app's reminder (e.g. `daily_timesafari_reminder`) keeps the correct `nextRunAt` after a notification fires.

### Added

- **Docs**: `doc/platform/android/CONSUMING_APP_ANDROID_NOTES.md` — notes for consuming apps on debouncing double `scheduleDailyNotification` calls and debugging alarms that are scheduled but do not fire (logcat with `DailyNotificationReceiver`).

## [1.1.4] - 2026-02-16

### Fixed

- **Android**: Re-setting a daily notification (edit/save same time) no longer cancels the alarm and then skips re-scheduling. DB idempotence in `NotifyReceiver.scheduleExactNotification()` now runs only when `!skipPendingIntentIdempotence`, so the app reset flow can re-register the alarm.
- **Android**: Static reminder title/body no longer revert to fallback after the first fire. `DailyNotificationWorker.scheduleNextNotification()` now preserves `is_static_reminder` and stable `scheduleId` on rollover so the next occurrence keeps custom text.

### Added

- **Android**: `cancelDailyReminder(call)` in `DailyNotificationPlugin.kt` for parity with iOS. Accepts `reminderId` (or `id`, `reminder_id`, `scheduleId`), cancels the AlarmManager alarm for that id, and performs best-effort DB cleanup (`setEnabled` false, `updateRunTimes` null).

## [1.1.3] - 2026-02-13

### Fixed

- **Android (Java)**: Java call sites for `NotifyReceiver.scheduleExactNotification()` now pass the 8th parameter `skipPendingIntentIdempotence`, fixing "actual and formal argument lists differ in length" when building consuming apps. Updated `DailyNotificationReceiver.java` and `DailyNotificationWorker.java`.

## [1.1.2] - 2026-02-13

### Fixed

- **Android**: Second daily notification not firing after reschedule. After cancel-then-schedule, the idempotence check could still see the cancelled PendingIntent in Android's cache and skip the new schedule. The cancel-then-schedule path now skips PendingIntent-based idempotence so the new alarm is always registered.

## [1.1.1] - 2026-02-05

### Fixed

- **Android**: Target alarm broadcast to app package so receiver is triggered correctly

### Documentation

- EMULATOR_GUIDE: prerequisites, API 35, Apple Silicon; build.sh Android-only sync

## [2.1.0] - 2025-01-02

### Added

- **Static Daily Reminders**: New functionality for simple daily notifications without network content
- **Cross-Platform Reminder API**: Consistent reminder management across Android, iOS, and Web
- **Reminder Management**: Full CRUD operations for reminder scheduling and management
- **Offline Reminder Support**: Reminders work completely offline without content caching
- **Rich Reminder Customization**: Support for custom titles, bodies, sounds, vibration, and priorities
- **Persistent Reminder Storage**: Reminders survive app restarts and device reboots

### New Methods

- `scheduleDailyReminder(options)`: Schedule a simple daily reminder
- `cancelDailyReminder(reminderId)`: Cancel a specific reminder
- `getScheduledReminders()`: Get all scheduled reminders
- `updateDailyReminder(reminderId, options)`: Update an existing reminder

### Features

- **No Network Dependency**: Static reminders work completely offline
- **Simple Time Format**: Easy HH:mm time format (e.g., "09:00")
- **Priority Levels**: Support for low, normal, and high priority notifications
- **Repeat Options**: Configurable daily repetition
- **Platform Integration**: Native notification channels and categories
- **Test App Integration**: Complete test app support for reminder functionality

### Documentation

- Updated README.md with static reminder examples and API reference
- Added comprehensive usage examples in USAGE.md
- Created detailed example file: `examples/static-daily-reminders.ts`
- Enhanced test apps with reminder management UI

## [1.0.0] - 2024-03-20

### Added

- Initial release of the Daily Notification Plugin
- Basic notification scheduling functionality
- Support for multiple notification schedules
- Timezone-aware scheduling
- Offline support with content caching
- Retry logic with exponential backoff
- Custom notification content handlers
- Event-based notification handling
- Comprehensive settings management
- TypeScript support with full type definitions

### Features

- Schedule daily notifications at specific times
- Support for multiple notification schedules
- Timezone-aware scheduling
- Offline support with content caching
- Retry logic with exponential backoff
- Custom notification content handlers
- Event-based notification handling
- Comprehensive settings management

### Security

- HTTPS-only network requests
- Content validation before display
- Secure storage of sensitive data
- Permission-based access control
- No sensitive data in logs

### Documentation

- Comprehensive API documentation
- Usage examples for basic and advanced scenarios
- Enterprise-level implementation examples
- Security best practices
- Platform-specific implementation details

### Testing

- Unit tests for core functionality
- Integration tests for platform features
- Advanced scenario tests
- Enterprise feature tests
- Security validation tests

## [0.9.0] - 2024-03-15

### Added

- Beta release with core functionality
- Basic notification scheduling
- Simple content handling
- Basic event system

### Changed

- Improved error handling
- Enhanced type definitions
- Better documentation

### Fixed

- Initial bug fixes and improvements
- TypeScript type issues
- Documentation clarity

## [0.8.0] - 2024-03-10

### Added

- Alpha release with basic features
- Initial plugin structure
- Basic TypeScript interfaces
- Simple notification scheduling

### Changed

- Early development improvements
- Initial documentation
- Basic test setup

### Fixed

- Early bug fixes
- Initial type issues
- Basic documentation

## [Unreleased]

### Added

- Enterprise features
  - Notification queue system
  - A/B testing support
  - Advanced analytics tracking
  - User preferences management
  - Content personalization
  - Rate limiting
- Additional test scenarios
- More example implementations
- Enhanced documentation

### Changed

- Improved error handling
- Enhanced type definitions
- Better documentation structure
- More comprehensive examples

### Fixed

- TypeScript type issues
- Documentation clarity
- Test coverage gaps
- Example code improvements

### Security

- Enhanced security measures
- Additional validation
- Improved error handling
- Better logging practices

### Documentation

- Added enterprise usage examples
- Enhanced API documentation
- Improved security guidelines
- Better troubleshooting guides

### Testing

- Added enterprise scenario tests
- Enhanced test coverage
- Improved test organization
- Better test documentation
