feat(scanning): scheduled scans (cron-like) (#7) - #17
Merged
Conversation
- Migration 006: adds schedules and schedule_runs tables
- SchedulerService backed by APScheduler AsyncIOScheduler; jobs are
registered at startup from all enabled schedules in the DB
- Redis SET NX EX lock prevents double-fire across multiple workers
when SECURESCAN_REDIS_URL is set; single-process fallback otherwise
- API: POST/GET/PATCH/DELETE /api/v1/schedules + GET /{id}/runs, all
admin scope, cron validated via CronTrigger.from_crontab
- Frontend: /settings/schedules page (DataTable, create/edit modal,
delete confirm, run-history drawer); sidebar entry added
- apscheduler>=3.10.0 added to pyproject.toml dependencies
- Docs: docs/src/scanning/scheduled-scans.md
- Tests: 18 unit+integration tests (CRUD, fire->scan, lock blocks
double-fire); Redis test skipped when SECURESCAN_REDIS_URL not set
- Updated test_migrations.py to expect version 6
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Implements #7: scheduled scans (cron-like recurring runs).
What's new
Backend
006_add_schedules_table.pyadds two tables:schedules(id, name, target_path, scan_types, cron_expression, last_run, enabled, created_at)schedule_runs(id, schedule_id, scan_id, triggered_at) with index on (schedule_id, triggered_at DESC)scheduler.py—SchedulerServiceover APSchedulerAsyncIOScheduler. Jobs registered from enabled DB rows at startup;reschedule/remove/addkeep the live scheduler in sync with API mutations._fire_schedule()uses a RedisSET NX EXlock (via the pubsub backplane from feat(infra): multi-worker uvicorn via Redis pubsub backplane #4) keyed onschedule:<id>:<minute_bucket>so two workers never fire the same trigger. Falls back to single-process whenSECURESCAN_REDIS_URLis unset.api/schedules.py—POST/GET/PATCH/DELETE /api/v1/schedulesandGET /{id}/runs. Admin scope. Cron expressions validated at 422 viaCronTrigger.from_crontab.apscheduler>=3.10.0added topyproject.toml.Frontend
/settings/schedulespage mirrors the keys/webhooks layout: DataTable, create/edit modal, delete confirm, schedule run-history drawer.Schedule/ScheduleRuntypes and CRUD helpers inlib/api.ts.Docs
docs/src/scanning/scheduled-scans.md.Tests
SECURESCAN_REDIS_URLexactly like the pubsub redis test).cd backend && ruff check . && ruff format --check . && python -m pytest tests/ -x -q— 950 passed, 4 skipped (pre-existing nmap/semgrep env-only failures excluded; same as main).Notes