feat: add quiz, question, answer and attempt models with migrations
This commit is contained in:
99
updates/20261002120404_create_quizzes_tables.go
Normal file
99
updates/20261002120404_create_quizzes_tables.go
Normal file
@@ -0,0 +1,99 @@
|
||||
// Code generated by summer make. DO NOT EDIT.
|
||||
|
||||
package updates
|
||||
|
||||
import (
|
||||
"github.com/go-gormigrate/gormigrate/v2"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
// CreateQuizzesTables returns the 20261002120404_create_quizzes_tables gormigrate entry.
|
||||
// It creates the quiz, question, answer, attempt and attempt answer tables.
|
||||
// Deleting a quiz deletes its questions, answers and attempts; deleting a
|
||||
// question deletes its answers and the attempt answers given to it; deleting
|
||||
// a user deletes their attempts.
|
||||
func CreateQuizzesTables() *gormigrate.Migration {
|
||||
return &gormigrate.Migration{
|
||||
ID: "20261002120404_create_quizzes_tables",
|
||||
Migrate: func(tx *gorm.DB) error {
|
||||
for _, stmt := range []string{
|
||||
`CREATE TABLE golem15_quizzes_quizzes (
|
||||
id BIGSERIAL PRIMARY KEY,
|
||||
title VARCHAR(255) NOT NULL,
|
||||
slug VARCHAR(255) NOT NULL UNIQUE,
|
||||
description TEXT NULL,
|
||||
context VARCHAR(255) NULL,
|
||||
is_published BOOLEAN NOT NULL DEFAULT FALSE,
|
||||
time_limit_seconds INTEGER NULL,
|
||||
passing_score INTEGER NOT NULL DEFAULT 50,
|
||||
shuffle_questions BOOLEAN NOT NULL DEFAULT FALSE,
|
||||
round_size INTEGER NULL,
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
||||
)`,
|
||||
`CREATE INDEX golem15_quizzes_quizzes_context_index ON golem15_quizzes_quizzes (context)`,
|
||||
`CREATE TABLE golem15_quizzes_questions (
|
||||
id BIGSERIAL PRIMARY KEY,
|
||||
quiz_id BIGINT NOT NULL REFERENCES golem15_quizzes_quizzes (id) ON DELETE CASCADE,
|
||||
text TEXT NOT NULL,
|
||||
type VARCHAR(20) NOT NULL DEFAULT 'single' CHECK (type IN ('single', 'multiple', 'self_check')),
|
||||
category VARCHAR(255) NULL,
|
||||
answer_text TEXT NULL,
|
||||
explanation TEXT NULL,
|
||||
sort_order INTEGER NOT NULL DEFAULT 0,
|
||||
points INTEGER NOT NULL DEFAULT 1,
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
||||
)`,
|
||||
`CREATE INDEX golem15_quizzes_questions_quiz_id_index ON golem15_quizzes_questions (quiz_id, sort_order)`,
|
||||
`CREATE INDEX golem15_quizzes_questions_category_index ON golem15_quizzes_questions (category)`,
|
||||
`CREATE TABLE golem15_quizzes_answers (
|
||||
id BIGSERIAL PRIMARY KEY,
|
||||
question_id BIGINT NOT NULL REFERENCES golem15_quizzes_questions (id) ON DELETE CASCADE,
|
||||
text TEXT NOT NULL,
|
||||
is_correct BOOLEAN NOT NULL DEFAULT FALSE,
|
||||
explanation TEXT NULL,
|
||||
sort_order INTEGER NOT NULL DEFAULT 0,
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
||||
)`,
|
||||
`CREATE INDEX golem15_quizzes_answers_question_id_index ON golem15_quizzes_answers (question_id, sort_order)`,
|
||||
`CREATE TABLE golem15_quizzes_attempts (
|
||||
id BIGSERIAL PRIMARY KEY,
|
||||
quiz_id BIGINT NOT NULL REFERENCES golem15_quizzes_quizzes (id) ON DELETE CASCADE,
|
||||
user_id INTEGER NOT NULL REFERENCES users (id) ON DELETE CASCADE,
|
||||
started_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
completed_at TIMESTAMPTZ NULL,
|
||||
score_points DOUBLE PRECISION NOT NULL DEFAULT 0,
|
||||
max_points INTEGER NOT NULL DEFAULT 0,
|
||||
score_percent DOUBLE PRECISION NULL,
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
||||
)`,
|
||||
`CREATE INDEX golem15_quizzes_attempts_user_id_index ON golem15_quizzes_attempts (user_id, quiz_id)`,
|
||||
`CREATE INDEX golem15_quizzes_attempts_quiz_id_index ON golem15_quizzes_attempts (quiz_id)`,
|
||||
`CREATE TABLE golem15_quizzes_attempt_answers (
|
||||
id BIGSERIAL PRIMARY KEY,
|
||||
attempt_id BIGINT NOT NULL REFERENCES golem15_quizzes_attempts (id) ON DELETE CASCADE,
|
||||
question_id BIGINT NOT NULL REFERENCES golem15_quizzes_questions (id) ON DELETE CASCADE,
|
||||
answer_ids JSONB NULL,
|
||||
self_check_known BOOLEAN NULL,
|
||||
is_correct BOOLEAN NOT NULL DEFAULT FALSE,
|
||||
points DOUBLE PRECISION NOT NULL DEFAULT 0,
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
CONSTRAINT golem15_quizzes_attempt_answers_attempt_question_unique UNIQUE (attempt_id, question_id)
|
||||
)`,
|
||||
`CREATE INDEX golem15_quizzes_attempt_answers_question_id_index ON golem15_quizzes_attempt_answers (question_id)`,
|
||||
} {
|
||||
if err := tx.Exec(stmt).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
},
|
||||
Rollback: func(tx *gorm.DB) error {
|
||||
return tx.Exec(`DROP TABLE IF EXISTS golem15_quizzes_attempt_answers, golem15_quizzes_attempts, golem15_quizzes_answers, golem15_quizzes_questions, golem15_quizzes_quizzes`).Error
|
||||
},
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user