| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081 |
- """Archive auto-purge endpoints (#1008 follow-up).
- Admin-only (``ARCHIVES_PURGE``). Provides:
- * ``GET /archives/purge/preview`` — live count for the admin slider
- * ``POST /archives/purge`` — one-shot manual bulk delete
- * ``GET/PUT /archives/purge/settings`` — auto-purge toggle + threshold
- """
- from __future__ import annotations
- import logging
- from fastapi import APIRouter, Depends, HTTPException, Query
- from sqlalchemy.ext.asyncio import AsyncSession
- from backend.app.core.auth import require_permission_if_auth_enabled
- from backend.app.core.database import get_db
- from backend.app.core.permissions import Permission
- from backend.app.models.user import User
- from backend.app.schemas.archive_purge import (
- ArchivePurgePreviewResponse,
- ArchivePurgeRequest,
- ArchivePurgeResponse,
- ArchivePurgeSettings,
- )
- from backend.app.services.archive_purge import (
- MAX_AUTO_PURGE_DAYS,
- MIN_AUTO_PURGE_DAYS,
- archive_purge_service,
- )
- logger = logging.getLogger(__name__)
- router = APIRouter(prefix="/archives", tags=["archives-purge"])
- @router.get("/purge/preview", response_model=ArchivePurgePreviewResponse)
- async def preview_archive_purge(
- older_than_days: int = Query(ge=1, le=3650),
- db: AsyncSession = Depends(get_db),
- _: User | None = Depends(require_permission_if_auth_enabled(Permission.ARCHIVES_PURGE)),
- ):
- """Count + size of archives eligible for purge. Read-only."""
- result = await archive_purge_service.preview_purge(db, older_than_days=older_than_days)
- return ArchivePurgePreviewResponse(**result)
- @router.post("/purge", response_model=ArchivePurgeResponse)
- async def execute_archive_purge(
- body: ArchivePurgeRequest,
- db: AsyncSession = Depends(get_db),
- _: User | None = Depends(require_permission_if_auth_enabled(Permission.ARCHIVES_PURGE)),
- ):
- """Hard-delete archives older than the threshold. Irreversible."""
- deleted = await archive_purge_service.purge_older_than(db, older_than_days=body.older_than_days)
- return ArchivePurgeResponse(deleted=deleted)
- @router.get("/purge/settings", response_model=ArchivePurgeSettings)
- async def get_archive_purge_settings(
- db: AsyncSession = Depends(get_db),
- _: User | None = Depends(require_permission_if_auth_enabled(Permission.ARCHIVES_PURGE)),
- ):
- cfg = await archive_purge_service.get_settings(db)
- return ArchivePurgeSettings(enabled=cfg["enabled"], days=cfg["days"])
- @router.put("/purge/settings", response_model=ArchivePurgeSettings)
- async def update_archive_purge_settings(
- body: ArchivePurgeSettings,
- db: AsyncSession = Depends(get_db),
- _: User | None = Depends(require_permission_if_auth_enabled(Permission.ARCHIVES_PURGE)),
- ):
- if body.days < MIN_AUTO_PURGE_DAYS or body.days > MAX_AUTO_PURGE_DAYS:
- raise HTTPException(
- status_code=400,
- detail=f"days must be between {MIN_AUTO_PURGE_DAYS} and {MAX_AUTO_PURGE_DAYS}",
- )
- saved = await archive_purge_service.set_settings(db, enabled=body.enabled, days=body.days)
- return ArchivePurgeSettings(enabled=saved["enabled"], days=saved["days"])
|