Task 14 — Scheduler + immediate first run
Depends on: 13
Unblocks: 15
Goal
Background scheduler that runs runPricingSync() once at startup and then
every --pricing-sync-interval-days days.
Scope
New file src/lib/pricing-scheduler.ts:
export function schedulePricingSync(intervalDays: number): void
Implementation:
const intervalMs = intervalDays * 86_400_000
function tick() {
const last = readMeta('last_pricing_sync_ts') ?? 0
const delay = Math.max(0, last + intervalMs - Date.now())
setTimeout(async () => {
try { await runPricingSync({}) }
catch (e) { consola.warn('Pricing sync failed:', e) }
tick()
}, delay)
}
tick()
Wire it from src/start.ts AFTER serve(...):
if (!options.pricingSyncDisabled) {
schedulePricingSync(options.pricingSyncIntervalDays)
}
Add CLI flags:
--pricing-sync-model <id> (default gpt-5.4)
--pricing-sync-interval-days <n> (default 7)
--pricing-sync-disabled (default false)
Definition of Done
Task 14 — Scheduler + immediate first run
Depends on: 13
Unblocks: 15
Goal
Background scheduler that runs
runPricingSync()once at startup and thenevery
--pricing-sync-interval-daysdays.Scope
New file
src/lib/pricing-scheduler.ts:Implementation:
Wire it from
src/start.tsAFTERserve(...):Add CLI flags:
--pricing-sync-model <id>(defaultgpt-5.4)--pricing-sync-interval-days <n>(default7)--pricing-sync-disabled(defaultfalse)Definition of Done
if accounts/network unavailable).
last_pricing_sync_ts = now - 1 daywaits 6 days.last_pricing_sync_ts = now - 8 dayssyncs immediately.--pricing-sync-disabledskips scheduling entirely.docs/tasks/14-pricing-scheduler.mddocs/design/