workspace/projects/gamilit/apps/database/_deprecated/migrations-removed-2025-11-24/2025-11-24-backfill-module-progress.sql
rckrdmrd ea1879f4ad feat: Initial workspace structure with multi-level Git configuration
- Configure workspace Git repository with comprehensive .gitignore
- Add Odoo as submodule for ERP reference code
- Include documentation: SETUP.md, GIT-STRUCTURE.md
- Add gitignore templates for projects (backend, frontend, database)
- Structure supports independent repos per project/subproject level

Workspace includes:
- core/ - Reusable patterns, modules, orchestration system
- projects/ - Active projects (erp-suite, gamilit, trading-platform, etc.)
- knowledge-base/ - Reference code and patterns (includes Odoo submodule)
- devtools/ - Development tools and templates
- customers/ - Client implementations template

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

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

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