import os import json from datetime import datetime from typing import Any, Dict, List, Optional def ensure_storage_dirs() -> None: os.makedirs("./data", exist_ok=True) def write_jsonl(path: str, record: Dict[str, Any]) -> None: ensure_storage_dirs() with open(path, "a", encoding="utf-8") as f: f.write(json.dumps(record, default=_json_default) + "\n") def read_jsonl(path: str) -> List[Dict[str, Any]]: records: List[Dict[str, Any]] = [] if not os.path.exists(path): return records with open(path, "r", encoding="utf-8") as f: for line in f: line = line.strip() if line: records.append(json.loads(line)) return records def save_receipt(receipt: Dict[str, Any]) -> None: from app.config import Settings path = Settings().get("receipt_storage_path", "./data/receipts.jsonl") write_jsonl(path, receipt) def load_receipt_by_id(receipt_id: str) -> Optional[Dict[str, Any]]: from app.config import Settings path = Settings().get("receipt_storage_path", "./data/receipts.jsonl") for record in read_jsonl(path): if record.get("receipt_id") == receipt_id: return record return None def save_session_event(event: Dict[str, Any]) -> None: write_jsonl("./data/session_events.jsonl", event) def save_job_event(event: Dict[str, Any]) -> None: write_jsonl("./data/job_events.jsonl", event) def compact_old_sessions() -> None: # v1: no-op; v2 can rotate logs pass def _json_default(obj: Any) -> Any: if isinstance(obj, datetime): return obj.isoformat() raise TypeError(f"Object of type {type(obj)} is not JSON serializable")