from __future__ import annotations
import json
from datetime import UTC, datetime
from pathlib import Path
class Checkpoint:
"""Per-account cursor persistence.
File shape: `{"cursor": "...", "updated_at": "2026-04-17T12:00:00+00:00"}`
One file per (provider, account_id) at `
/-.json`.
"""
def __init__(self, directory: Path, *, provider: str, account_id: str) -> None:
self._path = directory / f"{provider}-{account_id}.json"
def load(self) -> str | None:
if not self._path.exists():
return None
raw = json.loads(self._path.read_text())
cursor = raw.get("cursor")
if not isinstance(cursor, str):
return None
return cursor
def save(self, cursor: str) -> None:
self._path.parent.mkdir(parents=True, exist_ok=True)
payload = {"cursor": cursor, "updated_at": datetime.now(UTC).isoformat()}
self._path.write_text(json.dumps(payload))