Skip to content

feat: add CommentPolicy and CommentThreadPolicy (part 2 of Commontator removal) - #7835

Open
Shruti2110-coder wants to merge 7 commits into
CircuitVerse:masterfrom
Shruti2110-coder:feat/comment-policy
Open

feat: add CommentPolicy and CommentThreadPolicy (part 2 of Commontator removal)#7835
Shruti2110-coder wants to merge 7 commits into
CircuitVerse:masterfrom
Shruti2110-coder:feat/comment-policy

Conversation

@Shruti2110-coder

@Shruti2110-coder Shruti2110-coder commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

Depends on #7831.

Second step of replacing the Commontator gem. Ports the comment and thread
permission rules into Pundit policies.

What this adds

  • CommentThreadPolicy — read, comment, subscribe, close/reopen
  • CommentPolicy — show, create, update, destroy, restore, vote
  • Policy specs (32 examples)

Rules ported

Rule Behaviour
Read Project is public, or the user has project view access
Moderator Any site admin
Create Signed in, thread open, and can read
Edit Author only, thread open, not deleted, not edited by someone else
Delete Author when thread is open, or any moderator even when closed
Undelete Any moderator, or the author if they were the one who deleted it
Vote Signed in, not the author, thread open, comment not deleted

Note on how these were derived

Rules were read from commontator-7.0.1's Comment model rather than
inferred from the initializer. That surfaced three behaviours the config alone
does not describe:

  1. In can_be_deleted_by?, the moderator branch returns before the
    closed-thread check, so moderators may delete inside a closed thread.
  2. can_be_edited_by? also requires editor.nil? || user == editor.
  3. can_be_voted_on? blocks voting on closed threads and deleted comments.

What this does not do

Nothing calls these policies yet. The controllers still use Commontator, so
there is no behaviour change.

Approach note

Neither policy calls super. ApplicationPolicy#initialize raises for nil
users, but comments on public projects must stay readable anonymously — the
existing API spec asserts this. ProjectPolicy skips super for the same
reason.

Summary by CodeRabbit

  • New Features
    • Added project comment threads with replies and chronological discussions.
    • Added comment editing, soft deletion, restoration, and voting permissions.
    • Added thread subscription permissions.
    • Added moderator controls to close and reopen discussions.
    • Added visibility and access controls for public and private projects.
    • Added validation to prevent invalid reply relationships and comment cycles.
  • Tests
    • Added coverage for comment behavior, thread lifecycle, validation, restoration, and access permissions.

First step of replacing the Commontator gem. Adds the comment_threads and
comments tables together with their models, factories and model specs.

Mirrors Commontator's existing structure: threads attached polymorphically
to a commentable, comments with nested replies, soft delete and edit
tracking, and thread open/closed state.

Nothing is wired up and nothing is removed. Commontator remains fully in
use, so there is no behaviour change.
A comment could previously be set as its own parent, or two comments could
reference each other, causing replies to recurse indefinitely during
dependent: :destroy.
Second step of replacing the Commontator gem. Ports the comment and thread
permission rules into Pundit policies.

Rules were read from commontator-7.0.1's Comment model rather than inferred
from the initializer, which surfaced three behaviours the config alone does
not describe: moderators may delete inside a closed thread, editing requires
the comment not to have been edited by someone else, and voting is blocked on
closed threads and deleted comments.

Nothing calls these policies yet, so there is no behaviour change.
@coderabbitai

coderabbitai Bot commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Team

Run ID: f75ff0a0-829a-4f4f-bd2b-4ab4b6778703

📥 Commits

Reviewing files that changed from the base of the PR and between b01f5c2 and 5dcd4bc.

📒 Files selected for processing (2)
  • app/policies/comment_policy.rb
  • spec/policies/comment_policy_spec.rb
🚧 Files skipped from review as they are similar to previous changes (2)
  • app/policies/comment_policy.rb
  • spec/policies/comment_policy_spec.rb

Included review availability: Your plan provides up to 4 included reviews per hour; 2 remain after this review.


Walkthrough

Introduces CommentThread and Comment models with database tables, associations, validations, scopes, parent-cycle protection, thread closure, soft deletion, and editing state. Adds a polymorphic thread association to Project. Adds thread and comment policies for visibility, creation, editing, deletion, restoration, voting, subscriptions, and closure. Adds factories and model and policy specs covering these behaviors.

Merge Risk: ⚪ Minimal · up to 5dcd4

This change adds comment and thread permission policies without changing the controllers that currently enforce behavior, so no actionable merge-blocking risk remains after normal checks and review.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 23.33% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 30 functions across 12 files. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly identifies the main change: adding CommentPolicy and CommentThreadPolicy as part of the Commontator removal. It is concise and relevant to the pull request objectives.
  • Fix all pre-merge checks with AI
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1


ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Team

Run ID: bbba17b5-16b1-429f-87c2-a543472c70e7

📥 Commits

Reviewing files that changed from the base of the PR and between 79bd963 and fcad6c3.

📒 Files selected for processing (12)
  • app/models/comment.rb
  • app/models/comment_thread.rb
  • app/models/project.rb
  • app/policies/comment_policy.rb
  • app/policies/comment_thread_policy.rb
  • db/migrate/20260901000000_create_comment_tables.rb
  • db/schema.rb
  • spec/factories/comment.rb
  • spec/models/comment_spec.rb
  • spec/models/comment_thread_spec.rb
  • spec/policies/comment_policy_spec.rb
  • spec/policies/comment_thread_policy_spec.rb

Included review availability: Your plan provides up to 4 included reviews per hour; 3 remain after this review.

Comment thread app/policies/comment_policy.rb Outdated
restore? delegated to destroy?, which obscured that the two rules differ for
authors: restoring additionally requires the comment to be deleted and the
author to have been the one who deleted it.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1


ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Team

Run ID: 9a111c84-9cd7-40c2-8abc-5e60de5378f6

📥 Commits

Reviewing files that changed from the base of the PR and between fcad6c3 and b01f5c2.

📒 Files selected for processing (2)
  • app/policies/comment_policy.rb
  • spec/policies/comment_policy_spec.rb

Included review availability: Your plan provides up to 4 included reviews per hour; 2 remain after this review.

Comment thread app/policies/comment_policy.rb
restore? returned true for moderators before checking comment.deleted?, so it
authorized restoring a comment that was never deleted.

@JituRewar JituRewar left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Shruti2110-coder The cycle guard is currently application-level only, so writes through update_column, bulk SQL, or concurrent updates can still introduce a parent cycle. Since replies uses dependent: :destroy, such a cycle could cause recursive destruction issues.
Could we ensure the upcoming Commontator data migration and any bulk-write paths explicitly validate/preserve this invariant? If DB-level enforcement isn't practical, a migration-time validation would at least prevent importing invalid cycles.

@Shruti2110-coder

Copy link
Copy Markdown
Contributor Author

@JituRewar Yes, agreed — that's the plan. The data migration will do a bulk import from commontator_comments, which bypasses model validations entirely, so it's the one path where a cycle could realistically be introduced.

I'll include in that PR:

A cycle check on the source data before insert, so anything invalid in the Commontator tables is caught rather than carried over.
A verification query after the import confirming no parent_id chain loops.
The migration failing loudly rather than skipping bad rows, so a problem is visible instead of silent.

Beyond that, any bulk write goes through the model rather than raw SQL. I'll link back to this thread from the migration PR so the requirement is traceable.

@JituRewar

Copy link
Copy Markdown

@Shruti2110-coder Great

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants