61 lines
2.2 KiB
Python
61 lines
2.2 KiB
Python
|
|
"""Lifecycle für media_assets (Papierkorb) — MEDIA_ASSETS_AND_ARCHIVE_SPEC §5."""
|
||
|
|
from __future__ import annotations
|
||
|
|
|
||
|
|
from typing import Literal
|
||
|
|
|
||
|
|
from fastapi import APIRouter, Depends, HTTPException
|
||
|
|
from pydantic import BaseModel
|
||
|
|
|
||
|
|
from db import get_db, get_cursor
|
||
|
|
from tenant_context import TenantContext, get_tenant_context
|
||
|
|
from media_lifecycle import (
|
||
|
|
assert_can_manage_media_asset_lifecycle,
|
||
|
|
fetch_media_asset_row,
|
||
|
|
purge_media_asset,
|
||
|
|
transition_recover_from_hidden,
|
||
|
|
transition_to_trash_hidden,
|
||
|
|
transition_to_trash_soft,
|
||
|
|
)
|
||
|
|
|
||
|
|
router = APIRouter(prefix="/api/media-assets", tags=["media-assets"])
|
||
|
|
|
||
|
|
|
||
|
|
class MediaLifecycleBody(BaseModel):
|
||
|
|
action: Literal["trash_soft", "trash_hidden", "recover", "purge"]
|
||
|
|
|
||
|
|
|
||
|
|
@router.post("/{asset_id}/lifecycle")
|
||
|
|
def post_media_asset_lifecycle(
|
||
|
|
asset_id: int,
|
||
|
|
body: MediaLifecycleBody,
|
||
|
|
tenant: TenantContext = Depends(get_tenant_context),
|
||
|
|
):
|
||
|
|
"""Papierkorb-Übergänge (manuell). Rechte gemäß Spec §5.2."""
|
||
|
|
with get_db() as conn:
|
||
|
|
cur = get_cursor(conn)
|
||
|
|
asset = fetch_media_asset_row(cur, asset_id)
|
||
|
|
if not asset:
|
||
|
|
raise HTTPException(status_code=404, detail="Medium nicht gefunden")
|
||
|
|
assert_can_manage_media_asset_lifecycle(cur, tenant, asset)
|
||
|
|
|
||
|
|
action = body.action
|
||
|
|
if action == "trash_soft":
|
||
|
|
return transition_to_trash_soft(cur, conn, asset_id)
|
||
|
|
if action == "trash_hidden":
|
||
|
|
return transition_to_trash_hidden(cur, conn, asset_id)
|
||
|
|
if action == "recover":
|
||
|
|
return transition_recover_from_hidden(cur, conn, asset_id)
|
||
|
|
if action == "purge":
|
||
|
|
state = (asset.get("lifecycle_state") or "").strip().lower()
|
||
|
|
if state != "trash_hidden":
|
||
|
|
raise HTTPException(
|
||
|
|
status_code=400,
|
||
|
|
detail="Nur ausgeblendete Medien (Stufe 2) dürfen endgültig gelöscht werden",
|
||
|
|
)
|
||
|
|
ok = purge_media_asset(cur, conn, asset_id)
|
||
|
|
if not ok:
|
||
|
|
raise HTTPException(status_code=400, detail="Löschen nicht möglich")
|
||
|
|
return {"ok": True, "purged": asset_id}
|
||
|
|
|
||
|
|
raise HTTPException(status_code=500, detail="Interner Fehler: lifecycle action")
|