fix: no user ever had a username, so people search found nobody
Root cause of "still cannot find users": username was optional in better-auth's schema and no signup form or settings page ever set it, but search/profile/follow all key on username, not user id. Every account now gets a unique one auto-generated (from name/email) in the user.create.before hook — covers email/password and OAuth signups. Added a one-off db:backfill-usernames script for accounts created before this fix and ran it against the current database. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -13,6 +13,7 @@
|
||||
"migrate": "drizzle-kit migrate",
|
||||
"studio": "drizzle-kit studio",
|
||||
"seed": "tsx src/seed.ts",
|
||||
"backfill-usernames": "tsx src/backfill-usernames.ts",
|
||||
"typecheck": "tsc --noEmit"
|
||||
},
|
||||
"dependencies": {
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
import { db } from "./client";
|
||||
import { users } from "./schema";
|
||||
import { eq, isNull } from "drizzle-orm";
|
||||
|
||||
// Mirrors apps/web/lib/username.ts's slugify — duplicated rather than shared
|
||||
// since packages/db doesn't depend on apps/web. Kept intentionally simple.
|
||||
function slugify(seed: string): string {
|
||||
const base = seed
|
||||
.split("@")[0]!
|
||||
.toLowerCase()
|
||||
.replace(/[^a-z0-9_]/g, "")
|
||||
.slice(0, 20);
|
||||
return base.length >= 3 ? base : `${base}user`.slice(0, 20);
|
||||
}
|
||||
|
||||
async function backfillUsernames() {
|
||||
const rows = await db.query.users.findMany({
|
||||
where: isNull(users.username),
|
||||
columns: { id: true, name: true, email: true },
|
||||
});
|
||||
|
||||
console.log(`${rows.length} user(s) missing a username.`);
|
||||
|
||||
const taken = new Set(
|
||||
(await db.query.users.findMany({ columns: { username: true } }))
|
||||
.map((u) => u.username)
|
||||
.filter((u): u is string => !!u)
|
||||
);
|
||||
|
||||
for (const row of rows) {
|
||||
const base = slugify(row.name || row.email);
|
||||
let candidate = base;
|
||||
let suffix = 0;
|
||||
while (taken.has(candidate)) {
|
||||
suffix += 1;
|
||||
candidate = `${base}${suffix}`.slice(0, 20);
|
||||
}
|
||||
taken.add(candidate);
|
||||
|
||||
await db.update(users).set({ username: candidate }).where(eq(users.id, row.id));
|
||||
console.log(` ${row.email} -> @${candidate}`);
|
||||
}
|
||||
|
||||
console.log("Backfill complete.");
|
||||
process.exit(0);
|
||||
}
|
||||
|
||||
backfillUsernames().catch((err) => {
|
||||
console.error(err);
|
||||
process.exit(1);
|
||||
});
|
||||
Reference in New Issue
Block a user