feat(reminders): register module; init + startup reconcile (T8.6, FR-CAL-5)

Reschedules anything Windows' own toast schedule lost track of
(uninstall/reinstall, a changed AppUserModelID) — safe to run every
startup since schedule() is idempotent (cancels any existing entry for
the same action item id first).
This commit is contained in:
iamdoubz committed 2026-07-02 11:58:50 -05:00
1 parent f6e0de5486
commit 26ad920182
1 file changed
+23 -3
+23 -3
View File
@@ -16,6 +16,7 @@ pub mod mcp;
pub mod models;
pub mod notes;
pub mod paths;
pub mod reminders;
pub mod storage;
pub mod sync;
pub mod transcription;
@@ -94,9 +95,14 @@ pub fn run() {
.build(app)?;
app.manage(TrayHandle(tray));
// Startup recovery + retention pass (FR-REL-1, FR-STORE-2). Spawned so
// it never blocks the window from showing (NFR-PERF-4); nothing here
// repeats on a timer (NFR-RES-1).
// Reminders (Phase 8, T8.6, FR-CAL-5) are Windows-scheduled toasts, not
// an app-side timer — Windows itself is what's "polling", so this stays
// within NFR-RES-1. init() just registers the AppUserModelID.
reminders::init();
// Startup recovery + retention + reminder-reconcile pass (FR-REL-1,
// FR-STORE-2, FR-CAL-5). Spawned so it never blocks the window from
// showing (NFR-PERF-4); nothing here repeats on a timer (NFR-RES-1).
let store = store_for_setup;
tauri::async_runtime::spawn(async move {
match store.recover_scan().await {
@@ -114,6 +120,20 @@ pub fn run() {
if let Err(e) = store.enforce_retention(policy).await {
tracing::error!("startup retention enforcement failed: {e}");
}
// Re-schedules anything Windows' own toast schedule lost track of
// (uninstall/reinstall, a changed AppUserModelID, …) — schedule()
// itself is idempotent (cancels any existing entry for the same
// action item id first), so this is safe to run every startup.
match store.list_pending_reminders().await {
Ok(pending) => {
for item in &pending {
if let (Some(id), Some(due_at)) = (&item.id, item.due_at) {
reminders::schedule(id, &item.text, item.owner.as_deref(), due_at);
}
}
}
Err(e) => tracing::error!("startup reminder reconcile failed: {e}"),
}
});
Ok(())
})