from fastapi import APIRouter, Depends, HTTPException, UploadFile, File from sqlalchemy.orm import Session from typing import List from fastapi.responses import FileResponse from ... import schemas, auth, models from ...database import get_db from ...db_manager import DbManager router = APIRouter( prefix="/admin/db", tags=["Admin Database Backups"] ) @router.get("/backups", response_model=List[schemas.BackupInfo]) def get_backups( db: Session = Depends(get_db), current_admin: auth.TokenData = Depends(auth.get_current_admin) ): """List available database backups.""" return DbManager.get_backup_list() @router.get("/stats", response_model=schemas.DatabaseStats) def get_db_stats( db: Session = Depends(get_db), current_admin: auth.TokenData = Depends(auth.get_current_admin) ): """Get database backup storage statistics.""" return DbManager.get_stats() @router.post("/backup", response_model=schemas.BackupInfo) def trigger_manual_backup( db: Session = Depends(get_db), current_admin: auth.TokenData = Depends(auth.get_current_admin) ): """Trigger a manual database backup.""" filename = DbManager.create_backup(db, label="manual", user_id=current_admin.sub) backups = DbManager.get_backup_list() for b in backups: if b.filename == filename: return b raise HTTPException(status_code=500, detail="Backup created but info not found") @router.post("/restore") def restore_database( payload: dict, db: Session = Depends(get_db), current_admin: auth.TokenData = Depends(auth.get_current_admin) ): """Restore database from a specific file. DANGEROUS.""" filename = payload.get("filename") confirm = payload.get("confirm", False) if not filename: raise HTTPException(status_code=400, detail="Filename required") if not confirm: raise HTTPException(status_code=400, detail="Confirmation required") try: DbManager.restore_backup(filename, db, user_id=current_admin.sub) return {"status": "success", "message": f"Database restored from {filename}"} except Exception as e: raise HTTPException(status_code=500, detail=str(e)) @router.get("/export") def export_database( current_admin: auth.TokenData = Depends(auth.get_current_admin) ): """Download the current database file.""" try: path = DbManager.export_db() return FileResponse( path, media_type="application/x-sqlite3", filename="inventory_export.db" ) except Exception as e: raise HTTPException(status_code=500, detail=str(e)) @router.post("/import") async def import_database( file: UploadFile = File(...), db: Session = Depends(get_db), current_admin: auth.TokenData = Depends(auth.get_current_admin) ): """Upload and replace the current database. DANGEROUS.""" contents = await file.read() try: DbManager.import_db(contents, db, user_id=current_admin.sub) return {"status": "success", "message": "Database successfully imported and replaced."} except Exception as e: raise HTTPException(status_code=500, detail=str(e))