Files
daily-notification-plugin/docs/DATABASE_INTERFACES_IMPLEMENTATION.md
Matthew Raymer 18106e5ba8 feat(android): consolidate databases and add prefetch scheduling
Consolidate Java and Kotlin database implementations into unified
schema, add delayed prefetch scheduling, and fix notification
delivery issues.

Database Consolidation:
- Merge Java DailyNotificationDatabase into Kotlin DatabaseSchema
- Add migration path from v1 to v2 unified schema
- Include all entities: ContentCache, Schedule, Callback, History,
  NotificationContentEntity, NotificationDeliveryEntity,
  NotificationConfigEntity
- Add @JvmStatic getInstance() for Java interoperability
- Update DailyNotificationWorker and DailyNotificationStorageRoom
  to use unified database

Prefetch Functionality:
- Add scheduleDelayedFetch() to FetchWorker for 5-minute prefetch
  before notifications
- Support delayed WorkManager scheduling with initialDelay
- Update scheduleDailyNotification() to optionally schedule prefetch
  when URL is provided

Notification Delivery Fixes:
- Register NotifyReceiver in AndroidManifest.xml (was missing,
  causing notifications not to fire)
- Add safe database initialization with lazy getDatabase() helper
- Prevent PluginLoadException on database init failure

Build Configuration:
- Add kotlin-android and kotlin-kapt plugins
- Configure Room annotation processor (kapt) for Kotlin
- Add Room KTX dependency for coroutines support
- Fix Gradle settings with pluginManagement blocks

Plugin Methods Added:
- checkPermissionStatus() - detailed permission status
- requestNotificationPermissions() - request POST_NOTIFICATIONS
- scheduleDailyNotification() - schedule with AlarmManager
- configureNativeFetcher() - configure native content fetcher
- Various status and configuration methods

Code Cleanup:
- Remove duplicate BootReceiver.java (keep Kotlin version)
- Remove duplicate DailyNotificationPlugin.java (keep Kotlin version)
- Remove old Java database implementation
- Add native fetcher SPI registry (@JvmStatic methods)

The unified database ensures schedule persistence across reboots
and provides a single source of truth for all plugin data.
Prefetch scheduling enables content caching before notifications
fire, improving offline-first reliability.
2025-11-06 06:28:00 +00:00

5.9 KiB

Database Interfaces Implementation Summary

Author: Matthew Raymer
Date: 2025-01-21
Status: COMPLETE - TypeScript interfaces and Android implementations ready

Overview

The Daily Notification Plugin now exposes comprehensive TypeScript interfaces for accessing its internal SQLite database. Since the plugin owns its database (isolated from host apps), the webview accesses data through Capacitor bridge methods.

What Was Implemented

TypeScript Interface Definitions (src/definitions.ts)

Added 30+ database access methods with full type definitions:

  • Schedule Management: getSchedules(), createSchedule(), updateSchedule(), deleteSchedule(), enableSchedule(), calculateNextRunTime()
  • Content Cache Management: getContentCacheById(), getLatestContentCache(), getContentCacheHistory(), saveContentCache(), clearContentCacheEntries()
  • Callback Management: getCallbacks(), getCallback(), registerCallbackConfig(), updateCallback(), deleteCallback(), enableCallback()
  • History/Analytics: getHistory(), getHistoryStats()
  • Configuration Management: Stubs for getConfig(), setConfig(), updateConfig(), deleteConfig(), getAllConfigs() (pending database consolidation)

Android PluginMethods (DailyNotificationPlugin.kt)

Implemented all database access methods:

  • All operations run on background threads (Dispatchers.IO) for thread safety
  • Proper error handling with descriptive error messages
  • JSON serialization helpers for entity-to-JSObject conversion
  • Filter support (by kind, enabled status, time ranges, etc.)

Database Schema Extensions (DatabaseSchema.kt)

Extended DAOs with additional queries:

  • ScheduleDao: Added getAll(), getByKind(), getByKindAndEnabled(), deleteById(), update()
  • ContentCacheDao: Added getHistory(), deleteAll()
  • CallbackDao: Added getAll(), getByEnabled(), getById(), update()
  • HistoryDao: Added getSinceByKind(), getRecent()

Comprehensive Documentation (docs/DATABASE_INTERFACES.md)

Created 600+ line documentation guide:

  • Complete API reference with examples
  • Common usage patterns
  • Type definitions
  • Error handling guidance
  • Return format notes (Capacitor serialization)
  • Implementation status

Key Features

For Developers

  • Type-Safe: Full TypeScript type definitions
  • Well-Documented: Comprehensive JSDoc comments and examples
  • Error Handling: Clear error messages for debugging
  • Thread-Safe: All operations on background threads

For AI Assistants

  • Clear Structure: Methods organized by category
  • Comprehensive Examples: Real-world usage patterns
  • Type Information: Complete type definitions with JSDoc
  • Architecture Documentation: Clear explanation of plugin database ownership

Usage Example

import { DailyNotification } from '@capacitor-community/daily-notification';

// Get all enabled notification schedules
const result = await DailyNotification.getSchedules({ 
  kind: 'notify', 
  enabled: true 
});
const schedules = result.schedules;

// Get latest cached content
const cache = await DailyNotification.getLatestContentCache();
if (cache) {
  const content = JSON.parse(cache.payload);
  console.log('Content:', content);
}

// Create a new schedule
const newSchedule = await DailyNotification.createSchedule({
  kind: 'notify',
  cron: '0 9 * * *',  // Daily at 9 AM
  enabled: true
});

Implementation Status

Fully Implemented

  • Schedule management (CRUD)
  • Content cache management (CRUD)
  • Callback management (CRUD)
  • History/analytics (read operations)

⚠️ Pending Database Consolidation

  • Configuration management (Config table exists in Java DB, needs to be added to Kotlin schema)
  • See android/DATABASE_CONSOLIDATION_PLAN.md for details

Architecture Notes

Why Plugin Owns Database

  1. Isolation: Plugin data is separate from host app data
  2. Reboot Recovery: Schedules must persist across reboots (Android doesn't persist AlarmManager schedules)
  3. Offline-First: Cached content available without network
  4. Self-Contained: Plugin manages its own lifecycle

How Webview Accesses Database

TypeScript/Webview
  ↓ Capacitor Bridge
Android PluginMethod (@PluginMethod)
  ↓ Kotlin Coroutines (Dispatchers.IO)
Room Database (Kotlin)
  ↓ SQLite
daily_notification_plugin.db

Files Modified/Created

  1. src/definitions.ts - Added database interface methods and types
  2. android/src/main/java/com/timesafari/dailynotification/DailyNotificationPlugin.kt - Implemented PluginMethods
  3. android/src/main/java/com/timesafari/dailynotification/DatabaseSchema.kt - Extended DAOs
  4. docs/DATABASE_INTERFACES.md - Complete documentation
  5. android/DATABASE_CONSOLIDATION_PLAN.md - Updated with interface requirements

Next Steps

  1. Complete Database Consolidation: Merge Java and Kotlin databases into single unified schema
  2. Add Config Table: Implement Config management methods once consolidated
  3. Testing: Test all database methods end-to-end
  4. iOS Implementation: Adapt to iOS when ready

Documentation References

  • Complete API Reference: docs/DATABASE_INTERFACES.md
  • Consolidation Plan: android/DATABASE_CONSOLIDATION_PLAN.md
  • TypeScript Definitions: src/definitions.ts
  • Database Schema: android/src/main/java/com/timesafari/dailynotification/DatabaseSchema.kt

For AI Assistants

This implementation provides:

  • Clear Interface Contracts: TypeScript interfaces define exact method signatures
  • Comprehensive Examples: Every method has usage examples
  • Architecture Context: Clear explanation of why database is plugin-owned
  • Implementation Details: Android code shows how methods work internally
  • Error Patterns: Consistent error handling across all methods

All interfaces are type-safe, well-documented, and ready for use in projects that integrate this plugin.