workspace-v1/projects/gamilit/database/schemas/03-gamification-ddl.sql
Adrian Flores Cortes 967ab360bb Initial commit: Workspace v1 with 3-layer architecture
Structure:
- control-plane/: Registries, SIMCO directives, CI/CD templates
- projects/: Gamilit, ERP-Suite, Trading-Platform, Betting-Analytics
- shared/: Libs catalog, knowledge-base

Key features:
- Centralized port, domain, database, and service registries
- 23 SIMCO directives + 6 fundamental principles
- NEXUS agent profiles with delegation rules
- Validation scripts for workspace integrity
- Dockerfiles for all services
- Path aliases for quick reference

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-23 00:35:19 -06:00

148 lines
5.7 KiB
SQL

-- ==============================================================================
-- 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);