-- ===================================================== -- TABLE: education.enrollments -- ===================================================== -- Proyecto: OrbiQuant IA (Trading Platform) -- Módulo: OQI-002 - Education -- Especificación: ET-EDU-001-database.md -- ===================================================== CREATE TABLE education.enrollments ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), -- Relaciones user_id UUID NOT NULL REFERENCES auth.users(id) ON DELETE CASCADE, course_id UUID NOT NULL REFERENCES education.courses(id) ON DELETE RESTRICT, -- Estado status education.enrollment_status DEFAULT 'active', -- Progreso progress_percentage DECIMAL(5,2) DEFAULT 0.00, completed_lessons INTEGER DEFAULT 0, total_lessons INTEGER DEFAULT 0, -- Snapshot del total al enrollarse -- Fechas importantes enrolled_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), started_at TIMESTAMPTZ, -- Primera lección vista completed_at TIMESTAMPTZ, expires_at TIMESTAMPTZ, -- Para cursos con límite de tiempo -- Gamificación total_xp_earned INTEGER DEFAULT 0, -- Metadata created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), CONSTRAINT unique_user_course UNIQUE(user_id, course_id), CONSTRAINT valid_progress CHECK (progress_percentage >= 0 AND progress_percentage <= 100), CONSTRAINT valid_completion CHECK ( (status != 'completed') OR (completed_at IS NOT NULL AND progress_percentage = 100) ) ); -- Índices CREATE INDEX idx_enrollments_user ON education.enrollments(user_id); CREATE INDEX idx_enrollments_course ON education.enrollments(course_id); CREATE INDEX idx_enrollments_status ON education.enrollments(status); CREATE INDEX idx_enrollments_user_active ON education.enrollments(user_id, status) WHERE status = 'active'; -- Comentarios COMMENT ON TABLE education.enrollments IS 'Inscripciones de usuarios a cursos'; COMMENT ON COLUMN education.enrollments.total_lessons IS 'Snapshot del total de lecciones al momento de enrollarse'; COMMENT ON COLUMN education.enrollments.started_at IS 'Timestamp de la primera lección vista'; COMMENT ON COLUMN education.enrollments.expires_at IS 'Fecha de expiración para cursos con límite de tiempo';