Skip to content

Comment deletion by essay owner or admin, with tombstone and deleted-user attribution #5

Description

@yokoberek

Overview

Two related changes to comment persistence:

  1. Comment deletion — essay owners and admins can delete any comment on an essay; comment authors can delete their own. Threaded parent comments with existing replies are tombstoned rather than hard-deleted.
  2. Deleted-user attribution — when a user account is removed from the system, their comments stay on the essay but display as "Deleted user" instead of the original author.

Comment deletion

Who can delete

Actor Can delete
Comment author Their own comment only
Essay owner Any comment on their essay
Admin / superuser Any comment anywhere

Tombstone vs hard delete

  • Parent comment with replies → tombstone: mark is_deleted=True, clear content and quote, keep the record so the reply thread remains coherent. Display as "[comment deleted]" in the UI.
  • Leaf comment / reply with no children → hard delete.

Model changes

# Add to Comment
is_deleted = models.BooleanField(default=False)

Backend

  • delete_comment(comment, actor) service: checks permission, decides tombstone vs hard delete, sets is_deleted=True + clears content if tombstoning.
  • DELETE /interactions/comment/<id>/delete/ endpoint — returns {"deleted": true, "tombstoned": bool}.

UI

  • Trash icon (or three-dot menu item "Delete") shown only to users with delete permission
  • Confirm dialog before sending the request
  • On success: reactively replace comment node with tombstone placeholder or remove it entirely — no page reload

Deleted-user attribution

Model change

Comment.author currently uses on_delete=CASCADE — deleting a user cascades and removes all their comments.

Change to SET_NULL:

author = models.ForeignKey(
    settings.AUTH_USER_MODEL,
    on_delete=models.SET_NULL,
    null=True,
    blank=True,
    related_name="comments",
)

Template

{% if comment.author %}
  {{ comment.author.username }}
{% else %}
  <span class="text-neutral-500">Deleted user</span>
{% endif %}

Apply the same null-check to avatar display (fall back to a generic placeholder icon) and to the profile link (no link if author is None).


Acceptance criteria

  • Essay owner can delete any comment on their own essay
  • Comment author can delete their own comment
  • Admin can delete any comment
  • Parent comments with replies are tombstoned, not hard-deleted; replies remain visible
  • Leaf comments are hard-deleted
  • Deletion is confirmed via dialog before firing
  • UI updates reactively without page reload
  • Comment.author FK changed to SET_NULL — deleting a user account does not remove their comments
  • Comments by deleted accounts display "Deleted user" with a fallback avatar and no profile link
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions