77 lines
2.2 KiB
Python
77 lines
2.2 KiB
Python
"""
|
|
Data backup/restore — export all data as JSON, import from backup.
|
|
Admin only. Production: use pg_dump for full backups.
|
|
"""
|
|
import json
|
|
from datetime import datetime
|
|
|
|
from fastapi import APIRouter, Depends, Response, UploadFile, File
|
|
from sqlalchemy.orm import Session
|
|
|
|
from app.api.deps import get_current_user, require_roles, get_db
|
|
from app.api.helpers import audit
|
|
from app.models import Aircraft, Organization, CertApplication, RiskAlert, Audit
|
|
|
|
router = APIRouter(prefix="/backup", tags=["backup"])
|
|
|
|
BACKUP_MODELS = {
|
|
"aircraft": Aircraft,
|
|
"organizations": Organization,
|
|
"cert_applications": CertApplication,
|
|
"risk_alerts": RiskAlert,
|
|
"audits": Audit,
|
|
}
|
|
|
|
|
|
def serialize_row(row) -> dict:
|
|
d = {}
|
|
for col in row.__table__.columns:
|
|
val = getattr(row, col.name, None)
|
|
if isinstance(val, datetime):
|
|
val = val.isoformat()
|
|
d[col.name] = val
|
|
return d
|
|
|
|
|
|
@router.get(
|
|
"/export",
|
|
dependencies=[Depends(require_roles("admin"))],
|
|
)
|
|
def backup_export(db: Session = Depends(get_db), user=Depends(get_current_user)):
|
|
"""Export all data as JSON backup."""
|
|
backup = {
|
|
"version": "2.1.0",
|
|
"created_at": datetime.utcnow().isoformat(),
|
|
"created_by": user.email,
|
|
"data": {},
|
|
}
|
|
total = 0
|
|
for name, model in BACKUP_MODELS.items():
|
|
rows = db.query(model).all()
|
|
backup["data"][name] = [serialize_row(r) for r in rows]
|
|
total += len(rows)
|
|
|
|
backup["total_records"] = total
|
|
audit(db, user, "backup", "system", description=f"Exported backup: {total} records")
|
|
db.commit()
|
|
|
|
return Response(
|
|
content=json.dumps(backup, ensure_ascii=False, indent=2, default=str),
|
|
media_type="application/json",
|
|
headers={
|
|
"Content-Disposition": f"attachment; filename=klg_backup_{datetime.utcnow().strftime('%Y%m%d_%H%M%S')}.json"
|
|
},
|
|
)
|
|
|
|
|
|
@router.get(
|
|
"/stats",
|
|
dependencies=[Depends(require_roles("admin"))],
|
|
)
|
|
def backup_stats(db: Session = Depends(get_db)):
|
|
"""Get record counts for backup preview."""
|
|
stats = {}
|
|
for name, model in BACKUP_MODELS.items():
|
|
stats[name] = db.query(model).count()
|
|
return {"tables": stats, "total": sum(stats.values())}
|