System Architecture
Core Features
Data Management
Frontend Components
Extensibility
The following files were used as context for generating this wiki page:
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.
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.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, apps/api/src/comments/comments.service.ts, apps/api/src/comments/comments.module.ts
The Comments System uses several DTOs to structure data for requests and responses.
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, apps/api/src/comments/dto/update-comment.dto.ts, apps/api/src/comments/dto/delete-comment.dto.ts
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.The CommentsController exposes the following REST API endpoints:
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
CommentsServiceThe CommentsService encapsulates the business logic for comment management.
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.The createComment method handles the creation of new comments, including optional attachments and user mention notifications.
The system first calls validateEntityAccess to ensure the entityId and entityType are valid and accessible within the organizationId.
It retrieves the Member record for the userId within the organizationId to confirm the user is an active member.
A database transaction is used to ensure atomicity.
createCommentDto.attachments are provided, each attachment is uploaded via AttachmentsService.uploadAttachment and associated with the new comment.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.
The getComments method fetches all comments for a given entity.
validateEntityAccess.organizationId, entityId, and entityType, ordering them by creation date (descending).AttachmentsService.getAttachmentMetadata.CommentResponseDto objects, including author details and attachment metadata.The updateComment method allows modifying the content of an existing comment.
userId is the author of the comment.content is updated in the database.AttachmentsService.getAttachments.CommentMentionNotifierService.The deleteComment method removes a comment and its associated attachments.
userId is the author of the comment.AttachmentsService.deleteAttachment.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, apps/api/src/comments/comments.service.ts, apps/api/src/comments/comments.service.ts
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.
Sources: apps/api/src/comments/comments.controller.ts, apps/api/src/comments/comments.controller.ts, apps/api/src/comments/comments.controller.ts, apps/api/src/comments/comments.controller.ts
The CommentsModule integrates all necessary components for the Comments System.
@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.