Fixed hidden comments collapsing threaded replies#28123
Conversation
|
Caution Review failedThe pull request is closed. ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Run ID: ⛔ Files ignored due to path filters (1)
📒 Files selected for processing (9)
WalkthroughThis PR implements tombstone preservation for deleted and hidden comments that have visible descendants. The feature uses a recursive CTE query to identify displayable comment IDs while preserving thread structure through redacted (HTML-cleared) intermediate comments. The frontend deletion logic conditionally keeps deleted replies as tombstones when they have descendants, prunes orphaned tombstones, and updates reply counts accordingly. The backend query model computes displayable IDs, filters replies using parent scope, and includes documentation clarifying that reply counts reflect visible content only. Comprehensive E2E tests verify tombstone inclusion/exclusion across admin and member API endpoints, including pagination and ordering semantics. Suggested reviewers
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Warning There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure. 🔧 ast-grep (0.42.3)ghost/core/test/e2e-api/admin/comments.test.jsghost/core/test/e2e-api/members-comments/comments.test.jsThanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
| Command | Status | Duration | Result |
|---|---|---|---|
nx run ghost:test:ci:integration |
✅ Succeeded | 2m 6s | View ↗ |
nx run ghost:test:ci:e2e |
✅ Succeeded | 7m 47s | View ↗ |
nx run ghost:test:ci:legacy |
✅ Succeeded | 3m 8s | View ↗ |
nx build @tryghost/announcement-bar |
✅ Succeeded | <1s | View ↗ |
nx build @tryghost/activitypub |
✅ Succeeded | 2s | View ↗ |
nx build @tryghost/signup-form |
✅ Succeeded | <1s | View ↗ |
nx build @tryghost/sodo-search |
✅ Succeeded | <1s | View ↗ |
nx build @tryghost/portal |
✅ Succeeded | <1s | View ↗ |
Additional runs (8) |
✅ Succeeded | ... | View ↗ |
☁️ Nx Cloud last updated this comment at 2026-05-26 09:24:27 UTC
edb99d3 to
c3b432d
Compare
ref https://linear.app/ghost/issue/BER-3677/hidden-comments-collapse-thread-nesting-incorrectly Comment APIs need to return hidden/deleted tombstones when they preserve the path to visible descendants. This uses a post-scoped path-based recursive SQL query for displayable comment IDs, keeps reply counts tied to visible comments, preserves local deleted reply tombstones while descendants are loaded, and bumps Comments UI for release.
ref https://linear.app/ghost/issue/BER-3677/hidden-comments-collapse-thread-nesting-incorrectly Single-comment reads and mutation responses should not build displayable reply paths across the full comments table when the loaded comment already gives us the reply parent scope.
ref https://linear.app/ghost/issue/BER-3677/hidden-comments-collapse-thread-nesting-incorrectly Hidden comments are visible and actionable for admins, so local delete handling should only treat them as structural tombstones for member-facing state.
ref https://linear.app/ghost/issue/BER-3677/hidden-comments-collapse-thread-nesting-incorrectly Local delete handling should not retain structural placeholder replies once they have no loaded descendants, because they render no content but still affect reply state.
ref https://linear.app/ghost/issue/BER-3677/hidden-comments-collapse-thread-nesting-incorrectly The stacked comments-ui changes need their own package version bump so CI and release checks see the public app change.
8c7c316 to
9d9e215
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 9d9e215a6a
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| // pagination displays the correct number of replies still to load | ||
| if (hasDeletedReply && topLevelComment.count?.replies) { | ||
| topLevelComment.count.replies = topLevelComment.count.replies - 1; | ||
| if (hasDeletedReply && replyToDelete && !['hidden', 'deleted'].includes(replyToDelete.status)) { |
There was a problem hiding this comment.
Decrement counts when deleting hidden admin replies
When state.isAdmin is true, hidden replies are still admin-visible and the backend counts them because count.replies/count.direct_replies only exclude deleted for admin requests. This guard skips count updates for hidden replies, so deleting a hidden reply in the admin UI leaves the parent’s reply counts overstated until a refetch, which can make the remaining-replies pagination/counts incorrect.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Admins can only hide comments so this edge won't be hit

Summary
@tryghost/comments-uito1.5.4Context
This is stacked on #28024, which introduces the server-side threaded comment tombstone selection. These commits address the follow-up review findings around query scope, local comments-ui state after deleting replies in deep threads, and the package version bump needed for the public comments-ui change.
ref https://linear.app/ghost/issue/BER-3677/hidden-comments-collapse-thread-nesting-incorrectly
Testing
pnpm --dir ghost/core test:single test/unit/server/models/comment.test.jspnpm --filter @tryghost/comments-ui test:unit -- actions.test.js thread-graph.test.ts comment.test.jsx