Sprinter Docs

Comments

Threaded comments on entity records with one level of nesting, activity logging, and real-time updates.

Comments

The Comments module adds threaded discussion to any entity record. Comments support one level of reply nesting, display author information from user profiles, log activity on creation, and update in real time via the Realtime module.

Overview

Comments are scoped to a single entity and tenant. The module lives in features/comments/ and provides server actions for CRUD, React Query hooks for client-side state, and pre-built UI components for rendering threaded conversations. Comments appear on entity detail pages, typically in a dedicated section below the entity content.

Key Concepts

CommentRecord -- The core data type representing a comment:

  • id, tenant_id, entity_id -- identity and scoping
  • parent_id -- null for top-level comments, set for replies (one level deep only)
  • user_id, body, created_at -- content and metadata
  • author -- joined from profiles table (display_name, email)
  • replies -- child comments assembled during thread building

One-Level Threading -- Replies can only be added to top-level comments, not to other replies. The reply button is only shown on comments at depth 0. This keeps conversations readable without deep nesting.

Activity Logging -- Every new comment creates an activity record via logActivity() with action comment_added. The activity description is the comment body truncated to 100 characters.

Ownership Enforcement -- Users can only delete their own comments. The deleteComment action verifies user_id matches the current user before proceeding.

How It Works

Thread Building

The listComments() server action fetches all comments for an entity, then builds the threaded structure in memory:

  1. Fetch all comments ordered by created_at ascending
  2. Join with profiles table to get author display names
  3. Build a lookup map by comment ID
  4. Iterate: if a comment has a parent_id and that parent exists, push it into the parent's replies array. Otherwise, add it to the top-level list.

This returns a flat list of top-level comments, each with a replies array.

Client-Side Data Management

Three React Query hooks manage comment state:

  • useComments(entityId) -- fetches threaded comments via /api/comments?entityId=...
  • useCreateComment(entityId) -- mutation that POSTs to /api/comments and invalidates the comment query
  • useDeleteComment(entityId) -- mutation that DELETEs via /api/comments/\{id\} and invalidates

The commentsQueryKey(entityId) function returns ["comments", entityId], which aligns with the Realtime module's entity listeners for automatic cache invalidation when comments change remotely.

UI Components

CommentThread is the top-level component. It displays the full comment list with loading and empty states, plus a CommentInput at the bottom for new comments. Each comment is rendered by SingleComment, which shows the author avatar, name, timestamp, body, and action buttons (Reply for top-level, Delete for own comments).

CommentCount is a lightweight component that displays just the count, suitable for use in entity cards or list rows.

API Reference

Server Actions

FunctionLocationPurpose
listComments(entityId)features/comments/server/actions.tsFetch and thread all comments for an entity
createComment(entityId, body, parentId?)SameCreate a comment (with optional parent for replies)
deleteComment(id)SameDelete own comment (ownership verified)
getCommentCount(entityId)SameCount of comments on an entity

Hooks

HookPurpose
useComments(entityId)Fetch threaded comments
useCreateComment(entityId)Create comment mutation
useDeleteComment(entityId)Delete comment mutation
commentsQueryKey(entityId)Stable query key for cache sharing

Components

ComponentPurpose
CommentThreadFull threaded comment UI with input
CommentInputText input for writing comments
CommentCountComment count badge

For Agents

Agents do not currently have a dedicated tool for posting comments. Comments are a human-to-human collaboration feature. However, agents can observe comment activity through the searchEntities tool (activity records include comment_added events) and the entity's activity timeline.

If comment functionality is needed for agents in the future, a postComment tool could be added to the entity tool group.

  • Entity System (features/entities/) -- comments are scoped to entities
  • Realtime (features/realtime/) -- entity realtime listeners include comments table changes
  • Activity -- comment creation logs an activity record for the timeline

On this page