diff --git a/app/core/jobs.py b/app/core/jobs.py index cd65619..704c438 100644 --- a/app/core/jobs.py +++ b/app/core/jobs.py @@ -165,6 +165,7 @@ async def _dsar_collect_user_data(db: Any, tenant_id: str, user_id: str) -> dict from datetime import UTC, datetime from uuid import UUID as PyUUID + from sqlalchemy import or_ as sa_or_ from sqlalchemy import select as sa_select from app.models.audit import AuditLog @@ -252,6 +253,105 @@ async def _dsar_collect_user_data(db: Any, tenant_id: str, user_id: str) -> dict for n in notifications ] + # ── Categories promised by the dsgvo-export route docstring ── + # (G1-b: mail accounts, tasks, calendar entries, comm messages) + try: + from app.plugins.builtins.mail.models import MailAccount + + mail_accounts = ( + await db.execute( + sa_select(MailAccount).where( + MailAccount.tenant_id == tid, + MailAccount.user_id == uid, + ).limit(500) + ) + ).scalars().all() + export_data["data"]["mail_accounts"] = [ + { + "id": str(a.id), + "email_address": a.email_address, + "display_name": a.display_name, + "is_shared": a.is_shared, + "is_active": a.is_active, + } + for a in mail_accounts + ] + except ImportError: + pass + + try: + from app.plugins.builtins.tasks.models import Task as TaskModel + + tasks = ( + await db.execute( + sa_select(TaskModel).where( + sa_or_(TaskModel.owner_id == uid, TaskModel.assigned_to == uid), + TaskModel.tenant_id == tid, + TaskModel.deleted_at.is_(None), + ).limit(1000) + ) + ).scalars().all() + export_data["data"]["tasks"] = [ + { + "id": str(t.id), + "title": t.title, + "status": t.status, + "priority": t.priority, + "due_date": t.due_date.isoformat() if t.due_date else None, + } + for t in tasks + ] + except ImportError: + pass + + try: + from app.plugins.builtins.calendar.models import CalendarEntry as CalEntry + + cal_entries = ( + await db.execute( + sa_select(CalEntry).where( + CalEntry.tenant_id == tid, + CalEntry.owner_id == uid, + CalEntry.deleted_at.is_(None), + ).limit(1000) + ) + ).scalars().all() + export_data["data"]["calendar_entries"] = [ + { + "id": str(e.id), + "title": e.title, + "entry_type": e.entry_type, + "start_at": e.start_at.isoformat() if e.start_at else None, + "end_at": e.end_at.isoformat() if e.end_at else None, + } + for e in cal_entries + ] + except ImportError: + pass + + try: + from app.plugins.builtins.kommunikation.models import CommMessage + + comm_messages = ( + await db.execute( + sa_select(CommMessage).where( + CommMessage.sender_id == uid, + CommMessage.tenant_id == tid, + ).limit(1000) + ) + ).scalars().all() + export_data["data"]["comm_messages"] = [ + { + "id": str(m.id), + "sender_type": m.sender_type, + "content": m.content[:500], + "created_at": m.created_at.isoformat() if m.created_at else None, + } + for m in comm_messages + ] + except ImportError: + pass + return export_data