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
PeninsulaInd 2026-02-15 22:26:38 -06:00
parent f34d7507c2
commit 0b7950cefa
1 changed files with 32 additions and 0 deletions

View File

@ -65,6 +65,12 @@ class Database:
key TEXT PRIMARY KEY,
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()
@ -192,6 +198,32 @@ class Database:
row = self._conn.execute("SELECT value FROM kv_store WHERE key = ?", (key,)).fetchone()
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:
return datetime.now(timezone.utc).isoformat()