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>
156 lines
6.6 KiB
SQL
156 lines
6.6 KiB
SQL
-- ==============================================================================
|
|
-- GAMILIT - SCHEMA PROGRESS
|
|
-- ==============================================================================
|
|
-- Tablas de progreso, matriculas y estadisticas
|
|
-- Mantenido por: Database-Agent
|
|
-- Actualizado: 2025-12-18
|
|
-- ==============================================================================
|
|
|
|
-- ------------------------------------------------------------------------------
|
|
-- TABLA: ENROLLMENTS (Matriculas)
|
|
-- ------------------------------------------------------------------------------
|
|
CREATE TABLE IF NOT EXISTS enrollments (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
|
course_id UUID NOT NULL REFERENCES courses(id) ON DELETE CASCADE,
|
|
status VARCHAR(50) DEFAULT 'active', -- active, completed, dropped
|
|
enrolled_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,
|
|
completed_at TIMESTAMPTZ,
|
|
progress_percentage DECIMAL(5,2) DEFAULT 0,
|
|
last_accessed_at TIMESTAMPTZ,
|
|
UNIQUE(user_id, course_id)
|
|
);
|
|
|
|
CREATE INDEX idx_enrollments_user ON enrollments(user_id);
|
|
CREATE INDEX idx_enrollments_course ON enrollments(course_id);
|
|
CREATE INDEX idx_enrollments_status ON enrollments(status);
|
|
|
|
-- ------------------------------------------------------------------------------
|
|
-- TABLA: LESSON_PROGRESS
|
|
-- ------------------------------------------------------------------------------
|
|
CREATE TABLE IF NOT EXISTS lesson_progress (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
|
lesson_id UUID NOT NULL REFERENCES lessons(id) ON DELETE CASCADE,
|
|
status VARCHAR(50) DEFAULT 'not_started', -- not_started, in_progress, completed
|
|
started_at TIMESTAMPTZ,
|
|
completed_at TIMESTAMPTZ,
|
|
time_spent_seconds INTEGER DEFAULT 0,
|
|
score DECIMAL(5,2),
|
|
attempts INTEGER DEFAULT 0,
|
|
UNIQUE(user_id, lesson_id)
|
|
);
|
|
|
|
CREATE INDEX idx_lesson_progress_user ON lesson_progress(user_id);
|
|
CREATE INDEX idx_lesson_progress_lesson ON lesson_progress(lesson_id);
|
|
CREATE INDEX idx_lesson_progress_status ON lesson_progress(status);
|
|
|
|
-- ------------------------------------------------------------------------------
|
|
-- TABLA: QUIZ_ATTEMPTS
|
|
-- ------------------------------------------------------------------------------
|
|
CREATE TABLE IF NOT EXISTS quiz_attempts (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
|
quiz_id UUID NOT NULL REFERENCES quizzes(id) ON DELETE CASCADE,
|
|
score DECIMAL(5,2) NOT NULL,
|
|
passed BOOLEAN NOT NULL,
|
|
answers JSONB NOT NULL,
|
|
time_taken_seconds INTEGER,
|
|
started_at TIMESTAMPTZ NOT NULL,
|
|
completed_at TIMESTAMPTZ NOT NULL,
|
|
created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP
|
|
);
|
|
|
|
CREATE INDEX idx_quiz_attempts_user ON quiz_attempts(user_id);
|
|
CREATE INDEX idx_quiz_attempts_quiz ON quiz_attempts(quiz_id);
|
|
|
|
-- ------------------------------------------------------------------------------
|
|
-- TABLA: USER_ACHIEVEMENTS
|
|
-- ------------------------------------------------------------------------------
|
|
CREATE TABLE IF NOT EXISTS user_achievements (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
|
achievement_id UUID NOT NULL REFERENCES achievements(id) ON DELETE CASCADE,
|
|
earned_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,
|
|
progress_data JSONB DEFAULT '{}',
|
|
UNIQUE(user_id, achievement_id)
|
|
);
|
|
|
|
CREATE INDEX idx_user_achievements_user ON user_achievements(user_id);
|
|
CREATE INDEX idx_user_achievements_achievement ON user_achievements(achievement_id);
|
|
|
|
-- ------------------------------------------------------------------------------
|
|
-- TABLA: USER_POINTS
|
|
-- ------------------------------------------------------------------------------
|
|
CREATE TABLE IF NOT EXISTS user_points (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
|
points_type VARCHAR(50) NOT NULL, -- course, quiz, achievement, bonus
|
|
points INTEGER NOT NULL,
|
|
source_type VARCHAR(50), -- course, lesson, quiz, achievement
|
|
source_id UUID,
|
|
description TEXT,
|
|
created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP
|
|
);
|
|
|
|
CREATE INDEX idx_user_points_user ON user_points(user_id);
|
|
CREATE INDEX idx_user_points_type ON user_points(points_type);
|
|
CREATE INDEX idx_user_points_date ON user_points(created_at);
|
|
|
|
-- ------------------------------------------------------------------------------
|
|
-- TABLA: USER_XP (Experiencia)
|
|
-- ------------------------------------------------------------------------------
|
|
CREATE TABLE IF NOT EXISTS user_xp (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
|
total_xp INTEGER DEFAULT 0,
|
|
level INTEGER DEFAULT 1,
|
|
xp_to_next_level INTEGER DEFAULT 100,
|
|
updated_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,
|
|
UNIQUE(user_id)
|
|
);
|
|
|
|
CREATE INDEX idx_user_xp_user ON user_xp(user_id);
|
|
CREATE INDEX idx_user_xp_level ON user_xp(level);
|
|
|
|
-- ------------------------------------------------------------------------------
|
|
-- TABLA: STREAKS (Rachas)
|
|
-- ------------------------------------------------------------------------------
|
|
CREATE TABLE IF NOT EXISTS streaks (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
|
current_streak INTEGER DEFAULT 0,
|
|
longest_streak INTEGER DEFAULT 0,
|
|
last_activity_date DATE,
|
|
streak_type VARCHAR(50) DEFAULT 'daily', -- daily, weekly
|
|
updated_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,
|
|
UNIQUE(user_id, streak_type)
|
|
);
|
|
|
|
CREATE INDEX idx_streaks_user ON streaks(user_id);
|
|
|
|
-- ------------------------------------------------------------------------------
|
|
-- VISTA: LEADERBOARD
|
|
-- ------------------------------------------------------------------------------
|
|
CREATE OR REPLACE VIEW leaderboard AS
|
|
SELECT
|
|
u.id as user_id,
|
|
u.first_name,
|
|
u.last_name,
|
|
u.avatar_url,
|
|
u.tenant_id,
|
|
COALESCE(SUM(up.points), 0) as total_points,
|
|
COALESCE(ux.level, 1) as level,
|
|
COALESCE(ux.total_xp, 0) as total_xp,
|
|
COUNT(DISTINCT ua.achievement_id) as achievements_count,
|
|
COALESCE(s.current_streak, 0) as current_streak
|
|
FROM users u
|
|
LEFT JOIN user_points up ON u.id = up.user_id
|
|
LEFT JOIN user_xp ux ON u.id = ux.user_id
|
|
LEFT JOIN user_achievements ua ON u.id = ua.user_id
|
|
LEFT JOIN streaks s ON u.id = s.user_id AND s.streak_type = 'daily'
|
|
WHERE u.deleted_at IS NULL
|
|
GROUP BY u.id, u.first_name, u.last_name, u.avatar_url, u.tenant_id,
|
|
ux.level, ux.total_xp, s.current_streak
|
|
ORDER BY total_points DESC;
|