feat(service): CardService générique sur l'abstraction CardRepository
This commit is contained in:
1 parent
a3d9be86d8
commit
12670b7134
3 files changed
+83
No files matched your search
@@ -0,0 +1,25 @@
|
||||
import { NextResponse, type NextRequest } from 'next/server'
|
||||
import { ZodError } from 'zod'
|
||||
import { AppError, ValidationError } from '@/domain/errors'
|
||||
|
||||
export function handleError(error: unknown): NextResponse {
|
||||
if (error instanceof ZodError) {
|
||||
return NextResponse.json(
|
||||
{ error: 'ValidationError', message: 'Payload invalide', issues: error.flatten() },
|
||||
{ status: 400 },
|
||||
)
|
||||
}
|
||||
if (error instanceof AppError) {
|
||||
return NextResponse.json({ error: error.name, message: error.message }, { status: error.status })
|
||||
}
|
||||
console.error(error)
|
||||
return NextResponse.json({ error: 'InternalServerError', message: 'Erreur interne' }, { status: 500 })
|
||||
}
|
||||
|
||||
export async function parseJsonBody(request: NextRequest): Promise<unknown> {
|
||||
try {
|
||||
return await request.json()
|
||||
} catch {
|
||||
throw new ValidationError('Corps de requête invalide (JSON attendu)')
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
import { getCardRepository } from '@/config/card-repository-factory'
|
||||
import { CardService } from './card-service'
|
||||
|
||||
export function getCardService(): CardService {
|
||||
return new CardService(getCardRepository())
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
import type { Card, CardInput } from '@/domain/card'
|
||||
import type { CardRepository } from '@/domain/card-repository'
|
||||
import { NotFoundError } from '@/domain/errors'
|
||||
|
||||
export class CardService {
|
||||
constructor(private readonly repository: CardRepository) {}
|
||||
|
||||
async list(): Promise<Card[]> {
|
||||
return this.repository.findAll()
|
||||
}
|
||||
|
||||
async get(id: string): Promise<Card> {
|
||||
const card = await this.repository.findById(id)
|
||||
if (!card) {
|
||||
throw new NotFoundError(`Carte ${id} introuvable`)
|
||||
}
|
||||
return card
|
||||
}
|
||||
|
||||
async create(input: CardInput): Promise<Card> {
|
||||
return this.repository.create(input)
|
||||
}
|
||||
|
||||
async update(id: string, input: Partial<CardInput>): Promise<Card> {
|
||||
const card = await this.repository.update(id, input)
|
||||
if (!card) {
|
||||
throw new NotFoundError(`Carte ${id} introuvable`)
|
||||
}
|
||||
return card
|
||||
}
|
||||
|
||||
async remove(id: string): Promise<void> {
|
||||
const deleted = await this.repository.delete(id)
|
||||
if (!deleted) {
|
||||
throw new NotFoundError(`Carte ${id} introuvable`)
|
||||
}
|
||||
}
|
||||
|
||||
async random(theme?: string): Promise<Card> {
|
||||
const card = theme
|
||||
? await this.repository.findRandomByTheme(theme)
|
||||
: await this.repository.findRandom()
|
||||
if (!card) {
|
||||
throw new NotFoundError(theme ? `Aucune carte pour le thème ${theme}` : 'Aucune carte disponible')
|
||||
}
|
||||
return card
|
||||
}
|
||||
|
||||
async themes(): Promise<string[]> {
|
||||
return this.repository.findThemes()
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user