Files
2025-11-11 03:08:36 -03:00

250 lines
5.6 KiB
TypeScript

/**
* Queries de usuários usando Prisma
* Migrado de lib/db/queries/users.ts
*/
import type { User } from "@prisma/client";
import { prisma } from "../app";
import { getDefaultSubscriptionTier } from "./subscription-tiers";
export interface CreateUserData {
username: string;
email: string;
password_hash: string;
first_name: string;
last_name: string;
phone?: string;
cpf?: string;
}
export interface UpdateUserData {
first_name?: string;
last_name?: string;
phone?: string;
whatsapp_notifications?: boolean;
subscription_tier_id?: number | null;
}
/**
* Cria um novo usuário
*/
export async function createUser(
data: CreateUserData,
): Promise<{ userId: number; username: string; email: string }> {
const defaultTier = await getDefaultSubscriptionTier();
const user = await prisma.user.create({
data: {
username: data.username,
email: data.email,
password_hash: data.password_hash,
first_name: data.first_name,
last_name: data.last_name,
phone: data.phone || null,
cpf: data.cpf || null,
subscription_tier_id: defaultTier?.subscription_tier_id ?? undefined,
},
select: {
user_id: true,
username: true,
email: true,
},
});
return {
userId: user.user_id,
username: user.username,
email: user.email,
};
}
/**
* Busca usuário por email (inclui password_hash para login)
*/
type UserWithTier = User & {
subscription_tier?: {
subscription_tier_id: number;
name: string;
slug: string;
level: number;
} | null;
};
export async function getUserByEmail(
email: string,
): Promise<UserWithTier | null> {
return (await prisma.user.findUnique({
where: { email },
include: {
subscription_tier: {
select: {
subscription_tier_id: true,
name: true,
slug: true,
level: true,
},
},
},
})) as UserWithTier | null;
}
/**
* Busca usuário por username
*/
export async function getUserByUsername(
username: string,
): Promise<UserWithTier | null> {
return (await prisma.user.findUnique({
where: { username },
include: {
subscription_tier: {
select: {
subscription_tier_id: true,
name: true,
slug: true,
level: true,
},
},
},
})) as UserWithTier | null;
}
/**
* Busca usuário por ID (sem password_hash)
*/
type PublicUser = {
user_id: number;
username: string;
email: string;
first_name: string;
last_name: string;
phone: string | null;
cpf: string | null;
account_level: string;
has_donated: boolean;
whatsapp_notifications: boolean;
created_at: Date;
updated_at: Date;
last_login: Date | null;
is_active: boolean;
is_verified: boolean;
subscription_tier?: {
subscription_tier_id: number;
name: string;
slug: string;
level: number;
} | null;
};
export async function getUserById(userId: number): Promise<PublicUser | null> {
return (await prisma.user.findUnique({
where: { user_id: userId },
select: {
user_id: true,
username: true,
email: true,
first_name: true,
last_name: true,
phone: true,
cpf: true,
account_level: true,
has_donated: true,
whatsapp_notifications: true,
created_at: true,
updated_at: true,
last_login: true,
is_active: true,
is_verified: true,
subscription_tier: {
select: {
subscription_tier_id: true,
name: true,
slug: true,
level: true,
},
},
},
})) as PublicUser | null;
}
/**
* Busca usuário por CPF (verifica duplicidade)
*/
export async function getUserByCpf(
cpf: string,
): Promise<Pick<User, "user_id" | "username" | "email"> | null> {
return (await prisma.user.findUnique({
where: { cpf },
select: {
user_id: true,
username: true,
email: true,
},
})) as Pick<User, "user_id" | "username" | "email"> | null;
}
/**
* Atualiza dados do usuário
*/
export async function updateUser(
userId: number,
data: UpdateUserData,
): Promise<PublicUser> {
const updateData: any = {};
if (data.first_name !== undefined) updateData.first_name = data.first_name;
if (data.last_name !== undefined) updateData.last_name = data.last_name;
if (data.phone !== undefined) updateData.phone = data.phone || null;
if (data.whatsapp_notifications !== undefined)
updateData.whatsapp_notifications = data.whatsapp_notifications;
if (data.subscription_tier_id !== undefined) {
if (data.subscription_tier_id === null) {
updateData.subscription_tier = { disconnect: true };
} else {
updateData.subscription_tier = {
connect: { subscription_tier_id: data.subscription_tier_id },
};
}
}
const user = await prisma.user.update({
where: { user_id: userId },
data: updateData,
select: {
user_id: true,
username: true,
email: true,
first_name: true,
last_name: true,
phone: true,
cpf: true,
account_level: true,
has_donated: true,
whatsapp_notifications: true,
created_at: true,
updated_at: true,
last_login: true,
is_active: true,
is_verified: true,
subscription_tier: {
select: {
subscription_tier_id: true,
name: true,
slug: true,
level: true,
},
},
},
});
return user as PublicUser;
}
/**
* Atualiza timestamp de último login
*/
export async function updateLastLogin(userId: number): Promise<void> {
await prisma.user.update({
where: { user_id: userId },
data: { last_login: new Date() },
});
}