""" User data export API endpoints for GDPR compliance Implements Article 15 (Right to Access) and Article 20 (Right to Data Portability) """ from uuid import UUID from fastapi import APIRouter, Depends, HTTPException, status from fastapi.responses import JSONResponse import structlog from shared.auth.decorators import get_current_user_dep from app.core.database import get_db from app.services.data_export_service import DataExportService logger = structlog.get_logger() router = APIRouter() @router.get("/api/v1/auth/me/export") async def export_my_data( current_user: dict = Depends(get_current_user_dep), db = Depends(get_db) ): """ Export all personal data for the current user GDPR Article 15 - Right of access by the data subject GDPR Article 20 - Right to data portability Returns complete user data in machine-readable JSON format including: - Personal information - Account data - Consent history - Security logs - Audit trail Response is provided in JSON format for easy data portability. """ try: user_id = UUID(current_user["user_id"]) export_service = DataExportService(db) data = await export_service.export_user_data(user_id) logger.info( "data_export_requested", user_id=str(user_id), email=current_user.get("email") ) return JSONResponse( content=data, status_code=status.HTTP_200_OK, headers={ "Content-Disposition": f'attachment; filename="user_data_export_{user_id}.json"', "Content-Type": "application/json" } ) except Exception as e: logger.error( "data_export_failed", user_id=current_user.get("user_id"), error=str(e) ) raise HTTPException( status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail="Failed to export user data" ) @router.get("/api/v1/auth/me/export/summary") async def get_export_summary( current_user: dict = Depends(get_current_user_dep), db = Depends(get_db) ): """ Get a summary of what data would be exported Useful for showing users what data we have about them before they request full export. """ try: user_id = UUID(current_user["user_id"]) export_service = DataExportService(db) data = await export_service.export_user_data(user_id) summary = { "user_id": str(user_id), "data_categories": { "personal_data": bool(data.get("personal_data")), "account_data": bool(data.get("account_data")), "consent_data": bool(data.get("consent_data")), "security_data": bool(data.get("security_data")), "onboarding_data": bool(data.get("onboarding_data")), "audit_logs": bool(data.get("audit_logs")) }, "data_counts": { "active_sessions": data.get("account_data", {}).get("active_sessions_count", 0), "consent_changes": data.get("consent_data", {}).get("total_consent_changes", 0), "login_attempts": len(data.get("security_data", {}).get("recent_login_attempts", [])), "audit_logs": data.get("audit_logs", {}).get("total_logs_exported", 0) }, "export_format": "JSON", "gdpr_articles": ["Article 15 (Right to Access)", "Article 20 (Data Portability)"] } return summary except Exception as e: logger.error( "export_summary_failed", user_id=current_user.get("user_id"), error=str(e) ) raise HTTPException( status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail="Failed to generate export summary" )