Skip to content

Latest commit

 

History

History
92 lines (76 loc) · 8.02 KB

File metadata and controls

92 lines (76 loc) · 8.02 KB

Frappe Core Doctype: Comment

The Comment Doctype is a fundamental part of Frappe's communication and collaboration framework. It is used to store various types of interactions related to other documents, such as user-written comments, likes, system-generated messages (e.g., workflow updates, assignments), and attachments.

Core Purpose

  • To enable discussions and annotations on any document within Frappe.
  • To log system events and document lifecycle changes (e.g., creation, submission, cancellation) in a human-readable format.
  • To facilitate real-time updates of comment streams on document views.
  • To support features like @mentions and email integration for comments.

Key Files Defining Comment

  • comment.json: Defines the schema (fields, properties, permissions) of the Comment Doctype.
  • comment.py: Contains the server-side Python controller logic for handling comment creation, updates, notifications, and caching.
  • comment.js: The client-side JavaScript file for the Comment Doctype's own form view (which is minimal).
  • test_comment.py: Contains unit tests for the server-side logic.

comment.json - Schema Definition

This JSON file outlines the structure and metadata for Comment entries.

  • Key Fields:
    • comment_type (Select, Required, Default: "Comment"): Defines the nature of the entry. It includes a wide array of options:
      • User-driven: "Comment", "Like", "Edit"
      • System/Workflow: "Info", "Label", "Workflow", "Created", "Submitted", "Cancelled", "Updated", "Deleted", "Assigned", "Assignment Completed", "Attachment", "Attachment Removed", "Shared", "Unshared", "Relinked"
      • Automated: "Bot"
    • content (HTML Editor, ignore_xss_filter: 1): The main body of the comment or message. The ignore_xss_filter flag indicates that rich HTML content is permitted and is sanitized server-side.
    • comment_by (Data): The user ID (e.g., email address) of the person who created the comment.
    • comment_email (Data): Typically stores the email of the commenter, especially if the comment originated from an email reply.
    • reference_doctype (Link to DocType): The Doctype of the document to which this comment is linked (e.g., "Sales Order").
    • reference_name (Dynamic Link, options: reference_doctype): The specific name (ID) of the document being commented on (e.g., "SO-00001").
    • reference_owner (Data, Read Only): The owner of the reference_name document.
    • subject (Text): A subject line for the comment, often auto-generated based on the comment type and reference document.
    • published (Check): A flag indicating if the comment should be publicly visible (e.g., on web forms or public pages).
    • seen (Check): Used to track if a comment has been viewed by relevant users.
    • ip_address (Data, Hidden): Can store the IP address of the user who posted the comment.
  • Permissions:
    • "System Manager" and "Website Manager" roles have full CRUD (Create, Read, Update, Delete) permissions on Comment documents by default.
    • For other users, the ability to view, add, or delete comments is generally contextual, governed by their permissions on the reference_doctype and reference_name (the document being commented on) and specific sharing rules.
  • Other Properties:
    • quick_entry: 1 - Enables a simplified dialog for quickly adding comments.
    • track_changes: 1 - Changes made to Comment documents themselves (e.g., editing a comment) are versioned.
    • title_field: "comment_type" - The list view for comments might primarily display the type of comment.

comment.py - Server-Side Logic

The Python controller for the Comment Doctype is rich with logic for integration and real-time updates.

  • Comment(Document) Class:
    • no_feed_on_delete = True: Prevents the system from automatically creating a feed (Activity Log) entry when a Comment document itself is deleted.
    • after_insert():
      • Calls notify_mentions(): If the content includes @-mentions (e.g., @user@example.com), this function (from frappe.desk.notifications) processes them and sends notifications to the mentioned users.
      • Calls self.notify_change("add") to publish a real-time event.
    • validate():
      • Sets self.comment_email to the current frappe.session.user if it's empty.
      • Sanitizes the self.content using frappe.utils.sanitize_html() to prevent Cross-Site Scripting (XSS) vulnerabilities.
    • on_update():
      • Calls update_comment_in_doc(self) to update the cached summary of comments on the parent (reference_doctype) document.
      • If the comment is being updated (not new), it calls self.notify_change("update").
    • on_trash():
      • Calls self.remove_comment_from_cache() to remove this comment from the parent document's cached list.
      • Calls self.notify_change("delete").
    • notify_change(action):
      • Publishes a real-time event via frappe.publish_realtime().
      • The event is specific to the reference_doctype and reference_name.
      • It sends the comment data and an action type ("add", "update", "delete") to a specific key (e.g., "comments", "like_logs") based on the comment_type.
      • This enables live updates in the UI of the referenced document (e.g., the comment stream refreshes automatically).
  • Caching on Parent Document (update_comment_in_doc, get_comments_from_parent, update_comments_in_parent):
    • To improve performance when loading documents that have many comments, Frappe maintains a cached list of the most recent comments (typically the last 100 of comment_type="Comment") in a special _comments JSON field directly on the parent document's record (e.g., in the tabSales Order table).
    • update_comment_in_doc() is responsible for adding new comments or updating existing ones in this cached list.
    • get_comments_from_parent() retrieves this cached list.
    • update_comments_in_parent() saves the modified list back to the parent document using a direct SQL update to avoid triggering full on_update hooks of the parent.
  • on_doctype_update() (Global Function):
    • Ensures that a database index exists on the (reference_doctype, reference_name) columns in the tabComment table. This is crucial for quickly fetching all comments related to a specific document.

comment.js - Client-Side Logic

The client-side JavaScript for the "Comment" Doctype's own form view is minimal.

  • frappe.ui.form.on("Comment", { // refresh: function(frm) { // } });
  • The file is essentially empty, indicating that the direct form view of a single comment document does not require special client-side handling. Most user interactions with comments (viewing, adding, replying) occur within the context of the parent document's form (e.g., the timeline or communication composer).

How It's Used

  • User Comments: Users add comments to documents through the timeline/communication composer on a document's form. This creates a "Comment" document linked to the parent.
  • System Events: When a document is submitted, a "Comment" of type "Submitted" is automatically generated. Similar entries are made for "Created", "Cancelled", "Updated", etc.
  • Likes: Clicking a "like" button on a document or comment creates a "Comment" of type "Like".
  • Assignments: Assigning a document to a user creates a "Comment" of type "Assigned".
  • Email Integration: Incoming emails that are replies to system notifications (which often reference a document and a communication thread) can be processed to create new "Comment" documents linked to the relevant reference_doctype and reference_name.
  • Mentions: If a user types @anotheruser in a comment, anotheruser receives a notification.

The Comment Doctype is a cornerstone of Frappe's collaborative features, providing a unified way to track discussions, history, and various interactions around any document in the system.