diff --git a/src/fabledassistant/services/briefing_scheduler.py b/src/fabledassistant/services/briefing_scheduler.py index 44f1ed0..2a77eac 100644 --- a/src/fabledassistant/services/briefing_scheduler.py +++ b/src/fabledassistant/services/briefing_scheduler.py @@ -326,6 +326,23 @@ async def start_briefing_scheduler(loop: asyncio.AbstractEventLoop) -> None: for user_id, tz in users: _add_user_jobs(user_id, tz) + from fabledassistant.services.recurrence import spawn_recurring_tasks as _spawn_recurring + + def _run_recurrence_spawn() -> None: + future = asyncio.run_coroutine_threadsafe(_spawn_recurring(), _loop) + try: + count = future.result(timeout=300) + logger.info("Recurrence spawn: %d task(s) created", count) + except Exception as exc: + logger.error("Recurrence spawn failed: %s", exc) + + _scheduler.add_job( + _run_recurrence_spawn, + CronTrigger(hour=0, minute=0, timezone="UTC"), + id="recurrence_daily", + replace_existing=True, + ) + _scheduler.start() logger.info( "Briefing scheduler started with %d user(s) across %d job(s)", diff --git a/src/fabledassistant/services/notes.py b/src/fabledassistant/services/notes.py index 111de1f..be9e0ea 100644 --- a/src/fabledassistant/services/notes.py +++ b/src/fabledassistant/services/notes.py @@ -56,6 +56,7 @@ async def create_note( status: str | None = None, priority: str | None = None, due_date: date | None = None, + recurrence_rule: dict | None = None, ) -> Note: # Auto-populate project_id from milestone when not explicitly provided if milestone_id is not None and project_id is None: @@ -80,6 +81,7 @@ async def create_note( status=status, priority=priority, due_date=due_date, + recurrence_rule=recurrence_rule, ) session.add(note) await session.commit()