Files
openccb/services/cms-service/migrations/20260217000001_advanced_grading.sql
T

94 lines
3.9 KiB
SQL

-- Migration: Advanced Grading System (Rubrics)
-- Description: Creates tables for rubric-based assessment and grading workflows
-- Created: 2026-02-17
-- Rubrics table - Reusable evaluation templates
CREATE TABLE IF NOT EXISTS rubrics (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
organization_id UUID NOT NULL REFERENCES organizations(id) ON DELETE CASCADE,
course_id UUID REFERENCES courses(id) ON DELETE CASCADE, -- NULL = reusable across courses
created_by UUID NOT NULL REFERENCES users(id),
name VARCHAR(255) NOT NULL,
description TEXT,
total_points INTEGER NOT NULL DEFAULT 100,
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);
CREATE INDEX idx_rubrics_org ON rubrics(organization_id);
CREATE INDEX idx_rubrics_course ON rubrics(course_id);
-- Rubric Criteria - Evaluation dimensions
CREATE TABLE IF NOT EXISTS rubric_criteria (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
rubric_id UUID NOT NULL REFERENCES rubrics(id) ON DELETE CASCADE,
name VARCHAR(255) NOT NULL,
description TEXT,
max_points INTEGER NOT NULL,
position INTEGER NOT NULL DEFAULT 0,
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);
CREATE INDEX idx_criteria_rubric ON rubric_criteria(rubric_id);
-- Rubric Levels - Performance levels per criterion
CREATE TABLE IF NOT EXISTS rubric_levels (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
criterion_id UUID NOT NULL REFERENCES rubric_criteria(id) ON DELETE CASCADE,
name VARCHAR(100) NOT NULL, -- e.g., "Excellent", "Proficient", "Developing"
description TEXT,
points INTEGER NOT NULL,
position INTEGER NOT NULL DEFAULT 0,
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);
CREATE INDEX idx_levels_criterion ON rubric_levels(criterion_id);
-- Lesson-Rubric Association
CREATE TABLE IF NOT EXISTS lesson_rubrics (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
lesson_id UUID NOT NULL REFERENCES lessons(id) ON DELETE CASCADE,
rubric_id UUID NOT NULL REFERENCES rubrics(id) ON DELETE CASCADE,
is_active BOOLEAN DEFAULT TRUE,
assigned_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
UNIQUE(lesson_id, rubric_id)
);
CREATE INDEX idx_lesson_rubrics_lesson ON lesson_rubrics(lesson_id);
CREATE INDEX idx_lesson_rubrics_rubric ON lesson_rubrics(rubric_id);
-- Rubric Assessments - Student evaluation results
CREATE TABLE IF NOT EXISTS rubric_assessments (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
lesson_id UUID NOT NULL REFERENCES lessons(id) ON DELETE CASCADE,
rubric_id UUID NOT NULL REFERENCES rubrics(id),
user_id UUID NOT NULL REFERENCES users(id), -- student being assessed
graded_by UUID REFERENCES users(id), -- instructor or peer reviewer
submission_id UUID, -- if linked to peer_submissions
total_score DECIMAL(5,2) NOT NULL,
max_score INTEGER NOT NULL,
feedback TEXT,
status VARCHAR(50) DEFAULT 'draft', -- draft, submitted, published
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);
CREATE INDEX idx_assessments_lesson ON rubric_assessments(lesson_id);
CREATE INDEX idx_assessments_user ON rubric_assessments(user_id);
CREATE INDEX idx_assessments_grader ON rubric_assessments(graded_by);
CREATE INDEX idx_assessments_status ON rubric_assessments(status);
-- Assessment Scores - Individual criterion scores
CREATE TABLE IF NOT EXISTS assessment_scores (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
assessment_id UUID NOT NULL REFERENCES rubric_assessments(id) ON DELETE CASCADE,
criterion_id UUID NOT NULL REFERENCES rubric_criteria(id),
level_id UUID REFERENCES rubric_levels(id), -- selected performance level
points DECIMAL(5,2) NOT NULL,
feedback TEXT,
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);
CREATE INDEX idx_scores_assessment ON assessment_scores(assessment_id);
CREATE INDEX idx_scores_criterion ON assessment_scores(criterion_id);