"""Repository for the `flow_configs` table.""" from __future__ import annotations import json from typing import Any from db.connection import get_db FlowConfigRow = dict[str, Any] _FIELDS = [ "name", "is_active", "search_texts_json", "search_box_selector", "search_box_selector_type", "search_submit_selector", "search_submit_selector_type", "search_results_selector", "scroll_container_selector", "max_scrolls", "scroll_pause_ms", "no_new_content_timeout_ms", "item_selector_template", "item_selector_type", "target_item_ids_json", ] def _deserialise(row: dict[str, Any]) -> FlowConfigRow: for key in ("search_texts_json", "target_item_ids_json"): if isinstance(row.get(key), str): try: row[key] = json.loads(row[key]) except (json.JSONDecodeError, TypeError): row[key] = [] return row def _serialise(data: dict[str, Any]) -> dict[str, Any]: out = dict(data) for key in ("search_texts_json", "target_item_ids_json"): if isinstance(out.get(key), list): out[key] = json.dumps(out[key]) return out class FlowConfigRepository: async def list(self) -> list[FlowConfigRow]: async with get_db() as db: rows = await (await db.execute( "SELECT * FROM flow_configs ORDER BY id DESC" )).fetchall() return [_deserialise(dict(r)) for r in rows] async def get(self, cfg_id: int) -> FlowConfigRow | None: async with get_db() as db: row = await (await db.execute( "SELECT * FROM flow_configs WHERE id=?", (cfg_id,) )).fetchone() return _deserialise(dict(row)) if row else None async def get_active(self) -> FlowConfigRow | None: async with get_db() as db: row = await (await db.execute( "SELECT * FROM flow_configs WHERE is_active=1 ORDER BY id DESC LIMIT 1" )).fetchone() return _deserialise(dict(row)) if row else None async def create(self, data: dict[str, Any]) -> int: data = _serialise(data) async with get_db() as db: if data.get("is_active"): await db.execute("UPDATE flow_configs SET is_active=0") placeholders = ", ".join("?" for _ in _FIELDS) cols = ", ".join(_FIELDS) values = [data.get(f) for f in _FIELDS] cur = await db.execute( f"INSERT INTO flow_configs ({cols}) VALUES ({placeholders})", values ) await db.commit() return int(cur.lastrowid or 0) async def update(self, cfg_id: int, data: dict[str, Any]) -> None: data = _serialise(data) async with get_db() as db: if data.get("is_active"): await db.execute("UPDATE flow_configs SET is_active=0") set_clause = ", ".join(f"{f}=?" for f in _FIELDS) values = [data.get(f) for f in _FIELDS] + [cfg_id] await db.execute( f"UPDATE flow_configs SET {set_clause} WHERE id=?", values ) await db.commit() async def activate(self, cfg_id: int) -> None: async with get_db() as db: await db.execute("UPDATE flow_configs SET is_active=0") await db.execute("UPDATE flow_configs SET is_active=1 WHERE id=?", (cfg_id,)) await db.commit() async def delete(self, cfg_id: int) -> None: async with get_db() as db: await db.execute("DELETE FROM flow_configs WHERE id=?", (cfg_id,)) await db.commit() flow_config_repo = FlowConfigRepository()