feat: Implement multi-tenancy with organization ID in LMS tables and middleware, refactor web API calls, and update analytics and gamification features."

This commit is contained in:
2026-01-15 11:40:38 -03:00
parent 8bc034b82d
commit daeda7e905
12 changed files with 325 additions and 106 deletions
@@ -0,0 +1,59 @@
-- Migration: Update Analytics Functions for Multi-Tenancy
-- Scope: fn_get_cohort_analytics, fn_get_retention_data
-- 1. Update Course Cohort Analytics to include p_organization_id
CREATE OR REPLACE FUNCTION fn_get_cohort_analytics(p_course_id UUID, p_organization_id UUID)
RETURNS TABLE (
period TEXT,
student_count BIGINT,
completion_rate FLOAT4
) AS $$
BEGIN
RETURN QUERY
WITH cohort_students AS (
SELECT
user_id,
TO_CHAR(enrolled_at, 'YYYY-MM') as v_period
FROM enrollments
WHERE course_id = p_course_id AND organization_id = p_organization_id
),
course_lesson_count AS (
SELECT COUNT(*)::float4 as total_lessons
FROM lessons
WHERE module_id IN (SELECT id FROM modules WHERE course_id = p_course_id AND organization_id = p_organization_id)
AND organization_id = p_organization_id
)
SELECT
cs.v_period as period,
COUNT(DISTINCT cs.user_id) as student_count,
COALESCE(AVG(
(SELECT COUNT(DISTINCT lesson_id)::float4 FROM user_grades WHERE user_id = cs.user_id AND course_id = p_course_id AND organization_id = p_organization_id) /
NULLIF((SELECT total_lessons FROM course_lesson_count), 0)
), 0)::float4 as completion_rate
FROM cohort_students cs
GROUP BY cs.v_period
ORDER BY cs.v_period DESC;
END;
$$ LANGUAGE plpgsql;
-- 2. Update Retention Data Function to include p_organization_id
CREATE OR REPLACE FUNCTION fn_get_retention_data(p_course_id UUID, p_organization_id UUID)
RETURNS TABLE (
lesson_id UUID,
lesson_title VARCHAR,
student_count BIGINT
) AS $$
BEGIN
RETURN QUERY
SELECT
l.id as lesson_id,
l.title as lesson_title,
COUNT(DISTINCT ug.user_id) as student_count
FROM lessons l
LEFT JOIN user_grades ug ON l.id = ug.lesson_id AND ug.organization_id = p_organization_id
WHERE l.module_id IN (SELECT id FROM modules WHERE course_id = p_course_id AND organization_id = p_organization_id)
AND l.organization_id = p_organization_id
GROUP BY l.id, l.title, l.position
ORDER BY l.position;
END;
$$ LANGUAGE plpgsql;
@@ -0,0 +1,32 @@
-- Migration: Add organization_id to remaining content tables (LMS)
-- Tables: modules, lessons, grading_categories, user_grades, user_badges, points_log
-- 1. Add organization_id to modules
ALTER TABLE modules ADD COLUMN organization_id UUID NOT NULL DEFAULT '00000000-0000-0000-0000-000000000001';
ALTER TABLE modules ADD CONSTRAINT fk_module_organization FOREIGN KEY (organization_id) REFERENCES organizations(id) ON DELETE CASCADE;
ALTER TABLE modules ALTER COLUMN organization_id DROP DEFAULT;
-- 2. Add organization_id to lessons
ALTER TABLE lessons ADD COLUMN organization_id UUID NOT NULL DEFAULT '00000000-0000-0000-0000-000000000001';
ALTER TABLE lessons ADD CONSTRAINT fk_lesson_organization FOREIGN KEY (organization_id) REFERENCES organizations(id) ON DELETE CASCADE;
ALTER TABLE lessons ALTER COLUMN organization_id DROP DEFAULT;
-- 3. Add organization_id to grading_categories
ALTER TABLE grading_categories ADD COLUMN organization_id UUID NOT NULL DEFAULT '00000000-0000-0000-0000-000000000001';
ALTER TABLE grading_categories ADD CONSTRAINT fk_grading_category_organization FOREIGN KEY (organization_id) REFERENCES organizations(id) ON DELETE CASCADE;
ALTER TABLE grading_categories ALTER COLUMN organization_id DROP DEFAULT;
-- 4. Add organization_id to user_grades
ALTER TABLE user_grades ADD COLUMN organization_id UUID NOT NULL DEFAULT '00000000-0000-0000-0000-000000000001';
ALTER TABLE user_grades ADD CONSTRAINT fk_user_grade_organization FOREIGN KEY (organization_id) REFERENCES organizations(id) ON DELETE CASCADE;
ALTER TABLE user_grades ALTER COLUMN organization_id DROP DEFAULT;
-- 5. Add organization_id to user_badges
ALTER TABLE user_badges ADD COLUMN organization_id UUID NOT NULL DEFAULT '00000000-0000-0000-0000-000000000001';
ALTER TABLE user_badges ADD CONSTRAINT fk_user_badge_organization FOREIGN KEY (organization_id) REFERENCES organizations(id) ON DELETE CASCADE;
ALTER TABLE user_badges ALTER COLUMN organization_id DROP DEFAULT;
-- 6. Add organization_id to points_log
ALTER TABLE points_log ADD COLUMN organization_id UUID NOT NULL DEFAULT '00000000-0000-0000-0000-000000000001';
ALTER TABLE points_log ADD CONSTRAINT fk_points_log_organization FOREIGN KEY (organization_id) REFERENCES organizations(id) ON DELETE CASCADE;
ALTER TABLE points_log ALTER COLUMN organization_id DROP DEFAULT;