From 21a06f3b9e406d26b16c4bb202b4e0019b82e4c7 Mon Sep 17 00:00:00 2001 From: Rafi Arrafif Date: Sun, 22 Feb 2026 10:55:02 +0700 Subject: [PATCH] =?UTF-8?q?=F0=9F=91=94=20feat:=20add=20bulk=20thumbnail?= =?UTF-8?q?=20update=20logic?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../PUT/bulkUpdateThumbnail.repository.ts | 30 +++++++++++++++++++ .../updateAllEpisodeThumbnail.controller.ts | 3 +- .../http/updateAllEpisodeThumbnail.service.ts | 23 +++++++------- ...etAllVideoServiceWithEpisode.repository.ts | 4 +++ 4 files changed, 47 insertions(+), 13 deletions(-) create mode 100644 src/modules/episode/repositories/PUT/bulkUpdateThumbnail.repository.ts diff --git a/src/modules/episode/repositories/PUT/bulkUpdateThumbnail.repository.ts b/src/modules/episode/repositories/PUT/bulkUpdateThumbnail.repository.ts new file mode 100644 index 0000000..f772bb8 --- /dev/null +++ b/src/modules/episode/repositories/PUT/bulkUpdateThumbnail.repository.ts @@ -0,0 +1,30 @@ +import { Prisma } from "@prisma/client"; +import { AppError } from "../../../../helpers/error/instances/app"; +import { prisma } from "../../../../utils/databases/prisma/connection"; + +export const bulkUpdateThumbnailRepository = async ( + data: { episodeId: string; thumbnailCode: string }[], +) => { + try { + const values = Prisma.join( + data.map( + (item) => Prisma.sql`(${item.episodeId}::uuid, ${item.thumbnailCode})`, + ), + ); + + await prisma.$executeRaw` + UPDATE episodes e + SET "pictureThumbnail" = v."thumbnailCode" + FROM ( + VALUES ${values} + ) AS v("episodeId", "thumbnailCode") + WHERE e.id = v."episodeId" + `; + } catch (error) { + throw new AppError( + 500, + "An error occurred while bulk updating episode thumbnails.", + error, + ); + } +}; diff --git a/src/modules/internal/controllers/updateAllEpisodeThumbnail.controller.ts b/src/modules/internal/controllers/updateAllEpisodeThumbnail.controller.ts index e347587..c83279e 100644 --- a/src/modules/internal/controllers/updateAllEpisodeThumbnail.controller.ts +++ b/src/modules/internal/controllers/updateAllEpisodeThumbnail.controller.ts @@ -48,8 +48,7 @@ export const updateAllEpisodeThumbnailController = async ( return returnWriteResponse( ctx.set, 204, - `Updating episode thumbnails successfully.`, - newEpisodeThumbnailsCount, + `Updating ${newEpisodeThumbnailsCount} episode thumbnails successfully.`, ); } catch (error) { return mainErrorHandler(ctx.set, error); diff --git a/src/modules/internal/services/http/updateAllEpisodeThumbnail.service.ts b/src/modules/internal/services/http/updateAllEpisodeThumbnail.service.ts index 1c47c1e..43bc55b 100644 --- a/src/modules/internal/services/http/updateAllEpisodeThumbnail.service.ts +++ b/src/modules/internal/services/http/updateAllEpisodeThumbnail.service.ts @@ -1,5 +1,6 @@ import { AppError } from "../../../../helpers/error/instances/app"; import { ErrorForwarder } from "../../../../helpers/error/instances/forwarder"; +import { bulkUpdateThumbnailRepository } from "../../../episode/repositories/PUT/bulkUpdateThumbnail.repository"; import { getAllVideoServiceWithEpisodeRepository } from "../../../videoService/repositories/GET/getAllVideoServiceWithEpisode.repository"; export const updateAllEpisodeThumbnailService = async ( @@ -19,20 +20,20 @@ export const updateAllEpisodeThumbnailService = async ( "No episode with no thumbnail found in the specified video service.", ); - const updatePayload = videosData.map((videoService) => { + const updatePayload = videosData.flatMap((videoService) => { const { endpointThumbnail, videos } = videoService; - return videos - .filter((video) => video.thumbnailCode !== null) - .map((video) => ({ - episodeId: video.episode.id, - thumbnailCode: endpointThumbnail?.replace( - ":code:", - video.thumbnailCode!, - ), - })); + return videos.map((video) => ({ + episodeId: video.episode.id, + thumbnailCode: endpointThumbnail!.replace( + ":code:", + video.thumbnailCode || video.videoCode, + ), + })); }); - return updatePayload; + await bulkUpdateThumbnailRepository(updatePayload); + + return updatePayload.length; } catch (error) { ErrorForwarder(error); } diff --git a/src/modules/videoService/repositories/GET/getAllVideoServiceWithEpisode.repository.ts b/src/modules/videoService/repositories/GET/getAllVideoServiceWithEpisode.repository.ts index a6ad516..f712191 100644 --- a/src/modules/videoService/repositories/GET/getAllVideoServiceWithEpisode.repository.ts +++ b/src/modules/videoService/repositories/GET/getAllVideoServiceWithEpisode.repository.ts @@ -8,6 +8,9 @@ export const getAllVideoServiceWithEpisodeRepository = async ( return await videoServiceModel.findMany({ where: { id: videoServiceId, + endpointThumbnail: { + not: null, + }, videos: { some: { episode: { @@ -21,6 +24,7 @@ export const getAllVideoServiceWithEpisodeRepository = async ( videos: { select: { thumbnailCode: true, + videoCode: true, episode: { select: { id: true,