feat: APScheduler integration for maintenance flow auto-session creation

- Add backend/app/core/scheduler.py with AsyncIOScheduler, CronTrigger-based
  job registration, and _fire_maintenance_schedule to create batch sessions
- Wire scheduler.start()/load_all_schedules()/shutdown() into main.py lifespan
- Call register_schedule() in create_schedule endpoint after commit
- Call register_schedule()/unregister_schedule() in update_schedule based on is_active
- Add TreeShare to models/__init__.py so all SQLAlchemy mapper relationships
  resolve before ORM queries in the scheduler context

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
chihlasm
2026-02-17 14:21:29 -05:00
parent 55cd481e48
commit 5abff028bc
4 changed files with 162 additions and 1 deletions

View File

@@ -6,11 +6,12 @@ from slowapi import _rate_limit_exceeded_handler
from slowapi.errors import RateLimitExceeded
from app.core.config import settings
from app.core.database import init_db
from app.core.database import init_db, async_session_maker
from app.core.logging_config import setup_logging
from app.core.middleware import RequestLoggingMiddleware, ErrorLoggingMiddleware
from app.core.rate_limit import limiter
from app.api.router import api_router
from app.core.scheduler import scheduler, load_all_schedules
# Initialize logging configuration
setup_logging()
@@ -26,8 +27,16 @@ async def lifespan(app: FastAPI):
logger.info(f"ALLOW_RAILWAY_ORIGINS: {settings.ALLOW_RAILWAY_ORIGINS}")
# Note: In production, use Alembic migrations instead of init_db
# await init_db()
# Start maintenance schedule runner
scheduler.start()
async with async_session_maker() as db:
await load_all_schedules(db)
yield
# Shutdown
scheduler.shutdown(wait=False)
logger.info("Shutting down ResolutionFlow API server...")