feat(kevin_bridge): exit-scan daily job + cursor + audit writer
Some checks failed
ci/woodpecker/push/woodpecker Pipeline was canceled
Some checks failed
ci/woodpecker/push/woodpecker Pipeline was canceled
This commit is contained in:
parent
a417cae77b
commit
cff2564428
6 changed files with 480 additions and 0 deletions
28
services/kevin_signal_bridge/cursor.py
Normal file
28
services/kevin_signal_bridge/cursor.py
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
"""Redis-backed cursor for the bridge.
|
||||
|
||||
Tracks the highest `kevin_stock_mentions.id` we've already attempted to
|
||||
process. Stored at key `kevin:bridge:last_mention_id`.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import Any
|
||||
|
||||
|
||||
class RedisCursor:
|
||||
_KEY = "kevin:bridge:last_mention_id"
|
||||
|
||||
def __init__(self, redis: Any) -> None:
|
||||
self.redis = redis
|
||||
|
||||
async def last_seen_id(self) -> int:
|
||||
v = await self.redis.get(self._KEY)
|
||||
if v is None:
|
||||
return 0
|
||||
return int(v)
|
||||
|
||||
async def advance(self, mention_id: int) -> None:
|
||||
# Conservative: only set if mention_id > current
|
||||
current = await self.last_seen_id()
|
||||
if mention_id > current:
|
||||
await self.redis.set(self._KEY, str(mention_id))
|
||||
Loading…
Add table
Add a link
Reference in a new issue