diff --git a/docs/api-get-cleanup.md b/docs/api-get-cleanup.md index bef6dac..05932eb 100644 --- a/docs/api-get-cleanup.md +++ b/docs/api-get-cleanup.md @@ -24,14 +24,19 @@ Routes GET actuellement présentes : | Route | Utilisation actuelle | Pourquoi garder maintenant | Piste de simplification | |-------|----------------------|----------------------------|-------------------------| -| `GET /api/komga/libraries/[libraryId]/series` | `src/app/libraries/[libraryId]/LibraryClientWrapper.tsx` (pagination/filtre/recherche) | Navigation dynamique pilotée par query params côté client | Évaluer migration partielle vers navigation server (`searchParams`) | -| `GET /api/komga/series/[seriesId]/books` | `src/app/series/[seriesId]/SeriesClientWrapper.tsx` (pagination/filtre) | Même contrainte de pagination dynamique | Même stratégie: server-first puis interactions ciblées | | `GET /api/komga/random-book` | `src/components/layout/ClientLayout.tsx` | Action utilisateur ponctuelle (random) | Option: server action dédiée plutôt qu'API GET | | `GET /api/komga/books/[bookId]` | fallback dans `ClientBookPage.tsx`, usage `DownloadManager.tsx` | fallback utile hors flux page SSR | Limiter au fallback strict, éviter le double-fetch | | `GET /api/komga/series/[seriesId]` | utilisé via Sidebar pour enrichir les favoris | enrichissement client en cascade | Charger les métadonnées nécessaires en amont côté server | | `GET /api/user/profile` | pas d'appel client direct trouvé | route utile pour consommation API interne/outils | Vérifier si remplaçable par service server direct | | `GET /api/komga/home` | endpoint de données agrégées | peut rester tant que la page consomme un service centralisé | privilégier appel server direct depuis page/home | +### B2. Migrees en Lot 2 (pagination server-first) + +| Route | Utilisation client actuelle | Cible | Action | +|-------|-----------------------------|-------|--------| +| `GET /api/komga/libraries/[libraryId]/series` | `src/app/libraries/[libraryId]/LibraryClientWrapper.tsx` | Chargement via `searchParams` dans page server | ✅ Supprimée | +| `GET /api/komga/series/[seriesId]/books` | `src/app/series/[seriesId]/SeriesClientWrapper.tsx` | Chargement via `searchParams` dans page server | ✅ Supprimée | + ### C. A conserver (API de transport / framework) | Route | Raison | diff --git a/src/app/api/komga/libraries/[libraryId]/series/route.ts b/src/app/api/komga/libraries/[libraryId]/series/route.ts deleted file mode 100644 index 46b280c..0000000 --- a/src/app/api/komga/libraries/[libraryId]/series/route.ts +++ /dev/null @@ -1,57 +0,0 @@ -import { NextResponse } from "next/server"; -import { LibraryService } from "@/lib/services/library.service"; -import { ERROR_CODES } from "@/constants/errorCodes"; -import { AppError } from "@/utils/errors"; -import { getErrorMessage } from "@/utils/errors"; -import type { NextRequest } from "next/server"; -import logger from "@/lib/logger"; - -// Cache handled in service via fetchFromApi options - -const DEFAULT_PAGE_SIZE = 20; - -export async function GET( - request: NextRequest, - { params }: { params: Promise<{ libraryId: string }> } -) { - try { - const libraryId: string = (await params).libraryId; - const searchParams = request.nextUrl.searchParams; - - const page = parseInt(searchParams.get("page") || "0"); - const size = parseInt(searchParams.get("size") || String(DEFAULT_PAGE_SIZE)); - const unreadOnly = searchParams.get("unread") === "true"; - const search = searchParams.get("search") || undefined; - - const [series, library] = await Promise.all([ - LibraryService.getLibrarySeries(libraryId, page, size, unreadOnly, search), - LibraryService.getLibrary(libraryId), - ]); - - return NextResponse.json({ series, library }); - } catch (error) { - logger.error({ err: error }, "API Library Series - Erreur:"); - if (error instanceof AppError) { - return NextResponse.json( - { - error: { - code: error.code, - name: "Library series fetch error", - message: getErrorMessage(error.code), - }, - }, - { status: 500 } - ); - } - return NextResponse.json( - { - error: { - code: ERROR_CODES.SERIES.FETCH_ERROR, - name: "Library series fetch error", - message: getErrorMessage(ERROR_CODES.SERIES.FETCH_ERROR), - }, - }, - { status: 500 } - ); - } -} diff --git a/src/app/api/komga/series/[seriesId]/books/route.ts b/src/app/api/komga/series/[seriesId]/books/route.ts deleted file mode 100644 index a5bb56e..0000000 --- a/src/app/api/komga/series/[seriesId]/books/route.ts +++ /dev/null @@ -1,56 +0,0 @@ -import { NextResponse } from "next/server"; -import { SeriesService } from "@/lib/services/series.service"; -import { ERROR_CODES } from "@/constants/errorCodes"; -import { AppError } from "@/utils/errors"; -import { getErrorMessage } from "@/utils/errors"; -import type { NextRequest } from "next/server"; -import logger from "@/lib/logger"; - -// Cache handled in service via fetchFromApi options - -const DEFAULT_PAGE_SIZE = 20; - -export async function GET( - request: NextRequest, - { params }: { params: Promise<{ seriesId: string }> } -) { - try { - const seriesId: string = (await params).seriesId; - const searchParams = request.nextUrl.searchParams; - - const page = parseInt(searchParams.get("page") || "0"); - const size = parseInt(searchParams.get("size") || String(DEFAULT_PAGE_SIZE)); - const unreadOnly = searchParams.get("unread") === "true"; - - const [books, series] = await Promise.all([ - SeriesService.getSeriesBooks(seriesId, page, size, unreadOnly), - SeriesService.getSeries(seriesId), - ]); - - return NextResponse.json({ books, series }); - } catch (error) { - logger.error({ err: error }, "API Series Books - Erreur:"); - if (error instanceof AppError) { - return NextResponse.json( - { - error: { - code: error.code, - name: "Series books fetch error", - message: getErrorMessage(error.code), - }, - }, - { status: 500 } - ); - } - return NextResponse.json( - { - error: { - code: ERROR_CODES.BOOK.PAGES_FETCH_ERROR, - name: "Series books fetch error", - message: getErrorMessage(ERROR_CODES.BOOK.PAGES_FETCH_ERROR), - }, - }, - { status: 500 } - ); - } -} diff --git a/src/app/libraries/[libraryId]/LibraryClientWrapper.tsx b/src/app/libraries/[libraryId]/LibraryClientWrapper.tsx index efef5c1..d2d3d9d 100644 --- a/src/app/libraries/[libraryId]/LibraryClientWrapper.tsx +++ b/src/app/libraries/[libraryId]/LibraryClientWrapper.tsx @@ -5,51 +5,18 @@ import { useRouter } from "next/navigation"; import { PullToRefreshIndicator } from "@/components/common/PullToRefreshIndicator"; import { usePullToRefresh } from "@/hooks/usePullToRefresh"; import { RefreshProvider } from "@/contexts/RefreshContext"; -import type { UserPreferences } from "@/types/preferences"; interface LibraryClientWrapperProps { children: ReactNode; - libraryId: string; - currentPage: number; - unreadOnly: boolean; - search?: string; - pageSize: number; - preferences: UserPreferences; } -export function LibraryClientWrapper({ - children, - libraryId, - currentPage, - unreadOnly, - search, - pageSize, -}: LibraryClientWrapperProps) { +export function LibraryClientWrapper({ children }: LibraryClientWrapperProps) { const router = useRouter(); const [isRefreshing, setIsRefreshing] = useState(false); const handleRefresh = async () => { try { setIsRefreshing(true); - - // Fetch fresh data from network with cache bypass - const params = new URLSearchParams({ - page: String(currentPage), - size: String(pageSize), - ...(unreadOnly && { unreadOnly: "true" }), - ...(search && { search }), - }); - - const response = await fetch(`/api/komga/libraries/${libraryId}/series?${params}`, { - cache: "no-store", - headers: { "Cache-Control": "no-cache" }, - }); - - if (!response.ok) { - throw new Error("Failed to refresh library"); - } - - // Trigger Next.js revalidation to update the UI router.refresh(); return { success: true }; } catch { diff --git a/src/app/libraries/[libraryId]/page.tsx b/src/app/libraries/[libraryId]/page.tsx index e32daff..4dca9a5 100644 --- a/src/app/libraries/[libraryId]/page.tsx +++ b/src/app/libraries/[libraryId]/page.tsx @@ -43,14 +43,7 @@ export default async function LibraryPage({ params, searchParams }: PageProps) { ]); return ( - + { try { setIsRefreshing(true); - - // Fetch fresh data from network with cache bypass - const params = new URLSearchParams({ - page: String(currentPage), - size: String(pageSize), - ...(unreadOnly && { unreadOnly: "true" }), - }); - - const response = await fetch(`/api/komga/series/${seriesId}/books?${params}`, { - cache: "no-store", - headers: { "Cache-Control": "no-cache" }, - }); - - if (!response.ok) { - throw new Error("Failed to refresh series"); - } - - // Trigger Next.js revalidation to update the UI router.refresh(); return { success: true }; } catch { diff --git a/src/app/series/[seriesId]/page.tsx b/src/app/series/[seriesId]/page.tsx index dc96a82..8841c10 100644 --- a/src/app/series/[seriesId]/page.tsx +++ b/src/app/series/[seriesId]/page.tsx @@ -36,13 +36,7 @@ export default async function SeriesPage({ params, searchParams }: PageProps) { ]); return ( - +