-- ===================================================== -- TABLE: education.courses -- ===================================================== -- Proyecto: OrbiQuant IA (Trading Platform) -- Módulo: OQI-002 - Education -- Especificación: ET-EDU-001-database.md -- ===================================================== CREATE TABLE education.courses ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), -- Información básica title VARCHAR(200) NOT NULL, slug VARCHAR(200) NOT NULL UNIQUE, short_description VARCHAR(500), full_description TEXT, -- Categorización category_id UUID NOT NULL REFERENCES education.categories(id) ON DELETE RESTRICT, difficulty_level education.difficulty_level NOT NULL DEFAULT 'beginner', -- Contenido thumbnail_url VARCHAR(500), trailer_url VARCHAR(500), -- Video de presentación -- Metadata educativa duration_minutes INTEGER, -- Duración estimada total prerequisites TEXT[], -- IDs de cursos prerequisitos learning_objectives TEXT[], -- Array de objetivos -- Instructor instructor_id UUID NOT NULL REFERENCES auth.users(id) ON DELETE RESTRICT, instructor_name VARCHAR(200), -- Denormalizado para performance -- Pricing (para futuras features) is_free BOOLEAN DEFAULT true, price_usd DECIMAL(10,2), -- Gamificación xp_reward INTEGER DEFAULT 0, -- XP al completar el curso -- Estado status education.course_status DEFAULT 'draft', published_at TIMESTAMPTZ, -- Estadísticas (denormalizadas) total_modules INTEGER DEFAULT 0, total_lessons INTEGER DEFAULT 0, total_enrollments INTEGER DEFAULT 0, avg_rating DECIMAL(3,2) DEFAULT 0.00, total_reviews INTEGER DEFAULT 0, -- Metadata created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), CONSTRAINT valid_rating CHECK (avg_rating >= 0 AND avg_rating <= 5), CONSTRAINT valid_price CHECK (price_usd >= 0) ); -- Índices CREATE INDEX idx_courses_category ON education.courses(category_id); CREATE INDEX idx_courses_slug ON education.courses(slug); CREATE INDEX idx_courses_status ON education.courses(status); CREATE INDEX idx_courses_difficulty ON education.courses(difficulty_level); CREATE INDEX idx_courses_instructor ON education.courses(instructor_id); CREATE INDEX idx_courses_published ON education.courses(published_at) WHERE status = 'published'; -- Comentarios COMMENT ON TABLE education.courses IS 'Cursos del módulo educativo'; COMMENT ON COLUMN education.courses.instructor_name IS 'Denormalizado para performance en queries'; COMMENT ON COLUMN education.courses.prerequisites IS 'Array de UUIDs de cursos prerequisitos'; COMMENT ON COLUMN education.courses.learning_objectives IS 'Array de objetivos de aprendizaje'; COMMENT ON COLUMN education.courses.xp_reward IS 'XP otorgado al completar el curso';