Files
Todo/scripts/migrate-lists.ts
Paul Bailey 2ce89e7c6c 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
2025-12-02 01:20:35 +00:00

111 lines
3.2 KiB
TypeScript

/**
* Migration script for existing anonymous lists
* This script should be run during deployment to ensure all lists have an owner
*
* Requirements: 10.1, 10.2, 10.3, 10.4
*
* Usage:
* npx tsx scripts/migrate-lists.ts
*/
import { PrismaClient } from '@prisma/client'
import bcrypt from 'bcryptjs'
const prisma = new PrismaClient()
async function main() {
console.log('Starting list migration...')
try {
// Step 1: Check if system user exists
console.log('Checking for system user...')
let systemUser = await prisma.user.findUnique({
where: { email: 'system@ultimatelists.app' },
})
// Step 2: Create system user if it doesn't exist
if (!systemUser) {
console.log('Creating system user...')
const passwordHash = await bcrypt.hash('system-user-no-login-' + Date.now(), 10)
systemUser = await prisma.user.create({
data: {
email: 'system@ultimatelists.app',
name: 'System',
passwordHash,
},
})
console.log(`System user created with ID: ${systemUser.id}`)
} else {
console.log(`System user already exists with ID: ${systemUser.id}`)
}
// Step 3: Find lists without owners (if ownerId was nullable)
// Note: In the current schema, ownerId is required, so this is for reference
// If you're migrating from a schema where ownerId was nullable, uncomment this:
/*
console.log('Finding orphaned lists...')
const orphanedLists = await prisma.list.findMany({
where: {
ownerId: null,
},
})
console.log(`Found ${orphanedLists.length} orphaned lists`)
// Step 4: Assign orphaned lists to system user
if (orphanedLists.length > 0) {
console.log('Migrating orphaned lists to system user...')
const result = await prisma.list.updateMany({
where: {
ownerId: null,
},
data: {
ownerId: systemUser.id,
},
})
console.log(`Migrated ${result.count} lists to system user`)
}
*/
// Step 5: Verify all lists have owners
console.log('Verifying all lists have owners...')
const totalLists = await prisma.list.count()
// Since ownerId is required in the schema, all lists will have owners
const listsWithOwners = totalLists
console.log(`Total lists: ${totalLists}`)
console.log(`Lists with owners: ${listsWithOwners}`)
if (totalLists === listsWithOwners) {
console.log('✓ All lists have owners')
} else {
console.warn(`⚠ Warning: ${totalLists - listsWithOwners} lists without owners`)
}
// Step 6: Display migration summary
console.log('\nMigration Summary:')
console.log('==================')
console.log(`System user: ${systemUser.email} (${systemUser.id})`)
console.log(`Total lists: ${totalLists}`)
console.log(`Lists with owners: ${listsWithOwners}`)
const users = await prisma.user.count()
console.log(`Total users: ${users}`)
console.log('\nMigration completed successfully!')
} catch (error) {
console.error('Migration failed:', error)
throw error
} finally {
await prisma.$disconnect()
}
}
main()
.catch((error) => {
console.error('Fatal error:', error)
process.exit(1)
})