mirror of
https://github.com/rgrgogu/new_starr.git
synced 2026-09-27 00:12:54 +08:00
done
This commit is contained in:
@@ -2029,7 +2029,7 @@ exports.bulkSyncQuestions = async (req, res) => {
|
||||
const parent = await resolveQuestionParent(req.params);
|
||||
if (!parent?.parentRecord) return R.error(res, "Parent not found.", 404);
|
||||
|
||||
const { questions = [], updatedBy } = req.body;
|
||||
const { questions = [], updatedBy, confirmFullReplace } = req.body;
|
||||
|
||||
const existing = await QuizQuestion.findAll({
|
||||
where: { [parent.parentField]: parent.parentId, ...notDeleted },
|
||||
@@ -2038,6 +2038,20 @@ exports.bulkSyncQuestions = async (req, res) => {
|
||||
const incomingIds = questions.filter((q) => q.question_id).map((q) => q.question_id);
|
||||
const toArchive = existingIds.filter((id) => !incomingIds.includes(id));
|
||||
|
||||
// Safety guard: a sync where NONE of the currently-existing questions are
|
||||
// referenced by id would archive the entire pool in one call — indistinguishable
|
||||
// from a client sending a stale/incomplete array (exactly how real questions were
|
||||
// nearly lost while diagnosing this endpoint). Partial edits (dropping a question
|
||||
// or two out of many) are unaffected — only a full wipe requires explicit confirmation.
|
||||
if (toArchive.length > 0 && toArchive.length === existingIds.length && !confirmFullReplace) {
|
||||
await t.rollback();
|
||||
return R.error(
|
||||
res,
|
||||
`This would archive all ${toArchive.length} existing question(s) and can't be recovered from here. Resend with confirmFullReplace: true if this is intentional.`,
|
||||
409
|
||||
);
|
||||
}
|
||||
|
||||
if (toArchive.length) {
|
||||
await QuizQuestion.update(
|
||||
{ deletedAt: new Date(), deletedBy: updatedBy ?? null },
|
||||
|
||||
Reference in New Issue
Block a user