6.3 KiB
Multi-Household Architecture Migration Guide
Pre-Migration Checklist
-
Backup Database
pg_dump -U your_user -d grocery_list > backup_$(date +%Y%m%d_%H%M%S).sql -
Test on Staging First
- Copy production database to staging environment
- Run migration on staging
- Verify all data migrated correctly
- Test application functionality
-
Review Migration Script
- Read through
multi_household_architecture.sql - Understand each step
- Note verification queries
- Read through
-
Announce Maintenance Window
- Notify users of downtime
- Schedule during low-usage period
- Estimate 15-30 minutes for migration
Running the Migration
1. Connect to Database
psql -U your_user -d grocery_list
2. Run Migration
\i backend/migrations/multi_household_architecture.sql
The script will:
- ✅ Create 8 new tables
- ✅ Create default "Main Household"
- ✅ Create default "Costco" store
- ✅ Migrate all users to household members
- ✅ Extract items to master catalog
- ✅ Migrate grocery_list → household_lists
- ✅ Migrate classifications
- ✅ Migrate history records
- ✅ Update user system roles
3. Verify Migration
Run these queries inside psql:
-- Check household created
SELECT * FROM households;
-- Check all users migrated
SELECT u.username, u.role as system_role, hm.role as household_role
FROM users u
JOIN household_members hm ON u.id = hm.user_id
ORDER BY u.id;
-- Check item counts match
SELECT
(SELECT COUNT(DISTINCT item_name) FROM grocery_list) as old_unique_items,
(SELECT COUNT(*) FROM items) as new_items;
-- Check list counts
SELECT
(SELECT COUNT(*) FROM grocery_list) as old_lists,
(SELECT COUNT(*) FROM household_lists) as new_lists;
-- Check classification counts
SELECT
(SELECT COUNT(*) FROM item_classification) as old_classifications,
(SELECT COUNT(*) FROM household_item_classifications) as new_classifications;
-- Check history counts
SELECT
(SELECT COUNT(*) FROM grocery_history) as old_history,
(SELECT COUNT(*) FROM household_list_history) as new_history;
-- Verify no data loss - check if all old items have corresponding new records
SELECT gl.item_name
FROM grocery_list gl
LEFT JOIN items i ON LOWER(i.name) = LOWER(TRIM(gl.item_name))
LEFT JOIN household_lists hl ON hl.item_id = i.id
WHERE hl.id IS NULL;
-- Should return 0 rows
-- Check invite code
SELECT name, invite_code FROM households;
4. Test Application
- Users can log in
- Can view "Main Household" list
- Can add items
- Can mark items as bought
- History shows correctly
- Classifications preserved
- Images display correctly
Post-Migration Cleanup
Only after verifying everything works correctly:
-- Drop old tables (CAREFUL - THIS IS IRREVERSIBLE)
DROP TABLE IF EXISTS grocery_history CASCADE;
DROP TABLE IF EXISTS item_classification CASCADE;
DROP TABLE IF EXISTS grocery_list CASCADE;
Rollback Plan
If Migration Fails
-- Inside psql during migration
ROLLBACK;
-- Then restore from backup
\q
psql -U your_user -d grocery_list < backup_YYYYMMDD_HHMMSS.sql
If Issues Found After Migration
# Drop the database and restore
dropdb grocery_list
createdb grocery_list
psql -U your_user -d grocery_list < backup_YYYYMMDD_HHMMSS.sql
Common Issues & Solutions
Issue: Duplicate items in items table
Cause: Case-insensitive matching not working Solution: Check item names for leading/trailing spaces
Issue: Foreign key constraint errors
Cause: User or item references not found Solution: Verify all users and items exist before migrating lists
Issue: History not showing
Cause: household_list_id references incorrect Solution: Check JOIN conditions in history migration
Issue: Images not displaying
Cause: BYTEA encoding issues Solution: Verify image_mime_type correctly migrated
Migration Timeline
- T-0: Begin maintenance window
- T+2min: Backup complete
- T+3min: Start migration script
- T+8min: Migration complete (for ~1000 items)
- T+10min: Run verification queries
- T+15min: Test application functionality
- T+20min: If successful, announce completion
- T+30min: End maintenance window
Data Integrity Checks
-- Ensure all users belong to at least one household
SELECT u.id, u.username
FROM users u
LEFT JOIN household_members hm ON u.id = hm.user_id
WHERE hm.id IS NULL;
-- Should return 0 rows
-- Ensure all household lists have valid items
SELECT hl.id
FROM household_lists hl
LEFT JOIN items i ON hl.item_id = i.id
WHERE i.id IS NULL;
-- Should return 0 rows
-- Ensure all history has valid list references
SELECT hlh.id
FROM household_list_history hlh
LEFT JOIN household_lists hl ON hlh.household_list_id = hl.id
WHERE hl.id IS NULL;
-- Should return 0 rows
-- Check for orphaned classifications
SELECT hic.id
FROM household_item_classifications hic
LEFT JOIN household_lists hl ON hic.item_id = hl.item_id
AND hic.household_id = hl.household_id
AND hic.store_id = hl.store_id
WHERE hl.id IS NULL;
-- Should return 0 rows (or classifications for removed items, which is ok)
Success Criteria
✅ All tables created successfully ✅ All users migrated to "Main Household" ✅ Item count matches (unique items from old → new) ✅ List count matches (all grocery_list items → household_lists) ✅ Classification count matches ✅ History count matches ✅ No NULL foreign keys ✅ Application loads without errors ✅ Users can perform all CRUD operations ✅ Images display correctly ✅ Bought items still marked as bought ✅ Recently bought still shows correctly
Next Steps After Migration
- ✅ Update backend models (Sprint 2)
- ✅ Update API routes
- ✅ Update controllers
- ✅ Test all endpoints
- ✅ Update frontend contexts
- ✅ Update UI components
- ✅ Enable multi-household features
Support & Troubleshooting
If issues arise:
- Check PostgreSQL logs:
/var/log/postgresql/ - Check application logs
- Restore from backup if needed
- Review migration script for errors
Monitoring Post-Migration
For the first 24 hours after migration:
- Monitor error logs
- Watch for performance issues
- Verify user activity normal
- Check for any data inconsistencies
- Be ready to rollback if critical issues found