feat(notify-bridge): phase 8 - integration and wiring

Wire all components into a working application:
- Scheduler service: APScheduler loads enabled trackers, polls at intervals
- Watcher service: orchestrates poll -> detect -> notify flow
  - Eagerly loads DB data, then creates aiohttp session for provider
  - Saves tracker state after each poll
  - Logs events to EventLog table
  - Dispatches notifications to targets with template rendering
- Manual trigger endpoint: POST /api/trackers/{id}/trigger
- Scheduler starts on app lifespan startup
- Full end-to-end flow verified: server starts cleanly

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-03-19 23:55:15 +03:00
parent 9dfd1b79cd
commit 08814e9ae2
4 changed files with 249 additions and 0 deletions
@@ -102,3 +102,18 @@ async def delete_tracker(
raise HTTPException(status_code=404, detail="Tracker not found")
await session.delete(tracker)
await session.commit()
@router.post("/{tracker_id}/trigger")
async def trigger_tracker(
tracker_id: int,
user: User = Depends(get_current_user),
session: AsyncSession = Depends(get_session),
):
tracker = await session.get(Tracker, tracker_id)
if not tracker or tracker.user_id != user.id:
raise HTTPException(status_code=404, detail="Tracker not found")
from ..services.watcher import check_tracker
result = await check_tracker(tracker_id)
return result