trading-platform-database/ddl/schemas/education/tables/04-lessons.sql

67 lines
2.4 KiB
SQL

-- =====================================================
-- TABLE: education.lessons
-- =====================================================
-- Proyecto: OrbiQuant IA (Trading Platform)
-- Módulo: OQI-002 - Education
-- Especificación: ET-EDU-001-database.md
-- =====================================================
CREATE TABLE education.lessons (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
-- Relación con módulo
module_id UUID NOT NULL REFERENCES education.modules(id) ON DELETE CASCADE,
-- Información básica
title VARCHAR(200) NOT NULL,
description TEXT,
-- Tipo de contenido
content_type education.lesson_content_type NOT NULL DEFAULT 'video',
-- Contenido video
video_url VARCHAR(500), -- URL de Vimeo/S3
video_duration_seconds INTEGER,
video_provider VARCHAR(50), -- 'vimeo', 's3', etc.
video_id VARCHAR(200), -- ID del video en el provider
-- Contenido texto/article
article_content TEXT,
-- Recursos adicionales
attachments JSONB, -- [{name, url, type, size}]
-- Ordenamiento
display_order INTEGER NOT NULL DEFAULT 0,
-- Configuración
is_preview BOOLEAN DEFAULT false, -- Puede verse sin enrollment
is_mandatory BOOLEAN DEFAULT true, -- Requerido para completar el curso
-- Gamificación
xp_reward INTEGER DEFAULT 10, -- XP al completar la lección
-- Metadata
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
CONSTRAINT unique_module_order UNIQUE(module_id, display_order),
CONSTRAINT video_fields_required CHECK (
(content_type != 'video') OR
(video_url IS NOT NULL AND video_duration_seconds IS NOT NULL)
)
);
-- Índices
CREATE INDEX idx_lessons_module ON education.lessons(module_id);
CREATE INDEX idx_lessons_order ON education.lessons(module_id, display_order);
CREATE INDEX idx_lessons_type ON education.lessons(content_type);
CREATE INDEX idx_lessons_preview ON education.lessons(is_preview) WHERE is_preview = true;
-- Comentarios
COMMENT ON TABLE education.lessons IS 'Lecciones individuales dentro de módulos';
COMMENT ON COLUMN education.lessons.attachments IS 'Archivos adjuntos en formato JSON: [{name, url, type, size}]';
COMMENT ON COLUMN education.lessons.is_preview IS 'Puede verse sin enrollment (preview gratuito)';
COMMENT ON COLUMN education.lessons.is_mandatory IS 'Requerido para completar el curso';
COMMENT ON COLUMN education.lessons.xp_reward IS 'XP otorgado al completar la lección';