fix(upload): link attachments to comments via client-side ID tracking

Instead of regex-parsing markdown content to find attachment URLs
(fragile), the frontend now tracks uploaded attachment IDs and sends
them with the comment creation request. The backend links them by ID.

Frontend: upload returns attachment ID, comment/reply inputs collect
IDs during editing session, pass as attachment_ids on submit.
Backend: CreateComment accepts attachment_ids, links by ID+issue scope.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
yushen 2026-03-31 16:47:27 +08:00
parent acba0b8139
commit 79cd2a3a5d
11 changed files with 85 additions and 35 deletions

View file

@ -209,13 +209,14 @@ export class ApiClient {
return this.fetch(`/api/issues/${issueId}/comments`);
}
async createComment(issueId: string, content: string, type?: string, parentId?: string): Promise<Comment> {
async createComment(issueId: string, content: string, type?: string, parentId?: string, attachmentIds?: string[]): Promise<Comment> {
return this.fetch(`/api/issues/${issueId}/comments`, {
method: "POST",
body: JSON.stringify({
content,
type: type ?? "comment",
...(parentId ? { parent_id: parentId } : {}),
...(attachmentIds?.length ? { attachment_ids: attachmentIds } : {}),
}),
});
}

View file

@ -32,6 +32,7 @@ function isAllowedType(type: string): boolean {
}
export interface UploadResult {
id: string;
filename: string;
link: string;
}
@ -59,7 +60,7 @@ export function useFileUpload() {
issueId: ctx?.issueId,
commentId: ctx?.commentId,
});
return { filename: att.filename, link: att.url };
return { id: att.id, filename: att.filename, link: att.url };
} finally {
setUploading(false);
}