fix: prevent duplicate user_ prefix in usernames

- Update user creation logic to strip 'user_' prefix from Clerk ID before generating username
- Change default username pattern from 'user_<clerkId>' to 'user<cleanId>'
- This prevents usernames like 'user_user_35Z...' and creates 'user35Z...' instead
- Apply fix to both userService and reportController
- Add migration script to fix existing duplicate usernames

Example: user_user_35ZFZ... -> user35ZFZ...
This commit is contained in:
2025-11-16 21:44:21 +00:00
parent 426c4c7d7e
commit 258cbcf238
3 changed files with 71 additions and 2 deletions

View File

@@ -22,11 +22,15 @@ export class ReportController {
try { try {
const clerkUser = await clerkClient.users.getUser(clerkId); const clerkUser = await clerkClient.users.getUser(clerkId);
// Generate a clean username from Clerk ID (remove 'user_' prefix if present)
const cleanClerkId = clerkId.startsWith('user_') ? clerkId.substring(5) : clerkId;
const defaultUsername = clerkUser.username || `user${cleanClerkId.substring(0, 8)}`;
user = await prisma.user.create({ user = await prisma.user.create({
data: { data: {
clerkId, clerkId,
email: clerkUser.emailAddresses[0]?.emailAddress || `${clerkId}@temp.com`, email: clerkUser.emailAddresses[0]?.emailAddress || `${clerkId}@temp.com`,
username: clerkUser.username || `user_${clerkId.substring(0, 8)}`, username: defaultUsername,
firstName: clerkUser.firstName, firstName: clerkUser.firstName,
lastName: clerkUser.lastName, lastName: clerkUser.lastName,
avatarUrl: clerkUser.imageUrl, avatarUrl: clerkUser.imageUrl,

View File

@@ -0,0 +1,61 @@
/**
* Script to fix duplicate usernames that have the pattern user_user_xxxxx
*
* This script updates usernames that were created with the old logic
* where we used `user_${clerkId}` and the clerkId already started with 'user_'
*
* Usage: npx ts-node src/scripts/fixDuplicateUsernames.ts
*/
import prisma from '../config/database';
async function fixDuplicateUsernames() {
console.log('🔍 Finding users with duplicate username pattern...\n');
try {
// Find all users with usernames starting with 'user_user_'
const usersToFix = await prisma.user.findMany({
where: {
username: {
startsWith: 'user_user_',
},
},
});
console.log(`Found ${usersToFix.length} users to fix\n`);
if (usersToFix.length === 0) {
console.log('✅ No users need fixing!');
return;
}
// Fix each user
for (const user of usersToFix) {
const oldUsername = user.username;
// Remove the duplicate 'user_' prefix
const newUsername = oldUsername.replace(/^user_user_/, 'user');
console.log(`Updating user ${user.id}:`);
console.log(` Old: ${oldUsername}`);
console.log(` New: ${newUsername}`);
await prisma.user.update({
where: { id: user.id },
data: { username: newUsername },
});
console.log(' ✅ Updated\n');
}
console.log(`\n✅ Successfully fixed ${usersToFix.length} usernames!`);
} catch (error) {
console.error('❌ Error fixing usernames:', error);
throw error;
} finally {
await prisma.$disconnect();
}
}
// Run the script
fixDuplicateUsernames();

View File

@@ -36,11 +36,15 @@ export class UserService {
try { try {
const clerkUser = await clerkClient.users.getUser(clerkId); const clerkUser = await clerkClient.users.getUser(clerkId);
// Generate a clean username from Clerk ID (remove 'user_' prefix if present)
const cleanClerkId = clerkId.startsWith('user_') ? clerkId.substring(5) : clerkId;
const defaultUsername = clerkUser.username || `user${cleanClerkId.substring(0, 8)}`;
user = await prisma.user.create({ user = await prisma.user.create({
data: { data: {
clerkId, clerkId,
email: clerkUser.emailAddresses[0]?.emailAddress || `${clerkId}@temp.com`, email: clerkUser.emailAddresses[0]?.emailAddress || `${clerkId}@temp.com`,
username: clerkUser.username || `user_${clerkId.substring(0, 8)}`, username: defaultUsername,
firstName: clerkUser.firstName, firstName: clerkUser.firstName,
lastName: clerkUser.lastName, lastName: clerkUser.lastName,
avatarUrl: clerkUser.imageUrl, avatarUrl: clerkUser.imageUrl,