-- ============================================================================== -- GAMILIT - SCHEMA GAMIFICATION -- ============================================================================== -- Tablas de cursos, lecciones y contenido educativo -- Mantenido por: Database-Agent -- Actualizado: 2025-12-18 -- ============================================================================== -- ------------------------------------------------------------------------------ -- TABLA: COURSES -- ------------------------------------------------------------------------------ CREATE TABLE IF NOT EXISTS courses ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), title VARCHAR(255) NOT NULL, slug VARCHAR(255) NOT NULL, description TEXT, thumbnail_url TEXT, instructor_id UUID REFERENCES users(id), status VARCHAR(50) DEFAULT 'draft', difficulty VARCHAR(50) DEFAULT 'beginner', estimated_hours DECIMAL(5,2), points_reward INTEGER DEFAULT 0, tenant_id UUID REFERENCES tenants(id) ON DELETE CASCADE, settings JSONB DEFAULT '{}', published_at TIMESTAMPTZ, created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP, deleted_at TIMESTAMPTZ, UNIQUE(slug, tenant_id) ); CREATE INDEX idx_courses_instructor ON courses(instructor_id); CREATE INDEX idx_courses_tenant ON courses(tenant_id); CREATE INDEX idx_courses_status ON courses(status); CREATE INDEX idx_courses_slug ON courses(slug); CREATE TRIGGER update_courses_updated_at BEFORE UPDATE ON courses FOR EACH ROW EXECUTE FUNCTION update_updated_at_column(); -- ------------------------------------------------------------------------------ -- TABLA: MODULES (Secciones de curso) -- ------------------------------------------------------------------------------ CREATE TABLE IF NOT EXISTS modules ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), course_id UUID NOT NULL REFERENCES courses(id) ON DELETE CASCADE, title VARCHAR(255) NOT NULL, description TEXT, order_index INTEGER DEFAULT 0, points_reward INTEGER DEFAULT 0, created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP ); CREATE INDEX idx_modules_course ON modules(course_id); CREATE INDEX idx_modules_order ON modules(course_id, order_index); CREATE TRIGGER update_modules_updated_at BEFORE UPDATE ON modules FOR EACH ROW EXECUTE FUNCTION update_updated_at_column(); -- ------------------------------------------------------------------------------ -- TABLA: LESSONS -- ------------------------------------------------------------------------------ CREATE TABLE IF NOT EXISTS lessons ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), module_id UUID NOT NULL REFERENCES modules(id) ON DELETE CASCADE, title VARCHAR(255) NOT NULL, content_type VARCHAR(50) NOT NULL, -- video, text, quiz, exercise content JSONB DEFAULT '{}', duration_minutes INTEGER, order_index INTEGER DEFAULT 0, points_reward INTEGER DEFAULT 10, xp_reward INTEGER DEFAULT 5, created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP ); CREATE INDEX idx_lessons_module ON lessons(module_id); CREATE INDEX idx_lessons_order ON lessons(module_id, order_index); CREATE TRIGGER update_lessons_updated_at BEFORE UPDATE ON lessons FOR EACH ROW EXECUTE FUNCTION update_updated_at_column(); -- ------------------------------------------------------------------------------ -- TABLA: QUIZZES -- ------------------------------------------------------------------------------ CREATE TABLE IF NOT EXISTS quizzes ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), lesson_id UUID NOT NULL REFERENCES lessons(id) ON DELETE CASCADE, title VARCHAR(255) NOT NULL, description TEXT, time_limit_minutes INTEGER, passing_score INTEGER DEFAULT 70, max_attempts INTEGER DEFAULT 3, shuffle_questions BOOLEAN DEFAULT false, created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP ); CREATE INDEX idx_quizzes_lesson ON quizzes(lesson_id); CREATE TRIGGER update_quizzes_updated_at BEFORE UPDATE ON quizzes FOR EACH ROW EXECUTE FUNCTION update_updated_at_column(); -- ------------------------------------------------------------------------------ -- TABLA: QUIZ_QUESTIONS -- ------------------------------------------------------------------------------ CREATE TABLE IF NOT EXISTS quiz_questions ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), quiz_id UUID NOT NULL REFERENCES quizzes(id) ON DELETE CASCADE, question_type VARCHAR(50) NOT NULL, -- multiple_choice, true_false, short_answer question_text TEXT NOT NULL, options JSONB DEFAULT '[]', correct_answer JSONB NOT NULL, explanation TEXT, points INTEGER DEFAULT 10, order_index INTEGER DEFAULT 0, created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP ); CREATE INDEX idx_quiz_questions_quiz ON quiz_questions(quiz_id); -- ------------------------------------------------------------------------------ -- TABLA: ACHIEVEMENTS (Logros/Insignias) -- ------------------------------------------------------------------------------ CREATE TABLE IF NOT EXISTS achievements ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), name VARCHAR(255) NOT NULL, description TEXT, icon_url TEXT, badge_color VARCHAR(50), points_reward INTEGER DEFAULT 0, xp_reward INTEGER DEFAULT 0, criteria JSONB NOT NULL, -- Condiciones para obtener el logro is_secret BOOLEAN DEFAULT false, tenant_id UUID REFERENCES tenants(id) ON DELETE CASCADE, created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP ); CREATE INDEX idx_achievements_tenant ON achievements(tenant_id);