feat: replies to comments

A comment can answer another one (replyTo), one level deep: answering a
reply joins the same thread, and it must be on the same ticket. Whoever
wrote the comment gets a new REPLIED notification, and the activity says
"respondió a un comentario".

A comment deleted while it has replies stays, without its text
(deleted: true), so the thread still reads; it goes with its last reply
and does not count in commentCount.

The ticket page shows threads with their replies indented and a
"Responder" box; REST, GraphQL and the MCP (add_comment, get_issue) take
and show replyTo. Existing comments are unchanged. Docs, Word and PDF
updated.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-09 11:14:37 +02:00
parent c2928d2385
commit ea4ef82239
44 changed files with 517 additions and 60 deletions

View File

@@ -15,6 +15,12 @@ export interface CommentProps {
projectId: string;
authorId: string;
body: string;
/**
* The comment this one answers; always a top-level one (one level of
* replies). Null for a top-level comment, and on comments made before
* there were replies.
*/
replyTo: string | null;
deleted: boolean;
createdAt: string;
editedAt: string | null;
@@ -22,12 +28,13 @@ export interface CommentProps {
const MAX_BODY = 20_000;
/** Decisions and explanations inside a ticket. */
/** Decisions and explanations inside a ticket, and the replies to them. */
export class Comment extends VersionedAggregateRoot implements CommentProps {
public issueId!: string;
public projectId!: string;
public authorId!: string;
public body!: string;
public replyTo: string | null = null;
public deleted = false;
public createdAt!: string;
public editedAt: string | null = null;