You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

10 KiB

Database Consolidation Plan

Current State

Database 1: Java (daily_notification_plugin.db)

  • notification_content - Specific notification instances
  • notification_delivery - Delivery tracking/analytics
  • notification_config - Configuration

Database 2: Kotlin (daily_notification_database)

  • content_cache - Fetched content with TTL
  • schedules - Recurring schedule patterns (CRITICAL for reboot)
  • callbacks - Callback configurations
  • history - Execution history

Unified Schema Design

Required Tables (All Critical)

  1. schedules - Recurring schedule patterns

    • Stores cron/clockTime patterns
    • Used to restore schedules after reboot
    • Fields: id, kind ('fetch'/'notify'), cron, clockTime, enabled, lastRunAt, nextRunAt, jitterMs, backoffPolicy, stateJson
  2. content_cache - Fetched content with TTL

    • Stores prefetched content for offline-first display
    • Fields: id, fetchedAt, ttlSeconds, payload (BLOB), meta
  3. notification_config - Plugin configuration

    • Stores user preferences and plugin settings
    • Fields: id, timesafariDid, configType, configKey, configValue, configDataType, isEncrypted, createdAt, updatedAt
  4. callbacks - Callback configurations

    • Stores callback endpoint configurations
    • Fields: id, kind ('http'/'local'/'queue'), target, headersJson, enabled, createdAt

Optional Tables (Analytics/Debugging)

  1. notification_content - Specific notification instances

    • May still be needed for one-time notifications or TimeSafari integration
    • Fields: All existing fields from Java entity
  2. notification_delivery - Delivery tracking

    • Analytics for delivery attempts and user interactions
    • Fields: All existing fields from Java entity
  3. history - Execution history

    • Logs fetch/notify/callback execution
    • Fields: id, refId, kind, occurredAt, durationMs, outcome, diagJson

Consolidation Strategy

  • Keep Kotlin schema as base - It already has critical tables
  • Add Java tables to Kotlin schema - Merge missing entities
  • Update all Java code - Use unified database instance
  • Update all Kotlin code - Use unified database instance
  • Single database file: daily_notification_plugin.db

Migration Path

  • Create unified DailyNotificationDatabase with all entities
  • Update Java code to use unified database
  • Update Kotlin code to use unified database
  • Remove old DailyNotificationDatabase files
  • Test reboot recovery

Key Decisions

  • Primary language: Kotlin (more modern, better coroutine support)
  • Database name: daily_notification_plugin.db (Java naming convention)
  • All entities: Both Java and Kotlin compatible
  • DAOs: Mix of Java and Kotlin DAOs as needed

TypeScript Interface Requirements

Since the plugin owns the database, the host app/webview needs TypeScript interfaces to read/write data.

Required TypeScript Methods

Schedules Management

// Read schedules
getSchedules(options?: { kind?: 'fetch' | 'notify', enabled?: boolean }): Promise<Schedule[]>
getSchedule(id: string): Promise<Schedule | null>

// Write schedules
createSchedule(schedule: CreateScheduleInput): Promise<Schedule>
updateSchedule(id: string, updates: Partial<Schedule>): Promise<Schedule>
deleteSchedule(id: string): Promise<void>
enableSchedule(id: string, enabled: boolean): Promise<void>

// Utility
calculateNextRunTime(schedule: string): Promise<number>

Content Cache Management

// Read content cache
getContentCache(options?: { id?: string }): Promise<ContentCache | null>
getLatestContentCache(): Promise<ContentCache | null>
getContentCacheHistory(limit?: number): Promise<ContentCache[]>

// Write content cache
saveContentCache(content: CreateContentCacheInput): Promise<ContentCache>
clearContentCache(options?: { olderThan?: number }): Promise<void>

Configuration Management

// Read config
getConfig(key: string, options?: { timesafariDid?: string }): Promise<Config | null>
getAllConfigs(options?: { timesafariDid?: string, configType?: string }): Promise<Config[]>

// Write config
setConfig(config: CreateConfigInput): Promise<Config>
updateConfig(key: string, value: string, options?: { timesafariDid?: string }): Promise<Config>
deleteConfig(key: string, options?: { timesafariDid?: string }): Promise<void>

Callbacks Management

// Read callbacks
getCallbacks(options?: { enabled?: boolean }): Promise<Callback[]>
getCallback(id: string): Promise<Callback | null>

// Write callbacks
registerCallback(callback: CreateCallbackInput): Promise<Callback>
updateCallback(id: string, updates: Partial<Callback>): Promise<Callback>
deleteCallback(id: string): Promise<void>
enableCallback(id: string, enabled: boolean): Promise<void>

History/Analytics (Optional)

// Read history
getHistory(options?: { 
  since?: number, 
  kind?: 'fetch' | 'notify' | 'callback',
  limit?: number 
}): Promise<History[]>
getHistoryStats(): Promise<HistoryStats>

Type Definitions

interface Schedule {
  id: string
  kind: 'fetch' | 'notify'
  cron?: string
  clockTime?: string  // HH:mm format
  enabled: boolean
  lastRunAt?: number
  nextRunAt?: number
  jitterMs: number
  backoffPolicy: string
  stateJson?: string
}

interface ContentCache {
  id: string
  fetchedAt: number
  ttlSeconds: number
  payload: string  // Base64 or JSON string
  meta?: string
}

interface Config {
  id: string
  timesafariDid?: string
  configType: string
  configKey: string
  configValue: string
  configDataType: string
  isEncrypted: boolean
  createdAt: number
  updatedAt: number
}

interface Callback {
  id: string
  kind: 'http' | 'local' | 'queue'
  target: string
  headersJson?: string
  enabled: boolean
  createdAt: number
}

interface History {
  id: number
  refId: string
  kind: 'fetch' | 'notify' | 'callback' | 'boot_recovery'
  occurredAt: number
  durationMs?: number
  outcome: string
  diagJson?: string
}

Database Consolidation Plan

Status: CONSOLIDATION COMPLETE

The unified database has been successfully created and all code has been migrated to use it.

Current State

Unified Database (daily_notification_plugin.db)

Located in: android/src/main/java/com/timesafari/dailynotification/DatabaseSchema.kt

All Tables Consolidated:

  • content_cache - Fetched content with TTL (Kotlin)
  • schedules - Recurring schedule patterns (Kotlin, CRITICAL for reboot)
  • callbacks - Callback configurations (Kotlin)
  • history - Execution history (Kotlin)
  • notification_content - Specific notification instances (Java)
  • notification_delivery - Delivery tracking/analytics (Java)
  • notification_config - Configuration management (Java)

Old Database Files (DEPRECATED - REMOVED)

  • android/src/main/java/com/timesafari/dailynotification/database/DailyNotificationDatabase.java - REMOVED - All functionality merged into unified database

Migration Status

Completed Tasks

  • Analyzed both database schemas and identified all required tables
  • Designed unified database schema with all required entities
  • Created unified DailyNotificationDatabase class (Kotlin)
  • Added migration from version 1 (Kotlin-only) to version 2 (unified)
  • Updated all Java code to use unified database
    • DailyNotificationStorageRoom.java - Uses unified database
    • DailyNotificationWorker.java - Uses unified database
  • Updated all Kotlin code to use unified database
    • DailyNotificationPlugin.kt - Uses unified database
    • FetchWorker.kt - Uses unified database
    • NotifyReceiver.kt - Uses unified database
    • BootReceiver.kt - Uses unified database
  • Implemented all Config methods in PluginMethods
  • TypeScript interfaces updated for database CRUD operations
  • Documentation created for AI assistants

Pending Tasks

  • Remove old database files (DailyNotificationDatabase.java)
  • Test reboot recovery with unified database
  • Verify migration path works correctly

Unified Schema Design (IMPLEMENTED)

Required Tables (All Critical)

  1. schedules - Recurring schedule patterns

    • Stores cron/clockTime patterns
    • Used to restore schedules after reboot
    • Fields: id, kind ('fetch'/'notify'), cron, clockTime, enabled, lastRunAt, nextRunAt, jitterMs, backoffPolicy, stateJson
  2. content_cache - Fetched content with TTL

    • Stores prefetched content for offline-first display
    • Fields: id, fetchedAt, ttlSeconds, payload (BLOB), meta
  3. notification_config - Plugin configuration

    • Stores user preferences and plugin settings
    • Fields: id, timesafariDid, configType, configKey, configValue, configDataType, isEncrypted, createdAt, updatedAt, ttlSeconds, isActive, metadata
  4. callbacks - Callback configurations

    • Stores callback endpoint configurations
    • Fields: id, kind ('http'/'local'/'queue'), target, headersJson, enabled, createdAt
  5. notification_content - Specific notification instances

    • Stores notification content with plugin-specific fields
    • Fields: All existing fields from Java entity
  6. notification_delivery - Delivery tracking

    • Analytics for delivery attempts and user interactions
    • Fields: All existing fields from Java entity
  7. history - Execution history

    • Logs fetch/notify/callback execution
    • Fields: id, refId, kind, occurredAt, durationMs, outcome, diagJson

Implementation Details

Database Access

  • Kotlin: DailyNotificationDatabase.getDatabase(context)
  • Java: DailyNotificationDatabase.getInstance(context) (Java-compatible wrapper)

Migration Path

  • Version 1 → Version 2: Automatically creates Java entity tables when upgrading from Kotlin-only schema
  • Migration runs automatically on first access after upgrade

Thread Safety

  • All database operations use Kotlin coroutines (Dispatchers.IO)
  • Room handles thread safety internally
  • Singleton pattern ensures single database instance

Next Steps

  1. Remove Old Database File COMPLETE

    • Delete android/src/main/java/com/timesafari/dailynotification/database/DailyNotificationDatabase.java
    • Verify no remaining references
  2. Testing

    • Test reboot recovery with unified database
    • Verify schedule restoration works correctly
    • Verify all Config methods work correctly
    • Test migration from v1 to v2
  3. Documentation

    • Update any remaining documentation references
    • Verify AI documentation is complete