62 lines
1.9 KiB
Python
62 lines
1.9 KiB
Python
"""Storage contract for the generated-file library index."""
|
|
|
|
from __future__ import annotations
|
|
|
|
from abc import ABC, abstractmethod
|
|
from typing import Any
|
|
|
|
|
|
class ArtifactLibraryStore(ABC):
|
|
"""A user-scoped, replace-on-sync artifact metadata index."""
|
|
|
|
@abstractmethod
|
|
async def claim_sync(
|
|
self,
|
|
user_id: str,
|
|
*,
|
|
force: bool = False,
|
|
stale_after_seconds: float = 15.0,
|
|
lease_seconds: float = 300.0,
|
|
) -> str | None:
|
|
"""Claim one background refresh and return its generation token.
|
|
|
|
``None`` means another worker owns a live lease or the persisted index
|
|
is still fresh enough. Implementations must make this operation safe
|
|
when multiple Gateway workers receive the same request concurrently.
|
|
"""
|
|
raise NotImplementedError
|
|
|
|
@abstractmethod
|
|
async def finish_sync(
|
|
self,
|
|
user_id: str,
|
|
generation: str,
|
|
items: list[dict[str, Any]],
|
|
) -> bool:
|
|
"""Atomically publish ``items`` when ``generation`` still owns the lease."""
|
|
raise NotImplementedError
|
|
|
|
@abstractmethod
|
|
async def fail_sync(self, user_id: str, generation: str, error: str) -> bool:
|
|
"""Record a failed refresh when ``generation`` still owns the lease."""
|
|
raise NotImplementedError
|
|
|
|
@abstractmethod
|
|
async def get_sync_state(self, user_id: str) -> dict[str, Any]:
|
|
"""Return the persisted refresh state for one user."""
|
|
raise NotImplementedError
|
|
|
|
@abstractmethod
|
|
async def list_items(
|
|
self,
|
|
user_id: str,
|
|
*,
|
|
query: str | None = None,
|
|
file_kind: str = "all",
|
|
source_type: str = "all",
|
|
offset: int = 0,
|
|
limit: int = 50,
|
|
) -> tuple[int, list[dict[str, Any]]]:
|
|
"""Return an indexed, newest-first page and its filtered total."""
|
|
raise NotImplementedError
|