138 lines
4.4 KiB
Go
138 lines
4.4 KiB
Go
package model
|
|
|
|
import "time"
|
|
|
|
// Quiz target kinds.
|
|
const (
|
|
QuizChapter = "chapter"
|
|
QuizLecture = "lecture"
|
|
QuizConversation = "conversation"
|
|
QuizStandalone = "standalone"
|
|
)
|
|
|
|
// Attempt states, as seen by the person taking the quiz.
|
|
const (
|
|
QuizNotStarted = "not_started"
|
|
QuizInProgress = "in_progress"
|
|
QuizCompleted = "completed"
|
|
)
|
|
|
|
// Quiz is a set of multiple-choice questions, optionally tied to a page.
|
|
type Quiz struct {
|
|
ID string `json:"id"`
|
|
Title string `json:"title"`
|
|
Description string `json:"description"`
|
|
TargetKind string `json:"target_kind"`
|
|
TargetPath *string `json:"target_path,omitempty"`
|
|
TargetTitle string `json:"target_title"`
|
|
// TargetYear is the lecture or conversation's year, for grouping.
|
|
TargetYear *int `json:"target_year,omitempty"`
|
|
PublishedAt *time.Time `json:"published_at,omitempty"`
|
|
CreatedAt time.Time `json:"created_at"`
|
|
UpdatedAt time.Time `json:"updated_at"`
|
|
|
|
QuestionCount int `json:"question_count"`
|
|
// Admin-only counters.
|
|
AttemptCount int `json:"attempt_count,omitempty"`
|
|
CompletedCount int `json:"completed_count,omitempty"`
|
|
|
|
Questions []QuizQuestion `json:"questions,omitempty"`
|
|
}
|
|
|
|
// QuizQuestion is one question. Prompt and option bodies carry the same
|
|
// formatting markers as the rest of the admin text.
|
|
type QuizQuestion struct {
|
|
ID string `json:"id"`
|
|
Ord int `json:"ord"`
|
|
Prompt string `json:"prompt"`
|
|
Explanation string `json:"explanation,omitempty"`
|
|
// Multi questions ask for every correct option ("select all that apply").
|
|
Multi bool `json:"multi"`
|
|
Options []QuizOption `json:"options"`
|
|
}
|
|
|
|
// QuizOption is one choice. IsCorrect is nil whenever the reader must not
|
|
// know it yet — every response to someone mid-attempt.
|
|
type QuizOption struct {
|
|
ID string `json:"id"`
|
|
Ord int `json:"ord"`
|
|
Body string `json:"body"`
|
|
IsCorrect *bool `json:"is_correct,omitempty"`
|
|
}
|
|
|
|
// QuizStatus is the caller's progress on a quiz.
|
|
type QuizStatus struct {
|
|
State string `json:"state"`
|
|
Answered int `json:"answered"`
|
|
Total int `json:"total"`
|
|
Score *int `json:"score,omitempty"`
|
|
}
|
|
|
|
// QuizCard is a quiz plus the caller's progress, for buttons and lists.
|
|
type QuizCard struct {
|
|
Quiz
|
|
My QuizStatus `json:"my"`
|
|
}
|
|
|
|
// QuizPlay is the next step of an attempt: the current question, or Done.
|
|
type QuizPlay struct {
|
|
QuizID string `json:"quiz_id"`
|
|
Title string `json:"title"`
|
|
Answered int `json:"answered"`
|
|
Total int `json:"total"`
|
|
Done bool `json:"done"`
|
|
Question *QuizQuestion `json:"question,omitempty"`
|
|
}
|
|
|
|
// QuizResultItem is one question on a results screen.
|
|
type QuizResultItem struct {
|
|
QuizQuestion
|
|
ChosenOptionIDs []string `json:"chosen_option_ids"`
|
|
IsCorrect bool `json:"is_correct"`
|
|
ResponseMs *int `json:"response_ms,omitempty"`
|
|
}
|
|
|
|
// QuizResult is a finished attempt.
|
|
type QuizResult struct {
|
|
Quiz Quiz `json:"quiz"`
|
|
Score int `json:"score"`
|
|
Total int `json:"total"`
|
|
StartedAt time.Time `json:"started_at"`
|
|
CompletedAt *time.Time `json:"completed_at,omitempty"`
|
|
TotalMs int `json:"total_ms"`
|
|
Items []QuizResultItem `json:"items"`
|
|
}
|
|
|
|
// QuizParticipant is one person's attempt, for the admin participants list.
|
|
type QuizParticipant struct {
|
|
UserID string `json:"user_id"`
|
|
Handle string `json:"handle"`
|
|
Name string `json:"name"`
|
|
AvatarURL *string `json:"avatar_url,omitempty"`
|
|
StartedAt time.Time `json:"started_at"`
|
|
CompletedAt *time.Time `json:"completed_at,omitempty"`
|
|
Answered int `json:"answered"`
|
|
Score int `json:"score"`
|
|
Total int `json:"total"`
|
|
TotalMs int `json:"total_ms"`
|
|
}
|
|
|
|
// QuizOptionStat is how often one option was chosen.
|
|
type QuizOptionStat struct {
|
|
QuizOption
|
|
Picks int `json:"picks"`
|
|
}
|
|
|
|
// QuizQuestionStat aggregates every response to one question.
|
|
type QuizQuestionStat struct {
|
|
ID string `json:"id"`
|
|
Ord int `json:"ord"`
|
|
Prompt string `json:"prompt"`
|
|
Multi bool `json:"multi"`
|
|
Answered int `json:"answered"`
|
|
Correct int `json:"correct"`
|
|
AvgMs int `json:"avg_ms"`
|
|
MedianMs int `json:"median_ms"`
|
|
Options []QuizOptionStat `json:"options"`
|
|
}
|