""" =============================================================================== FILE: services/tasks/exporter.py PROJECT: SCUD Orion AI (Unified Architecture) MODULE: services / tasks ROLE: Экспорт задач в чистый Markdown и генерация прямой ссылки на скачивание. =============================================================================== """ import os import uuid from typing import Dict, Any, Optional from config import BASE_DIR from .repository import repo_get_tasks WEB_OUTPUT_DIR = os.path.join(BASE_DIR, "output", "web", "db_export_tasks_markdown") def export_tasks_to_markdown( user_id: int, filename: Optional[str] = "ROADMAP.md", status_filter: Optional[str] = None ) -> Dict[str, Any]: tasks = repo_get_tasks(user_id=user_id, status=status_filter) safe_filename = os.path.basename(filename or "ROADMAP.md") if not safe_filename.endswith(".md"): safe_filename += ".md" session_uuid = str(uuid.uuid4())[:8] target_dir = os.path.join(WEB_OUTPUT_DIR, session_uuid) os.makedirs(target_dir, exist_ok=True) target_filepath = os.path.join(target_dir, safe_filename) lines = [ f"# 📋 Реестр задач проекта ({safe_filename})", f"**Всего задач:** {len(tasks)} ", f"**Пользователь ID:** {user_id} ", "", "| ID | Статус | Приоритет | Модуль | Срок | Задача |", "| :--- | :--- | :--- | :--- | :--- | :--- |" ] status_icons = { "IN_PROGRESS": "⚙️ В работе", "COMPLETED": "✓ Завершено", "BACKLOG": "📋 Бэклог" } for t in tasks: t_id = t.get("task_id") or f"#{t.get('id')}" t_status = status_icons.get(t.get("status"), t.get("status", "BACKLOG")) t_prio = t.get("priority", "MEDIUM") t_mod = t.get("module", "general") t_due = t.get("due_date") or "—" t_title = str(t.get("title", "")).replace("|", "\\|").strip() lines.append(f"| `{t_id}` | {t_status} | {t_prio} | `{t_mod}` | {t_due} | {t_title} |") lines.append("") content = "\n".join(lines) with open(target_filepath, "w", encoding="utf-8") as f: f.write(content) download_url = f"/api/v1/files/download/db_export_tasks_markdown/{session_uuid}/{safe_filename}" return { "status": "success", "message": f"Отчет успешно сформирован в файл `{safe_filename}` (всего задач: {len(tasks)}).", "filename": safe_filename, "download_url": download_url, "tasks_count": len(tasks) }