Add state tracking and notifications DB support
Add kv_scan() for prefix-based key-value lookups (used by ClickUp task state tracking). Add notifications table with add_notification() and get_notifications_after() for the UI-agnostic notification bus. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>cora-start
parent
f34d7507c2
commit
0b7950cefa
|
|
@ -65,6 +65,12 @@ class Database:
|
||||||
key TEXT PRIMARY KEY,
|
key TEXT PRIMARY KEY,
|
||||||
value TEXT NOT NULL
|
value TEXT NOT NULL
|
||||||
);
|
);
|
||||||
|
CREATE TABLE IF NOT EXISTS notifications (
|
||||||
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
|
message TEXT NOT NULL,
|
||||||
|
category TEXT NOT NULL DEFAULT 'clickup',
|
||||||
|
created_at TEXT NOT NULL
|
||||||
|
);
|
||||||
""")
|
""")
|
||||||
self._conn.commit()
|
self._conn.commit()
|
||||||
|
|
||||||
|
|
@ -192,6 +198,32 @@ class Database:
|
||||||
row = self._conn.execute("SELECT value FROM kv_store WHERE key = ?", (key,)).fetchone()
|
row = self._conn.execute("SELECT value FROM kv_store WHERE key = ?", (key,)).fetchone()
|
||||||
return row["value"] if row else None
|
return row["value"] if row else None
|
||||||
|
|
||||||
|
def kv_scan(self, prefix: str) -> list[tuple[str, str]]:
|
||||||
|
"""Return all key-value pairs where key starts with prefix."""
|
||||||
|
rows = self._conn.execute(
|
||||||
|
"SELECT key, value FROM kv_store WHERE key LIKE ?", (prefix + "%",)
|
||||||
|
).fetchall()
|
||||||
|
return [(r["key"], r["value"]) for r in rows]
|
||||||
|
|
||||||
|
# -- Notifications --
|
||||||
|
|
||||||
|
def add_notification(self, message: str, category: str = "clickup") -> int:
|
||||||
|
now = _now()
|
||||||
|
cur = self._conn.execute(
|
||||||
|
"INSERT INTO notifications (message, category, created_at) VALUES (?, ?, ?)",
|
||||||
|
(message, category, now),
|
||||||
|
)
|
||||||
|
self._conn.commit()
|
||||||
|
return cur.lastrowid
|
||||||
|
|
||||||
|
def get_notifications_after(self, after_id: int = 0, limit: int = 50) -> list[dict]:
|
||||||
|
"""Get notifications with id > after_id."""
|
||||||
|
rows = self._conn.execute(
|
||||||
|
"SELECT id, message, category, created_at FROM notifications WHERE id > ? ORDER BY id ASC LIMIT ?",
|
||||||
|
(after_id, limit),
|
||||||
|
).fetchall()
|
||||||
|
return [dict(r) for r in rows]
|
||||||
|
|
||||||
|
|
||||||
def _now() -> str:
|
def _now() -> str:
|
||||||
return datetime.now(timezone.utc).isoformat()
|
return datetime.now(timezone.utc).isoformat()
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue