Comments overview

How comments and discussions work in Blue - one polymorphic Comment type attaches to records, discussions, and status updates, plus threading, reactions, and live updates.


Comments and discussions are how teams converse inside Blue. A single, polymorphic Comment attaches to a record (a Todo), a project discussion, or a status update via a category + categoryId pair — so the same createComment / editComment / deleteComment mutations and the commentList query cover every comment surface. Discussions are standalone, project-scoped conversation threads with their own create/update/delete mutations and queries. This section also covers emoji reactions on comments and the real-time subscriptions (new comments, typing indicators, discussion changes) that power live collaboration.

The polymorphic comment model

There is one Comment type and one set of comment mutations. A comment doesn’t have a separate “todo comment” or “discussion comment” type — instead, every comment names its target with two fields:

  • category — a CommentCategory enum: TODO, DISCUSSION, or STATUS_UPDATE.
  • categoryId — the ID of the target. Its meaning depends on the category: the record (Todo) ID for TODO, the Discussion ID for DISCUSSION, or the StatusUpdate ID for STATUS_UPDATE.

Together they answer “what is this comment attached to?”. You pass the same pair to write a comment (createComment) and to read a target’s comments (commentList). Once you understand this targeting, the rest of the section is just the same operations applied to three surfaces.

# A comment on a record, a discussion, and a status update —
# same mutation, only category + categoryId differ.
mutation CommentOnRecord {
  createComment(
    input: { category: TODO, categoryId: "todo_123", html: "<p>On it.</p>", text: "On it." }
  ) {
    id
  }
}
Discussions vs. discussion comments

A discussion is the thread itself — a Discussion row with a title, body, and members, created with createDiscussion. The replies inside it are Comment rows with category: DISCUSSION and categoryId set to that discussion’s ID. Creating a discussion does not create its comments; you add those separately with createComment.

The Comment type

Comment is the shape returned by createComment, editComment, and every element of CommentList.comments.

FieldTypeDescription
idID!Unique identifier for the comment.
uidString!Short reference identifier.
htmlString!The comment body as sanitized HTML. Blanked to "" when the comment is soft-deleted.
textString!The comment body as plain text. Blanked to "" when the comment is soft-deleted.
categoryCommentCategory!Which surface this comment belongs to: TODO, DISCUSSION, or STATUS_UPDATE.
createdAtDateTime!When the comment was created.
updatedAtDateTime!When the comment was last edited.
deletedAtDateTimeWhen the comment was soft-deleted, or null if it is still live. The row is kept even after deletion.
deletedByUserThe user who soft-deleted the comment, or null.
userUser!The author. Select id, fullName, email.
activityActivityThe activity-feed entry this comment generated, if any.
todoTodoThe parent record, when category is TODO; otherwise null.
discussionDiscussionThe parent discussion, when category is DISCUSSION; otherwise null.
statusUpdateStatusUpdateThe parent status update, when category is STATUS_UPDATE; otherwise null.
isReadBooleanWhether the calling user has read this comment.
isSeenBooleanWhether the calling user has seen this comment in the feed.
aiSummaryBooleanWhether the comment was generated as an AI summary.
parentIdStringThe ID of the comment this one replies to, or null for a top-level comment.
parentCommentThe parent comment when this is a threaded reply; null for top-level comments.
replies[Comment!]!Direct replies to this comment.
replyCountInt!Number of direct replies.
reactions[ReactionGroup!]!Emoji reactions on this comment, grouped by emoji. See Reactions.
files[File!]Files attached to the comment.

Threaded replies

Comments thread one level deep. A reply is an ordinary comment created with a parentId pointing at the comment it answers; from the parent’s side you read replies and replyCount. Top-level comments have parentId: null. The commentList query returns only top-level comments — fetch a thread’s replies through the replies field on each comment.

Read state and soft deletion

isRead and isSeen are evaluated per calling user, so the same comment can come back read for one member and unread for another. Deletion is a soft delete: deleteComment blanks html/text and stamps deletedAt + deletedBy rather than removing the row, which keeps reply chains and thread structure intact.

The CommentList type

CommentList is returned by the commentList query — a page of top-level comments for one target, plus pagination metadata.

FieldTypeDescription
comments[Comment!]!The top-level comments on this page.
pageInfoPageInfo!Cursor/offset pagination metadata for the result.
totalCountInt!Total number of top-level comments matching the query.

The CommentCategory enum

CommentCategory is the discriminator that makes the comment model polymorphic. Its value pairs with categoryId to identify the comment’s target.

ValuecategoryId refers toSurface
TODOa Todo (record) IDA comment on a record. See Records › Add a comment.
DISCUSSIONa Discussion IDA reply inside a project discussion.
STATUS_UPDATEa StatusUpdate IDA comment on a status update.

Pages in this section

PageWhat it covers
Create, edit & delete commentscreateComment, editComment, and the soft-delete deleteComment — the write lifecycle on any surface, with mentions and permissions.
Query commentsThe commentList query: scope to a record, discussion, or status update with category + categoryId, paginate, and order results.
Create, update & delete discussionscreateDiscussion, updateDiscussion (title only), and the hard-delete deleteDiscussion for project-scoped threads.
Query discussionsThe three read paths: discussion(id), the offset-paginated discussions, and the project-scoped cursor list discussionList.
ReactionsaddReaction / removeReaction for emoji reactions on a comment, returning the full [ReactionGroup!]! set.

Live updates for comments and discussions — new comments, typing indicators, and discussion changes — are documented with the rest of the real-time API in Comments, Discussions & Chat subscriptions.

Product nouns to schema types

Use the UI word in prose and the schema name in code. The mapping for this section:

UI / docs wordSchema type / field
CommentComment
DiscussionDiscussion
Status updateStatusUpdate
RecordTodo
Workspace / ProjectProject
Comment target kindCommentCategory + categoryId
Reaction (grouped)ReactionGroup