新增后台数据库备份与回滚
This commit is contained in:
82
backend/app/api/routes/admin_backups.py
Normal file
82
backend/app/api/routes/admin_backups.py
Normal file
@@ -0,0 +1,82 @@
|
||||
from fastapi import APIRouter, Body, Depends, HTTPException, status
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
from app.api.deps import require_roles
|
||||
from app.db.session import SessionLocal, get_db
|
||||
from app.models import AdminUser
|
||||
from app.schemas.backup import (
|
||||
CreateDatabaseBackupRequest,
|
||||
DatabaseBackupOut,
|
||||
RestoreDatabaseBackupOut,
|
||||
RestoreDatabaseBackupRequest,
|
||||
)
|
||||
from app.services.db_backup import BackupError, create_database_backup, list_database_backups, restore_database_backup
|
||||
from app.services.logs import log_action
|
||||
|
||||
router = APIRouter()
|
||||
|
||||
|
||||
@router.get("", response_model=list[DatabaseBackupOut])
|
||||
def list_backups(
|
||||
_: AdminUser = Depends(require_roles("system_admin")),
|
||||
) -> list[dict[str, object]]:
|
||||
return list_database_backups()
|
||||
|
||||
|
||||
@router.post("", response_model=DatabaseBackupOut)
|
||||
def create_backup(
|
||||
payload: CreateDatabaseBackupRequest | None = Body(default=None),
|
||||
db: Session = Depends(get_db),
|
||||
current_admin: AdminUser = Depends(require_roles("system_admin")),
|
||||
) -> dict[str, object]:
|
||||
try:
|
||||
backup = create_database_backup(reason=payload.reason if payload else "manual")
|
||||
except BackupError as exc:
|
||||
raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=str(exc)) from exc
|
||||
|
||||
log_action(
|
||||
db,
|
||||
current_admin,
|
||||
"create_database_backup",
|
||||
"database_backup",
|
||||
backup["filename"],
|
||||
detail={
|
||||
"filename": backup["filename"],
|
||||
"database_type": backup["database_type"],
|
||||
"size_label": backup["size_label"],
|
||||
"reason": backup.get("reason"),
|
||||
},
|
||||
)
|
||||
db.commit()
|
||||
return backup
|
||||
|
||||
|
||||
@router.post("/{filename}/restore", response_model=RestoreDatabaseBackupOut)
|
||||
def restore_backup(
|
||||
filename: str,
|
||||
payload: RestoreDatabaseBackupRequest,
|
||||
db: Session = Depends(get_db),
|
||||
current_admin: AdminUser = Depends(require_roles("system_admin")),
|
||||
) -> dict[str, object]:
|
||||
db.close()
|
||||
try:
|
||||
result = restore_database_backup(filename, payload.confirmation)
|
||||
except BackupError as exc:
|
||||
raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=str(exc)) from exc
|
||||
|
||||
with SessionLocal() as log_db:
|
||||
log_action(
|
||||
log_db,
|
||||
current_admin,
|
||||
"restore_database_backup",
|
||||
"database_backup",
|
||||
filename,
|
||||
detail={
|
||||
"filename": filename,
|
||||
"restored_backup": result["restored_backup"],
|
||||
"pre_restore_backup": result["pre_restore_backup"],
|
||||
},
|
||||
)
|
||||
log_db.commit()
|
||||
|
||||
return result
|
||||
Reference in New Issue
Block a user