Coverage for arclith / application / use_cases / purge.py: 100%
21 statements
« prev ^ index » next coverage.py v7.13.5, created at 2026-03-25 15:02 +0100
« prev ^ index » next coverage.py v7.13.5, created at 2026-03-25 15:02 +0100
1from datetime import datetime, timedelta, timezone
2from typing import Generic, TypeVar
4from arclith.domain.models.entity import Entity
5from arclith.domain.ports.logger import Logger
6from arclith.domain.ports.repository import Repository
8T = TypeVar("T", bound=Entity)
11class PurgeUseCase(Generic[T]):
12 def __init__(self, repository: Repository[T], logger: Logger, retention_days: float | None = None) -> None:
13 self._repository = repository
14 self._logger = logger
15 self._retention_days = retention_days
17 async def execute(self) -> int:
18 if self._retention_days is None:
19 self._logger.info("⏭️ Purge skipped — retention is infinite")
20 return 0
22 cutoff = datetime.now(timezone.utc) - timedelta(days=self._retention_days)
23 expired = [
24 e for e in await self._repository.find_deleted()
25 if e.deleted_at is not None and e.deleted_at <= cutoff
26 ]
28 for entity in expired:
29 await self._repository.delete(entity.uuid)
31 self._logger.info("🧹 Purge complete", purged=len(expired), retention_days=self._retention_days)
32 return len(expired)