Files
oai-web/server/inbox/triggers.py
2026-04-08 12:43:24 +02:00

126 lines
3.7 KiB
Python

"""
inbox/triggers.py — CRUD for email_triggers table (async).
"""
from __future__ import annotations
import uuid
from datetime import datetime, timezone
from typing import Any
from ..database import _rowcount, get_pool
def _now() -> str:
return datetime.now(timezone.utc).isoformat()
async def list_triggers(user_id: str | None = "GLOBAL") -> list[dict]:
"""
- user_id="GLOBAL" (default): global triggers (user_id IS NULL)
- user_id=None: ALL triggers (admin view)
- user_id="<uuid>": that user's triggers only
"""
pool = await get_pool()
if user_id == "GLOBAL":
rows = await pool.fetch(
"SELECT t.*, a.name AS agent_name "
"FROM email_triggers t LEFT JOIN agents a ON a.id = t.agent_id "
"WHERE t.user_id IS NULL ORDER BY t.created_at"
)
elif user_id is None:
rows = await pool.fetch(
"SELECT t.*, a.name AS agent_name "
"FROM email_triggers t LEFT JOIN agents a ON a.id = t.agent_id "
"ORDER BY t.created_at"
)
else:
rows = await pool.fetch(
"SELECT t.*, a.name AS agent_name "
"FROM email_triggers t LEFT JOIN agents a ON a.id = t.agent_id "
"WHERE t.user_id = $1 ORDER BY t.created_at",
user_id,
)
return [dict(r) for r in rows]
async def create_trigger(
trigger_word: str,
agent_id: str,
description: str = "",
enabled: bool = True,
user_id: str | None = None,
) -> dict:
now = _now()
trigger_id = str(uuid.uuid4())
pool = await get_pool()
await pool.execute(
"""
INSERT INTO email_triggers
(id, trigger_word, agent_id, description, enabled, user_id, created_at, updated_at)
VALUES ($1, $2, $3, $4, $5, $6, $7, $8)
""",
trigger_id, trigger_word, agent_id, description, enabled, user_id, now, now,
)
return {
"id": trigger_id,
"trigger_word": trigger_word,
"agent_id": agent_id,
"description": description,
"enabled": enabled,
"user_id": user_id,
"created_at": now,
"updated_at": now,
}
async def update_trigger(id: str, **fields) -> bool:
fields["updated_at"] = _now()
set_parts = []
values: list[Any] = []
for i, (k, v) in enumerate(fields.items(), start=1):
set_parts.append(f"{k} = ${i}")
values.append(v)
id_param = len(fields) + 1
values.append(id)
pool = await get_pool()
status = await pool.execute(
f"UPDATE email_triggers SET {', '.join(set_parts)} WHERE id = ${id_param}",
*values,
)
return _rowcount(status) > 0
async def delete_trigger(id: str) -> bool:
pool = await get_pool()
status = await pool.execute("DELETE FROM email_triggers WHERE id = $1", id)
return _rowcount(status) > 0
async def toggle_trigger(id: str) -> bool:
pool = await get_pool()
await pool.execute(
"UPDATE email_triggers SET enabled = NOT enabled, updated_at = $1 WHERE id = $2",
_now(), id,
)
return True
async def get_enabled_triggers(user_id: str | None = "GLOBAL") -> list[dict]:
"""Return enabled triggers scoped to user_id (same semantics as list_triggers)."""
pool = await get_pool()
if user_id == "GLOBAL":
rows = await pool.fetch(
"SELECT * FROM email_triggers WHERE enabled = TRUE AND user_id IS NULL"
)
elif user_id is None:
rows = await pool.fetch("SELECT * FROM email_triggers WHERE enabled = TRUE")
else:
rows = await pool.fetch(
"SELECT * FROM email_triggers WHERE enabled = TRUE AND user_id = $1",
user_id,
)
return [dict(r) for r in rows]