--- phase: 17-telegram-scheduler plan: 02 subsystem: scheduler tags: [gocron, sqlite, cron, scheduler, telegram] requires: - phase: 01-foundation provides: pkg/storage DB wrapper with schema.sql embed pattern provides: - pkg/scheduler/ package with gocron wrapper, start/stop lifecycle - Storage CRUD for subscribers table (Add/Remove/List/IsSubscribed) - Storage CRUD for scheduled_jobs table (Save/List/Get/Delete/UpdateLastRun/SetEnabled) - subscribers and scheduled_jobs SQLite tables in schema.sql affects: [17-telegram-scheduler, 17-03, 17-04, 17-05] tech-stack: added: [gocron/v2 v2.19.1] patterns: [scheduler wraps gocron with DB persistence, ScanFunc abstraction decouples from engine] key-files: created: - pkg/scheduler/scheduler.go - pkg/scheduler/jobs.go - pkg/scheduler/scheduler_test.go - pkg/storage/subscribers.go - pkg/storage/scheduled_jobs.go modified: - pkg/storage/schema.sql - go.mod - go.sum key-decisions: - "Scheduler.ScanFunc callback decouples from engine -- Plan 17-04 wires the real scan logic" - "OnComplete callback bridges scheduler to notification system without direct bot dependency" - "Disabled jobs skipped during Start() but remain in DB for re-enabling" patterns-established: - "Scheduler pattern: gocron wrapper with DB persistence and callback-based extensibility" requirements-completed: [SCHED-01] duration: 2min completed: 2026-04-06 --- # Phase 17 Plan 02: Scheduler + Storage Summary **gocron v2.19.1 wrapper with SQLite persistence for subscribers and scheduled scan jobs, callback-based scan/notify extensibility** ## Performance - **Duration:** 2 min - **Started:** 2026-04-06T14:25:04Z - **Completed:** 2026-04-06T14:27:08Z - **Tasks:** 2 - **Files modified:** 8 ## Accomplishments - Created pkg/scheduler/ package wrapping gocron with Start/Stop lifecycle and DB-backed job persistence - Implemented full CRUD for subscribers (Add/Remove/List/IsSubscribed) and scheduled_jobs (Save/List/Get/Delete/UpdateLastRun/SetEnabled) - Added subscribers and scheduled_jobs tables to schema.sql - All 5 tests pass: storage round-trip, subscriber round-trip, scheduler start/add/remove/run ## Task Commits Each task was committed atomically: 1. **Task 1: Add gocron dependency, create storage tables, and subscriber/job CRUD** - `c8f7592` (feat) 2. **Task 2 RED: Failing tests for scheduler package** - `89cc133` (test) 3. **Task 2 GREEN: Implement scheduler package** - `c71faa9` (feat) ## Files Created/Modified - `pkg/scheduler/scheduler.go` - Scheduler struct wrapping gocron with Start/Stop/AddJob/RemoveJob/RunJob/ListJobs - `pkg/scheduler/jobs.go` - Job and JobResult types - `pkg/scheduler/scheduler_test.go` - 5 tests covering storage, subscriber, and scheduler lifecycle - `pkg/storage/subscribers.go` - Subscriber struct and CRUD methods on DB - `pkg/storage/scheduled_jobs.go` - ScheduledJob struct and CRUD methods on DB - `pkg/storage/schema.sql` - subscribers and scheduled_jobs CREATE TABLE statements - `go.mod` - gocron/v2 v2.19.1 promoted to direct dependency - `go.sum` - Updated checksums ## Decisions Made - ScanFunc callback decouples scheduler from engine -- Plan 17-04 wires real scan logic - OnComplete callback bridges scheduler to notification system without direct bot dependency - Disabled jobs skipped during Start() but remain in DB for re-enabling via SetJobEnabled ## Deviations from Plan None - plan executed exactly as written. ## Issues Encountered None ## User Setup Required None - no external service configuration required. ## Next Phase Readiness - pkg/scheduler/ ready for CLI wiring in Plan 17-03 (schedule add/list/remove commands) - Subscriber storage ready for bot /subscribe handler in Plan 17-01 - OnComplete callback ready for notification bridge in Plan 17-04 --- *Phase: 17-telegram-scheduler* *Completed: 2026-04-06*