Data Strategy
The application employs a Local-First strategy with asynchronous background synchronization.- Preferences: Managed via , wrapped in reactive .
- App Categorization: Uses a State-Machine Sync strategy. Apps are discovered locally, marked as
NEEDS_CHECK, and synchronized with a remote service via . - Notifications: Persisted in a database with automated retention policies to prevent storage bloat.
Key Repositories
- SettingsRepository: The for user preferences (Themes, Dark Mode, Nudge intervals, and the “Pledge”).
- AppCategoryRepository: Manages the mapping between Android package names and their productivity categories (e.g., “Social”, “Work”).
Schema & Performance (Data Engineering)
App Categorization State Machine
TheAppCategory entity tracks the sync status of every installed app:
- NEEDS_CHECK: Newly discovered app, not yet sent to API.
- PENDING: API acknowledged the app but is still processing the category (triggers a retry in 15/30 mins).
- SYNCED: Category successfully retrieved.
- FAILED: Max retries reached or API error.
Data Integrity
- User Overrides: If a user manually categorizes an app, the
isUserCategorizedflag is set totrue. The sync engine is hard-coded to never overwrite user-defined data with API results. - Batching: API requests are chunked into groups of 100 packages to optimize network overhead and prevent during large initial scans.
Storage & Caching
| Data Type | Storage Mechanism | Caching Policy |
|---|---|---|
| User Settings | SharedPreferences | Memory-cached via Flow; persistent across restarts. |
| App Categories | Room DB | Permanent local cache; refreshed only if NEEDS_CHECK. |
| Notifications | Room DB | 60-day retention (configurable) managed by NotificationRetentionWorker. |
Threading & Concurrency
The module relies heavily on to ensure the UI remains responsive:- Reactive Updates:
SettingsRepositoryusescallbackFlowto convert standard listener-based SharedPreferences into streams. - Background Execution: All heavy lifting (API calls, DB cleanup) is encapsulated in
CoroutineWorkerclasses. - Safe Dispatching: Repository methods are marked as , ensuring they are safe to call from any .
Background Workers
CategorySyncWorker
Triggered either by a full periodic scan or a “Targeted Sync” when a new app is installed. It communicates with theCategoryApiService to fetch metadata.
NotificationRetentionWorker
A periodic worker that runs daily (usually with a 6-hour initial delay). It calculates a “Cutoff Date” and executes aDELETE query on the notifications table to maintain performance.
NotificationBatchWorker (Post Box)
Handles the “Post Box” feature. Instead of showing notifications immediately, it:- Queries the DB for undelivered batched notifications.
- Generates a summary notification (e.g., “You have 12 notifications from 4 apps”).
- Schedules the next delivery window using
NotificationBatchScheduler.
Pro-Tip: The
NotificationBatchScheduler uses LocalTime.parse to handle user-defined delivery windows (e.g., “09:00”, “18:00”) and calculates the millisecond delay until the next window accurately, even across day boundaries.