Compare commits
5 Commits
26909154ab
...
feat/colle
| Author | SHA1 | Date | |
|---|---|---|---|
| 56c921e800 | |||
| e798338107 | |||
| dade012888 | |||
| 4001aec6ef | |||
| dd70f9f9d4 |
@ -0,0 +1,14 @@
|
||||
/*
|
||||
Warnings:
|
||||
|
||||
- You are about to alter the column `name` on the `collections` table. The data in that column could be lost. The data in that column will be cast from `VarChar(255)` to `VarChar(115)`.
|
||||
- A unique constraint covering the columns `[slug,ownerId]` on the table `collections` will be added. If there are existing duplicate values, this will fail.
|
||||
- Added the required column `slug` to the `collections` table without a default value. This is not possible if the table is not empty.
|
||||
|
||||
*/
|
||||
-- AlterTable
|
||||
ALTER TABLE "collections" ADD COLUMN "slug" VARCHAR(115) NOT NULL,
|
||||
ALTER COLUMN "name" SET DATA TYPE VARCHAR(115);
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "collections_slug_ownerId_key" ON "collections"("slug", "ownerId");
|
||||
@ -418,7 +418,8 @@ model UserLog {
|
||||
|
||||
model Collection {
|
||||
id String @id @db.Uuid
|
||||
name String @db.VarChar(255)
|
||||
name String @db.VarChar(115)
|
||||
slug String @db.VarChar(115)
|
||||
medias Media[] @relation("MediaCollections")
|
||||
owner User @relation("UserCollections", fields: [ownerId], references: [id])
|
||||
ownerId String @db.Uuid
|
||||
@ -429,6 +430,8 @@ model Collection {
|
||||
deletedAt DateTime?
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @default(now()) @updatedAt
|
||||
|
||||
@@unique([slug, ownerId])
|
||||
@@map("collections")
|
||||
}
|
||||
|
||||
|
||||
@ -0,0 +1,10 @@
|
||||
import { Context, Static } from "elysia";
|
||||
import { returnWriteResponse } from "../../../helpers/callback/httpResponse";
|
||||
import { addItemToCollectionSchema } from "../schemas/addItemToCollection.schema";
|
||||
|
||||
export const addItemToCollectionController = async (ctx: {
|
||||
set: Context["set"];
|
||||
headers: Static<typeof addItemToCollectionSchema.headers>;
|
||||
}) => {
|
||||
return returnWriteResponse(ctx.set, 200, "Item added to collection successfully" + ctx.headers.cookie);
|
||||
};
|
||||
9
src/modules/collection/index.ts
Normal file
9
src/modules/collection/index.ts
Normal file
@ -0,0 +1,9 @@
|
||||
import Elysia from "elysia";
|
||||
import { addItemToCollectionController } from "./controllers/addItemToCollection.controller";
|
||||
import { addItemToCollectionSchema } from "./schemas/addItemToCollection.schema";
|
||||
|
||||
export const collectionModule = new Elysia({ prefix: "/collections", tags: ["Collections"] }).post(
|
||||
"/:name",
|
||||
addItemToCollectionController,
|
||||
addItemToCollectionSchema,
|
||||
);
|
||||
35
src/modules/collection/schemas/addItemToCollection.schema.ts
Normal file
35
src/modules/collection/schemas/addItemToCollection.schema.ts
Normal file
@ -0,0 +1,35 @@
|
||||
import { t } from "elysia";
|
||||
import { AppRouteSchema } from "../../../helpers/types/AppRouteSchema";
|
||||
|
||||
export const addItemToCollectionSchema = {
|
||||
headers: t.Object({
|
||||
cookie: t.String({ description: "Authentication token in cookie format, e.g., auth_token=your_jwt_token;" }),
|
||||
}),
|
||||
params: t.Object({
|
||||
name: t.String({ description: "Name of the collection to which the item will be added" }),
|
||||
}),
|
||||
body: t.Object({
|
||||
itemId: t.String({ description: "ID of the item to be added to the collection", examples: ["12345"] }),
|
||||
}),
|
||||
detail: {
|
||||
summary: "Add an item to a collection",
|
||||
description: "Adds a specified item to a collection identified by its name.",
|
||||
responses: {
|
||||
200: {
|
||||
description: "The item was successfully added to the collection.",
|
||||
content: {
|
||||
"application/json": {
|
||||
schema: {
|
||||
type: "object",
|
||||
properties: {
|
||||
success: { type: "boolean", example: true },
|
||||
status: { type: "number", example: 200 },
|
||||
message: { type: "string", example: "Item added to collection successfully" },
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
} satisfies AppRouteSchema;
|
||||
@ -20,6 +20,25 @@ export const findAllActiveHeroBannerRepository = async () => {
|
||||
startDate: "asc",
|
||||
},
|
||||
],
|
||||
select: {
|
||||
orderPriority: true,
|
||||
imageUrl: true,
|
||||
media: {
|
||||
select: {
|
||||
id: true,
|
||||
title: true,
|
||||
slug: true,
|
||||
pictureLarge: true,
|
||||
synopsis: true,
|
||||
genres: {
|
||||
select: {
|
||||
slug: true,
|
||||
name: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
} catch (error) {
|
||||
throw new AppError(500, "Failed to fetch active hero banners", error);
|
||||
|
||||
@ -8,26 +8,31 @@ import { findAllActiveHeroBannerRepository } from "../repositories/GET/findAllAc
|
||||
export const getActiveHeroBannerService = async () => {
|
||||
try {
|
||||
// Check if Hero Banner is enabled in system preferences
|
||||
const isHeroBannerEnabled = await findSystemPreferenceService(
|
||||
"HERO_BANNER_ENABLED",
|
||||
"boolean",
|
||||
);
|
||||
if (!isHeroBannerEnabled)
|
||||
throw new AppError(403, "Hero Banner is disabled");
|
||||
const isHeroBannerEnabled = await findSystemPreferenceService("HERO_BANNER_ENABLED", "boolean");
|
||||
if (!isHeroBannerEnabled) throw new AppError(403, "Hero Banner is disabled");
|
||||
|
||||
// Try to get active banners from Redis cache
|
||||
const cachedBanners = await redis.get(
|
||||
`${redisKey.filter((key) => key.name === "HERO_BANNER")[0].key}`,
|
||||
);
|
||||
const cachedBanners = await redis.get(`${redisKey.filter((key) => key.name === "HERO_BANNER")[0].key}`);
|
||||
if (cachedBanners) return JSON.parse(cachedBanners);
|
||||
|
||||
// If not in cache, fetch from database and cache the result
|
||||
const activeBanners = await findAllActiveHeroBannerRepository();
|
||||
const constructedBanners = activeBanners.map((banner) => ({
|
||||
id: banner.media.id,
|
||||
title: banner.media.title,
|
||||
slug: banner.media.slug,
|
||||
imageUrl: banner.imageUrl || banner.media.pictureLarge,
|
||||
synopsis: banner.media.synopsis,
|
||||
genres: banner.media.genres.map((genre) => ({
|
||||
slug: genre.slug,
|
||||
name: genre.name,
|
||||
})),
|
||||
}));
|
||||
await redis.set(
|
||||
`${redisKey.filter((key) => key.name === "HERO_BANNER")[0].key}`,
|
||||
JSON.stringify(activeBanners),
|
||||
JSON.stringify(constructedBanners),
|
||||
);
|
||||
return activeBanners;
|
||||
return constructedBanners;
|
||||
} catch (error) {
|
||||
ErrorForwarder(error);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user