|
# retoor <retoor@molodetz.nl>
|
|
|
|
from .._shared import endpoint, field
|
|
|
|
GROUP = {
|
|
"slug": "issues",
|
|
"title": "Issue Reports",
|
|
"intro": """
|
|
# Issue Reports
|
|
|
|
The issue tracker is a full integration with a Gitea repository. The listing and detail views read
|
|
issues straight from Gitea with their live status, and a report you file is first rewritten by the
|
|
internal AI service into a consistent ticket, then posted to Gitea as an issue. The original
|
|
reporter is notified when a developer replies or the status changes, and a comment posted here is
|
|
pushed to Gitea and attributed to your account.
|
|
|
|
Every endpoint follows the shared [Conventions & Errors](/docs/conventions.html) (auth, content
|
|
negotiation, pagination, status codes); see [Authentication](/docs/authentication.html) for the
|
|
four ways to sign requests.
|
|
""",
|
|
"endpoints": [
|
|
endpoint(
|
|
id="issues-list",
|
|
method="GET",
|
|
path="/issues",
|
|
title="List issue tickets",
|
|
summary="Render the issue board from Gitea, paginated and filterable by state.",
|
|
auth="public",
|
|
interactive=True,
|
|
params=[
|
|
field(
|
|
"state",
|
|
"query",
|
|
"string",
|
|
False,
|
|
"open",
|
|
"Filter: open (default), closed, or all.",
|
|
),
|
|
field("page", "query", "integer", False, "1", "1-based page."),
|
|
],
|
|
),
|
|
endpoint(
|
|
id="issues-create",
|
|
method="POST",
|
|
path="/issues/create",
|
|
title="Report an issue",
|
|
summary="Enqueue an issue report. It is enhanced by AI and filed on the tracker.",
|
|
auth="user",
|
|
encoding="form",
|
|
ajax=True,
|
|
destructive=True,
|
|
params=[
|
|
field(
|
|
"title",
|
|
"form",
|
|
"string",
|
|
True,
|
|
"Login button misaligned",
|
|
"Title, 1-200 characters.",
|
|
),
|
|
field(
|
|
"description",
|
|
"form",
|
|
"textarea",
|
|
True,
|
|
"Steps to reproduce...",
|
|
"Description, 1-5000 characters.",
|
|
),
|
|
],
|
|
notes=["Returns a job uid and status_url. Poll the status_url until status is done to get the issue number."],
|
|
sample_response={
|
|
"uid": "JOB_UID",
|
|
"status_url": "/issues/jobs/JOB_UID",
|
|
},
|
|
),
|
|
endpoint(
|
|
id="issues-job",
|
|
method="GET",
|
|
path="/issues/jobs/{uid}",
|
|
title="Issue filing job status",
|
|
summary="Poll the filing job; the result carries the new issue number and url.",
|
|
auth="public",
|
|
ajax=True,
|
|
params=[field("uid", "path", "string", True, "JOB_UID", "Job uid.")],
|
|
sample_response={
|
|
"uid": "JOB_UID",
|
|
"kind": "issue_create",
|
|
"status": "done",
|
|
"number": 42,
|
|
"issue_url": "/issues/42",
|
|
"enhanced": True,
|
|
"error": None,
|
|
"created_at": "2026-06-12T09:00:00+00:00",
|
|
"completed_at": "2026-06-12T09:00:03+00:00",
|
|
},
|
|
),
|
|
endpoint(
|
|
id="issues-planning-queue",
|
|
method="POST",
|
|
path="/issues/planning",
|
|
title="Generate a tickets planning report",
|
|
summary="Enqueue a phased markdown implementation document for open tickets, with each ticket's full description reproduced verbatim (inline plus a Source Tickets appendix) alongside implementation steps and acceptance criteria. Admin only.",
|
|
auth="admin",
|
|
encoding="form",
|
|
ajax=True,
|
|
params=[field("numbers", "form", "string", False, "1,4,7", "Comma-separated issue numbers to include. Omit to plan every open ticket.")],
|
|
notes=["Returns a job uid and status_url. Poll the status_url until status is done to read the markdown and download it.", "Provide 'numbers' to plan only a chosen subset of open tickets; omitting it plans all open tickets."],
|
|
sample_response={
|
|
"uid": "PLANNING_JOB_UID",
|
|
"status_url": "/issues/planning/PLANNING_JOB_UID",
|
|
},
|
|
),
|
|
endpoint(
|
|
id="issues-planning-status",
|
|
method="GET",
|
|
path="/issues/planning/{uid}",
|
|
title="Planning report job status",
|
|
summary="Poll the planning job; the result carries the rendered markdown and the download URL. Admin only.",
|
|
auth="admin",
|
|
ajax=True,
|
|
params=[field("uid", "path", "string", True, "PLANNING_JOB_UID", "Planning job uid.")],
|
|
sample_response={
|
|
"uid": "PLANNING_JOB_UID",
|
|
"kind": "planning",
|
|
"status": "done",
|
|
"download_url": "/issues/planning/PLANNING_JOB_UID/download",
|
|
"markdown": "# Open Tickets Implementation Plan\n\n...",
|
|
"ai_used": True,
|
|
"issue_count": 12,
|
|
"bytes_out": 4096,
|
|
"error": None,
|
|
"created_at": "2026-06-15T09:00:00+00:00",
|
|
"completed_at": "2026-06-15T09:00:05+00:00",
|
|
},
|
|
),
|
|
endpoint(
|
|
id="issues-planning-download",
|
|
method="GET",
|
|
path="/issues/planning/{uid}/download",
|
|
title="Download the planning report",
|
|
summary="Download the generated planning report as a markdown file. Admin only.",
|
|
auth="admin",
|
|
interactive=True,
|
|
params=[field("uid", "path", "string", True, "PLANNING_JOB_UID", "Planning job uid.")],
|
|
),
|
|
endpoint(
|
|
id="issues-detail",
|
|
method="GET",
|
|
path="/issues/{number}",
|
|
title="View an issue ticket",
|
|
summary="Render a Gitea issue and its comments. Returns an HTML page.",
|
|
auth="public",
|
|
interactive=True,
|
|
params=[
|
|
field("number", "path", "integer", True, "12", "Issue number.")
|
|
],
|
|
),
|
|
endpoint(
|
|
id="issues-comment",
|
|
method="POST",
|
|
path="/issues/{number}/comment",
|
|
title="Comment on an issue",
|
|
summary="Post a comment to the Gitea issue, attributed to the current user.",
|
|
auth="user",
|
|
encoding="form",
|
|
destructive=True,
|
|
params=[
|
|
field("number", "path", "integer", True, "12", "Issue number."),
|
|
field(
|
|
"body",
|
|
"form",
|
|
"textarea",
|
|
True,
|
|
"I can reproduce this on mobile.",
|
|
"Comment, 1-5000 characters.",
|
|
),
|
|
],
|
|
),
|
|
endpoint(
|
|
id="issues-status",
|
|
method="POST",
|
|
path="/issues/{number}/status",
|
|
title="Change an issue status",
|
|
summary="Open or close the Gitea issue. Admin only.",
|
|
auth="admin",
|
|
encoding="form",
|
|
destructive=True,
|
|
params=[
|
|
field("number", "path", "integer", True, "12", "Issue number."),
|
|
field(
|
|
"status",
|
|
"form",
|
|
"string",
|
|
True,
|
|
"closed",
|
|
"New status: open or closed.",
|
|
),
|
|
],
|
|
),
|
|
endpoint(
|
|
id="issues-attachments-list",
|
|
method="GET",
|
|
path="/issues/{number}/attachments",
|
|
title="List issue attachments",
|
|
summary="Return the files attached to an issue ticket.",
|
|
auth="public",
|
|
params=[
|
|
field("number", "path", "integer", True, "12", "Issue number."),
|
|
],
|
|
),
|
|
endpoint(
|
|
id="issues-attachments-add",
|
|
method="POST",
|
|
path="/issues/{number}/attachments",
|
|
title="Attach files to an issue",
|
|
summary=(
|
|
"Link already-uploaded files (from /uploads/upload) to an open issue. The "
|
|
"files are also mirrored to the Gitea tracker. Allowed only while the issue is open."
|
|
),
|
|
auth="user",
|
|
encoding="form",
|
|
destructive=True,
|
|
params=[
|
|
field("number", "path", "integer", True, "12", "Issue number."),
|
|
field(
|
|
"attachment_uids",
|
|
"form",
|
|
"string",
|
|
True,
|
|
"a1b2c3d4,e5f6g7h8",
|
|
"Comma separated attachment uids returned by /uploads/upload.",
|
|
),
|
|
],
|
|
notes=[
|
|
"Only the open issue accepts changes; a closed issue returns 409.",
|
|
"You can only link your own uploads unless you are an administrator.",
|
|
],
|
|
),
|
|
endpoint(
|
|
id="issues-attachments-delete",
|
|
method="DELETE",
|
|
path="/issues/{number}/attachments/{uid}",
|
|
title="Delete an issue attachment",
|
|
summary=(
|
|
"Soft-delete a file from an open issue (owner or administrator) and remove it "
|
|
"from the tracker."
|
|
),
|
|
auth="user",
|
|
destructive=True,
|
|
params=[
|
|
field("number", "path", "integer", True, "12", "Issue number."),
|
|
field("uid", "path", "string", True, "a1b2c3d4", "Attachment uid."),
|
|
],
|
|
),
|
|
endpoint(
|
|
id="issues-comment-attachments-add",
|
|
method="POST",
|
|
path="/issues/{number}/comments/{cid}/attachments",
|
|
title="Attach files to an issue comment",
|
|
summary=(
|
|
"Link already-uploaded files to an issue comment (issue must be open). Mirrored "
|
|
"to the Gitea comment."
|
|
),
|
|
auth="user",
|
|
encoding="form",
|
|
destructive=True,
|
|
params=[
|
|
field("number", "path", "integer", True, "12", "Issue number."),
|
|
field("cid", "path", "integer", True, "1", "Gitea comment id."),
|
|
field(
|
|
"attachment_uids",
|
|
"form",
|
|
"string",
|
|
True,
|
|
"a1b2c3d4",
|
|
"Comma separated attachment uids returned by /uploads/upload.",
|
|
),
|
|
],
|
|
),
|
|
endpoint(
|
|
id="issues-comment-attachments-delete",
|
|
method="DELETE",
|
|
path="/issues/{number}/comments/{cid}/attachments/{uid}",
|
|
title="Delete an issue comment attachment",
|
|
summary=(
|
|
"Soft-delete a file from an issue comment (owner or administrator) and remove it "
|
|
"from the tracker."
|
|
),
|
|
auth="user",
|
|
destructive=True,
|
|
params=[
|
|
field("number", "path", "integer", True, "12", "Issue number."),
|
|
field("cid", "path", "integer", True, "1", "Gitea comment id."),
|
|
field("uid", "path", "string", True, "a1b2c3d4", "Attachment uid."),
|
|
],
|
|
),
|
|
],
|
|
}
|