WR-06: a Question save hook clears grading_status on the answers of a question that changed type away from open, in the save's transaction, so they leave the review queue and needs_review. GradeAnswer ignores a question that is no longer open, and a choice or self-check re-answer clears the text, grade and review columns of its row.
46 lines
1.5 KiB
Go
46 lines
1.5 KiB
Go
package models
|
|
|
|
import (
|
|
"time"
|
|
|
|
"gorm.io/gorm"
|
|
)
|
|
|
|
// wasOpenKey is the statement setting by which BeforeSave tells AfterSave
|
|
// that the saved question was open before.
|
|
const wasOpenKey = "golem15.quizzes:question_was_open"
|
|
|
|
// BeforeSave notes whether a stored question that is saved as another
|
|
// type was open, for AfterSave. Every write path (the admin form and
|
|
// relation manager, the manage API and MCP, the importer) saves through
|
|
// GORM, so the hooks cover them all.
|
|
func (q *Question) BeforeSave(tx *gorm.DB) error {
|
|
if q.ID == 0 || q.Type == TypeOpen {
|
|
return nil
|
|
}
|
|
var stored string
|
|
err := tx.Session(&gorm.Session{NewDB: true}).Model(&Question{}).
|
|
Where("id = ?", q.ID).Limit(1).Pluck("type", &stored).Error
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if stored == TypeOpen {
|
|
tx.InstanceSet(wasOpenKey, true)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// AfterSave ends the grading of the answers to a question that stopped
|
|
// being open, in the same transaction as the save: their grading_status
|
|
// becomes NULL, so they leave the review queue and needs_review, and a
|
|
// grading job still queued for them does nothing. Their text, grades and
|
|
// points stay for the record (stored scores are never touched).
|
|
func (q *Question) AfterSave(tx *gorm.DB) error {
|
|
if was, ok := tx.InstanceGet(wasOpenKey); !ok || was != true {
|
|
return nil
|
|
}
|
|
return tx.Session(&gorm.Session{NewDB: true}).Model(&AttemptAnswer{}).
|
|
Where("question_id = ? AND grading_status IS NOT NULL", q.ID).
|
|
Updates(map[string]any{"grading_status": nil, "updated_at": time.Now().UTC()}).Error
|
|
}
|