"""Shared recurring NextAction helpers.""" from __future__ import annotations from typing import Any from db import get_connection from psycopg2.extras import RealDictCursor from tenant_context import TenantContext def recurring_due_candidates( ctx: TenantContext, initiative_id: str, *, limit: int ) -> list[dict[str, Any]]: conn = get_connection() try: with conn.cursor(cursor_factory=RealDictCursor) as cur: cur.execute( """ SELECT 'recurring_due' AS kind, re.title AS title, 'Wiederkehrendes Element fällig' AS summary, re.initiative_id, re.id AS recurring_id, NULL::uuid AS action_id, NULL::uuid AS backlog_item_id, 'recurring_due' AS reason_code, 'Übung heute erledigen' AS recommended_action FROM recurring_elements re WHERE re.tenant_id = %s AND re.initiative_id = %s AND re.status = 'active' AND re.next_due_at IS NOT NULL AND re.next_due_at <= NOW() ORDER BY re.next_due_at ASC LIMIT %s """, (ctx.tenant_id, initiative_id, limit), ) items: list[dict[str, Any]] = [] for row in cur.fetchall(): item = dict(row) item["initiative_id"] = str(item["initiative_id"]) if item.get("recurring_id"): item["recurring_id"] = str(item["recurring_id"]) items.append(item) return items finally: conn.close() def active_recurring_candidates( ctx: TenantContext, initiative_id: str, *, limit: int = 1 ) -> list[dict[str, Any]]: """Active recurring as 'heutige Übung' when nothing is due yet.""" conn = get_connection() try: with conn.cursor(cursor_factory=RealDictCursor) as cur: cur.execute( """ SELECT 'recurring_due' AS kind, re.title AS title, 'Heutige Übung / Routine' AS summary, re.initiative_id, re.id AS recurring_id, NULL::uuid AS action_id, NULL::uuid AS backlog_item_id, 'recurring_active' AS reason_code, 'Übung heute erledigen' AS recommended_action FROM recurring_elements re WHERE re.tenant_id = %s AND re.initiative_id = %s AND re.status = 'active' ORDER BY re.next_due_at ASC NULLS LAST, re.title LIMIT %s """, (ctx.tenant_id, initiative_id, limit), ) items: list[dict[str, Any]] = [] for row in cur.fetchall(): item = dict(row) item["initiative_id"] = str(item["initiative_id"]) if item.get("recurring_id"): item["recurring_id"] = str(item["recurring_id"]) items.append(item) return items finally: conn.close()