from fastapi import APIRouter, Depends, status from fastapi.responses import FileResponse from sqlalchemy.orm import Session from starlette.requests import Request from app.core.rbac import require_permission from app.db.database import get_db from app.models.user import User from app.schemas.api_response import ApiSuccess from app.schemas.backup import BackupRestoreRequest from app.services.audit_service import write_audit_log from app.services.backup_service import BackupService router = APIRouter(prefix="/backups", tags=["Backups"]) @router.get("", response_model=ApiSuccess) def list_backups( db: Session = Depends(get_db), current_user: User = Depends(require_permission("backup.read")), ): return ApiSuccess(data=BackupService.list_backups(), message="Backups geladen") @router.post("/create", response_model=ApiSuccess, status_code=status.HTTP_201_CREATED) def create_backup( request: Request, db: Session = Depends(get_db), current_user: User = Depends(require_permission("backup.create")), ): backup = BackupService.create_backup(actor=current_user) write_audit_log( db, action="backups.create", entity_type="backup", entity_label=backup.filename, actor=current_user, request=request, metadata={ "filename": backup.filename, "size_bytes": backup.size_bytes, "app_version": backup.app_version, }, ) return ApiSuccess(data=backup, message="Backup erstellt") @router.get("/{filename}/download") def download_backup( filename: str, request: Request, db: Session = Depends(get_db), current_user: User = Depends(require_permission("backup.download")), ): path = BackupService.resolve_backup_path(filename) write_audit_log( db, action="backups.download", entity_type="backup", entity_label=path.name, actor=current_user, request=request, metadata={"filename": path.name, "size_bytes": path.stat().st_size}, ) return FileResponse(path=path, media_type="application/zip", filename=path.name) @router.delete("/{filename}", response_model=ApiSuccess) def delete_backup( filename: str, request: Request, db: Session = Depends(get_db), current_user: User = Depends(require_permission("backup.delete")), ): path = BackupService.resolve_backup_path(filename) size_bytes = path.stat().st_size BackupService.delete_backup(filename) write_audit_log( db, action="backups.delete", entity_type="backup", entity_label=path.name, actor=current_user, request=request, metadata={"filename": path.name, "size_bytes": size_bytes}, ) return ApiSuccess(message="Backup geloescht") @router.post("/{filename}/restore/validate", response_model=ApiSuccess) def validate_backup_restore( filename: str, request: Request, db: Session = Depends(get_db), current_user: User = Depends(require_permission("backup.restore")), ): validation = BackupService.validate_backup(filename) write_audit_log( db, action="backups.validate", entity_type="backup", entity_label=filename, actor=current_user, request=request, metadata={"filename": filename, "valid": validation.valid, "issues": validation.issues}, ) return ApiSuccess(data=validation, message=validation.message) @router.post("/{filename}/restore", response_model=ApiSuccess) def restore_backup( filename: str, payload: BackupRestoreRequest, request: Request, db: Session = Depends(get_db), current_user: User = Depends(require_permission("backup.restore")), ): write_audit_log( db, action="backups.restore_started", entity_type="backup", entity_label=filename, actor=current_user, request=request, metadata={"filename": filename}, ) try: validation = BackupService.restore_backup(filename, confirm_text=payload.confirm_text) except Exception: write_audit_log( db, action="backups.restore_failed", entity_type="backup", entity_label=filename, actor=current_user, request=request, metadata={"filename": filename}, ) raise write_audit_log( db, action="backups.restore_completed", entity_type="backup", entity_label=filename, actor=current_user, request=request, metadata={"filename": filename}, ) return ApiSuccess(data=validation, message="Restore abgeschlossen")