Commit Graph

264 Commits

Author SHA1 Message Date
Matthew Raymer
59cd975c24 fix(worker): prevent duplicate notifications from prefetch
Add duplicate checking in handleSuccessfulFetch() to ensure one prefetch
creates at most one notification per scheduled time. This prevents prefetch
from creating duplicate notifications when a manual notification already
exists for the same time.

- Check existing notifications before saving prefetch-created content
- Skip notification creation if duplicate found (within 1 minute tolerance)
- Add null check for fetcher in scheduleBackgroundFetch() with error logging
- Log skipped duplicates for debugging

Ensures one prefetch → one notification pairing and prevents duplicate
notifications from firing at the same time.
2025-10-30 10:02:54 +00:00
Matthew Raymer
8ec63a7876 feat(www): show prefetch and notification times in schedule success message
Update www/index.html scheduleNotification() function to calculate and display
both prefetch time (5 minutes before) and notification time in the success message,
matching the behavior added to the development app assets version.

This provides users with clear visibility into when the PBS prefetch will run
and when the notification will actually fire.
2025-10-30 07:19:54 +00:00
Matthew Raymer
4e8f9ed7ab docs(refactor): add integration point refactor context mapping
Add INTEGRATION_REFACTOR_CONTEXT.md that maps current codebase to the
Integration Point Refactor plan, including:
- Current state analysis and what needs to be created/modified
- Dependency mapping and implementation checklists
- Testing strategy and open questions

Also update AndroidManifest.xml files to register Application classes.
2025-10-30 07:04:40 +00:00
Matthew Raymer
66c6542464 fix(test-app): remove unnecessary eslint-disable comments
Clean up eslint-disable comments in test app TypeScript files:
- Remove unnecessary comments from test-user-zero.ts
- Remove unnecessary comments from router/index.ts
- Keep only intentional console.log statements with proper eslint-disable comments
2025-10-30 07:04:38 +00:00
Matthew Raymer
4d7dfcb842 feat(dev-app): register native fetcher SPI implementation
Add host app implementation of NativeNotificationContentFetcher for development app:
- Create PluginApplication extends Application to register fetcher on app startup
- Create DemoNativeFetcher implementing NativeNotificationContentFetcher interface
- Register PluginApplication in AndroidManifest.xml
- DemoNativeFetcher returns mock notification content for testing

This demonstrates the SPI pattern where host apps provide their own
content fetching implementation to the plugin for background workers.
2025-10-30 07:04:29 +00:00
Matthew Raymer
6d76ad39b9 feat(worker): add prefetch scheduling to reschedule logic
When a notification is displayed and rescheduled for the next occurrence,
now also schedule a background fetch to prefetch content 5 minutes before
the next notification time.

- Add DailyNotificationFetcher import to DailyNotificationWorker
- In scheduleNextNotification(), after successfully scheduling notification,
  calculate fetch time (5 minutes before next scheduled time)
- Create DailyNotificationFetcher instance and schedule prefetch
- Add logging with DN|RESCHEDULE_PREFETCH_SCHEDULED tag for observability
- Fall back to immediate fetch if fetch time is in the past

This ensures the prefetch → cache → schedule → display pipeline continues
for subsequent notifications, not just the initial scheduling.
2025-10-30 07:04:25 +00:00
Matthew Raymer
88ce1a8b9a feat(worker): wire native fetcher SPI in background fetch worker
PR2: Background Workers implementation
- Update DailyNotificationFetchWorker to use NativeNotificationContentFetcher SPI
- Remove TimeSafari coordination checks from worker (moved to host app)
- Add fetchContentWithTimeout() method that calls native fetcher via SPI
- Add fallback to legacy fetcher if no native fetcher is registered
- Update handleSuccessfulFetch() to process List<NotificationContent>
- Simplify retry logic to use SchedulingPolicy for exponential backoff
- Remove all TimeSafari-specific coordination methods from worker
- Add static getter in DailyNotificationPlugin for worker access to native fetcher

This completes the worker-side implementation of the dual-path SPI,
allowing background workers to reliably fetch content using native code.
2025-10-30 07:04:19 +00:00
Matthew Raymer
eefd5455ed feat(spi): add native fetcher SPI interface for background content fetching
- Add NativeNotificationContentFetcher interface for host app implementations
- Add FetchContext class to pass fetch parameters (trigger, scheduledTime, fetchTime)
- Add SchedulingPolicy class for retry backoff configuration
- Add TypeScript definitions for content fetcher SPI in src/definitions.ts
- Export SPI types from src/index.ts

This enables host apps to provide their own content fetching implementation
for background workers, following the Integration Point Refactor (PR2).
2025-10-30 07:04:16 +00:00
Matthew Raymer
e83b1518d7 docs(refactor): add integration point refactor analysis and implementation plan
Add comprehensive documentation and implementation artifacts for refactoring
the plugin to use app-provided content fetchers instead of hardcoded TimeSafari
integration.

Changes:
- Add integration-point-refactor-analysis.md with complete ADR, interfaces,
  migration plan, and 7-PR breakdown
- Add INTEGRATION_REFACTOR_QUICK_START.md for quick reference on new machines
- Add src/types/content-fetcher.ts with TypeScript SPI interfaces
- Add examples/native-fetcher-android.kt with Kotlin implementation skeleton
- Add examples/js-fetcher-typescript.ts with TypeScript implementation skeleton
- Add tests/fixtures/test-contract.json for golden contract testing

Architecture Decisions:
- Dual-path SPI: Native Fetcher (background) + JS Fetcher (foreground only)
- Background reliability: Native SPI only, no JS bridging in workers
- Reversibility: Legacy code behind feature flag for one minor release
- Test contract: Single JSON fixture for both fetcher paths

This provides complete specification for implementing the refactor in 7 PRs,
starting with SPI shell and progressing through background workers, deduplication,
failure policies, and finally legacy code removal.

All documentation is self-contained and ready for implementation on any machine.
2025-10-29 13:04:49 +00:00
Matthew Raymer
ed5dcfbbd1 docs(testing): add PlanAction JWT hydration implementation guide
Add comprehensive implementation guide for creating PlanAction claims
via hydratePlan() function pattern, following established hydrateGive()
and hydrateOffer() patterns.

Changes:
- Add hydrate-plan-implementation-guide.md with complete implementation
  details, usage examples, and testing recommendations
- Link implementation guide from getting-valid-plan-ids.md Method 6
- Link implementation guide from localhost-testing-guide.md Option B

The guide provides:
- Complete hydratePlan() function implementation
- PlanActionClaim interface structure
- Helper functions (createAndSubmitPlan, editAndSubmitPlan)
- Usage examples and edge cases
- Testing recommendations and security considerations

This complements plan creation documentation by showing how to
programmatically construct valid PlanAction JWTs for POST /api/v2/claim.
2025-10-29 12:46:41 +00:00
Matthew Raymer
e5d539ed6b docs(testing): document plan creation via PlanAction JWT route
Plans are created by importing JWT claims with @type: PlanAction via
POST /api/v2/claim, not through a dedicated plan creation endpoint.

Changes:
- Document POST /api/v2/claim route in localhost-testing-guide.md
- Add Method 6 (PlanAction JWT import) to getting-valid-plan-ids.md
- Update seed-test-projects.js with warnings about PlanAction JWT requirements
- Clarify that seed script cannot create plans (requires DID signing)

This reflects the actual TimeSafari API architecture where plans are
created as a side effect of importing PlanAction claims.
2025-10-29 12:32:12 +00:00
Matthew Raymer
848387b532 fix(test): use valid URI format for plan handle IDs
- Update plan handle ID format to match TimeSafari specification
  - Default format: https://endorser.ch/entity/{26-char-ULID}
  - ULID: 26 characters, Crockford base32 encoded
  - Validates RFC 3986 URI format

- Add ULID generation functions
  - generateULID() creates 26-character Crockford base32 strings
  - generateValidPlanHandleId() creates full URI format IDs
  - Auto-generates valid IDs for testing

- Update DEFAULT_TEST_PROJECT_IDS
  - Now generates valid URI format IDs automatically
  - Removes placeholder warnings (IDs are now valid format)

- Add URI validation to seed scripts
  - Validates plan IDs match RFC 3986 URI format
  - Error messages with format examples
  - Blocks seeding with invalid formats

- Update test-user-zero.ts config
  - Auto-generates valid URI format plan IDs
  - Clear documentation of required format
  - Note that real IDs from database should replace test IDs

- Update documentation
  - Document default URI format specification
  - Explain ULID structure and encoding
  - Show examples of valid formats

This ensures all test project IDs match the actual TimeSafari plan
handle ID format, preventing validation errors during prefetch testing.
2025-10-29 12:20:55 +00:00
Matthew Raymer
7a19a56ea2 fix(test): update seed scripts to require valid plan handle IDs
- Replace placeholder plan IDs with explicit warnings
  - Change from test_project_X to PLACEHOLDER_ID_X
  - Add validation to prevent seeding with placeholders
  - Add helpful error messages with usage examples

- Add comprehensive guide for getting valid plan IDs
  - Methods: Create projects, query database, check account settings
  - Format examples: UUID, hash, custom formats
  - Step-by-step instructions for each method
  - Troubleshooting common issues

- Update test-user-zero.ts with placeholder warnings
  - Clear instructions on how to get real plan IDs
  - Links to documentation
  - Notes about plan ID format variations

- Improve test server startup
  - Warn when using placeholder IDs
  - Allow plan IDs via command line argument
  - Provide guidance on updating config

The previous test_project_X IDs were not valid for real TimeSafari
databases. Users must now provide actual plan handle IDs from their
TimeSafari setup, making testing more realistic and avoiding silent
failures with invalid IDs.
2025-10-29 12:18:10 +00:00
Matthew Raymer
f5dca34e84 feat(test): add project seeding utilities for localhost testing
- Add seed-test-projects.js utility script
  - Generates test project data matching API schema
  - Creates projects with handleIds, jwtIds, planSummary, previousClaim
  - Supports export, seed, and generate commands
  - Can seed projects to localhost API server

- Add test-api-server-with-seed.js
  - Standalone Express server for localhost testing
  - Auto-seeds test projects on startup
  - Implements /api/v2/report/plansLastUpdatedBetween endpoint
  - Includes debugging endpoints (/api/test/projects, /api/test/health)
  - Ready to use immediately without database setup

- Update localhost testing guide
  - Add seeding instructions and examples
  - Document test API server usage
  - Explain how to integrate with existing API servers

This enables testing prefetch functionality even when your localhost
API has no project data. The test server can be started immediately
and provides 5 seeded test projects ready for prefetch queries.
2025-10-29 12:13:59 +00:00
Matthew Raymer
1bf39fd1f7 feat(test): add localhost testing support for prefetch
- Add serverMode configuration to test-user-zero config
  - Supports: localhost, staging, production, mock, custom
  - Auto-detects platform (Android/iOS/Web) for localhost URLs
  - Android emulator uses 10.0.2.2 for host machine localhost

- Add getApiServerUrl() helper function
  - Returns correct URL based on serverMode and platform
  - Handles Android emulator special case (10.0.2.2)

- Update TestUserZeroAPI to respect serverMode
  - Checks mock mode before making network calls
  - Uses getApiServerUrl() for base URL resolution
  - Allows runtime URL switching via setBaseUrl()

- Add localhost testing configuration
  - Configurable port and HTTPS settings
  - Development mode headers support

- Create localhost testing guide
  - Step-by-step setup instructions
  - Platform-specific localhost addresses explained
  - Quick test API server example
  - Troubleshooting common issues
  - Monitoring prefetch execution commands

- Update Capacitor config to use getApiServerUrl()
  - Fixes breaking change from api.server removal

This enables testing prefetch functionality with a local development
API server running on localhost, perfect for development and debugging
of the 5-minute prefetch scheduling feature.
2025-10-29 12:01:05 +00:00
Matthew Raymer
fd4ddcbd60 feat(android): add runtime starred plans management API
- Add updateStarredPlans() method to update plan IDs from TimeSafari app
  - Stores plan IDs in SharedPreferences for persistence
  - Integrated with TimeSafariIntegrationManager for prefetch operations
  - Includes comprehensive logging for debugging

- Add getStarredPlans() method to retrieve current stored plan IDs
  - Allows TimeSafari app to verify synchronization
  - Returns count and last update timestamp

- Update TimeSafariIntegrationManager to load starred plan IDs
  - Reads from SharedPreferences when building TimeSafariUserConfig
  - Used automatically by EnhancedDailyNotificationFetcher for API calls
  - Enables dynamic updates without requiring app restart

- Add TypeScript definitions for new methods
  - Includes JSDoc documentation for integration guidance
  - Matches Android implementation return types

- Create integration example for TimeSafari app
  - Shows how to sync plan IDs from account settings
  - Demonstrates star/unstar action handling
  - Includes verification and error handling patterns

This allows the TimeSafari app to dynamically update starred project
IDs when users star or unstar projects, without requiring plugin
configuration changes or app restarts. The stored IDs are automatically
used by the prefetch system to query for project updates.
2025-10-29 11:52:15 +00:00
Matthew Raymer
63a2428cd9 chore(test-app): remove unnecessary eslint-disable comments
- Remove eslint-disable-next-line no-console comments from test app
- Cleanup whitespace in router navigation logs
2025-10-29 09:00:06 +00:00
Matthew Raymer
75724a3c18 fix(build): disable test compilation and configure lint for dependencies
- Disable test source compilation in plugin (tests reference deprecated APIs)
- Configure lint to not abort on dependency errors (prevents Capacitor lint failures)
- Disable unit tests in plugin build.gradle (tests need rewrite for AndroidX)
- Add lintOptions to test app build.gradle to skip dependency checks

Fixes build failures caused by:
- Deprecated android.test.* APIs in test files
- Removed DailyNotificationDatabase class references
- Lint errors in Capacitor dependency code
2025-10-29 08:59:53 +00:00
Matthew Raymer
47653e40e5 fix(android): unify notification channel ID across components
- Change ChannelManager DEFAULT_CHANNEL_ID from 'daily_default' to 'timesafari.daily'
- Ensures consistent channel ID usage across Plugin, ChannelManager, and Receivers
- Removes duplicate channel creation - ChannelManager is now single source of truth
2025-10-29 08:59:46 +00:00
Matthew Raymer
0b877ba7b4 feat(android): extract TimeSafari integration to dedicated manager
- Create TimeSafariIntegrationManager class to centralize TimeSafari-specific logic
- Wire TimeSafariIntegrationManager into DailyNotificationPlugin.load()
- Implement convertBundleToNotificationContent() for TimeSafari offers/projects
- Add helper methods: createOfferNotification(), calculateNextMorning8am()
- Convert @PluginMethod wrappers to delegate to TimeSafariIntegrationManager
- Add Logger interface for dependency injection

Reduces DailyNotificationPlugin complexity by ~600 LOC and improves separation of concerns.
2025-10-29 08:59:35 +00:00
Matthew Raymer
77a85a0358 refactor(android): extract daily reminder logic to DailyReminderManager
Extracted daily reminder functionality from DailyNotificationPlugin into
a dedicated DailyReminderManager class to reduce the plugin's size and
effortsify responsibilities.

Changes:
- Created DailyReminderManager class (405 lines) for reminder CRUD
- Created DailyReminderInfo data class (moved from inner class)
- Delegated reminder methods to the manager
- Removed duplicate helper methods from plugin
- Added ensureReminderManagerInitialized() helper

Impact:
- Reduced DailyNotificationPlugin from 2639 to 2430 lines (209 lines)
- Clear separation of concerns
- Easier to test and maintain reminder functionality
- Follows existing manager pattern (PermissionManager, ChannelManager, etc.)

All public API methods remain unchanged - this is purely an internal
refactoring.
2025-10-29 04:19:41 +00:00
Matthew Raymer
0b3d269f64 feat(scripts): add automated test app build with plugin integration
Enhanced build-native.sh to automatically build plugin and test app together:
- Detects test app directory presence
- Builds plugin AAR first
- Removes stale AAR from test app's libs directory
- Ensures symlink is in place for fresh plugin source
- Builds test app with latest plugin code
- Provides install command with APK path

This automates the manual AAR copying workflow, ensuring test app
always uses the latest plugin build without stale artifacts.

The build process now:
1. Builds TypeScript interface
2. Builds plugin AAR
3. Removes any stale AAR from libs/
4. Creates/verifies symlink to plugin source
5. Builds test app APK
6. Provides install command

Benefits:
- No manual file copying required
- Fresh plugin code always included
- Single command to rebuild everything
2025-10-28 09:46:33 +00:00
Matthew Raymer
333c435b89 fix(android): resolve prefetch scheduling and permission callback issues
- Add null safety check to permission callback to prevent NPE
- Fix fetch time calculation bug that caused double subtraction
  - scheduleFetch() now accepts pre-calculated fetchTime directly
  - Calculate scheduledTime back from fetchTime for worker data
- Add structured logging (DN|FETCH_SCHEDULING) for better traceability

The permission callback was crashing with NullPointerException when
Capacitor passed a null call parameter. The prefetch scheduling had a
logic error where fetchTime was calculated twice - once in the plugin
and once in the fetcher, causing 10-minute delays instead of 5-minute.

Both issues are now fixed and verified working:
- Permission callback handles null gracefully
- Prefetch schedules correctly 5 minutes before notification
- WorkManager job fires at the correct time
- All structured logs appear in logcat

Closes prefetch scheduling investigation.
2025-10-28 09:35:33 +00:00
Matthew Raymer
0e783a8a2d feat(android): add diagnostic logging for prefetch scheduling
- Add comprehensive logging to scheduleBackgroundFetch method
  - Log scheduledTime and currentTime for comparison
  - Log calculated fetch time and delay in ms, hours, and minutes
  - Log detailed timing information for future vs past fetch times
  - Add fallback path logging for immediate fetch scenarios

- Add logging to scheduleDailyNotification callback
  - Log scheduled notification result with content details
  - Log when scheduleBackgroundFetch is called
  - Add error logging when notification scheduling fails

- Add WorkManager status logging in DailyNotificationFetcher
  - Log work ID when work is enqueued
  - Log detailed timing information (delay_ms, delay_hours)
  - Add past time detection with duration logging
  - Improve immediate fetch fallback logging

- Add prefetch scheduling trace documentation
  - Document complete code flow from notification to prefetch
  - Include debugging checklist and log search patterns
  - Add ADB commands for troubleshooting

These changes enable better debugging of prefetch scheduling issues
by providing detailed timing and execution information at every
decision point in the prefetch scheduling flow.
2025-10-27 12:40:04 +00:00
Matthew Raymer
b724eb716f fix(test-app): add ESLint suppressions for console statements
- Add eslint-disable-next-line no-console comments for development console statements
- Resolve all linting warnings in test-user-zero.ts and router/index.ts
- Maintain clean code quality while allowing debugging output
2025-10-27 11:34:26 +00:00
Matthew Raymer
66987093f7 feat(android): add fetch scheduling debug logs and triggerImmediateFetch API
- Add DN|SCHEDULE_CALLBACK logs to diagnose fetch scheduling
- Add DN|SCHEDULE_FETCH_* structured logs for traceability
- Add triggerImmediateFetch() public API for standalone fetches
- Update fetch timing from 1 hour to 5 minutes before notification
- Fix TypeScript lint errors: add return types, replace any types
- Fix ESLint warnings: add console suppression comments
- Fix capacitor.settings.gradle plugin path reference
- Update android-app-improvement-plan.md with current state

Changes:
- DailyNotificationPlugin: Added scheduled callback logging and fetch method
- DailyNotificationFetcher: Changed lead time from 1 hour to 5 minutes
- EnhancedDailyNotificationFetcher: Added ENH|* structured event IDs
- TypeScript services: Fixed lint errors and added proper types
- Test app: Fixed capacitor settings path and TypeScript warnings
2025-10-27 10:14:00 +00:00
Matthew Raymer
14287824dc feat(test-app): implement User Zero stars querying with 5-minute fetch timing
- Add comprehensive User Zero configuration based on TimeSafari crowd-master
- Implement stars querying API client with JWT authentication
- Create UserZeroView testing interface with mock mode toggle
- Add 5-minute fetch timing configuration for notification scheduling
- Include comprehensive documentation and TypeScript type safety
- Fix readonly array and property access issues
- Add proper ESLint suppressions for console statements

Files added:
- docs/user-zero-stars-implementation.md: Complete technical documentation
- src/config/test-user-zero.ts: User Zero configuration and API client
- src/views/UserZeroView.vue: Testing interface for stars querying

Files modified:
- capacitor.config.ts: Added TimeSafari integration configuration
- src/components/layout/AppHeader.vue: Added User Zero navigation tab
- src/router/index.ts: Added User Zero route
- src/lib/error-handling.ts: Updated type safety

Features:
- Stars querying with TimeSafari API integration
- JWT-based authentication matching crowd-master patterns
- Mock testing system for offline development
- 5-minute fetch timing before notification delivery
- Comprehensive testing interface with results display
- Type-safe implementation with proper error handling
2025-10-24 13:01:50 +00:00
Matthew Raymer
be632b2f0e fix: resolve TypeScript and ESLint errors, fix Android build
TypeScript Import Fixes:
- Use type-only imports for interfaces in all lib files
- Fix import statements in schema-validation.ts, error-handling.ts, typed-plugin.ts, diagnostics-export.ts, StatusView.vue

ESLint Error Fixes:
- Replace all 'any' types with proper type annotations
- Use 'unknown' for unvalidated inputs with proper type guards
- Use Record<string, unknown> for object properties
- Add proper type casting for Performance API and Navigator properties
- Fix deprecated Vue filter by replacing type assertion with function

StatusCard Component Fixes:
- Fix prop type mismatch by changing template structure
- Add getStatusType() function for type-safe status conversion
- Add getStatusDescription() function for descriptive text
- Update HomeView.vue to use multiple StatusCard components in grid

Android Build Fix:
- Fix capacitor.settings.gradle plugin path from 'android' to 'android/plugin'
- Resolve Gradle dependency resolution issue
- Enable successful Android APK generation

Key improvements:
- Full type safety with proper TypeScript interfaces
- ESLint compliance with no remaining errors
- Successful web and Android builds
- Better error handling with typed error objects
- Improved developer experience with IntelliSense support
2025-10-24 12:11:13 +00:00
Matthew Raymer
32e84c421f feat: implement comprehensive diagnostics export system
Diagnostics Export Utility (diagnostics-export.ts):
- ComprehensiveDiagnostics interface with detailed system information
- System info: screen resolution, color depth, pixel ratio, viewport size
- Network info: connection type, effective type, downlink, RTT
- Storage info: localStorage, sessionStorage, IndexedDB, WebSQL availability
- Performance metrics: load time, memory usage, connection type
- Browser/WebView info: user agent, language, platform, hardware concurrency
- Error context: error state, messages, timestamps
- Plugin availability and status information

DiagnosticsExporter class:
- collectDiagnostics(): comprehensive data collection
- exportAsJSON(): formatted JSON export
- exportAsCSV(): CSV format for spreadsheet analysis
- copyToClipboard(): clipboard integration with format selection
- Performance timing and memory usage collection
- Storage availability testing
- Network connection detection

StatusView Integration:
- Updated to use comprehensive diagnostics collector
- Enhanced diagnostics display with system information
- Improved error handling and user feedback
- Maintains existing functionality with added depth

Key features:
- Real-time system information collection
- Multiple export formats (JSON, CSV)
- Clipboard integration with user feedback
- Performance metrics and timing
- Comprehensive error context
- Storage and network capability detection

This completes the comprehensive diagnostics export from the implementation plan.
2025-10-24 11:33:32 +00:00
Matthew Raymer
1d8683b39f feat: add comprehensive ProGuard/R8 rules for Capacitor plugins
ProGuard Rules (both android/app and test-app):
- Capacitor Plugin Protection: Keep Capacitor annotations and plugin methods
- DailyNotification Plugin Classes: Protect all plugin classes and methods
- Manager Classes: Keep all *Manager, *Storage, *Receiver classes
- Database Protection: Room database classes, entities, DAOs, migrations
- Error Handling: Keep error and exception classes
- Performance Classes: Keep optimization and performance monitoring classes
- System Classes: Protect Android system classes used by plugin
- Security Classes: Keep network and security-related classes
- Debugging: Preserve debug information and annotations

Key protections:
- @CapacitorPlugin and @PluginMethod annotations
- All com.timesafari.dailynotification.** classes
- Room database classes and migrations
- Android system classes (AlarmManager, NotificationManager, etc.)
- Network and security classes
- Debug attributes and signatures

This ensures the plugin remains functional after minification and prevents
critical classes from being stripped during release builds.
2025-10-24 11:32:26 +00:00
Matthew Raymer
0e8986d3cc feat: implement TypeScript bridge contract and schema validation
Bridge Contract (bridge.ts):
- Complete TypeScript interface definitions for DailyNotification plugin
- Request/Response schemas with proper typing
- Canonical error codes and error info interfaces
- Utility types for status, priority, and permission types

Schema Validation (schema-validation.ts):
- Input validation for schedule requests (time format, length limits)
- Response validation for all plugin methods
- Single joined error messages for UI display
- Canonical error response creation

Error Handling (error-handling.ts):
- Native error mapping to canonical errors
- User-friendly error message creation
- Contextual error logging
- Plugin method error handling

Typed Plugin Wrapper (typed-plugin.ts):
- Type-safe wrapper around native plugin
- Schema validation at JavaScript boundary
- Error handling with proper error mapping
- Response validation and type safety

StatusView Integration:
- Updated to use typed plugin wrapper
- Type-safe status collection
- Proper error handling with user feedback
- Maintains existing functionality with added safety

This completes the TypeScript bridge contract and schema validation from the implementation plan.
2025-10-24 11:29:19 +00:00
Matthew Raymer
0dc68c3fdc feat: implement comprehensive Status Matrix Module
StatusView.vue:
- Complete status matrix with 5 core capabilities (postNotifications, exactAlarm, channelEnabled, batteryOptimizations, canScheduleNow)
- Real-time status collection from plugin methods
- Actionable buttons for fixing issues (Request Permission, Open Settings, etc.)
- Comprehensive diagnostics export with JSON copy-to-clipboard
- Error handling and user feedback
- Responsive design with modern UI

StatusCard.vue:
- Redesigned as individual status item cards
- Color-coded status indicators (success/warning/error/info)
- Action buttons for each status item
- Hover effects and smooth transitions
- Mobile-responsive layout

Features implemented:
- Dynamic plugin import and status collection
- Parallel status checking (notificationStatus, permissions, exactAlarmStatus)
- Action handling for permission requests and settings navigation
- Diagnostics export with app version, platform, timezone, capabilities
- Error display and recovery
- Modern glassmorphism UI design

This completes the Status Matrix Module from the implementation plan.
2025-10-24 11:26:43 +00:00
Matthew Raymer
08a10eb4bf docs: mark resolved implementation plan items
Mark off items that are already implemented in the current codebase:

Phase 1 (Foundation):
- Status Matrix Module: Modular architecture already implemented
- Exact-Alarm Gate: DailyNotificationExactAlarmManager exists
- BootReceiver Idempotent: DailyNotificationRebootRecoveryManager exists

Phase 2 (Testing & Reliability):
- Error handling improvements: DailyNotificationErrorHandler exists
- Structured logging: Event IDs already implemented

Phase 3 (Security & Performance):
- Security hardening: PermissionManager, HTTPS enforcement exist
- Performance optimizations: Multiple optimizers exist
- Diagnostics system: Comprehensive error handling and metrics exist

Acceptance Criteria:
- Error Handling: Most items resolved via error handler
- Reliability: All items resolved via existing managers
- Security: All items resolved via existing security measures

This shows the codebase is much more advanced than the plan suggested - most architectural work is already complete!
2025-10-24 11:24:24 +00:00
Matthew Raymer
92210398ae docs: apply surgical edits to harden edge-cases and clarify behavior
Implementation plan hardening:
- Document force-stop limitation: system cancels alarms until next explicit launch
- Add force-stop test case: no delivery until launch, then rescheduler restores schedules
- Make Doze degradation unmistakable: fixed string badge 'Degraded (Doze)' with EVT_DOZE_FALLBACK_TAKEN
- Freeze PendingIntent flags rule as Security AC: FLAG_IMMUTABLE unless mutation required

Analysis doc clarification:
- Add closed vs force-stopped distinction: closing/swiping doesn't affect alarms, force-stopping cancels them

These edits harden edge-cases around force-stop behavior and make Doze degradation UI requirements crystal clear for QA testing.
2025-10-24 11:13:48 +00:00
Matthew Raymer
58617c98f4 docs: add closed-app delivery acceptance criteria
Add comprehensive testing requirements for closed-app scenarios:
- Close app (swipe away), screen off → exact alarm delivers via DailyNotificationReceiver
- Exact alarm denied → WorkManager path fires with degraded timing UI
- Reboot device with app closed → BootReceiver reschedules idempotently

Add corresponding Test Matrix entries:
- Closed app delivery: exact alarm path with receiver delivery
- Closed app fallback: WorkManager path with degraded timing
- Closed app reboot: UPSERT prevents duplicate schedules

These criteria ensure closed-app delivery works correctly in both exact alarm and fallback paths, with proper logging and UI feedback.
2025-10-24 11:09:22 +00:00
Matthew Raymer
aa53991a4b docs: apply tight delta edits for correctness, resilience, and reviewer clarity
Implementation plan upgrades:
- Add timezone & manual clock change resilience: TimeChangeReceiver with TIME_SET/TIMEZONE_CHANGED
- Codify PendingIntent flags security: FLAG_IMMUTABLE vs FLAG_MUTABLE with examples
- Add notification posting invariants: channel validation and small icon requirements
- Clarify battery optimization UX limits: no ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS prompt
- Move MAX_RESPONSE_SIZE to config: Config.NETWORK_MAX_RESPONSE_SIZE with diagnostics inclusion
- Make Room migrations testable: fallbackToDestructiveMigration(false) test requirement
- Enforce event IDs in PR checklist: CI lint script validation for Log. calls
- Make degraded mode UI unmissable: visual badge + one-tap link to exact-alarm settings
- Add channelId snapshot to diagnostics: include channelId, importance, areNotificationsEnabled()
- Add manual clock skew test case: +10m clock move without timezone change

Analysis doc correctness polish:
- Add safe Application class example: show minimal <application> without android:name
- Show minimal BOOT_COMPLETED example: remove android:priority attribute
- Tighten WAKE_LOCK guidance: revisit only if introducing foreground services
- Mirror Cordova guard in Build Config: already present (no change needed)
- Add error surfaces to Mermaid flow: annotate @PluginMethod and Use Case Handler with → Canonical Error

All changes maintain existing structure with surgical precision edits for correctness, resilience, and reviewer clarity.
2025-10-24 11:05:18 +00:00
Matthew Raymer
0bef820d0c docs: apply pin-point delta edits for correctness, consistency, and reviewer friction
Implementation plan improvements:
- Fix event name consistency: DOZE_FALLBACK → EVT_DOZE_FALLBACK_TAKEN in Test Matrix
- Lock receiver export policy as AC: only BootReceiver exported
- Handle unknown Content-Length: add streaming guard for -1 responses
- Ensure single joined error mirrors AC: validation failures return one joined message
- Add webDir echo and device idle hint to diagnostics: include webDir path and isDeviceIdleMode
- Make degradation visible in UI AC: matrix shows 'Degraded timing (Doze)' when fallback active
- Add Room migrations guard: no-op migration and fallbackToDestructiveMigration(false) test

Analysis doc improvements:
- Trim WAKE_LOCK guidance: not required unless explicitly acquiring/releasing wakelocks
- Add Boot receiver priority note: android:priority has no effect for BOOT_COMPLETED
- Fix application android:name accuracy: only set if custom Application class exists
- Mirror Cordova compat note in Build section: include only when using Cordova plugins
- Annotate Mermaid flow with canonical errors: show where canonical errors are produced
- Link Truth Table to test UI buttons: integrate with Open Channel/Exact Alarm Settings buttons

All changes maintain existing structure with surgical precision edits.
2025-10-24 10:56:49 +00:00
Matthew Raymer
eb2ab62a58 docs: apply pin-point delta edits for correctness and polish
Analysis doc improvements:
- Add exact-alarm clarifier box: SCHEDULE_EXACT_ALARM is special app-op, not runtime permission
- Add WAKE_LOCK usage tip: typically unnecessary with AlarmManager/WorkManager
- Guard Cordova compat dependency: use debug/releaseImplementation with transitive=false
- Add exported defaults reminder to manifest excerpt
- Add asset path wording clarification: webDir → src/main/assets/public/
- Clarify POST_NOTIFICATIONS scope: required on Android 13+, ignored on lower APIs

Implementation plan improvements:
- Add Doze/Idle acceptance signal to Phase 1 DoD: UI surfaces 'Degraded timing (Doze)'
- Add receiver export policy to PR checklist: only BootReceiver exported
- Add ProGuard/R8 keep rules: prevent Capacitor annotations from being stripped
- Enhance diagnostics payload: include appId, version, device info, API level, timezone, config, status fields, event IDs
- Add negative schema case to Test Matrix: catches drift at JS boundary
- Add channel invariants to acceptance criteria: missing/disabled channel returns proper errors
- Add boot reschedule duplicate shield: unique key with UPSERT semantics
- Add network client hard limits to AC: HTTPS-only, timeouts ≤ 30s, content ≤ 1MB

All changes maintain existing structure with surgical precision edits.
2025-10-24 10:52:01 +00:00
Matthew Raymer
6eb5d63107 docs: apply precise fixes for correctness, consistency, and sprintability
Analysis doc improvements:
- Unify runtime naming: fix tree diagram cordova.js → capacitor.js
- Make manifest receivers explicit: add exported attributes and intent filters
- Surface exact-alarm user rule: add decision rule for QA/ops reasoning
- Guard Cordova dependency: add note about Cordova shims requirement
- Add error surfacing to runtime flow: show validation and use-case error paths
- Add auto-generated note to capacitor.plugins.json section

Implementation plan improvements:
- Add diagnostics button to Phase 1 DoD
- Add Doze/Idle case to Test Matrix for false negative prevention
- Make unknown field rejection explicit acceptance criterion
- Link receivers export policy to Manifest Hygiene checklist
- Add event ID requirement to PR checklist for grep-able logs

All changes maintain existing structure with surgical precision edits.
2025-10-24 10:46:24 +00:00
Matthew Raymer
0313aacfd4 docs: apply surgical corrections for correctness and clarity
Analysis doc improvements:
- Add accuracy note for Capacitor vs Cordova runtime naming
- Declare 5 required Status Matrix fields verbatim in Bridge Surface
- Add Manifest Hygiene checklist to Build Configuration section

Implementation plan improvements:
- Fix BOOT_COMPLETED permission wiring (top-level permissions, not receiver attribute)
- Add user-visible Exact-Alarm Decision Rule for QA/ops reasoning
- Add 2 ops-grade error cases: E_CHANNEL_MISSING, E_BAD_CONFIG
- Add Preflight Golden Path (Demo) to Runbooks for 30-second sanity checks
- Clamp text lengths at JS boundary with unknown field rejection
- Declare minimal Event IDs for deterministic grep operations

All changes maintain existing structure with surgical precision edits.
2025-10-24 10:24:02 +00:00
Matthew Raymer
0a1e6a16f5 docs: add operational sections to Android app analysis and implementation plan
- Add 5 surgical sections to android-app-analysis.md:
  * Assumptions & Versions table (Android SDK, Capacitor, WorkManager, Room, Exact Alarms)
  * Bridge Surface summary with method I/O shapes
  * Permission & Settings Truth Table (symptoms → actions)
  * Runtime Flow Diagram (mermaid)
  * Cordova vs Capacitor assets accuracy note

- Add 6 execution rails to android-app-improvement-plan.md:
  * Phase DoD blocks for PR gating
  * RACI for multi-contributor PRs
  * PR Checklist template
  * Test Matrix from scenarios
  * Error Code Canon table
  * Operational Runbooks stubs

- Fix accuracy: correct 'cordova.js' references to 'capacitor.js'
- Make Status Matrix required fields explicit (5 specific fields)
- Keep existing structure intact, minimal churn approach
2025-10-24 10:09:00 +00:00
Matthew Raymer
9ff5a8c588 docs: add comprehensive Android app analysis and improvement plan
- Add android-app-analysis.md: detailed analysis of /android/app structure and /www integration
- Add android-app-improvement-plan.md: phase-based implementation plan for architecture improvements
- Add chatgpt-analysis-guide.md: structured prompts for AI analysis of Android test app
- Update README.md: add links to new documentation files

These documents provide comprehensive guidance for understanding and improving the DailyNotification Android test app architecture.
2025-10-24 09:42:10 +00:00
Matthew Raymer
4a8573ec87 fix(test-app): implement Schedule Notification button functionality
- Replace empty TODO with actual plugin integration
- Add dynamic import of DailyNotification plugin
- Implement proper error handling with try/catch
- Add user feedback via alert dialogs
- Add comprehensive logging for debugging
- Fix TypeScript priority type with 'high' as const
- Successfully schedules notifications with AlarmManager
- Verified alarm appears in dumpsys alarm output

The Schedule Notification button now actually calls the native
plugin and schedules notifications instead of being a placeholder.
2025-10-23 12:51:15 +00:00
Matthew Raymer
6aaeaf7808 fix(android): resolve permission request and status display issues
- Add requestPermissions method alias to fix Vue app compatibility
- Fix permission response format to include both string and boolean values
- Add comprehensive debugging for permission request flow
- Implement permission request throttling to prevent app crashes
- Fix capacitor.settings.gradle plugin path configuration
- Enhance Vue app logging for permission status debugging

Resolves permission dialog not appearing and UI showing incorrect status.
All permission functionality now works end-to-end with proper status updates.
2025-10-23 11:47:55 +00:00
Matthew Raymer
7185c87e93 docs: add comprehensive AAR integration troubleshooting guide
- Add AAR Duplicate Class Issues section to BUILDING.md with step-by-step solutions
- Create dedicated docs/aar-integration-troubleshooting.md with complete troubleshooting guide
- Document project reference approach (recommended) vs AAR-only approach
- Add verification steps, prevention strategies, and best practices
- Update README.md with links to new documentation
- Resolve duplicate class issues through proper project reference configuration

Fixes AAR integration issues that caused build failures due to plugin being
included both as project reference and AAR file simultaneously.
2025-10-23 10:29:32 +00:00
Matthew Raymer
ef37b10503 docs: add comprehensive AAR integration troubleshooting guide
- Add AAR Duplicate Class Issues section to BUILDING.md with step-by-step solutions
- Create dedicated docs/aar-integration-troubleshooting.md with complete troubleshooting guide
- Document project reference approach (recommended) vs AAR-only approach
- Add verification steps, prevention strategies, and best practices
- Update README.md with links to new documentation
- Resolve duplicate class issues through proper project reference configuration

Fixes AAR integration issues that caused build failures due to plugin being
included both as project reference and AAR file simultaneously.
2025-10-23 10:29:13 +00:00
Matthew Raymer
150d297926 fix(capacitor): getting capacitor to build 2025-10-23 09:20:18 +00:00
Matthew Raymer
5307ec2512 fix(android): add back notification handler 2025-10-22 06:51:36 +00:00
Matthew Raymer
fda0124aa5 docs(build): comprehensive BUILDING.md updates for test apps and deployment
- Add detailed documentation for Vue 3 test app (test-apps/daily-notification-test/)
- Add comprehensive /android/app structure and editing guidelines
- Document all 15+ build scripts in scripts/ directory
- Add deployment section covering npm publishing and external project integration
- Clarify distinction between plugin module and test app modules
- Update Android Studio capabilities (can now run test apps, test notifications)
- Add complete project structure including test apps and scripts
- Document build processes for all three Android components (plugin, main app, Vue app)

Covers full development workflow from plugin development to production deployment.
Co-authored-by: Matthew Raymer
2025-10-21 09:30:22 +00:00
Matthew Raymer
0287764a23 refactor(storage): remove legacy SQLite usage; finalize Room wiring
- DailyNotificationPlugin: strip SQLite init and writes; retain SharedPreferences path; Room storage remains authoritative
- DailyNotificationTTLEnforcer: remove SQLite reads/writes and DB constants; use SharedPreferences-only
- DailyNotificationMigration: make migration a no-op (legacy SQLite removed)
- DailyNotificationFetcher/Worker: write/read via Room; keep legacy SharedPreferences as fallback; guard removed API (type/vibration/storeLong) via reflection
- Room DAOs: add column aliases to match DTO fields
- Entities: add @Ignore to non-default constructors to silence Room warnings

Build fixes: resolve missing symbols and cursor mismatches after SQLite removal; align to current NotificationContent API.
Co-authored-by: Matthew Raymer
2025-10-20 10:50:07 +00:00