feat(schema): add githubUsername field to User model for contributor attribution

This commit is contained in:
Fatih Kadir Akın
2025-12-13 17:13:54 +03:00
parent 140a2ef566
commit 38dd65d708
5 changed files with 25 additions and 16 deletions

View File

@@ -20,18 +20,19 @@ enum UserRole {
}
model User {
id String @id @default(cuid())
email String @unique
username String @unique
name String?
password String? // For credentials auth
avatar String?
role UserRole @default(USER)
locale String @default("en")
verified Boolean @default(false)
emailVerified DateTime?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
id String @id @default(cuid())
email String @unique
username String @unique
name String?
password String? // For credentials auth
avatar String?
role UserRole @default(USER)
locale String @default("en")
verified Boolean @default(false)
emailVerified DateTime?
githubUsername String? // Immutable GitHub username for contributor attribution
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
// Relations
prompts Prompt[] @relation("PromptAuthor")

View File

@@ -29,7 +29,8 @@ export async function GET() {
},
author: {
select: {
username: true,
email: true,
githubUsername: true,
},
},
},
@@ -42,7 +43,9 @@ export async function GET() {
const promptContent = escapeCSVField(prompt.content);
const forDevs = prompt.category?.slug === "coding" ? "TRUE" : "FALSE";
const type = prompt.type;
const contributor = escapeCSVField(prompt.author.username);
// Use githubUsername for GitHub users, email for others (Google, credentials)
// This prevents impersonation since these identifiers are immutable
const contributor = escapeCSVField(prompt.author.githubUsername || prompt.author.email);
return [act, promptContent, forDevs, type, contributor].join(",");
});

View File

@@ -41,9 +41,11 @@ function CustomPrismaAdapter(): Adapter {
return {
...prismaAdapter,
async createUser(data: AdapterUser & { username?: string }) {
async createUser(data: AdapterUser & { username?: string; githubUsername?: string }) {
// Use GitHub username if provided, otherwise generate one
let username = (data as any).username;
const githubUsername = (data as any).githubUsername; // Immutable GitHub username
if (!username) {
username = await generateUsername(data.email, data.name);
} else {
@@ -64,6 +66,7 @@ function CustomPrismaAdapter(): Adapter {
email: data.email,
avatar: data.image,
emailVerified: data.emailVerified,
githubUsername: githubUsername || undefined, // Store immutable GitHub username
},
});
@@ -91,6 +94,7 @@ function CustomPrismaAdapter(): Adapter {
avatar: data.image,
emailVerified: data.emailVerified,
username,
githubUsername: githubUsername || undefined, // Store immutable GitHub username
},
});

View File

@@ -14,7 +14,8 @@ export const githubPlugin: AuthPlugin = {
name: profile.name || profile.login,
email: profile.email,
image: profile.avatar_url,
username: profile.login, // GitHub username
username: profile.login, // GitHub username (used as display username)
githubUsername: profile.login, // Immutable GitHub username for contributor attribution
};
},
}),