Files
sm-quizzes-plugin/models/attempt_answer.go
Jakub Zych 297780cb8e feat: add open questions with a pending grading state
- migration: open question type, rubric, max_length, quiz grader and
  the grading and review columns of attempt answers
- open answers are checked, stored as pending and never scored on
  answer; a changed text resets the grading state
- student JSON gains text, grading_status, grader_feedback,
  review_comment, max_length, needs_review and open_answers; the
  rubric is never serialized
2026-11-09 17:48:11 +01:00

68 lines
3.0 KiB
Go

// Code generated by summer make. DO NOT EDIT.
package models
import (
"time"
"git.golem15.com/golem15/summercms/modules/lagoon"
)
// Grading states of an open answer (AttemptAnswer.GradingStatus).
const (
// GradingPending waits for a grader or for the owner.
GradingPending = "pending"
// GradingGraded holds a grader's score the owner has not confirmed.
GradingGraded = "graded"
// GradingFailed is an answer the grader could not score; the owner
// grades it.
GradingFailed = "failed"
// GradingReviewed is final: the owner confirmed or set the score.
GradingReviewed = "reviewed"
)
// GradingStatuses lists the valid values of AttemptAnswer.GradingStatus.
var GradingStatuses = []string{GradingPending, GradingGraded, GradingFailed, GradingReviewed}
// AttemptAnswer is the user's answer to one question of an attempt. There is
// one row per attempt and question; answering again overwrites it.
//
// TextAnswer and the grading fields belong to open questions only:
// GradingStatus is NULL for every other row. GradingSeq grows with every new
// text, so a grading job for an older text is ignored; GradingAttempts counts
// the grader runs for the current text. The review fields record the owner's
// decision: ReviewedByUserID for a frontend user (MCP), ReviewedByAdminID for
// a backend administrator.
type AttemptAnswer struct {
ID uint `gorm:"column:id;primaryKey"`
AttemptID uint `gorm:"column:attempt_id"`
QuestionID uint `gorm:"column:question_id"`
AnswerIDs lagoon.Jsonable[[]uint] `gorm:"column:answer_ids"`
SelfCheckKnown *bool `gorm:"column:self_check_known"`
IsCorrect bool `gorm:"column:is_correct"`
Points float64 `gorm:"column:points"`
CreatedAt time.Time `gorm:"column:created_at"`
UpdatedAt time.Time `gorm:"column:updated_at"`
TextAnswer *string `gorm:"column:text_answer"`
GradingStatus *string `gorm:"column:grading_status"`
GradingSeq int `gorm:"column:grading_seq"`
GradingAttempts int `gorm:"column:grading_attempts"`
Grader *string `gorm:"column:grader"`
GraderPoints *float64 `gorm:"column:grader_points"`
GraderFeedback *string `gorm:"column:grader_feedback"`
GradingError *string `gorm:"column:grading_error"`
GradedAt *time.Time `gorm:"column:graded_at"`
ReviewComment *string `gorm:"column:review_comment"`
ReviewedAt *time.Time `gorm:"column:reviewed_at"`
ReviewedByUserID *uint `gorm:"column:reviewed_by_user_id"`
ReviewedByAdminID *uint `gorm:"column:reviewed_by_admin_id"`
}
// TableName is the plugin-prefixed table.
func (AttemptAnswer) TableName() string { return "golem15_quizzes_attempt_answers" }
// Fillable is empty: answers are written by the API, never by mass
// assignment.
func (AttemptAnswer) Fillable() []string { return []string{} }