feat: implement data migration for existing lists

- Created migration-actions.ts with server actions for claiming lists
- Added ClaimListsModal component for UI during registration
- Integrated claim modal into RegisterForm
- Created anonymous-lists.ts utilities for tracking lists in localStorage
- Added migrate-lists.ts script for deployment migration
- Created comprehensive MIGRATION_GUIDE.md documentation
- Added migration tests with 100% pass rate
- Updated package.json with db:migrate script
- Added tsx as dev dependency for running migration scripts

Requirements: 10.2, 10.3, 10.4, 10.5
- Users can claim existing lists on first registration
- All list data is preserved during migration
- All lists have an owner after migration
- Migrated lists appear in user's account
This commit is contained in:
2025-12-02 01:20:35 +00:00
parent 54612a4782
commit 2ce89e7c6c
9 changed files with 976 additions and 4 deletions

160
MIGRATION_GUIDE.md Normal file
View File

@@ -0,0 +1,160 @@
# Data Migration Guide
This guide explains how to migrate existing anonymous lists to the new user authentication system.
## Overview
The Ultimate Lists App now supports user authentication and private lists. This migration ensures that:
- All existing lists are preserved (Requirement 10.3)
- All lists have an associated owner (Requirement 10.4)
- Users can claim their existing lists when they register (Requirement 10.2)
- All list data including items, metadata, and timestamps remain unchanged (Requirement 10.3)
## Migration Strategy
### For New Deployments
If you're deploying the authentication system for the first time:
1. **Run the migration script** before enabling authentication:
```bash
npx tsx scripts/migrate-lists.ts
```
This script will:
- Create a system user if it doesn't exist
- Assign any orphaned lists to the system user
- Verify all lists have owners
2. **Deploy the application** with authentication enabled
3. **Users can claim lists** when they register:
- Lists created before registration are tracked in localStorage
- During registration, users are prompted to claim their lists
- Lists are transferred from system user to the new user account
### For Existing Users
When a user registers for the first time:
1. The app checks localStorage for any tracked list IDs
2. If lists are found, a modal appears asking the user to claim them
3. User can select which lists to claim
4. Selected lists are transferred to the user's account
5. All list data (items, metadata, timestamps) is preserved
## Technical Details
### Database Schema Changes
The migration adds:
- `User` table with authentication fields
- `ownerId` field on `List` table (required)
- `Collaborator` table for list sharing
- `Invitation` table for sharing invitations
### Migration Script
Location: `scripts/migrate-lists.ts`
The script:
- Creates a system user (`system@ultimatelists.app`)
- Assigns orphaned lists to the system user
- Verifies data integrity
- Provides a migration summary
### Client-Side Tracking
Location: `lib/anonymous-lists.ts`
Utilities for tracking anonymous lists:
- `trackAnonymousList(listId)` - Add a list to tracking
- `getAnonymousListIds()` - Get all tracked lists
- `clearAnonymousLists()` - Clear tracking after migration
- `hasAnonymousLists()` - Check if there are lists to migrate
### Migration Actions
Location: `lib/migration-actions.ts`
Server actions for migration:
- `getClaimableLists(listIds)` - Fetch lists that can be claimed
- `claimLists(listIds)` - Transfer lists to user account
- `hasExistingLists()` - Check if user has lists
- `migrateOrphanedListsToSystemUser()` - One-time migration script
### UI Components
Location: `components/ClaimListsModal.tsx`
Modal component that:
- Displays claimable lists with details
- Allows users to select which lists to claim
- Handles the claim process
- Clears localStorage after successful claim
## Testing the Migration
### Test Scenario 1: New User with Anonymous Lists
1. Create lists without being logged in
2. Register for an account
3. Verify the claim modal appears
4. Select lists to claim
5. Verify lists appear in the user's account
6. Verify all items and metadata are preserved
### Test Scenario 2: New User without Anonymous Lists
1. Register for an account without creating lists
2. Verify no claim modal appears
3. Verify user is redirected to the app
### Test Scenario 3: Existing User
1. Log in with an existing account
2. Verify existing lists are displayed
3. Verify all data is intact
## Rollback Plan
If issues occur during migration:
1. **Database Rollback**:
```bash
npx prisma migrate reset
```
2. **Restore from Backup**:
- Restore database from pre-migration backup
- Redeploy previous version of the application
3. **Manual Data Recovery**:
- Export lists from system user
- Manually assign to correct users
- Verify data integrity
## Monitoring
After migration, monitor:
- Number of orphaned lists (should be 0)
- Number of lists owned by system user
- User registration and claim rates
- Any errors in migration logs
## Support
If users experience issues:
1. Check browser console for errors
2. Verify localStorage contains list IDs
3. Check server logs for migration errors
4. Manually transfer lists if needed using admin tools
## Requirements Validation
This migration satisfies:
- ✓ Requirement 10.1: Authentication system provides migration path
- ✓ Requirement 10.2: Users can claim existing lists on registration
- ✓ Requirement 10.3: All list data is preserved during migration
- ✓ Requirement 10.4: All lists have an associated owner
- ✓ Requirement 10.5: Migrated lists appear in user's account