@angus님의 Custom Wizard Plugin 토픽을 익명 사용자로 확인해 보면, 중첩된 답변 보기에서 다음과 같은 문제가 발생합니다: https://meta.discourse.org/n/-/73345.json?page=0&sort=old
/n/-/73345.json?page=0&sort=old 요청에 대해 20개의 루트가 반환되지만, 모든 항목이 삭제된 플레이스홀더입니다 — cooked 콘텐츠가 비어 있고, 작성자가 없으며 total_descendant_count: 0입니다. 즉, 첫 페이지 전체가 빈 “삭제됨” 행으로 가득 차 있습니다.
같은 게시글들의 플랫(평탄) 뷰에서는 아무것도 표시되지 않습니다(2번 게시글이 관련 토픽으로 바로 건너뜀), 따라서 해당 뷰에서는 올바르게 숨겨지고 있습니다. 하지만 중첩 뷰에서는 이 게시글들을 유지하고 페이지 계산에 포함시키므로 불일치가 발생합니다.
트리 로더는 의도적으로 삭제된 게시글을 가져오는 것 같습니다(아래에 살아있는 답변이 있는 삭제된 부모 게시글을 표시하기 위함). 그러나 가시적인 답변이 더 이상 없는 삭제된 게시글도 유지하고 있습니다. 초기 답변이 모두 삭제된 이 토픽과 같은 경우, 실제 콘텐츠 대신 빈 플레이스홀더로 가득 찬 페이지가 생성됩니다.
설정은 확실히 활성화되어 있습니다 — 엔드포인트가 404 대신 200을 반환했기 때문입니다.
문제 원인은 NestedReplies::TreeLoader의 apply_visibility로 보입니다. scope.unscope(where: :deleted_at)은 모든 삭제된 게시글을 트리에 포함시킵니다. 아래에 살아있는 답변이 있는 삭제된 부모 게시글의 경우엔 합리적인 조치이지만, 삭제된 리프(말단) 노드와 완전히 삭제된 가지도 유지하게 되어 ROOTS_PER_PAGE 윈도우의 슬롯을 차지하고 has_more_roots 계산에도 포함됩니다.
비스태프 사용자의 경우, 적어도 하나 이상의 비삭제된 후손이 있는 경우에만 삭제된 게시글을 유지하는 것이 적절해 보입니다. 즉, 가시적인 total_descendant_count > 0인 경우에만 유지하면 됩니다. NestedViewPostStat는 이미 삭제된/위스퍼 후손을 해당 계산에서 제외하므로 추가 쿼리가 필요하지 않습니다.
페이지가 짧아지는 문제를 방지하려면 페이지를 구성하는 세 곳(root_posts_scope, batch_preload_tree, 그리고 페이지 채우기/has_more_roots 부분)에 적용해야 합니다. 스태프 경로는 복구 목적을 위해 그대로 유지해야 합니다.



