feat/collection #29

Merged
vivy-agent merged 8 commits from feat/collection into main 2026-03-29 14:18:30 +07:00
13 changed files with 353 additions and 12 deletions
Showing only changes of commit 68d834ae6b - Show all commits

View File

@ -1,16 +1,16 @@
import { Context, Static } from "elysia"; import { Context, Static } from "elysia";
import { returnWriteResponse } from "../../../helpers/callback/httpResponse"; import { returnWriteResponse } from "../../../helpers/callback/httpResponse";
import { addItemToCollectionSchema } from "../schemas/addItemToCollection.schema"; import { addItemToCollectionBySytemSchema } from "../schemas/addItemToCollectionBySytem.schema";
import { addItemToCollectionService } from "../services/addItemToCollection.service"; import { addItemToCollectionBySystemService } from "../services/addItemToCollectionBySystem.service";
import { mainErrorHandler } from "../../../helpers/error/handler"; import { mainErrorHandler } from "../../../helpers/error/handler";
export const addItemToCollectionController = async (ctx: { export const addItemToCollectionBySytemController = async (ctx: {
set: Context["set"]; set: Context["set"];
headers: Static<typeof addItemToCollectionSchema.headers>; headers: Static<typeof addItemToCollectionBySytemSchema.headers>;
body: Static<typeof addItemToCollectionSchema.body>; body: Static<typeof addItemToCollectionBySytemSchema.body>;
}) => { }) => {
try { try {
const savedItem = await addItemToCollectionService({ const savedItem = await addItemToCollectionBySystemService({
cookie: ctx.headers.cookie, cookie: ctx.headers.cookie,
collectionName: ctx.body.name, collectionName: ctx.body.name,
mediaId: ctx.body.itemId, mediaId: ctx.body.itemId,

View File

@ -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<typeof removeItemFromCollectionBySytemSchema.headers>;
body: Static<typeof removeItemFromCollectionBySytemSchema.body>;
}) => {
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);
}
};

View File

@ -1,9 +1,9 @@
import Elysia from "elysia"; import Elysia from "elysia";
import { addItemToCollectionController } from "./controllers/addItemToCollection.controller"; import { addItemToCollectionBySytemController } from "./controllers/addItemToCollectionBySytem.controller";
import { addItemToCollectionSchema } from "./schemas/addItemToCollection.schema"; 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( export const collectionModule = new Elysia({ prefix: "/collections", tags: ["Collections"] })
"/sys", .post("/sys", addItemToCollectionBySytemController, addItemToCollectionBySytemSchema)
addItemToCollectionController, .delete("/sys", removeItemFromCollectionBySytemController, removeItemFromCollectionBySytemSchema);
addItemToCollectionSchema,
);

View File

@ -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");
}
};

View File

@ -1,7 +1,7 @@
import { t } from "elysia"; import { t } from "elysia";
import { AppRouteSchema } from "../../../helpers/types/AppRouteSchema"; import { AppRouteSchema } from "../../../helpers/types/AppRouteSchema";
export const addItemToCollectionSchema = { export const addItemToCollectionBySytemSchema = {
headers: t.Object({ headers: t.Object({
cookie: t.String({ description: "Authentication token in cookie format, e.g., auth_token=your_jwt_token;" }), cookie: t.String({ description: "Authentication token in cookie format, e.g., auth_token=your_jwt_token;" }),
}), }),

View File

@ -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;

View File

@ -9,17 +9,15 @@ export type AddItemToCollectionPayload = {
mediaId: string; mediaId: string;
}; };
export const addItemToCollectionService = async (payload: AddItemToCollectionPayload) => { export const addItemToCollectionBySystemService = async (payload: AddItemToCollectionPayload) => {
try { try {
const { auth_token } = parse(payload.cookie); const { auth_token } = parse(payload.cookie);
const userData = await tokenValidationService(auth_token as string); const userData = await tokenValidationService(auth_token as string);
const saveMediaToCollection = await upsertUserCollectionBySystemRepository({ return await upsertUserCollectionBySystemRepository({
userId: userData.user.id, userId: userData.user.id,
collectionName: payload.collectionName, collectionName: payload.collectionName,
mediaConnectId: payload.mediaId, mediaConnectId: payload.mediaId,
}); });
return saveMediaToCollection;
} catch (error) { } catch (error) {
ErrorForwarder(error); ErrorForwarder(error);
} }

View File

@ -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);
}
};