user.repository.ts•4.42 kB
/**
* User repository implementation
*/
import {
User,
UserCreateInput,
UserOrderByWithRelationInput
} from '../models/prisma.types';
import { prisma } from '../utils/db';
import {
ISearchableRepository,
SearchOptions,
SearchResult
} from './base.repository';
import { logger } from '../utils/logger';
/**
* Repository for user data access
*/
export class UserRepository implements ISearchableRepository<User, number> {
/**
* Find user by ID
* @param id User ID
* @returns User or null if not found
*/
async findById(id: number): Promise<User | null> {
try {
return await prisma.user.findUnique({
where: { id }
});
} catch (error) {
logger.error('Error finding user by ID:', error);
throw error;
}
}
/**
* Find all users
* @returns Array of users
*/
async findAll(): Promise<User[]> {
try {
return await prisma.user.findMany();
} catch (error) {
logger.error('Error finding all users:', error);
throw error;
}
}
/**
* Create a new user
* @param data User data
* @returns Created user
*/
async create(data: Omit<User, 'id' | 'createdAt' | 'updatedAt'>): Promise<User> {
try {
return await prisma.user.create({
data: data as UserCreateInput
});
} catch (error) {
logger.error('Error creating user:', error);
throw error;
}
}
/**
* Update a user
* @param id User ID
* @param data Updated user data
* @returns Updated user
*/
async update(id: number, data: Partial<User>): Promise<User> {
try {
return await prisma.user.update({
where: { id },
data
});
} catch (error) {
logger.error('Error updating user:', error);
throw error;
}
}
/**
* Delete a user
* @param id User ID
* @returns True if deleted, false otherwise
*/
async delete(id: number): Promise<boolean> {
try {
await prisma.user.delete({
where: { id }
});
return true;
} catch (error) {
logger.error('Error deleting user:', error);
return false;
}
}
/**
* Search users with filtering, sorting, and pagination
* @param options Search options
* @returns Search results with pagination metadata
*/
async search(options: SearchOptions): Promise<SearchResult<User>> {
const { skip = 0, take = 10, orderBy = { createdAt: 'desc' }, where = {} } = options;
const page = Math.floor(skip / take) + 1;
try {
// Get total count for pagination
const total = await prisma.user.count({ where });
// Get results with pagination
const items = await prisma.user.findMany({
skip,
take,
where,
orderBy: orderBy as UserOrderByWithRelationInput
});
const totalPages = Math.ceil(total / take);
return {
items,
total,
page,
limit: take,
totalPages,
hasNext: page < totalPages,
hasPrevious: page > 1
};
} catch (error) {
logger.error('Error searching users:', error);
throw error;
}
}
/**
* Find user by email
* @param email User email
* @returns User or null if not found
*/
async findByEmail(email: string): Promise<User | null> {
try {
return await prisma.user.findUnique({
where: { email }
});
} catch (error) {
logger.error('Error finding user by email:', error);
throw error;
}
}
/**
* Get user with relationships (articles, searches)
* @param id User ID
* @returns User with relationships or null if not found
*/
async getUserWithRelations(id: number): Promise<any | null> {
try {
return await prisma.user.findUnique({
where: { id },
include: {
userArticles: true,
searches: true
}
});
} catch (error) {
logger.error('Error getting user with relations:', error);
throw error;
}
}
/**
* Update last login time
* @param id User ID
* @returns Updated user
*/
async updateLastLogin(id: number): Promise<User> {
try {
return await prisma.user.update({
where: { id },
data: {
lastLoginAt: new Date()
}
});
} catch (error) {
logger.error('Error updating user last login:', error);
throw error;
}
}
}