# retoor import logging from typing import Annotated from fastapi import Depends, APIRouter, Request from fastapi.responses import JSONResponse from devplacepy.attachments import get_orphan_attachments_batch, split_attachment_uids from devplacepy.models import IssueForm from devplacepy.responses import json_error from devplacepy.schemas import IssueJobOut from devplacepy.services.audit import record as audit from devplacepy.services.gitea.config import gitea_config from devplacepy.services.jobs import queue from devplacepy.utils import not_found, require_user, track_action from devplacepy.dependencies import json_or_form logger = logging.getLogger(__name__) router = APIRouter() @router.post("/create") async def create_issue(request: Request, data: Annotated[IssueForm, Depends(json_or_form(IssueForm))]): user = require_user(request) if not gitea_config().is_configured: return json_error(503, "The issue tracker is not configured") title = data.title.strip() uid = queue.enqueue( "issue_create", { "author_uid": user["uid"], "title": title, "description": data.description.strip(), "attachment_uids": get_orphan_attachments_batch( split_attachment_uids(data.attachment_uids), user ), }, "user", user["uid"], title[:64], ) audit.record( request, "issue.create.request", user=user, target_type="issue", summary=f"{user['username']} requested an issue report: {title[:60]}", metadata={"title": title}, links=[audit.job(uid)], ) track_action(user["uid"], "issue") logger.info("Issue report enqueued by %s: %s", user["username"], title[:60]) return JSONResponse({"uid": uid, "status_url": f"/issues/jobs/{uid}"}) @router.get("/jobs/{uid}") async def issue_job_status(request: Request, uid: str): job = queue.get_job(uid) if not job or job.get("kind") != "issue_create": raise not_found("Job not found") result = job.get("result", {}) done = job.get("status") == queue.DONE payload = { "uid": job.get("uid", ""), "kind": job.get("kind", ""), "status": job.get("status", ""), "number": result.get("number") if done else None, "issue_url": result.get("issue_url") if done else None, "enhanced": bool(result.get("enhanced")) if done else False, "error": job.get("error") or None, "created_at": job.get("created_at"), "completed_at": job.get("completed_at") or None, } return JSONResponse(IssueJobOut.model_validate(payload).model_dump(mode="json"))