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>
136 lines
5.0 KiB
SQL
136 lines
5.0 KiB
SQL
-- =====================================================
|
|
-- Migration: Backfill module_progress for existing users
|
|
-- Date: 2025-11-24
|
|
-- Priority: CRITICAL
|
|
-- Reason: Bug fix - initialize_user_stats() didn't create module_progress records
|
|
--
|
|
-- ISSUE: The trigger gamilit.initialize_user_stats() was incomplete.
|
|
-- It created user_stats, comodines_inventory, and user_ranks,
|
|
-- but NEVER created progress_tracking.module_progress records.
|
|
-- This caused new users to see "no modules available" errors.
|
|
--
|
|
-- IMPACT: All users registered before 2025-11-24 are missing module_progress.
|
|
-- This migration backfills those records.
|
|
--
|
|
-- SAFETY: This script is idempotent and safe to run multiple times.
|
|
-- Uses ON CONFLICT DO NOTHING to prevent duplicates.
|
|
-- =====================================================
|
|
|
|
DO $$
|
|
DECLARE
|
|
v_affected_users INTEGER;
|
|
v_affected_records INTEGER;
|
|
v_total_users INTEGER;
|
|
v_users_needing_fix INTEGER;
|
|
BEGIN
|
|
RAISE NOTICE '================================================';
|
|
RAISE NOTICE 'Migration: Backfill module_progress';
|
|
RAISE NOTICE 'Started at: %', NOW();
|
|
RAISE NOTICE '================================================';
|
|
|
|
-- Count total users with gamification roles
|
|
SELECT COUNT(*)
|
|
INTO v_total_users
|
|
FROM auth_management.profiles
|
|
WHERE role IN ('student', 'admin_teacher', 'super_admin')
|
|
AND deleted_at IS NULL;
|
|
|
|
RAISE NOTICE 'Total users with gamification: %', v_total_users;
|
|
|
|
-- Count users who are missing module_progress records
|
|
SELECT COUNT(DISTINCT p.id)
|
|
INTO v_users_needing_fix
|
|
FROM auth_management.profiles p
|
|
WHERE p.role IN ('student', 'admin_teacher', 'super_admin')
|
|
AND p.deleted_at IS NULL
|
|
AND NOT EXISTS (
|
|
SELECT 1
|
|
FROM progress_tracking.module_progress mp
|
|
WHERE mp.user_id = p.id -- FIXED: Use p.id (profiles.id) not p.user_id
|
|
);
|
|
|
|
RAISE NOTICE 'Users missing module_progress: %', v_users_needing_fix;
|
|
|
|
-- Insert module_progress for users who don't have any
|
|
-- This matches the logic in the fixed initialize_user_stats() function
|
|
-- IMPORTANT: module_progress.user_id references profiles.id (NOT auth.users.id)
|
|
INSERT INTO progress_tracking.module_progress (
|
|
user_id,
|
|
module_id,
|
|
status,
|
|
progress_percentage,
|
|
created_at,
|
|
updated_at
|
|
)
|
|
SELECT
|
|
p.id, -- FIXED: Use p.id (profiles.id) not p.user_id (auth.users.id)
|
|
m.id as module_id,
|
|
'not_started'::progress_tracking.progress_status,
|
|
0,
|
|
NOW(),
|
|
NOW()
|
|
FROM auth_management.profiles p
|
|
CROSS JOIN educational_content.modules m
|
|
WHERE p.role IN ('student', 'admin_teacher', 'super_admin')
|
|
AND p.deleted_at IS NULL
|
|
AND m.is_published = true
|
|
AND m.status = 'published'
|
|
AND NOT EXISTS (
|
|
SELECT 1
|
|
FROM progress_tracking.module_progress mp
|
|
WHERE mp.user_id = p.id -- FIXED: Use p.id (profiles.id) not p.user_id
|
|
AND mp.module_id = m.id
|
|
)
|
|
ON CONFLICT (user_id, module_id) DO NOTHING;
|
|
|
|
GET DIAGNOSTICS v_affected_records = ROW_COUNT;
|
|
|
|
-- Count how many users now have module_progress
|
|
SELECT COUNT(DISTINCT p.id)
|
|
INTO v_affected_users
|
|
FROM auth_management.profiles p
|
|
WHERE p.role IN ('student', 'admin_teacher', 'super_admin')
|
|
AND p.deleted_at IS NULL
|
|
AND EXISTS (
|
|
SELECT 1
|
|
FROM progress_tracking.module_progress mp
|
|
WHERE mp.user_id = p.id -- FIXED: Use p.id (profiles.id) not p.user_id
|
|
);
|
|
|
|
RAISE NOTICE '================================================';
|
|
RAISE NOTICE 'Migration Results:';
|
|
RAISE NOTICE ' - Total module_progress records created: %', v_affected_records;
|
|
RAISE NOTICE ' - Users affected: %', v_users_needing_fix;
|
|
RAISE NOTICE ' - Users now with module_progress: %', v_affected_users;
|
|
RAISE NOTICE ' - Completed at: %', NOW();
|
|
RAISE NOTICE '================================================';
|
|
|
|
-- Validation check
|
|
IF v_affected_users < v_total_users THEN
|
|
RAISE WARNING 'Some users still missing module_progress! Check: % of %',
|
|
v_total_users - v_affected_users, v_total_users;
|
|
ELSE
|
|
RAISE NOTICE 'SUCCESS: All users now have module_progress records!';
|
|
END IF;
|
|
|
|
EXCEPTION
|
|
WHEN OTHERS THEN
|
|
RAISE EXCEPTION 'Migration failed: % - %', SQLERRM, SQLSTATE;
|
|
END $$;
|
|
|
|
-- =====================================================
|
|
-- Verification Query (Run after migration)
|
|
-- =====================================================
|
|
-- SELECT
|
|
-- p.id, -- FIXED: Use p.id (profiles.id) for grouping
|
|
-- p.email,
|
|
-- p.role,
|
|
-- COUNT(mp.id) as module_count
|
|
-- FROM auth_management.profiles p
|
|
-- LEFT JOIN progress_tracking.module_progress mp ON mp.user_id = p.id -- FIXED: Use p.id
|
|
-- WHERE p.role IN ('student', 'admin_teacher', 'super_admin')
|
|
-- AND p.deleted_at IS NULL
|
|
-- GROUP BY p.id, p.email, p.role -- FIXED: Use p.id
|
|
-- ORDER BY module_count ASC, p.email;
|
|
-- =====================================================
|