Skip to content

Bug: Admin answer deletion uses findByIdAndDelete — bypasses pre-delete middleware, answerCount drifts and acceptedAnswer stays orphaned #100

Description

@vipul674

Bug

`server/models/Answer.js:171` registers an answer-count / accepted-answer cleanup hook scoped to document deletion only:

```js
answerSchema.pre(deleteOne, { document: true, query: false }, async function(next) {
const Question = mongoose.model(Question)
const update = { $inc: { answerCount: -1 } }
if (this.isAccepted) {
update.$unset = { acceptedAnswer: }
}
await Question.findByIdAndUpdate(this.question, update)
next()
})
```

The regular route deletes via the document instance (`answers.js:133` → `await answer.deleteOne()`), which fires the hook. But the admin route deletes via a model query:

`server/routes/admin.js:274`:
```js
content = await Answer.findByIdAndDelete(contentId)
```

`findByIdAndDelete` runs query middleware, not document middleware — the `{ document: true, query: false }` hook never fires.

Reproduction

  1. Question with 5 answers, one accepted.
  2. Admin `DELETE /api/admin/answers/:id` for an accepted answer.
  3. The answer is gone, but `question.answerCount` stays 5 and `question.acceptedAnswer` still references the deleted answer ID.

Expected

Deleting an answer (by any path) decrements `answerCount` and clears `acceptedAnswer` when it was the accepted one.

Actual

Via the admin API the counters never update — question list shows wrong answer count, and the accepted-answer link dangles to a deleted document.

Suggested fix

Switch the admin delete to trigger the same cleanup, e.g. load then `.deleteOne()`:

```js
content = await Answer.findById(contentId)
if (content) await content.deleteOne()
```

or register a second query-scoped hook (`{ query: true }`) that performs the same decrement.

Activity

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

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions