feat: implement automation module
- Event-based triggers (Phase 1): - Trigger/TriggerLog models with field_change type - TriggerService for condition evaluation and action execution - Trigger CRUD API endpoints - Task integration (status, assignee, priority changes) - Frontend: TriggerList, TriggerForm components - Weekly reports (Phase 2): - ScheduledReport/ReportHistory models - ReportService for stats generation - APScheduler for Friday 16:00 job - Report preview/generate/history API - Frontend: WeeklyReportPreview, ReportHistory components - Tests: 23 new tests (14 triggers + 9 reports) - OpenSpec: add-automation change archived 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
53
backend/app/core/scheduler.py
Normal file
53
backend/app/core/scheduler.py
Normal file
@@ -0,0 +1,53 @@
|
||||
import logging
|
||||
from apscheduler.schedulers.asyncio import AsyncIOScheduler
|
||||
from apscheduler.triggers.cron import CronTrigger
|
||||
|
||||
from app.core.database import SessionLocal
|
||||
from app.services.report_service import ReportService
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
scheduler = AsyncIOScheduler()
|
||||
|
||||
|
||||
async def weekly_report_job():
|
||||
"""Job function to generate weekly reports."""
|
||||
logger.info("Starting weekly report generation...")
|
||||
|
||||
db = SessionLocal()
|
||||
try:
|
||||
generated_for = await ReportService.generate_all_weekly_reports(db)
|
||||
logger.info(f"Weekly reports generated for {len(generated_for)} users")
|
||||
except Exception as e:
|
||||
logger.error(f"Error generating weekly reports: {e}")
|
||||
finally:
|
||||
db.close()
|
||||
|
||||
|
||||
def init_scheduler():
|
||||
"""Initialize the scheduler with jobs."""
|
||||
# Weekly report - Every Friday at 16:00
|
||||
scheduler.add_job(
|
||||
weekly_report_job,
|
||||
CronTrigger(day_of_week='fri', hour=16, minute=0),
|
||||
id='weekly_report',
|
||||
name='Generate Weekly Reports',
|
||||
replace_existing=True,
|
||||
)
|
||||
|
||||
logger.info("Scheduler initialized with weekly report job (Friday 16:00)")
|
||||
|
||||
|
||||
def start_scheduler():
|
||||
"""Start the scheduler."""
|
||||
if not scheduler.running:
|
||||
init_scheduler()
|
||||
scheduler.start()
|
||||
logger.info("Scheduler started")
|
||||
|
||||
|
||||
def shutdown_scheduler():
|
||||
"""Shutdown the scheduler gracefully."""
|
||||
if scheduler.running:
|
||||
scheduler.shutdown(wait=False)
|
||||
logger.info("Scheduler shutdown")
|
||||
Reference in New Issue
Block a user