feat: add modular services and repositories for improved code organization

Introduce repository pattern across multiple services, including `favorites`, `tags`, `sessions`, `reports`, `auth`, and more. Decouple crypto functionalities into modular services like `HashingService`, `JwtService`, and `EncryptionService`. Improve testability and maintainability by simplifying dependencies and consolidating utility logic.
This commit is contained in:
Mathis HERRIOT
2026-01-14 12:11:39 +01:00
parent 9c45bf11e4
commit 514bd354bf
64 changed files with 1801 additions and 1295 deletions

View File

@@ -4,46 +4,32 @@ import {
Logger,
NotFoundException,
} from "@nestjs/common";
import { and, eq } from "drizzle-orm";
import { DatabaseService } from "../database/database.service";
import { contents, favorites } from "../database/schemas";
import { FavoritesRepository } from "./repositories/favorites.repository";
@Injectable()
export class FavoritesService {
private readonly logger = new Logger(FavoritesService.name);
constructor(private readonly databaseService: DatabaseService) {}
constructor(private readonly favoritesRepository: FavoritesRepository) {}
async addFavorite(userId: string, contentId: string) {
this.logger.log(`Adding favorite: user ${userId}, content ${contentId}`);
// Vérifier si le contenu existe
const content = await this.databaseService.db
.select()
.from(contents)
.where(eq(contents.id, contentId))
.limit(1);
if (content.length === 0) {
const content = await this.favoritesRepository.findContentById(contentId);
if (!content) {
throw new NotFoundException("Content not found");
}
try {
return await this.databaseService.db
.insert(favorites)
.values({ userId, contentId })
.returning();
return await this.favoritesRepository.add(userId, contentId);
} catch (_error) {
// Probablement une violation de clé primaire (déjà en favori)
throw new ConflictException("Content already in favorites");
}
}
async removeFavorite(userId: string, contentId: string) {
this.logger.log(`Removing favorite: user ${userId}, content ${contentId}`);
const result = await this.databaseService.db
.delete(favorites)
.where(and(eq(favorites.userId, userId), eq(favorites.contentId, contentId)))
.returning();
const result = await this.favoritesRepository.remove(userId, contentId);
if (result.length === 0) {
throw new NotFoundException("Favorite not found");
@@ -53,16 +39,6 @@ export class FavoritesService {
}
async getUserFavorites(userId: string, limit: number, offset: number) {
const data = await this.databaseService.db
.select({
content: contents,
})
.from(favorites)
.innerJoin(contents, eq(favorites.contentId, contents.id))
.where(eq(favorites.userId, userId))
.limit(limit)
.offset(offset);
return data.map((item) => item.content);
return await this.favoritesRepository.findByUserId(userId, limit, offset);
}
}