From 68d834ae6b43c8014fec4bca87c9e0315d5d0af2 Mon Sep 17 00:00:00 2001 From: Rafi Arrafif Date: Sun, 29 Mar 2026 12:10:50 +0700 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=20feat:=20add=20delete=20endpoint=20t?= =?UTF-8?q?o=20collection?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ... addItemToCollectionBySytem.controller.ts} | 12 +++---- ...oveItemFromCollectionBySytem.controller.ts | 22 +++++++++++++ src/modules/collection/index.ts | 14 ++++---- ...ItemInUserCollectionBySystem.repository.ts | 32 ++++++++++++++++++ ...s => addItemToCollectionBySytem.schema.ts} | 2 +- .../removeItemFromCollectionBySytem.schema.ts | 33 +++++++++++++++++++ ...=> addItemToCollectionBySystem.service.ts} | 6 ++-- ...emoveItemFromCollectionBySystem.service.ts | 24 ++++++++++++++ 8 files changed, 127 insertions(+), 18 deletions(-) rename src/modules/collection/controllers/{addItemToCollection.controller.ts => addItemToCollectionBySytem.controller.ts} (52%) create mode 100644 src/modules/collection/controllers/removeItemFromCollectionBySytem.controller.ts create mode 100644 src/modules/collection/repositories/deleteItemInUserCollectionBySystem.repository.ts rename src/modules/collection/schemas/{addItemToCollection.schema.ts => addItemToCollectionBySytem.schema.ts} (95%) create mode 100644 src/modules/collection/schemas/removeItemFromCollectionBySytem.schema.ts rename src/modules/collection/services/{addItemToCollection.service.ts => addItemToCollectionBySystem.service.ts} (78%) create mode 100644 src/modules/collection/services/removeItemFromCollectionBySystem.service.ts diff --git a/src/modules/collection/controllers/addItemToCollection.controller.ts b/src/modules/collection/controllers/addItemToCollectionBySytem.controller.ts similarity index 52% rename from src/modules/collection/controllers/addItemToCollection.controller.ts rename to src/modules/collection/controllers/addItemToCollectionBySytem.controller.ts index b82a9a6..50c3bb2 100644 --- a/src/modules/collection/controllers/addItemToCollection.controller.ts +++ b/src/modules/collection/controllers/addItemToCollectionBySytem.controller.ts @@ -1,16 +1,16 @@ import { Context, Static } from "elysia"; import { returnWriteResponse } from "../../../helpers/callback/httpResponse"; -import { addItemToCollectionSchema } from "../schemas/addItemToCollection.schema"; -import { addItemToCollectionService } from "../services/addItemToCollection.service"; +import { addItemToCollectionBySytemSchema } from "../schemas/addItemToCollectionBySytem.schema"; +import { addItemToCollectionBySystemService } from "../services/addItemToCollectionBySystem.service"; import { mainErrorHandler } from "../../../helpers/error/handler"; -export const addItemToCollectionController = async (ctx: { +export const addItemToCollectionBySytemController = async (ctx: { set: Context["set"]; - headers: Static; - body: Static; + headers: Static; + body: Static; }) => { try { - const savedItem = await addItemToCollectionService({ + const savedItem = await addItemToCollectionBySystemService({ cookie: ctx.headers.cookie, collectionName: ctx.body.name, mediaId: ctx.body.itemId, diff --git a/src/modules/collection/controllers/removeItemFromCollectionBySytem.controller.ts b/src/modules/collection/controllers/removeItemFromCollectionBySytem.controller.ts new file mode 100644 index 0000000..fccdbd8 --- /dev/null +++ b/src/modules/collection/controllers/removeItemFromCollectionBySytem.controller.ts @@ -0,0 +1,22 @@ +import { Context, Static } from "elysia"; +import { mainErrorHandler } from "../../../helpers/error/handler"; +import { returnWriteResponse } from "../../../helpers/callback/httpResponse"; +import { removeItemFromCollectionBySystemService } from "../services/removeItemFromCollectionBySystem.service"; +import { removeItemFromCollectionBySytemSchema } from "../schemas/removeItemFromCollectionBySytem.schema"; + +export const removeItemFromCollectionBySytemController = async (ctx: { + set: Context["set"]; + headers: Static; + body: Static; +}) => { + try { + const removedItem = await removeItemFromCollectionBySystemService({ + cookie: ctx.headers.cookie, + collectionName: ctx.body.name, + mediaId: ctx.body.itemId, + }); + return returnWriteResponse(ctx.set, 200, "Item removed from collection successfully", removedItem); + } catch (error) { + return mainErrorHandler(ctx.set, error); + } +}; diff --git a/src/modules/collection/index.ts b/src/modules/collection/index.ts index 943f510..4c768c5 100644 --- a/src/modules/collection/index.ts +++ b/src/modules/collection/index.ts @@ -1,9 +1,9 @@ import Elysia from "elysia"; -import { addItemToCollectionController } from "./controllers/addItemToCollection.controller"; -import { addItemToCollectionSchema } from "./schemas/addItemToCollection.schema"; +import { addItemToCollectionBySytemController } from "./controllers/addItemToCollectionBySytem.controller"; +import { addItemToCollectionBySytemSchema } from "./schemas/addItemToCollectionBySytem.schema"; +import { removeItemFromCollectionBySytemController } from "./controllers/removeItemFromCollectionBySytem.controller"; +import { removeItemFromCollectionBySytemSchema } from "./schemas/removeItemFromCollectionBySytem.schema"; -export const collectionModule = new Elysia({ prefix: "/collections", tags: ["Collections"] }).post( - "/sys", - addItemToCollectionController, - addItemToCollectionSchema, -); +export const collectionModule = new Elysia({ prefix: "/collections", tags: ["Collections"] }) + .post("/sys", addItemToCollectionBySytemController, addItemToCollectionBySytemSchema) + .delete("/sys", removeItemFromCollectionBySytemController, removeItemFromCollectionBySytemSchema); diff --git a/src/modules/collection/repositories/deleteItemInUserCollectionBySystem.repository.ts b/src/modules/collection/repositories/deleteItemInUserCollectionBySystem.repository.ts new file mode 100644 index 0000000..16c3cab --- /dev/null +++ b/src/modules/collection/repositories/deleteItemInUserCollectionBySystem.repository.ts @@ -0,0 +1,32 @@ +import slugify from "slugify"; +import { AppError } from "../../../helpers/error/instances/app"; +import { prisma } from "../../../utils/databases/prisma/connection"; +import { Prisma } from "@prisma/client"; + +export type DeleteUserCollectionBySystemPayload = { + userId: string; + collectionName: string; + itemId: string; +}; + +export const deleteItemInUserCollectionBySystemRepository = async (payload: DeleteUserCollectionBySystemPayload) => { + try { + return await prisma.collection.update({ + where: { + slug_ownerId: { + slug: slugify(payload.collectionName, { lower: true }), + ownerId: payload.userId, + }, + }, + data: { + media_saved: { + deleteMany: { + mediaId: payload.itemId, + }, + }, + }, + }); + } catch (error) { + throw new AppError(500, "Failed to remove item from collection"); + } +}; diff --git a/src/modules/collection/schemas/addItemToCollection.schema.ts b/src/modules/collection/schemas/addItemToCollectionBySytem.schema.ts similarity index 95% rename from src/modules/collection/schemas/addItemToCollection.schema.ts rename to src/modules/collection/schemas/addItemToCollectionBySytem.schema.ts index cd5d740..35b4574 100644 --- a/src/modules/collection/schemas/addItemToCollection.schema.ts +++ b/src/modules/collection/schemas/addItemToCollectionBySytem.schema.ts @@ -1,7 +1,7 @@ import { t } from "elysia"; import { AppRouteSchema } from "../../../helpers/types/AppRouteSchema"; -export const addItemToCollectionSchema = { +export const addItemToCollectionBySytemSchema = { headers: t.Object({ cookie: t.String({ description: "Authentication token in cookie format, e.g., auth_token=your_jwt_token;" }), }), diff --git a/src/modules/collection/schemas/removeItemFromCollectionBySytem.schema.ts b/src/modules/collection/schemas/removeItemFromCollectionBySytem.schema.ts new file mode 100644 index 0000000..54a4382 --- /dev/null +++ b/src/modules/collection/schemas/removeItemFromCollectionBySytem.schema.ts @@ -0,0 +1,33 @@ +import { t } from "elysia"; +import { AppRouteSchema } from "../../../helpers/types/AppRouteSchema"; + +export const removeItemFromCollectionBySytemSchema = { + headers: t.Object({ + cookie: t.String({ description: "Authentication token in cookie format, e.g., auth_token=your_jwt_token;" }), + }), + body: t.Object({ + name: t.String({ description: "Name of the collection to which the item will be added" }), + itemId: t.String({ description: "ID of the item to be added to the collection", examples: ["12345"] }), + }), + detail: { + summary: "Remove an item from a collection", + description: "Removes a specified item from a collection identified by its name.", + responses: { + 200: { + description: "The item was successfully removed from the collection.", + content: { + "application/json": { + schema: { + type: "object", + properties: { + success: { type: "boolean", example: true }, + status: { type: "number", example: 200 }, + message: { type: "string", example: "Item removed from collection successfully" }, + }, + }, + }, + }, + }, + }, + }, +} satisfies AppRouteSchema; diff --git a/src/modules/collection/services/addItemToCollection.service.ts b/src/modules/collection/services/addItemToCollectionBySystem.service.ts similarity index 78% rename from src/modules/collection/services/addItemToCollection.service.ts rename to src/modules/collection/services/addItemToCollectionBySystem.service.ts index 18318aa..ca5f3ff 100644 --- a/src/modules/collection/services/addItemToCollection.service.ts +++ b/src/modules/collection/services/addItemToCollectionBySystem.service.ts @@ -9,17 +9,15 @@ export type AddItemToCollectionPayload = { mediaId: string; }; -export const addItemToCollectionService = async (payload: AddItemToCollectionPayload) => { +export const addItemToCollectionBySystemService = async (payload: AddItemToCollectionPayload) => { try { const { auth_token } = parse(payload.cookie); const userData = await tokenValidationService(auth_token as string); - const saveMediaToCollection = await upsertUserCollectionBySystemRepository({ + return await upsertUserCollectionBySystemRepository({ userId: userData.user.id, collectionName: payload.collectionName, mediaConnectId: payload.mediaId, }); - - return saveMediaToCollection; } catch (error) { ErrorForwarder(error); } diff --git a/src/modules/collection/services/removeItemFromCollectionBySystem.service.ts b/src/modules/collection/services/removeItemFromCollectionBySystem.service.ts new file mode 100644 index 0000000..a3e200d --- /dev/null +++ b/src/modules/collection/services/removeItemFromCollectionBySystem.service.ts @@ -0,0 +1,24 @@ +import { parse } from "cookie"; +import { ErrorForwarder } from "../../../helpers/error/instances/forwarder"; +import { tokenValidationService } from "../../auth/services/http/tokenValidation.service"; +import { deleteItemInUserCollectionBySystemRepository } from "../repositories/deleteItemInUserCollectionBySystem.repository"; + +export type RemoveItemFromCollectionPayload = { + cookie: string; + collectionName: string; + mediaId: string; +}; + +export const removeItemFromCollectionBySystemService = async (payload: RemoveItemFromCollectionPayload) => { + try { + const { auth_token } = parse(payload.cookie); + const { user } = await tokenValidationService(auth_token as string); + return await deleteItemInUserCollectionBySystemRepository({ + userId: user.id, + collectionName: payload.collectionName, + itemId: payload.mediaId, + }); + } catch (error) { + ErrorForwarder(error); + } +};