# retoor <retoor@molodetz.nl>
import logging
from typing import Annotated
from fastapi import APIRouter, Form, Request
from fastapi.responses import JSONResponse
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
logger = logging.getLogger(__name__)
router = APIRouter()
@router.post("/create")
async def create_issue(request: Request, data: Annotated[IssueForm, Form()]):
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(),
},
"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)],
)
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"))