---
title: "Comments System"
description: "The Comments System provides a robust API for managing comments associated with various entities within the application, such as tasks, policies, vendors, and risks. It supports creating, retrievin..."
last_updated: "2026-05-06T07:29:41.656037+00:00"
canonical_url: "https://www.doc0.dev/docs/49c89830-117b-4def-8edc-b5bcc50766e0/technical/section-5/comments-system"
---

<details>
<summary>Relevant source files</summary>

The following files were used as context for generating this wiki page:

- [apps/api/src/comments/comments.service.ts](https://github.com/blade47/comp/blob/main/apps/api/src/comments/comments.service.ts)
- [apps/api/src/comments/comments.controller.ts](https://github.com/blade47/comp/blob/main/apps/api/src/comments/comments.controller.ts)
- [apps/api/src/comments/dto/comment-responses.dto.ts](https://github.com/blade47/comp/blob/main/apps/api/src/comments/dto/comment-responses.dto.ts)
- [apps/api/src/comments/comments.module.ts](https://github.com/blade47/comp/blob/main/apps/api/src/comments/comments.module.ts)
- [apps/api/src/comments/dto/update-comment.dto.ts](https://github.com/blade47/comp/blob/main/apps/api/src/comments/dto/update-comment.dto.ts)
- [apps/api/src/comments/dto/create-comment.dto.ts](https://github.com/blade47/comp/blob/main/apps/api/src/comments/dto/create-comment.dto.ts)
- [apps/api/src/comments/dto/delete-comment.dto.ts](https://github.com/blade47/comp/blob/main/apps/api/src/comments/dto/delete-comment.dto.ts)
</details>

The Comments System provides a robust API for managing comments associated with various entities within the application, such as tasks, policies, vendors, and risks. It supports creating, retrieving, updating, and deleting comments, including handling file attachments and user mentions. The system is designed to ensure data consistency through transactions and integrates with an attachment service for file management and a notification service for user mentions.

## Architecture Overview

The Comments System is implemented as a NestJS module, following a standard Controller-Service pattern.

*   **`CommentsController`**: Handles incoming HTTP requests, validates input, and delegates business logic to the `CommentsService`. It defines the API endpoints for comment operations.
*   **`CommentsService`**: Contains the core business logic for managing comments, interacting with the database, `AttachmentsService`, and `CommentMentionNotifierService`. It also includes access validation for entities.
*   **DTOs (Data Transfer Objects)**: Define the structure for request payloads and API responses, ensuring clear data contracts.
*   **`CommentsModule`**: Orchestrates the components, declares providers and controllers, and manages dependencies.

The system leverages `HybridAuthGuard` for flexible authentication (JWT or API Key) and uses `AuthContext` to determine the authenticated user and organization.

Sources: [apps/api/src/comments/comments.controller.ts](https://github.com/blade47/comp/blob/main/apps/api/src/comments/comments.controller.ts#L22-L30), [apps/api/src/comments/comments.service.ts](https://github.com/blade47/comp/blob/main/apps/api/src/comments/comments.service.ts#L21-L24), [apps/api/src/comments/comments.module.ts](https://github.com/blade47/comp/blob/main/apps/api/src/comments/comments.module.ts#L6-L12)

## Data Transfer Objects (DTOs)

The Comments System uses several DTOs to structure data for requests and responses.

### Request DTOs

*   **`CreateCommentDto`**: Used when creating a new comment.
    *   `content`: The text content of the comment (max 2000 characters).
    *   `entityId`: The ID of the entity the comment belongs to.
    *   `entityType`: The type of entity (`task`, `policy`, `vendor`, `risk`).
    *   `contextUrl?`: Optional URL for deep-linking in notifications.
    *   `attachments?`: An array of `UploadAttachmentDto` for files to be attached.
    *   `userId?`: Required for API key authentication to specify the author.
*   **`UpdateCommentDto`**: Used when updating an existing comment.
    *   `content`: The new text content of the comment (max 2000 characters).
    *   `contextUrl?`: Optional updated URL for deep-linking.
    *   `userId?`: Required for API key authentication to specify the author.
*   **`DeleteCommentDto`**: Used when deleting a comment.
    *   `userId?`: Required for API key authentication to specify the user performing the deletion.

Sources: [apps/api/src/comments/dto/create-comment.dto.ts](https://github.com/blade47/comp/blob/main/apps/api/src/comments/dto/create-comment.dto.ts#L9-L55), [apps/api/src/comments/dto/update-comment.dto.ts](https://github.com/blade47/comp/blob/main/apps/api/src/comments/dto/update-comment.dto.ts#L6-L34), [apps/api/src/comments/dto/delete-comment.dto.ts](https://github.com/blade47/comp/blob/main/apps/api/src/comments/dto/delete-comment.dto.ts#L5-L15)

### Response DTOs

The primary response DTO is `CommentResponseDto`, which includes nested DTOs for author information and attachment metadata.



*   **`CommentResponseDto`**: Represents a single comment returned by the API.
    *   `id`: Unique identifier for the comment.
    *   `content`: The comment's text content.
    *   `author`: An `AuthorResponseDto` object containing details about the comment's author.
    *   `attachments`: An array of `AttachmentMetadataDto` objects, providing metadata about attached files (without download URLs, which are generated on-demand).
    *   `createdAt`: Timestamp of when the comment was created.
*   **`AuthorResponseDto`**: Details about the user who authored the comment.
    *   `id`, `name`, `email`, `image`, `deactivated`.
*   **`AttachmentMetadataDto`**: Basic metadata for an attachment associated with a comment.
    *   `id`, `name`, `type`, `createdAt`.
*   **`AttachmentResponseDto`**: Similar to `AttachmentMetadataDto` but includes a `downloadUrl` and `size`. This is used internally by the service when handling attachments, but `AttachmentMetadataDto` is returned in `CommentResponseDto`.

Sources: [apps/api/src/comments/dto/comment-responses.dto.ts](https://github.com/blade47/comp/blob/main/apps/api/src/comments/dto/comment-responses.dto.ts#L4-L95)

## API Endpoints

The `CommentsController` exposes the following REST API endpoints:

| Method | Path                  | Description                                                               | Request Body          | Response Type        | Authentication |
| :----- | :-------------------- | :------------------------------------------------------------------------ | :-------------------- | :------------------- | :------------- |
| `GET`  | `/comments`           | Retrieve all comments for a specific entity.                              | Query: `entityId`, `entityType` | `CommentResponseDto[]` | HybridAuthGuard |
| `POST` | `/comments`           | Create a new comment on an entity with optional attachments.              | `CreateCommentDto`    | `CommentResponseDto` | HybridAuthGuard |
| `PUT`  | `/comments/:commentId` | Update the content of an existing comment (author only).                  | `UpdateCommentDto`    | `CommentResponseDto` | HybridAuthGuard |
| `DELETE` | `/comments/:commentId` | Delete a comment and all its attachments (author only).                   | `DeleteCommentDto`    | `{ success: boolean, deletedCommentId: string, message: string }` | HybridAuthGuard |

All endpoints require an `X-Organization-Id` header for session authentication, which is optional for API key authentication.
Sources: [apps/api/src/comments/comments.controller.ts](https://github.com/blade47/comp/blob/main/apps/api/src/comments/comments.controller.ts#L22-L218)

## Core Logic: `CommentsService`

The `CommentsService` encapsulates the business logic for comment management.

### Entity Access Validation

Before performing any comment operation, the service validates that the target entity exists within the specified organization and that the user has access. This is handled by the `validateEntityAccess` method.



The supported `CommentEntityType` values are:
*   `task`: Checks for `TaskItem` first, then `Task`.
*   `policy`: Checks for `Policy`.
*   `vendor`: Checks for `Vendor`. Includes logging if a vendor exists in a different organization.
*   `risk`: Checks for `Risk`.

Sources: [apps/api/src/comments/comments.service.ts](https://github.com/blade47/comp/blob/main/apps/api/src/comments/comments.service.ts#L40-L124)

### Creating a Comment

The `createComment` method handles the creation of new comments, including optional attachments and user mention notifications.

<Steps>
<Step>
### Validate Entity Access
The system first calls `validateEntityAccess` to ensure the `entityId` and `entityType` are valid and accessible within the `organizationId`.
</Step>
<Step>
### Verify Member
It retrieves the `Member` record for the `userId` within the `organizationId` to confirm the user is an active member.
</Step>
<Step>
### Create Comment and Attachments in Transaction
A database transaction is used to ensure atomicity.
1.  The comment record is created in the database.
2.  If `createCommentDto.attachments` are provided, each attachment is uploaded via `AttachmentsService.uploadAttachment` and associated with the new comment.
</Step>
<Step>
### Notify Mentioned Users
After the comment is successfully created, the `extractMentionedUserIds` utility parses the comment content for user mentions. If any users are mentioned, `CommentMentionNotifierService.notifyMentionedUsers` is called asynchronously to send notifications.
</Step>
</Steps>

Sources: [apps/api/src/comments/comments.service.ts](https://github.com/blade47/comp/blob/main/apps/api/src/comments/comments.service.ts#L162-L253)

```mermaid
sequenceDiagram
    participant Client
    participant CommentsController
    participant CommentsService
    participant AttachmentsService
    participant CommentMentionNotifierService
    participant Database

    Client->>CommentsController: POST /comments (CreateCommentDto)
    CommentsController->>CommentsService: createComment(orgId, userId, dto)
    CommentsService->>CommentsService: validateEntityAccess(orgId, dto.entityId, dto.entityType)
    CommentsService->>Database: Find Member (userId, orgId)
    alt Member not found
        CommentsService-->>CommentsController: BadRequestException
        CommentsController-->>Client: 400 Bad Request
    else Member found
        CommentsService->>Database: Begin Transaction
        CommentsService->>Database: Create Comment
        opt Attachments present
            loop For each attachment
                CommentsService->>AttachmentsService: uploadAttachment(orgId, commentId, type, attachmentDto, userId)
                AttachmentsService-->>CommentsService: AttachmentResponseDto
            end
        end
        CommentsService->>Database: Commit Transaction
        CommentsService->>CommentsService: extractMentionedUserIds(content)
        opt Users mentioned
            CommentsService->>CommentMentionNotifierService: notifyMentionedUsers(notificationData)
        end
        CommentsService-->>CommentsController: CommentResponseDto
        CommentsController-->>Client: 201 Created (CommentResponseDto)
    end
```

### Retrieving Comments

The `getComments` method fetches all comments for a given entity.

1.  It first validates entity access using `validateEntityAccess`.
2.  It queries the database for comments matching the `organizationId`, `entityId`, and `entityType`, ordering them by creation date (descending).
3.  For each comment, it retrieves attachment metadata using `AttachmentsService.getAttachmentMetadata`.
4.  The results are mapped to `CommentResponseDto` objects, including author details and attachment metadata.

Sources: [apps/api/src/comments/comments.service.ts](https://github.com/blade47/comp/blob/main/apps/api/src/comments/comments.service.ts#L127-L160)

### Updating a Comment

The `updateComment` method allows modifying the content of an existing comment.

1.  It retrieves the existing comment and verifies that the `userId` is the author of the comment.
2.  The comment's `content` is updated in the database.
3.  Existing attachments are retrieved using `AttachmentsService.getAttachments`.
4.  It compares the newly mentioned users with previously mentioned users in the comment content. Only newly mentioned users are notified via `CommentMentionNotifierService`.

Sources: [apps/api/src/comments/comments.service.ts](https://github.com/blade47/comp/blob/main/apps/api/src/comments/comments.service.ts#L256-L338)

### Deleting a Comment

The `deleteComment` method removes a comment and its associated attachments.

1.  It retrieves the existing comment and verifies that the `userId` is the author of the comment.
2.  A database transaction is initiated.
3.  All attachments linked to the comment are retrieved.
4.  Each attachment is deleted from storage via `AttachmentsService.deleteAttachment`.
5.  Finally, the comment record is deleted from the database.

Sources: [apps/api/src/comments/comments.service.ts](https://github.com/blade47/comp/blob/main/apps/api/src/comments/comments.service.ts#L341-L397)

## Mention Notification

The system includes functionality to notify users who are mentioned in a comment.
The `extractMentionedUserIds` utility function parses the comment content (expected to be JSON) to find user IDs marked as 'mention' nodes.
When a comment is created or updated, if new mentions are detected, the `CommentMentionNotifierService` is used to send notifications to the mentioned users. This process is fire-and-forget to avoid blocking comment operations.

Sources: [apps/api/src/comments/comments.service.ts](https://github.com/blade47/comp/blob/main/apps/api/src/comments/comments.service.ts#L10-L33), [apps/api/src/comments/comments.service.ts](https://github.com/blade47/comp/blob/main/apps/api/src/comments/comments.service.ts#L225-L242), [apps/api/src/comments/comments.service.ts](https://github.com/blade47/comp/blob/main/apps/api/src/comments/comments.service.ts#L310-L327)

## Authentication and Authorization

The `CommentsController` uses `HybridAuthGuard` to support both JWT (session-based) and API key authentication.
The `@AuthContext()` decorator provides an `AuthContextType` object, which indicates whether the request originated from an API key (`isApiKey`) and provides the `userId`.

<Accordions>
<Accordion title="Handling User ID for Different Authentication Methods">
When using API key authentication, the `userId` must be explicitly provided in the request body (`CreateCommentDto`, `UpdateCommentDto`, `DeleteCommentDto`). For JWT authentication, the `userId` is extracted directly from the authenticated session. This ensures that the correct user context is always available for authorization checks (e.g., verifying comment authorship).
</Accordion>
</Accordions>

Sources: [apps/api/src/comments/comments.controller.ts](https://github.com/blade47/comp/blob/main/apps/api/src/comments/comments.controller.ts#L26-L30), [apps/api/src/comments/comments.controller.ts](https://github.com/blade47/comp/blob/main/apps/api/src/comments/comments.controller.ts#L86-L101), [apps/api/src/comments/comments.controller.ts](https://github.com/blade47/comp/blob/main/apps/api/src/comments/comments.controller.ts#L130-L145), [apps/api/src/comments/comments.controller.ts](https://github.com/blade47/comp/blob/main/apps/api/src/comments/comments.controller.ts#L191-L206)

## Module Structure

The `CommentsModule` integrates all necessary components for the Comments System.

```typescript
@Module({
  imports: [AuthModule, AttachmentsModule],
  controllers: [CommentsController],
  providers: [CommentsService, CommentMentionNotifierService, NovuService],
  exports: [CommentsService],
})
export class CommentsModule {}
```

*   **`imports`**:
    *   `AuthModule`: Provides authentication-related services and guards, including `HybridAuthGuard`.
    *   `AttachmentsModule`: Provides `AttachmentsService` for handling file uploads and management.
*   **`controllers`**: Registers `CommentsController` to handle API routes.
*   **`providers`**: Registers `CommentsService`, `CommentMentionNotifierService`, and `NovuService` as injectable services.
*   **`exports`**: Makes `CommentsService` available for injection into other modules if needed.

Sources: [apps/api/src/comments/comments.module.ts](https://github.com/blade47/comp/blob/main/apps/api/src/comments/comments.module.ts#L6-L12)

## Sitemap

See the full [sitemap](https://www.doc0.dev/docs/49c89830-117b-4def-8edc-b5bcc50766e0/llms.txt) for all pages in this wiki.
