diff --git a/motomate/src/hooks.server.ts b/motomate/src/hooks.server.ts index 45e1ad1..3614097 100644 --- a/motomate/src/hooks.server.ts +++ b/motomate/src/hooks.server.ts @@ -1,15 +1,10 @@ import { lucia } from '$lib/auth/index.js'; import type { Handle } from '@sveltejs/kit'; import { env } from '$env/dynamic/private'; -import { runWorkflowChecks } from '$lib/workflow/engine.js'; import { initScheduler } from '$lib/server/scheduler.js'; initScheduler(); -// Per-user timestamps to throttle passive workflow checks (in-memory, resets on server restart) -const lastWorkflowCheck = new Map(); -const WORKFLOW_CHECK_INTERVAL_MS = 60 * 60 * 1000; // 1 hour - /** * Runtime CSRF origin validation. * Reads PUBLIC_APP_ORIGINS at runtime so self-hosted users can configure their own origins. @@ -167,15 +162,6 @@ export const handle: Handle = async ({ event, resolve }) => { event.locals.user = user; event.locals.session = session; - // Passive workflow check: fire at most once per hour per user, non-blocking - if (user) { - const last = lastWorkflowCheck.get(user.id) ?? 0; - if (Date.now() - last > WORKFLOW_CHECK_INTERVAL_MS) { - lastWorkflowCheck.set(user.id, Date.now()); - runWorkflowChecks(user.id).catch(() => {}); - } - } - const response = await resolve(event, { transformPageChunk({ html }) { const theme = (event.locals.user as any)?.settings?.theme; diff --git a/motomate/src/lib/workflow/engine.ts b/motomate/src/lib/workflow/engine.ts index ce2f85b..a9300dc 100644 --- a/motomate/src/lib/workflow/engine.ts +++ b/motomate/src/lib/workflow/engine.ts @@ -252,13 +252,8 @@ export async function runWorkflowChecks( for (const result of results) { if (result.trackerId) { - // Tracker-based triggers use cycle-based dedup: once any rule has fired - // for this tracker in the current service cycle, all rules are blocked - // until the user logs a service (which clears notified_by). - // This ensures exactly one notification per cycle regardless of how - // many matching rules are enabled (e.g. upcoming + overdue both on). const notifiedBy = (result.trackerState?.notified_by ?? {}) as Record; - if (Object.keys(notifiedBy).length > 0) continue; + if (notifiedBy[rule.id]) continue; } else { // Non-tracker triggers (calendar, no_odometer_update, etc.) use 23h cooldown if (rule.last_triggered_at) { @@ -287,9 +282,11 @@ export async function runWorkflowChecks( }) .where(eq(active_trackers.id, result.trackerId)); } else { + const now = new Date().toISOString(); + rule.last_triggered_at = now; await db .update(workflow_rules) - .set({ last_triggered_at: new Date().toISOString() }) + .set({ last_triggered_at: now }) .where(eq(workflow_rules.id, rule.id)); } }