- Approve endpoint now only creates Jira tickets immediately when
start_date is now/past; a new periodic job (every 15 min) catches
campaigns whose scheduled start_date has since arrived.
- Recurring campaign clones now go to pending_approval instead of
active, routing through the same manager-approval gate as any other
campaign; managers are notified instead of red_tech.
- Fix UTC conversion for the campaign approval start_date input and
extract shared isoToDatetimeLocal/datetimeLocalToIso helpers.
Foundational changes required before any new feature work can begin.
- 0.1 Redis infrastructure: add redis:7-alpine to docker-compose dev and prod,
REDIS_URL config, singleton client in app/infrastructure/redis_client.py
- 0.2 Token blacklist on Redis SEC-001: replace in-memory dict with Redis SETEX
keyed by jti, auto-expiring TTL derived from token exp
- 0.3 Database indexes SR-006: Alembic migration b019 with 5 composite indexes
for scoring, MTTD/MTTR, remediation, and notification queries
- 0.4 Domain exceptions TD-003: app/domain/exceptions.py with typed errors,
error_handler middleware mapping them to HTTP, services decoupled from FastAPI
- 0.5 Fix silenced exceptions TD-007: replace 4 bare except-pass blocks in
test_workflow_service with logger.warning with exc_info
- 0.6 CI pipeline TD-009: GitHub Actions workflow with Postgres and Redis
service containers, ruff lint, pytest; ruff.toml for baseline config