Compare commits
1 Commits
main
...
a6200605f8
| Author | SHA1 | Date | |
|---|---|---|---|
| a6200605f8 |
@ -28,11 +28,10 @@ Table medias {
|
|||||||
deletedAt DateTime
|
deletedAt DateTime
|
||||||
createdAt DateTime [default: `now()`, not null]
|
createdAt DateTime [default: `now()`, not null]
|
||||||
updatedAt DateTime [default: `now()`, not null]
|
updatedAt DateTime [default: `now()`, not null]
|
||||||
bannerPromotion hero_banner [not null]
|
|
||||||
logs media_logs [not null]
|
logs media_logs [not null]
|
||||||
episodes episodes [not null]
|
episodes episodes [not null]
|
||||||
|
collections collections [not null]
|
||||||
reviews movie_reviews [not null]
|
reviews movie_reviews [not null]
|
||||||
inCollections CollectionMedia [not null]
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Table media_logs {
|
Table media_logs {
|
||||||
@ -369,7 +368,7 @@ Table user_logs {
|
|||||||
Table collections {
|
Table collections {
|
||||||
id String [pk]
|
id String [pk]
|
||||||
name String [not null]
|
name String [not null]
|
||||||
slug String [not null]
|
medias medias [not null]
|
||||||
owner users [not null]
|
owner users [not null]
|
||||||
ownerId String [not null]
|
ownerId String [not null]
|
||||||
accessStatus AccessStatus [not null, default: 'private']
|
accessStatus AccessStatus [not null, default: 'private']
|
||||||
@ -379,24 +378,6 @@ Table collections {
|
|||||||
deletedAt DateTime
|
deletedAt DateTime
|
||||||
createdAt DateTime [default: `now()`, not null]
|
createdAt DateTime [default: `now()`, not null]
|
||||||
updatedAt DateTime [default: `now()`, not null]
|
updatedAt DateTime [default: `now()`, not null]
|
||||||
media_saved CollectionMedia [not null]
|
|
||||||
|
|
||||||
indexes {
|
|
||||||
(slug, ownerId) [unique]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Table CollectionMedia {
|
|
||||||
id String [pk]
|
|
||||||
collection collections [not null]
|
|
||||||
collectionId String [not null]
|
|
||||||
media medias [not null]
|
|
||||||
mediaId String [not null]
|
|
||||||
savedAt DateTime [default: `now()`, not null]
|
|
||||||
|
|
||||||
indexes {
|
|
||||||
(collectionId, mediaId) [unique]
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Table watch_histories {
|
Table watch_histories {
|
||||||
@ -515,8 +496,12 @@ Table email_system_histories {
|
|||||||
Table hero_banner {
|
Table hero_banner {
|
||||||
id String [pk]
|
id String [pk]
|
||||||
orderPriority Int [unique]
|
orderPriority Int [unique]
|
||||||
mediaId String [not null]
|
isClickable Boolean [not null, default: false]
|
||||||
media medias [not null]
|
title String
|
||||||
|
tags String[] [not null]
|
||||||
|
description String
|
||||||
|
buttonContent String
|
||||||
|
buttonLink String
|
||||||
imageUrl String
|
imageUrl String
|
||||||
startDate DateTime [not null]
|
startDate DateTime [not null]
|
||||||
endDate DateTime [not null]
|
endDate DateTime [not null]
|
||||||
@ -575,9 +560,9 @@ Table MediaCharacters {
|
|||||||
mediasId String [ref: > medias.id]
|
mediasId String [ref: > medias.id]
|
||||||
}
|
}
|
||||||
|
|
||||||
Table CollectionMedia {
|
Table MediaCollections {
|
||||||
incollectionsId String [ref: > CollectionMedia.id]
|
collectionsId String [ref: > collections.id]
|
||||||
media_savedId String [ref: > CollectionMedia.id]
|
mediasId String [ref: > medias.id]
|
||||||
}
|
}
|
||||||
|
|
||||||
Table UserFavoriteGenres {
|
Table UserFavoriteGenres {
|
||||||
@ -765,10 +750,6 @@ Ref: user_logs.sessionId > user_sessions.id
|
|||||||
|
|
||||||
Ref: collections.ownerId > users.id
|
Ref: collections.ownerId > users.id
|
||||||
|
|
||||||
Ref: CollectionMedia.collectionId > collections.id
|
|
||||||
|
|
||||||
Ref: CollectionMedia.mediaId > medias.id
|
|
||||||
|
|
||||||
Ref: watch_histories.id > episodes.id
|
Ref: watch_histories.id > episodes.id
|
||||||
|
|
||||||
Ref: watch_histories.userId > users.id
|
Ref: watch_histories.userId > users.id
|
||||||
@ -799,8 +780,6 @@ Ref: email_system_accounts.createdBy > users.id
|
|||||||
|
|
||||||
Ref: email_system_histories.userRelated > users.id
|
Ref: email_system_histories.userRelated > users.id
|
||||||
|
|
||||||
Ref: hero_banner.mediaId > medias.id
|
|
||||||
|
|
||||||
Ref: hero_banner.creatorId > users.id
|
Ref: hero_banner.creatorId > users.id
|
||||||
|
|
||||||
Ref: system_notifications.createdBy > users.id
|
Ref: system_notifications.createdBy > users.id
|
||||||
|
|||||||
@ -7,9 +7,6 @@ CREATE TYPE "MediaType" AS ENUM ('TV', 'ONA', 'OVA', 'Movie', 'Special', 'Music'
|
|||||||
-- CreateEnum
|
-- CreateEnum
|
||||||
CREATE TYPE "Country" AS ENUM ('Japanese', 'English', 'Indonesia', 'Korea');
|
CREATE TYPE "Country" AS ENUM ('Japanese', 'English', 'Indonesia', 'Korea');
|
||||||
|
|
||||||
-- CreateEnum
|
|
||||||
CREATE TYPE "Season" AS ENUM ('Winter', 'Spring', 'Summer', 'Fall');
|
|
||||||
|
|
||||||
-- CreateEnum
|
-- CreateEnum
|
||||||
CREATE TYPE "CharacterRole" AS ENUM ('Main', 'Supporting');
|
CREATE TYPE "CharacterRole" AS ENUM ('Main', 'Supporting');
|
||||||
|
|
||||||
@ -75,8 +72,6 @@ CREATE TABLE "medias" (
|
|||||||
"deletedAt" TIMESTAMP(3),
|
"deletedAt" TIMESTAMP(3),
|
||||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
"updatedAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
"updatedAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
"season" "Season",
|
|
||||||
"yearReleased" SMALLINT NOT NULL,
|
|
||||||
|
|
||||||
CONSTRAINT "medias_pkey" PRIMARY KEY ("id")
|
CONSTRAINT "medias_pkey" PRIMARY KEY ("id")
|
||||||
);
|
);
|
||||||
@ -211,8 +206,7 @@ CREATE TABLE "videos" (
|
|||||||
"id" UUID NOT NULL,
|
"id" UUID NOT NULL,
|
||||||
"episodeId" UUID NOT NULL,
|
"episodeId" UUID NOT NULL,
|
||||||
"serviceId" UUID NOT NULL,
|
"serviceId" UUID NOT NULL,
|
||||||
"videoCode" VARCHAR(255) NOT NULL,
|
"code" VARCHAR(255) NOT NULL,
|
||||||
"thumbnailCode" TEXT,
|
|
||||||
"pendingUpload" BOOLEAN NOT NULL DEFAULT true,
|
"pendingUpload" BOOLEAN NOT NULL DEFAULT true,
|
||||||
"uploadedBy" UUID NOT NULL,
|
"uploadedBy" UUID NOT NULL,
|
||||||
"deletedAt" TIMESTAMP(3),
|
"deletedAt" TIMESTAMP(3),
|
||||||
@ -372,7 +366,7 @@ CREATE TABLE "user_logs" (
|
|||||||
-- CreateTable
|
-- CreateTable
|
||||||
CREATE TABLE "collections" (
|
CREATE TABLE "collections" (
|
||||||
"id" UUID NOT NULL,
|
"id" UUID NOT NULL,
|
||||||
"name" VARCHAR(115) NOT NULL,
|
"name" VARCHAR(255) NOT NULL,
|
||||||
"ownerId" UUID NOT NULL,
|
"ownerId" UUID NOT NULL,
|
||||||
"accessStatus" "AccessStatus" NOT NULL DEFAULT 'private',
|
"accessStatus" "AccessStatus" NOT NULL DEFAULT 'private',
|
||||||
"password" VARCHAR(255),
|
"password" VARCHAR(255),
|
||||||
@ -380,21 +374,10 @@ CREATE TABLE "collections" (
|
|||||||
"deletedAt" TIMESTAMP(3),
|
"deletedAt" TIMESTAMP(3),
|
||||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
"updatedAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
"updatedAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
"slug" VARCHAR(115) NOT NULL,
|
|
||||||
|
|
||||||
CONSTRAINT "collections_pkey" PRIMARY KEY ("id")
|
CONSTRAINT "collections_pkey" PRIMARY KEY ("id")
|
||||||
);
|
);
|
||||||
|
|
||||||
-- CreateTable
|
|
||||||
CREATE TABLE "CollectionMedia" (
|
|
||||||
"id" UUID NOT NULL,
|
|
||||||
"collectionId" UUID NOT NULL,
|
|
||||||
"mediaId" UUID NOT NULL,
|
|
||||||
"savedAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
||||||
|
|
||||||
CONSTRAINT "CollectionMedia_pkey" PRIMARY KEY ("id")
|
|
||||||
);
|
|
||||||
|
|
||||||
-- CreateTable
|
-- CreateTable
|
||||||
CREATE TABLE "watch_histories" (
|
CREATE TABLE "watch_histories" (
|
||||||
"id" UUID NOT NULL,
|
"id" UUID NOT NULL,
|
||||||
@ -514,21 +497,6 @@ CREATE TABLE "email_system_histories" (
|
|||||||
CONSTRAINT "email_system_histories_pkey" PRIMARY KEY ("id")
|
CONSTRAINT "email_system_histories_pkey" PRIMARY KEY ("id")
|
||||||
);
|
);
|
||||||
|
|
||||||
-- CreateTable
|
|
||||||
CREATE TABLE "hero_banner" (
|
|
||||||
"id" UUID NOT NULL,
|
|
||||||
"orderPriority" INTEGER,
|
|
||||||
"imageUrl" TEXT,
|
|
||||||
"startDate" TIMESTAMP(3) NOT NULL,
|
|
||||||
"endDate" TIMESTAMP(3) NOT NULL,
|
|
||||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
||||||
"updatedAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
||||||
"creatorId" UUID NOT NULL,
|
|
||||||
"mediaId" UUID NOT NULL,
|
|
||||||
|
|
||||||
CONSTRAINT "hero_banner_pkey" PRIMARY KEY ("id")
|
|
||||||
);
|
|
||||||
|
|
||||||
-- CreateTable
|
-- CreateTable
|
||||||
CREATE TABLE "system_preferences" (
|
CREATE TABLE "system_preferences" (
|
||||||
"id" UUID NOT NULL,
|
"id" UUID NOT NULL,
|
||||||
@ -602,6 +570,14 @@ CREATE TABLE "_MediaCharacters" (
|
|||||||
CONSTRAINT "_MediaCharacters_AB_pkey" PRIMARY KEY ("A","B")
|
CONSTRAINT "_MediaCharacters_AB_pkey" PRIMARY KEY ("A","B")
|
||||||
);
|
);
|
||||||
|
|
||||||
|
-- CreateTable
|
||||||
|
CREATE TABLE "_MediaCollections" (
|
||||||
|
"A" UUID NOT NULL,
|
||||||
|
"B" UUID NOT NULL,
|
||||||
|
|
||||||
|
CONSTRAINT "_MediaCollections_AB_pkey" PRIMARY KEY ("A","B")
|
||||||
|
);
|
||||||
|
|
||||||
-- CreateTable
|
-- CreateTable
|
||||||
CREATE TABLE "_UserSelectedSharingCollention" (
|
CREATE TABLE "_UserSelectedSharingCollention" (
|
||||||
"A" UUID NOT NULL,
|
"A" UUID NOT NULL,
|
||||||
@ -653,7 +629,7 @@ CREATE UNIQUE INDEX "lang_va_char_language_vaId_charId_key" ON "lang_va_char"("l
|
|||||||
CREATE UNIQUE INDEX "episodes_mediaId_episode_key" ON "episodes"("mediaId", "episode");
|
CREATE UNIQUE INDEX "episodes_mediaId_episode_key" ON "episodes"("mediaId", "episode");
|
||||||
|
|
||||||
-- CreateIndex
|
-- CreateIndex
|
||||||
CREATE UNIQUE INDEX "videos_serviceId_videoCode_key" ON "videos"("serviceId", "videoCode");
|
CREATE UNIQUE INDEX "videos_serviceId_code_key" ON "videos"("serviceId", "code");
|
||||||
|
|
||||||
-- CreateIndex
|
-- CreateIndex
|
||||||
CREATE UNIQUE INDEX "video_services_name_key" ON "video_services"("name");
|
CREATE UNIQUE INDEX "video_services_name_key" ON "video_services"("name");
|
||||||
@ -676,12 +652,6 @@ CREATE UNIQUE INDEX "user_roles_name_key" ON "user_roles"("name");
|
|||||||
-- CreateIndex
|
-- CreateIndex
|
||||||
CREATE INDEX "user_sessions_userId_isAuthenticated_deletedAt_idx" ON "user_sessions"("userId", "isAuthenticated", "deletedAt");
|
CREATE INDEX "user_sessions_userId_isAuthenticated_deletedAt_idx" ON "user_sessions"("userId", "isAuthenticated", "deletedAt");
|
||||||
|
|
||||||
-- CreateIndex
|
|
||||||
CREATE UNIQUE INDEX "collections_slug_ownerId_key" ON "collections"("slug", "ownerId");
|
|
||||||
|
|
||||||
-- CreateIndex
|
|
||||||
CREATE UNIQUE INDEX "CollectionMedia_collectionId_mediaId_key" ON "CollectionMedia"("collectionId", "mediaId");
|
|
||||||
|
|
||||||
-- CreateIndex
|
-- CreateIndex
|
||||||
CREATE UNIQUE INDEX "languages_code_key" ON "languages"("code");
|
CREATE UNIQUE INDEX "languages_code_key" ON "languages"("code");
|
||||||
|
|
||||||
@ -694,12 +664,6 @@ CREATE UNIQUE INDEX "email_system_accounts_email_key" ON "email_system_accounts"
|
|||||||
-- CreateIndex
|
-- CreateIndex
|
||||||
CREATE UNIQUE INDEX "email_system_accounts_username_key" ON "email_system_accounts"("username");
|
CREATE UNIQUE INDEX "email_system_accounts_username_key" ON "email_system_accounts"("username");
|
||||||
|
|
||||||
-- CreateIndex
|
|
||||||
CREATE UNIQUE INDEX "hero_banner_orderPriority_key" ON "hero_banner"("orderPriority");
|
|
||||||
|
|
||||||
-- CreateIndex
|
|
||||||
CREATE UNIQUE INDEX "system_preferences_key_key" ON "system_preferences"("key");
|
|
||||||
|
|
||||||
-- CreateIndex
|
-- CreateIndex
|
||||||
CREATE INDEX "_MediaStudios_B_index" ON "_MediaStudios"("B");
|
CREATE INDEX "_MediaStudios_B_index" ON "_MediaStudios"("B");
|
||||||
|
|
||||||
@ -712,21 +676,24 @@ CREATE INDEX "_UserFavoriteGenres_B_index" ON "_UserFavoriteGenres"("B");
|
|||||||
-- CreateIndex
|
-- CreateIndex
|
||||||
CREATE INDEX "_MediaCharacters_B_index" ON "_MediaCharacters"("B");
|
CREATE INDEX "_MediaCharacters_B_index" ON "_MediaCharacters"("B");
|
||||||
|
|
||||||
|
-- CreateIndex
|
||||||
|
CREATE INDEX "_MediaCollections_B_index" ON "_MediaCollections"("B");
|
||||||
|
|
||||||
-- CreateIndex
|
-- CreateIndex
|
||||||
CREATE INDEX "_UserSelectedSharingCollention_B_index" ON "_UserSelectedSharingCollention"("B");
|
CREATE INDEX "_UserSelectedSharingCollention_B_index" ON "_UserSelectedSharingCollention"("B");
|
||||||
|
|
||||||
-- AddForeignKey
|
-- AddForeignKey
|
||||||
ALTER TABLE "medias" ADD CONSTRAINT "medias_uploadedBy_fkey" FOREIGN KEY ("uploadedBy") REFERENCES "users"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
ALTER TABLE "medias" ADD CONSTRAINT "medias_uploadedBy_fkey" FOREIGN KEY ("uploadedBy") REFERENCES "users"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||||
|
|
||||||
|
-- AddForeignKey
|
||||||
|
ALTER TABLE "media_logs" ADD CONSTRAINT "media_logs_proposedBy_fkey" FOREIGN KEY ("proposedBy") REFERENCES "users"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||||
|
|
||||||
-- AddForeignKey
|
-- AddForeignKey
|
||||||
ALTER TABLE "media_logs" ADD CONSTRAINT "media_logs_approvedBy_fkey" FOREIGN KEY ("approvedBy") REFERENCES "users"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
ALTER TABLE "media_logs" ADD CONSTRAINT "media_logs_approvedBy_fkey" FOREIGN KEY ("approvedBy") REFERENCES "users"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||||
|
|
||||||
-- AddForeignKey
|
-- AddForeignKey
|
||||||
ALTER TABLE "media_logs" ADD CONSTRAINT "media_logs_mediaId_fkey" FOREIGN KEY ("mediaId") REFERENCES "medias"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
ALTER TABLE "media_logs" ADD CONSTRAINT "media_logs_mediaId_fkey" FOREIGN KEY ("mediaId") REFERENCES "medias"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||||
|
|
||||||
-- AddForeignKey
|
|
||||||
ALTER TABLE "media_logs" ADD CONSTRAINT "media_logs_proposedBy_fkey" FOREIGN KEY ("proposedBy") REFERENCES "users"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
|
||||||
|
|
||||||
-- AddForeignKey
|
-- AddForeignKey
|
||||||
ALTER TABLE "genres" ADD CONSTRAINT "genres_createdBy_fkey" FOREIGN KEY ("createdBy") REFERENCES "users"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
ALTER TABLE "genres" ADD CONSTRAINT "genres_createdBy_fkey" FOREIGN KEY ("createdBy") REFERENCES "users"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||||
|
|
||||||
@ -739,15 +706,15 @@ ALTER TABLE "characters" ADD CONSTRAINT "characters_creatorId_fkey" FOREIGN KEY
|
|||||||
-- AddForeignKey
|
-- AddForeignKey
|
||||||
ALTER TABLE "voice_actors" ADD CONSTRAINT "voice_actors_creatorId_fkey" FOREIGN KEY ("creatorId") REFERENCES "users"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
ALTER TABLE "voice_actors" ADD CONSTRAINT "voice_actors_creatorId_fkey" FOREIGN KEY ("creatorId") REFERENCES "users"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||||
|
|
||||||
|
-- AddForeignKey
|
||||||
|
ALTER TABLE "lang_va_char" ADD CONSTRAINT "lang_va_char_vaId_fkey" FOREIGN KEY ("vaId") REFERENCES "voice_actors"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||||
|
|
||||||
-- AddForeignKey
|
-- AddForeignKey
|
||||||
ALTER TABLE "lang_va_char" ADD CONSTRAINT "lang_va_char_charId_fkey" FOREIGN KEY ("charId") REFERENCES "characters"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
ALTER TABLE "lang_va_char" ADD CONSTRAINT "lang_va_char_charId_fkey" FOREIGN KEY ("charId") REFERENCES "characters"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||||
|
|
||||||
-- AddForeignKey
|
-- AddForeignKey
|
||||||
ALTER TABLE "lang_va_char" ADD CONSTRAINT "lang_va_char_creatorId_fkey" FOREIGN KEY ("creatorId") REFERENCES "users"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
ALTER TABLE "lang_va_char" ADD CONSTRAINT "lang_va_char_creatorId_fkey" FOREIGN KEY ("creatorId") REFERENCES "users"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||||
|
|
||||||
-- AddForeignKey
|
|
||||||
ALTER TABLE "lang_va_char" ADD CONSTRAINT "lang_va_char_vaId_fkey" FOREIGN KEY ("vaId") REFERENCES "voice_actors"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
|
||||||
|
|
||||||
-- AddForeignKey
|
-- AddForeignKey
|
||||||
ALTER TABLE "episodes" ADD CONSTRAINT "episodes_mediaId_fkey" FOREIGN KEY ("mediaId") REFERENCES "medias"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
ALTER TABLE "episodes" ADD CONSTRAINT "episodes_mediaId_fkey" FOREIGN KEY ("mediaId") REFERENCES "medias"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||||
|
|
||||||
@ -755,13 +722,13 @@ ALTER TABLE "episodes" ADD CONSTRAINT "episodes_mediaId_fkey" FOREIGN KEY ("medi
|
|||||||
ALTER TABLE "episodes" ADD CONSTRAINT "episodes_uploadedBy_fkey" FOREIGN KEY ("uploadedBy") REFERENCES "users"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
ALTER TABLE "episodes" ADD CONSTRAINT "episodes_uploadedBy_fkey" FOREIGN KEY ("uploadedBy") REFERENCES "users"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||||
|
|
||||||
-- AddForeignKey
|
-- AddForeignKey
|
||||||
ALTER TABLE "episode_likes" ADD CONSTRAINT "episode_likes_episodeId_fkey" FOREIGN KEY ("episodeId") REFERENCES "episodes"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
ALTER TABLE "episode_likes" ADD CONSTRAINT "episode_likes_userId_fkey" FOREIGN KEY ("userId") REFERENCES "users"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||||
|
|
||||||
-- AddForeignKey
|
-- AddForeignKey
|
||||||
ALTER TABLE "episode_likes" ADD CONSTRAINT "episode_likes_sessionId_fkey" FOREIGN KEY ("sessionId") REFERENCES "user_sessions"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
ALTER TABLE "episode_likes" ADD CONSTRAINT "episode_likes_sessionId_fkey" FOREIGN KEY ("sessionId") REFERENCES "user_sessions"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||||
|
|
||||||
-- AddForeignKey
|
-- AddForeignKey
|
||||||
ALTER TABLE "episode_likes" ADD CONSTRAINT "episode_likes_userId_fkey" FOREIGN KEY ("userId") REFERENCES "users"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
ALTER TABLE "episode_likes" ADD CONSTRAINT "episode_likes_episodeId_fkey" FOREIGN KEY ("episodeId") REFERENCES "episodes"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||||
|
|
||||||
-- AddForeignKey
|
-- AddForeignKey
|
||||||
ALTER TABLE "videos" ADD CONSTRAINT "videos_episodeId_fkey" FOREIGN KEY ("episodeId") REFERENCES "episodes"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
ALTER TABLE "videos" ADD CONSTRAINT "videos_episodeId_fkey" FOREIGN KEY ("episodeId") REFERENCES "episodes"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||||
@ -775,23 +742,23 @@ ALTER TABLE "videos" ADD CONSTRAINT "videos_uploadedBy_fkey" FOREIGN KEY ("uploa
|
|||||||
-- AddForeignKey
|
-- AddForeignKey
|
||||||
ALTER TABLE "video_services" ADD CONSTRAINT "video_services_createdBy_fkey" FOREIGN KEY ("createdBy") REFERENCES "users"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
ALTER TABLE "video_services" ADD CONSTRAINT "video_services_createdBy_fkey" FOREIGN KEY ("createdBy") REFERENCES "users"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||||
|
|
||||||
|
-- AddForeignKey
|
||||||
|
ALTER TABLE "user_preferences" ADD CONSTRAINT "user_preferences_userId_fkey" FOREIGN KEY ("userId") REFERENCES "users"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||||
|
|
||||||
-- AddForeignKey
|
-- AddForeignKey
|
||||||
ALTER TABLE "user_preferences" ADD CONSTRAINT "user_preferences_langPreference_fkey" FOREIGN KEY ("langPreference") REFERENCES "languages"("code") ON DELETE SET NULL ON UPDATE CASCADE;
|
ALTER TABLE "user_preferences" ADD CONSTRAINT "user_preferences_langPreference_fkey" FOREIGN KEY ("langPreference") REFERENCES "languages"("code") ON DELETE SET NULL ON UPDATE CASCADE;
|
||||||
|
|
||||||
-- AddForeignKey
|
-- AddForeignKey
|
||||||
ALTER TABLE "user_preferences" ADD CONSTRAINT "user_preferences_serviceDefaultId_fkey" FOREIGN KEY ("serviceDefaultId") REFERENCES "video_services"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|
ALTER TABLE "user_preferences" ADD CONSTRAINT "user_preferences_serviceDefaultId_fkey" FOREIGN KEY ("serviceDefaultId") REFERENCES "video_services"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|
||||||
|
|
||||||
-- AddForeignKey
|
|
||||||
ALTER TABLE "user_preferences" ADD CONSTRAINT "user_preferences_userId_fkey" FOREIGN KEY ("userId") REFERENCES "users"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
|
||||||
|
|
||||||
-- AddForeignKey
|
-- AddForeignKey
|
||||||
ALTER TABLE "user_roles" ADD CONSTRAINT "user_roles_createdBy_fkey" FOREIGN KEY ("createdBy") REFERENCES "users"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
ALTER TABLE "user_roles" ADD CONSTRAINT "user_roles_createdBy_fkey" FOREIGN KEY ("createdBy") REFERENCES "users"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||||
|
|
||||||
-- AddForeignKey
|
-- AddForeignKey
|
||||||
ALTER TABLE "user_role_assignments" ADD CONSTRAINT "user_role_assignments_roleId_fkey" FOREIGN KEY ("roleId") REFERENCES "user_roles"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
ALTER TABLE "user_role_assignments" ADD CONSTRAINT "user_role_assignments_userId_fkey" FOREIGN KEY ("userId") REFERENCES "users"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||||
|
|
||||||
-- AddForeignKey
|
-- AddForeignKey
|
||||||
ALTER TABLE "user_role_assignments" ADD CONSTRAINT "user_role_assignments_userId_fkey" FOREIGN KEY ("userId") REFERENCES "users"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
ALTER TABLE "user_role_assignments" ADD CONSTRAINT "user_role_assignments_roleId_fkey" FOREIGN KEY ("roleId") REFERENCES "user_roles"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||||
|
|
||||||
-- AddForeignKey
|
-- AddForeignKey
|
||||||
ALTER TABLE "user_notifications" ADD CONSTRAINT "user_notifications_userId_fkey" FOREIGN KEY ("userId") REFERENCES "users"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
ALTER TABLE "user_notifications" ADD CONSTRAINT "user_notifications_userId_fkey" FOREIGN KEY ("userId") REFERENCES "users"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||||
@ -800,35 +767,29 @@ ALTER TABLE "user_notifications" ADD CONSTRAINT "user_notifications_userId_fkey"
|
|||||||
ALTER TABLE "user_sessions" ADD CONSTRAINT "user_sessions_userId_fkey" FOREIGN KEY ("userId") REFERENCES "users"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
ALTER TABLE "user_sessions" ADD CONSTRAINT "user_sessions_userId_fkey" FOREIGN KEY ("userId") REFERENCES "users"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||||
|
|
||||||
-- AddForeignKey
|
-- AddForeignKey
|
||||||
ALTER TABLE "user_logs" ADD CONSTRAINT "user_logs_sessionId_fkey" FOREIGN KEY ("sessionId") REFERENCES "user_sessions"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
ALTER TABLE "user_logs" ADD CONSTRAINT "user_logs_userId_fkey" FOREIGN KEY ("userId") REFERENCES "users"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||||
|
|
||||||
-- AddForeignKey
|
-- AddForeignKey
|
||||||
ALTER TABLE "user_logs" ADD CONSTRAINT "user_logs_userId_fkey" FOREIGN KEY ("userId") REFERENCES "users"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
ALTER TABLE "user_logs" ADD CONSTRAINT "user_logs_sessionId_fkey" FOREIGN KEY ("sessionId") REFERENCES "user_sessions"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||||
|
|
||||||
-- AddForeignKey
|
-- AddForeignKey
|
||||||
ALTER TABLE "collections" ADD CONSTRAINT "collections_ownerId_fkey" FOREIGN KEY ("ownerId") REFERENCES "users"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
ALTER TABLE "collections" ADD CONSTRAINT "collections_ownerId_fkey" FOREIGN KEY ("ownerId") REFERENCES "users"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||||
|
|
||||||
-- AddForeignKey
|
|
||||||
ALTER TABLE "CollectionMedia" ADD CONSTRAINT "CollectionMedia_collectionId_fkey" FOREIGN KEY ("collectionId") REFERENCES "collections"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
|
||||||
|
|
||||||
-- AddForeignKey
|
|
||||||
ALTER TABLE "CollectionMedia" ADD CONSTRAINT "CollectionMedia_mediaId_fkey" FOREIGN KEY ("mediaId") REFERENCES "medias"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
|
||||||
|
|
||||||
-- AddForeignKey
|
-- AddForeignKey
|
||||||
ALTER TABLE "watch_histories" ADD CONSTRAINT "watch_histories_id_fkey" FOREIGN KEY ("id") REFERENCES "episodes"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
ALTER TABLE "watch_histories" ADD CONSTRAINT "watch_histories_id_fkey" FOREIGN KEY ("id") REFERENCES "episodes"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||||
|
|
||||||
-- AddForeignKey
|
|
||||||
ALTER TABLE "watch_histories" ADD CONSTRAINT "watch_histories_sessionId_fkey" FOREIGN KEY ("sessionId") REFERENCES "user_sessions"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
|
||||||
|
|
||||||
-- AddForeignKey
|
-- AddForeignKey
|
||||||
ALTER TABLE "watch_histories" ADD CONSTRAINT "watch_histories_userId_fkey" FOREIGN KEY ("userId") REFERENCES "users"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
ALTER TABLE "watch_histories" ADD CONSTRAINT "watch_histories_userId_fkey" FOREIGN KEY ("userId") REFERENCES "users"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||||
|
|
||||||
-- AddForeignKey
|
-- AddForeignKey
|
||||||
ALTER TABLE "movie_reviews" ADD CONSTRAINT "movie_reviews_createdBy_fkey" FOREIGN KEY ("createdBy") REFERENCES "users"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
ALTER TABLE "watch_histories" ADD CONSTRAINT "watch_histories_sessionId_fkey" FOREIGN KEY ("sessionId") REFERENCES "user_sessions"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||||
|
|
||||||
-- AddForeignKey
|
-- AddForeignKey
|
||||||
ALTER TABLE "movie_reviews" ADD CONSTRAINT "movie_reviews_mediaId_fkey" FOREIGN KEY ("mediaId") REFERENCES "medias"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
ALTER TABLE "movie_reviews" ADD CONSTRAINT "movie_reviews_mediaId_fkey" FOREIGN KEY ("mediaId") REFERENCES "medias"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||||
|
|
||||||
|
-- AddForeignKey
|
||||||
|
ALTER TABLE "movie_reviews" ADD CONSTRAINT "movie_reviews_createdBy_fkey" FOREIGN KEY ("createdBy") REFERENCES "users"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||||
|
|
||||||
-- AddForeignKey
|
-- AddForeignKey
|
||||||
ALTER TABLE "comments" ADD CONSTRAINT "comments_episodeId_fkey" FOREIGN KEY ("episodeId") REFERENCES "episodes"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
ALTER TABLE "comments" ADD CONSTRAINT "comments_episodeId_fkey" FOREIGN KEY ("episodeId") REFERENCES "episodes"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||||
|
|
||||||
@ -845,10 +806,10 @@ ALTER TABLE "comment_likes" ADD CONSTRAINT "comment_likes_commentId_fkey" FOREIG
|
|||||||
ALTER TABLE "comment_likes" ADD CONSTRAINT "comment_likes_userLiked_fkey" FOREIGN KEY ("userLiked") REFERENCES "users"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
ALTER TABLE "comment_likes" ADD CONSTRAINT "comment_likes_userLiked_fkey" FOREIGN KEY ("userLiked") REFERENCES "users"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||||
|
|
||||||
-- AddForeignKey
|
-- AddForeignKey
|
||||||
ALTER TABLE "comment_reports" ADD CONSTRAINT "comment_reports_approvedBy_fkey" FOREIGN KEY ("approvedBy") REFERENCES "users"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|
ALTER TABLE "comment_reports" ADD CONSTRAINT "comment_reports_userReporter_fkey" FOREIGN KEY ("userReporter") REFERENCES "users"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||||
|
|
||||||
-- AddForeignKey
|
-- AddForeignKey
|
||||||
ALTER TABLE "comment_reports" ADD CONSTRAINT "comment_reports_userReporter_fkey" FOREIGN KEY ("userReporter") REFERENCES "users"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
ALTER TABLE "comment_reports" ADD CONSTRAINT "comment_reports_approvedBy_fkey" FOREIGN KEY ("approvedBy") REFERENCES "users"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|
||||||
|
|
||||||
-- AddForeignKey
|
-- AddForeignKey
|
||||||
ALTER TABLE "languages" ADD CONSTRAINT "languages_craetedBy_fkey" FOREIGN KEY ("craetedBy") REFERENCES "users"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
ALTER TABLE "languages" ADD CONSTRAINT "languages_craetedBy_fkey" FOREIGN KEY ("craetedBy") REFERENCES "users"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||||
@ -859,12 +820,6 @@ ALTER TABLE "email_system_accounts" ADD CONSTRAINT "email_system_accounts_create
|
|||||||
-- AddForeignKey
|
-- AddForeignKey
|
||||||
ALTER TABLE "email_system_histories" ADD CONSTRAINT "email_system_histories_userRelated_fkey" FOREIGN KEY ("userRelated") REFERENCES "users"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
ALTER TABLE "email_system_histories" ADD CONSTRAINT "email_system_histories_userRelated_fkey" FOREIGN KEY ("userRelated") REFERENCES "users"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||||
|
|
||||||
-- AddForeignKey
|
|
||||||
ALTER TABLE "hero_banner" ADD CONSTRAINT "hero_banner_creatorId_fkey" FOREIGN KEY ("creatorId") REFERENCES "users"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
|
||||||
|
|
||||||
-- AddForeignKey
|
|
||||||
ALTER TABLE "hero_banner" ADD CONSTRAINT "hero_banner_mediaId_fkey" FOREIGN KEY ("mediaId") REFERENCES "medias"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
|
||||||
|
|
||||||
-- AddForeignKey
|
-- AddForeignKey
|
||||||
ALTER TABLE "system_notifications" ADD CONSTRAINT "system_notifications_createdBy_fkey" FOREIGN KEY ("createdBy") REFERENCES "users"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
ALTER TABLE "system_notifications" ADD CONSTRAINT "system_notifications_createdBy_fkey" FOREIGN KEY ("createdBy") REFERENCES "users"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||||
|
|
||||||
@ -895,6 +850,12 @@ ALTER TABLE "_MediaCharacters" ADD CONSTRAINT "_MediaCharacters_A_fkey" FOREIGN
|
|||||||
-- AddForeignKey
|
-- AddForeignKey
|
||||||
ALTER TABLE "_MediaCharacters" ADD CONSTRAINT "_MediaCharacters_B_fkey" FOREIGN KEY ("B") REFERENCES "medias"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
ALTER TABLE "_MediaCharacters" ADD CONSTRAINT "_MediaCharacters_B_fkey" FOREIGN KEY ("B") REFERENCES "medias"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||||
|
|
||||||
|
-- AddForeignKey
|
||||||
|
ALTER TABLE "_MediaCollections" ADD CONSTRAINT "_MediaCollections_A_fkey" FOREIGN KEY ("A") REFERENCES "collections"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||||
|
|
||||||
|
-- AddForeignKey
|
||||||
|
ALTER TABLE "_MediaCollections" ADD CONSTRAINT "_MediaCollections_B_fkey" FOREIGN KEY ("B") REFERENCES "medias"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||||
|
|
||||||
-- AddForeignKey
|
-- AddForeignKey
|
||||||
ALTER TABLE "_UserSelectedSharingCollention" ADD CONSTRAINT "_UserSelectedSharingCollention_A_fkey" FOREIGN KEY ("A") REFERENCES "collections"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
ALTER TABLE "_UserSelectedSharingCollention" ADD CONSTRAINT "_UserSelectedSharingCollention_A_fkey" FOREIGN KEY ("A") REFERENCES "collections"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||||
|
|
||||||
@ -0,0 +1,17 @@
|
|||||||
|
/*
|
||||||
|
Warnings:
|
||||||
|
|
||||||
|
- You are about to drop the column `code` on the `videos` table. All the data in the column will be lost.
|
||||||
|
- A unique constraint covering the columns `[serviceId,videoCode]` on the table `videos` will be added. If there are existing duplicate values, this will fail.
|
||||||
|
- Added the required column `videoCode` to the `videos` table without a default value. This is not possible if the table is not empty.
|
||||||
|
|
||||||
|
*/
|
||||||
|
-- DropIndex
|
||||||
|
DROP INDEX "videos_serviceId_code_key";
|
||||||
|
|
||||||
|
-- AlterTable
|
||||||
|
ALTER TABLE "videos" RENAME COLUMN "code" TO "videoCode";
|
||||||
|
|
||||||
|
-- CreateIndex
|
||||||
|
DROP INDEX IF EXISTS "videos_serviceId_code_key";
|
||||||
|
CREATE UNIQUE INDEX "videos_serviceId_videoCode_key" ON "videos"("serviceId", "videoCode");
|
||||||
@ -0,0 +1,2 @@
|
|||||||
|
-- AlterTable
|
||||||
|
ALTER TABLE "videos" ADD COLUMN "thumbnailCode" TEXT;
|
||||||
@ -0,0 +1,20 @@
|
|||||||
|
-- CreateTable
|
||||||
|
CREATE TABLE "HeroBanner" (
|
||||||
|
"id" UUID NOT NULL,
|
||||||
|
"isClickable" BOOLEAN NOT NULL DEFAULT false,
|
||||||
|
"title" VARCHAR(225),
|
||||||
|
"description" TEXT,
|
||||||
|
"buttonContent" VARCHAR(100),
|
||||||
|
"buttonLink" TEXT,
|
||||||
|
"imageUrl" TEXT,
|
||||||
|
"startDate" TIMESTAMP(3) NOT NULL,
|
||||||
|
"endDate" TIMESTAMP(3) NOT NULL,
|
||||||
|
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
"updatedAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
"creatorId" UUID NOT NULL,
|
||||||
|
|
||||||
|
CONSTRAINT "HeroBanner_pkey" PRIMARY KEY ("id")
|
||||||
|
);
|
||||||
|
|
||||||
|
-- AddForeignKey
|
||||||
|
ALTER TABLE "HeroBanner" ADD CONSTRAINT "HeroBanner_creatorId_fkey" FOREIGN KEY ("creatorId") REFERENCES "users"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||||
@ -0,0 +1,32 @@
|
|||||||
|
/*
|
||||||
|
Warnings:
|
||||||
|
|
||||||
|
- You are about to drop the `HeroBanner` table. If the table is not empty, all the data it contains will be lost.
|
||||||
|
|
||||||
|
*/
|
||||||
|
-- DropForeignKey
|
||||||
|
ALTER TABLE "HeroBanner" DROP CONSTRAINT "HeroBanner_creatorId_fkey";
|
||||||
|
|
||||||
|
-- DropTable
|
||||||
|
DROP TABLE "HeroBanner";
|
||||||
|
|
||||||
|
-- CreateTable
|
||||||
|
CREATE TABLE "hero_banner" (
|
||||||
|
"id" UUID NOT NULL,
|
||||||
|
"isClickable" BOOLEAN NOT NULL DEFAULT false,
|
||||||
|
"title" VARCHAR(225),
|
||||||
|
"description" TEXT,
|
||||||
|
"buttonContent" VARCHAR(100),
|
||||||
|
"buttonLink" TEXT,
|
||||||
|
"imageUrl" TEXT,
|
||||||
|
"startDate" TIMESTAMP(3) NOT NULL,
|
||||||
|
"endDate" TIMESTAMP(3) NOT NULL,
|
||||||
|
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
"updatedAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
"creatorId" UUID NOT NULL,
|
||||||
|
|
||||||
|
CONSTRAINT "hero_banner_pkey" PRIMARY KEY ("id")
|
||||||
|
);
|
||||||
|
|
||||||
|
-- AddForeignKey
|
||||||
|
ALTER TABLE "hero_banner" ADD CONSTRAINT "hero_banner_creatorId_fkey" FOREIGN KEY ("creatorId") REFERENCES "users"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||||
@ -0,0 +1,11 @@
|
|||||||
|
/*
|
||||||
|
Warnings:
|
||||||
|
|
||||||
|
- A unique constraint covering the columns `[order]` on the table `hero_banner` will be added. If there are existing duplicate values, this will fail.
|
||||||
|
|
||||||
|
*/
|
||||||
|
-- AlterTable
|
||||||
|
ALTER TABLE "hero_banner" ADD COLUMN "order" INTEGER;
|
||||||
|
|
||||||
|
-- CreateIndex
|
||||||
|
CREATE UNIQUE INDEX "hero_banner_order_key" ON "hero_banner"("order");
|
||||||
@ -0,0 +1,16 @@
|
|||||||
|
/*
|
||||||
|
Warnings:
|
||||||
|
|
||||||
|
- You are about to drop the column `order` on the `hero_banner` table. All the data in the column will be lost.
|
||||||
|
- A unique constraint covering the columns `[orderPriority]` on the table `hero_banner` will be added. If there are existing duplicate values, this will fail.
|
||||||
|
|
||||||
|
*/
|
||||||
|
-- DropIndex
|
||||||
|
DROP INDEX "hero_banner_order_key";
|
||||||
|
|
||||||
|
-- AlterTable
|
||||||
|
ALTER TABLE "hero_banner" DROP COLUMN "order",
|
||||||
|
ADD COLUMN "orderPriority" INTEGER;
|
||||||
|
|
||||||
|
-- CreateIndex
|
||||||
|
CREATE UNIQUE INDEX "hero_banner_orderPriority_key" ON "hero_banner"("orderPriority");
|
||||||
@ -0,0 +1,2 @@
|
|||||||
|
-- AlterTable
|
||||||
|
ALTER TABLE "hero_banner" ADD COLUMN "tags" TEXT[];
|
||||||
@ -0,0 +1,8 @@
|
|||||||
|
/*
|
||||||
|
Warnings:
|
||||||
|
|
||||||
|
- A unique constraint covering the columns `[key]` on the table `system_preferences` will be added. If there are existing duplicate values, this will fail.
|
||||||
|
|
||||||
|
*/
|
||||||
|
-- CreateIndex
|
||||||
|
CREATE UNIQUE INDEX "system_preferences_key_key" ON "system_preferences"("key");
|
||||||
@ -1,14 +0,0 @@
|
|||||||
/*
|
|
||||||
Warnings:
|
|
||||||
|
|
||||||
- The values [Winter,Spring,Summer,Fall] on the enum `Season` will be removed. If these variants are still used in the database, this will fail.
|
|
||||||
|
|
||||||
*/
|
|
||||||
-- AlterEnum
|
|
||||||
BEGIN;
|
|
||||||
CREATE TYPE "Season_new" AS ENUM ('winter', 'spring', 'summer', 'fall');
|
|
||||||
ALTER TABLE "medias" ALTER COLUMN "season" TYPE "Season_new" USING ("season"::text::"Season_new");
|
|
||||||
ALTER TYPE "Season" RENAME TO "Season_old";
|
|
||||||
ALTER TYPE "Season_new" RENAME TO "Season";
|
|
||||||
DROP TYPE "public"."Season_old";
|
|
||||||
COMMIT;
|
|
||||||
@ -1,48 +1,58 @@
|
|||||||
|
// This is your Prisma schema file,
|
||||||
|
// learn more about it in the docs: https://pris.ly/d/prisma-schema
|
||||||
|
|
||||||
|
// Looking for ways to speed up your queries, or scale easily with your serverless or edge functions?
|
||||||
|
// Try Prisma Accelerate: https://pris.ly/cli/accelerate-init
|
||||||
|
|
||||||
|
|
||||||
|
//// Prisma Configuration ////
|
||||||
|
|
||||||
generator client {
|
generator client {
|
||||||
provider = "prisma-client-js"
|
provider = "prisma-client-js"
|
||||||
}
|
}
|
||||||
|
datasource db {
|
||||||
|
provider = "postgresql"
|
||||||
|
}
|
||||||
|
|
||||||
generator dbml {
|
generator dbml {
|
||||||
provider = "prisma-dbml-generator"
|
provider = "prisma-dbml-generator"
|
||||||
}
|
}
|
||||||
|
|
||||||
datasource db {
|
|
||||||
provider = "postgresql"
|
|
||||||
}
|
//// Prisma Model ////
|
||||||
|
|
||||||
model Media {
|
model Media {
|
||||||
id String @id @db.Uuid
|
id String @id @db.Uuid
|
||||||
title String
|
title String @db.Text
|
||||||
titleAlternative Json
|
titleAlternative Json
|
||||||
slug String @unique
|
slug String @db.Text @unique
|
||||||
malId Int? @unique
|
malId Int? @unique
|
||||||
pictureMedium String
|
pictureMedium String @db.Text
|
||||||
pictureLarge String
|
pictureLarge String @db.Text
|
||||||
|
genres Genre[] @relation("MediaGenres")
|
||||||
country Country @default(JP)
|
country Country @default(JP)
|
||||||
score Decimal @default(0.00) @db.Decimal(4, 2)
|
score Decimal @db.Decimal(4, 2) @default(0.00)
|
||||||
status String
|
status String
|
||||||
startAiring DateTime?
|
startAiring DateTime?
|
||||||
endAiring DateTime?
|
endAiring DateTime?
|
||||||
synopsis String
|
synopsis String @db.Text
|
||||||
ageRating String
|
ageRating String
|
||||||
mediaType MediaType
|
mediaType MediaType
|
||||||
source String?
|
source String?
|
||||||
|
studios Studio[] @relation("MediaStudios")
|
||||||
|
characters Character[] @relation("MediaCharacters")
|
||||||
onDraft Boolean @default(true)
|
onDraft Boolean @default(true)
|
||||||
season Season?
|
uploader User @relation("UserUploadedMedias", fields: [uploadedBy], references: [id])
|
||||||
yearReleased Int @db.SmallInt
|
|
||||||
uploadedBy String @db.Uuid
|
uploadedBy String @db.Uuid
|
||||||
deletedAt DateTime?
|
deletedAt DateTime?
|
||||||
createdAt DateTime @default(now())
|
createdAt DateTime @default(now())
|
||||||
updatedAt DateTime @default(now()) @updatedAt
|
updatedAt DateTime @default(now()) @updatedAt
|
||||||
inCollections CollectionMedia[] @relation("CollectionMedia")
|
|
||||||
episodes Episode[] @relation("MediaEpisodes")
|
|
||||||
bannerPromotion HeroBanner[] @relation("MediaBannerPromotion")
|
|
||||||
logs MediaLog[] @relation("MediaLogs")
|
logs MediaLog[] @relation("MediaLogs")
|
||||||
uploader User @relation("UserUploadedMedias", fields: [uploadedBy], references: [id])
|
episodes Episode[] @relation("MediaEpisodes")
|
||||||
|
collections Collection[] @relation("MediaCollections")
|
||||||
reviews MediaReview[] @relation("MediaReviews")
|
reviews MediaReview[] @relation("MediaReviews")
|
||||||
characters Character[] @relation("MediaCharacters")
|
|
||||||
genres Genre[] @relation("MediaGenres")
|
|
||||||
studios Studio[] @relation("MediaStudios")
|
|
||||||
|
|
||||||
@@index([status, onDraft, deletedAt])
|
@@index([status, onDraft, deletedAt])
|
||||||
@@index([mediaType])
|
@@index([mediaType])
|
||||||
@ -55,29 +65,29 @@ model MediaLog {
|
|||||||
id String @id @db.Uuid
|
id String @id @db.Uuid
|
||||||
status MediaOperation
|
status MediaOperation
|
||||||
approval Boolean @default(false)
|
approval Boolean @default(false)
|
||||||
|
proposer User @relation("UserProposedMedias", fields: [proposedBy], references: [id])
|
||||||
proposedBy String @db.Uuid
|
proposedBy String @db.Uuid
|
||||||
|
approver User @relation("UserApprovedMedias", fields: [approvedBy], references: [id])
|
||||||
approvedBy String @db.Uuid
|
approvedBy String @db.Uuid
|
||||||
|
media Media @relation("MediaLogs", fields: [mediaId], references: [id])
|
||||||
mediaId String @db.Uuid
|
mediaId String @db.Uuid
|
||||||
createdAt DateTime @default(now())
|
createdAt DateTime @default(now())
|
||||||
updatedAt DateTime @default(now()) @updatedAt
|
updatedAt DateTime @default(now()) @updatedAt
|
||||||
approver User @relation("UserApprovedMedias", fields: [approvedBy], references: [id])
|
|
||||||
media Media @relation("MediaLogs", fields: [mediaId], references: [id])
|
|
||||||
proposer User @relation("UserProposedMedias", fields: [proposedBy], references: [id])
|
|
||||||
|
|
||||||
@@map("media_logs")
|
@@map("media_logs")
|
||||||
}
|
}
|
||||||
|
|
||||||
model Genre {
|
model Genre {
|
||||||
id String @id @db.Uuid
|
id String @id @db.Uuid
|
||||||
name String @db.VarChar(255)
|
name String @db.VarChar(255)
|
||||||
slug String @unique @db.VarChar(255)
|
slug String @db.VarChar(255) @unique
|
||||||
malId Int @unique
|
malId Int @unique
|
||||||
malUrl String @db.VarChar(255)
|
malUrl String @db.VarChar(255)
|
||||||
|
creator User @relation("UserCreatedGenres", fields: [createdBy], references: [id])
|
||||||
createdBy String @db.Uuid
|
createdBy String @db.Uuid
|
||||||
deletedAt DateTime?
|
deletedAt DateTime?
|
||||||
createdAt DateTime @default(now())
|
createdAt DateTime @default(now())
|
||||||
updatedAt DateTime @default(now()) @updatedAt
|
updatedAt DateTime @default(now()) @updatedAt
|
||||||
creator User @relation("UserCreatedGenres", fields: [createdBy], references: [id])
|
|
||||||
medias Media[] @relation("MediaGenres")
|
medias Media[] @relation("MediaGenres")
|
||||||
user_favourite_genres UserPreference[] @relation("UserFavoriteGenres")
|
user_favourite_genres UserPreference[] @relation("UserFavoriteGenres")
|
||||||
|
|
||||||
@ -87,36 +97,36 @@ model Genre {
|
|||||||
model Studio {
|
model Studio {
|
||||||
id String @id @db.Uuid
|
id String @id @db.Uuid
|
||||||
name String @db.VarChar(255)
|
name String @db.VarChar(255)
|
||||||
slug String @unique @db.VarChar(255)
|
slug String @db.VarChar(255) @unique
|
||||||
linkAbout String
|
linkAbout String @db.Text
|
||||||
malId Int @unique
|
malId Int @unique
|
||||||
logoUrl String?
|
logoUrl String? @db.Text
|
||||||
|
creator User @relation("UserCreatedStudios", fields: [createdBy], references: [id])
|
||||||
createdBy String @db.Uuid
|
createdBy String @db.Uuid
|
||||||
deletedAt DateTime?
|
deletedAt DateTime?
|
||||||
createdAt DateTime @default(now())
|
createdAt DateTime @default(now())
|
||||||
updatedAt DateTime @default(now()) @updatedAt
|
updatedAt DateTime @default(now()) @updatedAt
|
||||||
creator User @relation("UserCreatedStudios", fields: [createdBy], references: [id])
|
|
||||||
medias Media[] @relation("MediaStudios")
|
|
||||||
|
|
||||||
|
medias Media[] @relation("MediaStudios")
|
||||||
@@map("studios")
|
@@map("studios")
|
||||||
}
|
}
|
||||||
|
|
||||||
model Character {
|
model Character {
|
||||||
id String @id @db.Uuid
|
id String @id@db.Uuid
|
||||||
malId Int @unique
|
malId Int @unique
|
||||||
name String
|
name String
|
||||||
role CharacterRole
|
role CharacterRole
|
||||||
favorites Int @default(0)
|
favorites Int @default(0)
|
||||||
imageUrl String?
|
imageUrl String?
|
||||||
smallImageUrl String?
|
smallImageUrl String?
|
||||||
|
createdBy User @relation("UserCreatedCharacters", fields: [creatorId], references: [id])
|
||||||
creatorId String @db.Uuid
|
creatorId String @db.Uuid
|
||||||
deletedAt DateTime?
|
deletedAt DateTime?
|
||||||
createdAt DateTime @default(now())
|
createdAt DateTime @default(now())
|
||||||
updatedAt DateTime @default(now()) @updatedAt
|
updatedAt DateTime @default(now()) @updatedAt
|
||||||
createdBy User @relation("UserCreatedCharacters", fields: [creatorId], references: [id])
|
|
||||||
voice_actors LangVAChar[] @relation("CharVALanguage")
|
|
||||||
medias Media[] @relation("MediaCharacters")
|
|
||||||
|
|
||||||
|
medias Media[] @relation("MediaCharacters")
|
||||||
|
voice_actors LangVAChar[] @relation("CharVALanguage")
|
||||||
@@map("characters")
|
@@map("characters")
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -125,31 +135,31 @@ model VoiceActor {
|
|||||||
malId Int @unique
|
malId Int @unique
|
||||||
name String
|
name String
|
||||||
birthday DateTime?
|
birthday DateTime?
|
||||||
description String?
|
description String? @db.Text
|
||||||
aboutUrl String?
|
aboutUrl String?
|
||||||
imageUrl String?
|
imageUrl String?
|
||||||
websiteUrl String?
|
websiteUrl String?
|
||||||
|
createdBy User @relation("UserCreatedVoiceActors", fields: [creatorId], references: [id])
|
||||||
creatorId String @db.Uuid
|
creatorId String @db.Uuid
|
||||||
deletedAt DateTime?
|
deletedAt DateTime?
|
||||||
createdAt DateTime @default(now())
|
createdAt DateTime @default(now())
|
||||||
updatedAt DateTime @default(now()) @updatedAt
|
updatedAt DateTime @default(now()) @updatedAt
|
||||||
characters LangVAChar[] @relation("VACharLanguage")
|
|
||||||
createdBy User @relation("UserCreatedVoiceActors", fields: [creatorId], references: [id])
|
|
||||||
|
|
||||||
|
characters LangVAChar[] @relation("VACharLanguage")
|
||||||
@@map("voice_actors")
|
@@map("voice_actors")
|
||||||
}
|
}
|
||||||
|
|
||||||
model LangVAChar {
|
model LangVAChar {
|
||||||
id String @id @db.Uuid
|
id String @id @db.Uuid
|
||||||
language String
|
language String
|
||||||
|
voiceActor VoiceActor @relation("VACharLanguage", fields: [vaId], references: [id])
|
||||||
vaId String @db.Uuid
|
vaId String @db.Uuid
|
||||||
|
character Character @relation("CharVALanguage", fields: [charId], references: [id])
|
||||||
charId String @db.Uuid
|
charId String @db.Uuid
|
||||||
|
createdBy User @relation("UserCreatedLangVAChar", fields: [creatorId], references: [id])
|
||||||
creatorId String @db.Uuid
|
creatorId String @db.Uuid
|
||||||
createdAt DateTime @default(now())
|
createdAt DateTime @default(now())
|
||||||
updatedAt DateTime @default(now()) @updatedAt
|
updatedAt DateTime @default(now()) @updatedAt
|
||||||
character Character @relation("CharVALanguage", fields: [charId], references: [id])
|
|
||||||
createdBy User @relation("UserCreatedLangVAChar", fields: [creatorId], references: [id])
|
|
||||||
voiceActor VoiceActor @relation("VACharLanguage", fields: [vaId], references: [id])
|
|
||||||
|
|
||||||
@@unique([language, vaId, charId])
|
@@unique([language, vaId, charId])
|
||||||
@@map("lang_va_char")
|
@@map("lang_va_char")
|
||||||
@ -157,25 +167,26 @@ model LangVAChar {
|
|||||||
|
|
||||||
model Episode {
|
model Episode {
|
||||||
id String @id @db.Uuid
|
id String @id @db.Uuid
|
||||||
|
media Media @relation("MediaEpisodes", fields: [mediaId], references: [id])
|
||||||
mediaId String @db.Uuid
|
mediaId String @db.Uuid
|
||||||
episode Int
|
episode Int
|
||||||
name String @db.VarChar(255)
|
name String @db.VarChar(255)
|
||||||
score Decimal @default(0.00) @db.Decimal(4, 2)
|
score Decimal @db.Decimal(4,2) @default(0.00)
|
||||||
pictureThumbnail String?
|
pictureThumbnail String? @db.Text
|
||||||
viewed BigInt @default(0)
|
viewed BigInt @default(0)
|
||||||
likes BigInt @default(0)
|
likes BigInt @default(0)
|
||||||
dislikes BigInt @default(0)
|
dislikes BigInt @default(0)
|
||||||
pendingUpload Boolean @default(true)
|
pendingUpload Boolean @default(true)
|
||||||
|
uploader User @relation("UserEpisodes", fields: [uploadedBy], references: [id])
|
||||||
uploadedBy String @db.Uuid
|
uploadedBy String @db.Uuid
|
||||||
deletedAt DateTime?
|
deletedAt DateTime?
|
||||||
createdAt DateTime @default(now())
|
createdAt DateTime @default(now())
|
||||||
updatedAt DateTime @default(now()) @updatedAt
|
updatedAt DateTime @default(now()) @updatedAt
|
||||||
comments Comment[] @relation("EpisodeComments")
|
|
||||||
user_likes EpisodeLike[] @relation("EpisodeLikes")
|
user_likes EpisodeLike[] @relation("EpisodeLikes")
|
||||||
media Media @relation("MediaEpisodes", fields: [mediaId], references: [id])
|
|
||||||
uploader User @relation("UserEpisodes", fields: [uploadedBy], references: [id])
|
|
||||||
videos Video[] @relation("EpisodeVideos")
|
videos Video[] @relation("EpisodeVideos")
|
||||||
user_histories WatchHistory? @relation("EpisodeWatchHistories")
|
user_histories WatchHistory[] @relation("EpisodeWatchHistories")
|
||||||
|
comments Comment[] @relation("EpisodeComments")
|
||||||
|
|
||||||
@@unique([mediaId, episode])
|
@@unique([mediaId, episode])
|
||||||
@@map("episodes")
|
@@map("episodes")
|
||||||
@ -183,32 +194,31 @@ model Episode {
|
|||||||
|
|
||||||
model EpisodeLike {
|
model EpisodeLike {
|
||||||
id String @id @db.Uuid
|
id String @id @db.Uuid
|
||||||
|
user User @relation("UserEpisodeLikes", fields: [userId], references: [id])
|
||||||
userId String @db.Uuid
|
userId String @db.Uuid
|
||||||
|
session UserSession @relation("SessionEpisodeLikes", fields: [sessionId], references: [id])
|
||||||
sessionId String @db.Uuid
|
sessionId String @db.Uuid
|
||||||
|
episode Episode @relation("EpisodeLikes", fields: [episodeId], references: [id])
|
||||||
episodeId String @db.Uuid
|
episodeId String @db.Uuid
|
||||||
createdAt DateTime @default(now())
|
createdAt DateTime @default(now())
|
||||||
updatedAt DateTime @default(now()) @updatedAt
|
updatedAt DateTime @default(now()) @updatedAt
|
||||||
episode Episode @relation("EpisodeLikes", fields: [episodeId], references: [id])
|
|
||||||
session UserSession @relation("SessionEpisodeLikes", fields: [sessionId], references: [id])
|
|
||||||
user User @relation("UserEpisodeLikes", fields: [userId], references: [id])
|
|
||||||
|
|
||||||
@@map("episode_likes")
|
@@map("episode_likes")
|
||||||
}
|
}
|
||||||
|
|
||||||
model Video {
|
model Video {
|
||||||
id String @id @db.Uuid
|
id String @id @db.Uuid
|
||||||
|
episode Episode @relation("EpisodeVideos", fields: [episodeId], references: [id])
|
||||||
episodeId String @db.Uuid
|
episodeId String @db.Uuid
|
||||||
|
service VideoService @relation("VideoServices", fields: [serviceId], references: [id])
|
||||||
serviceId String @db.Uuid
|
serviceId String @db.Uuid
|
||||||
videoCode String @db.VarChar(255)
|
videoCode String @db.VarChar(255)
|
||||||
thumbnailCode String?
|
thumbnailCode String?
|
||||||
pendingUpload Boolean @default(true)
|
pendingUpload Boolean @default(true)
|
||||||
|
uploader User @relation("UserVideos", fields: [uploadedBy], references: [id])
|
||||||
uploadedBy String @db.Uuid
|
uploadedBy String @db.Uuid
|
||||||
deletedAt DateTime?
|
deletedAt DateTime?
|
||||||
createdAt DateTime @default(now())
|
createdAt DateTime @default(now())
|
||||||
updatedAt DateTime @default(now()) @updatedAt
|
updatedAt DateTime @default(now()) @updatedAt
|
||||||
episode Episode @relation("EpisodeVideos", fields: [episodeId], references: [id])
|
|
||||||
service VideoService @relation("VideoServices", fields: [serviceId], references: [id])
|
|
||||||
uploader User @relation("UserVideos", fields: [uploadedBy], references: [id])
|
|
||||||
|
|
||||||
@@unique([serviceId, videoCode])
|
@@unique([serviceId, videoCode])
|
||||||
@@map("videos")
|
@@map("videos")
|
||||||
@ -216,21 +226,21 @@ model Video {
|
|||||||
|
|
||||||
model VideoService {
|
model VideoService {
|
||||||
id String @id @db.Uuid
|
id String @id @db.Uuid
|
||||||
name String @unique @db.VarChar(255)
|
name String @db.VarChar(255) @unique
|
||||||
domain String @db.VarChar(255)
|
domain String @db.VarChar(255)
|
||||||
logo String?
|
logo String? @db.Text
|
||||||
hexColor String @db.VarChar(10)
|
hexColor String @db.VarChar(10)
|
||||||
endpointVideo String
|
endpointVideo String @db.Text
|
||||||
endpointThumbnail String?
|
endpointThumbnail String? @db.Text
|
||||||
endpointDownload String?
|
endpointDownload String?
|
||||||
|
creator User @relation("UserVideoServices", fields: [createdBy], references: [id])
|
||||||
createdBy String @db.Uuid
|
createdBy String @db.Uuid
|
||||||
deletedAt DateTime?
|
deletedAt DateTime?
|
||||||
createdAt DateTime @default(now())
|
createdAt DateTime @default(now())
|
||||||
updatedAt DateTime @default(now()) @updatedAt
|
updatedAt DateTime @default(now()) @updatedAt
|
||||||
user_preferences UserPreference[] @relation("UserServiceDefault")
|
|
||||||
creator User @relation("UserVideoServices", fields: [createdBy], references: [id])
|
|
||||||
videos Video[] @relation("VideoServices")
|
|
||||||
|
|
||||||
|
videos Video[] @relation("VideoServices")
|
||||||
|
user_preferences UserPreference[] @relation("UserServiceDefault")
|
||||||
@@map("video_services")
|
@@map("video_services")
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -238,87 +248,86 @@ model User {
|
|||||||
id String @id @db.Uuid
|
id String @id @db.Uuid
|
||||||
name String @db.VarChar(255)
|
name String @db.VarChar(255)
|
||||||
username String @unique @db.VarChar(255)
|
username String @unique @db.VarChar(255)
|
||||||
email String @unique
|
email String @unique @db.Text
|
||||||
password String
|
password String @db.Text
|
||||||
birthDate DateTime? @db.Date
|
birthDate DateTime? @db.Date
|
||||||
gender UserGender?
|
gender UserGender?
|
||||||
phoneCC Int?
|
phoneCC Int?
|
||||||
phoneNumber Int?
|
phoneNumber Int?
|
||||||
bioProfile String?
|
assignedRoles UserRoleAssignment[]
|
||||||
avatar String?
|
bioProfile String? @db.Text
|
||||||
commentBackground String?
|
avatar String? @db.Text
|
||||||
|
commentBackground String? @db.Text
|
||||||
provider String? @db.VarChar(255)
|
provider String? @db.VarChar(255)
|
||||||
providerId String? @unique @db.VarChar(255)
|
providerId String? @unique @db.VarChar(255)
|
||||||
providerToken String?
|
providerToken String? @db.Text
|
||||||
providerPayload Json? @db.Json
|
providerPayload Json? @db.Json
|
||||||
|
preference UserPreference?
|
||||||
verifiedAt DateTime?
|
verifiedAt DateTime?
|
||||||
disabledAt DateTime?
|
disabledAt DateTime?
|
||||||
deletedAt DateTime?
|
deletedAt DateTime?
|
||||||
createdAt DateTime @default(now())
|
createdAt DateTime @default(now())
|
||||||
updatedAt DateTime @default(now()) @updatedAt
|
updatedAt DateTime @default(now()) @updatedAt
|
||||||
|
|
||||||
|
medias Media[] @relation("UserUploadedMedias")
|
||||||
|
media_proposeds MediaLog[] @relation("UserProposedMedias")
|
||||||
|
media_approveds MediaLog[] @relation("UserApprovedMedias")
|
||||||
|
genres Genre[] @relation("UserCreatedGenres")
|
||||||
|
studios Studio[] @relation("UserCreatedStudios")
|
||||||
characters Character[] @relation("UserCreatedCharacters")
|
characters Character[] @relation("UserCreatedCharacters")
|
||||||
|
voice_actor VoiceActor[] @relation("UserCreatedVoiceActors")
|
||||||
|
lang_va_char LangVAChar[] @relation("UserCreatedLangVAChar")
|
||||||
|
episodes Episode[] @relation("UserEpisodes")
|
||||||
|
episode_likes EpisodeLike[] @relation("UserEpisodeLikes")
|
||||||
|
videos Video[] @relation("UserVideos")
|
||||||
|
video_services VideoService[] @relation("UserVideoServices")
|
||||||
|
create_roles UserRole[] @relation("UserCreateRoles")
|
||||||
|
notifications UserNotification[] @relation("UserNotifications")
|
||||||
|
sessions UserSession[] @relation("UserSession")
|
||||||
|
logs UserLog[] @relation("UserLogs")
|
||||||
collections Collection[] @relation("UserCollections")
|
collections Collection[] @relation("UserCollections")
|
||||||
liked_comments CommentLike[] @relation("UserCommentLikes")
|
allowed_collections Collection[] @relation("UserSelectedSharingCollention")
|
||||||
approved_comments CommentReport[] @relation("ApprovedReportComments")
|
watch_histories WatchHistory[] @relation("UserWatchHistories")
|
||||||
reported_comments CommentReport[] @relation("UserReportComments")
|
media_reviews MediaReview[] @relation("UserMediaReviews")
|
||||||
comments Comment[] @relation("UserComments")
|
comments Comment[] @relation("UserComments")
|
||||||
|
liked_comments CommentLike[] @relation("UserCommentLikes")
|
||||||
|
reported_comments CommentReport[] @relation("UserReportComments")
|
||||||
|
approved_comments CommentReport[] @relation("ApprovedReportComments")
|
||||||
|
create_languages Language[] @relation("UserCreateLanguages")
|
||||||
user_create_email EmailSystemAccount[] @relation("UserCreateSystemAccount")
|
user_create_email EmailSystemAccount[] @relation("UserCreateSystemAccount")
|
||||||
user_emails EmailSystemHistory[] @relation("UserEmails")
|
user_emails EmailSystemHistory[] @relation("UserEmails")
|
||||||
episode_likes EpisodeLike[] @relation("UserEpisodeLikes")
|
|
||||||
episodes Episode[] @relation("UserEpisodes")
|
|
||||||
genres Genre[] @relation("UserCreatedGenres")
|
|
||||||
user_hero_banner HeroBanner[] @relation("UserHeroBanner")
|
user_hero_banner HeroBanner[] @relation("UserHeroBanner")
|
||||||
lang_va_char LangVAChar[] @relation("UserCreatedLangVAChar")
|
|
||||||
create_languages Language[] @relation("UserCreateLanguages")
|
|
||||||
media_approveds MediaLog[] @relation("UserApprovedMedias")
|
|
||||||
media_proposeds MediaLog[] @relation("UserProposedMedias")
|
|
||||||
medias Media[] @relation("UserUploadedMedias")
|
|
||||||
media_reviews MediaReview[] @relation("UserMediaReviews")
|
|
||||||
studios Studio[] @relation("UserCreatedStudios")
|
|
||||||
sys_logs SystemLog[] @relation("UserSystemLogs")
|
|
||||||
sys_notifications SystemNotification[] @relation("UserCreatorSystemNotifications")
|
sys_notifications SystemNotification[] @relation("UserCreatorSystemNotifications")
|
||||||
logs UserLog[] @relation("UserLogs")
|
sys_logs SystemLog[] @relation("UserSystemLogs")
|
||||||
notifications UserNotification[] @relation("UserNotifications")
|
|
||||||
preference UserPreference?
|
|
||||||
assignedRoles UserRoleAssignment[]
|
|
||||||
create_roles UserRole[] @relation("UserCreateRoles")
|
|
||||||
sessions UserSession[] @relation("UserSession")
|
|
||||||
video_services VideoService[] @relation("UserVideoServices")
|
|
||||||
videos Video[] @relation("UserVideos")
|
|
||||||
voice_actor VoiceActor[] @relation("UserCreatedVoiceActors")
|
|
||||||
watch_histories WatchHistory[] @relation("UserWatchHistories")
|
|
||||||
allowed_collections Collection[] @relation("UserSelectedSharingCollention")
|
|
||||||
|
|
||||||
@@map("users")
|
@@map("users")
|
||||||
}
|
}
|
||||||
|
|
||||||
model UserPreference {
|
model UserPreference {
|
||||||
id String @id @db.Uuid
|
id String @id @db.Uuid
|
||||||
|
user User @relation(fields: [userId], references: [id])
|
||||||
userId String @unique @db.Uuid
|
userId String @unique @db.Uuid
|
||||||
|
lang Language? @relation("UserPreferenceLang", fields: [langPreference], references: [code])
|
||||||
langPreference String?
|
langPreference String?
|
||||||
adultFiltering AdultFiltering @default(hide)
|
adultFiltering AdultFiltering @default(hide)
|
||||||
adultAlert AdultAlert @default(show)
|
adultAlert AdultAlert @default(show)
|
||||||
videoQuality VideoQuality @default(Q1080)
|
videoQuality VideoQuality @default(Q1080)
|
||||||
|
serviceDefault VideoService? @relation("UserServiceDefault", fields: [serviceDefaultId], references: [id])
|
||||||
serviceDefaultId String? @db.Uuid
|
serviceDefaultId String? @db.Uuid
|
||||||
hideContries Country[]
|
hideContries Country[]
|
||||||
|
favoriteGenres Genre[] @relation("UserFavoriteGenres")
|
||||||
createdAt DateTime @default(now())
|
createdAt DateTime @default(now())
|
||||||
updatedAt DateTime @default(now()) @updatedAt
|
updatedAt DateTime @default(now()) @updatedAt
|
||||||
lang Language? @relation("UserPreferenceLang", fields: [langPreference], references: [code])
|
|
||||||
serviceDefault VideoService? @relation("UserServiceDefault", fields: [serviceDefaultId], references: [id])
|
|
||||||
user User @relation(fields: [userId], references: [id])
|
|
||||||
favoriteGenres Genre[] @relation("UserFavoriteGenres")
|
|
||||||
|
|
||||||
@@map("user_preferences")
|
@@map("user_preferences")
|
||||||
}
|
}
|
||||||
|
|
||||||
model UserRole {
|
model UserRole {
|
||||||
id String @id @db.Uuid
|
id String @id @db.Uuid
|
||||||
name String @unique @db.VarChar(255)
|
name String @db.VarChar(255) @unique
|
||||||
description String?
|
description String? @db.Text
|
||||||
primaryColor String? @db.VarChar(10)
|
primaryColor String? @db.VarChar(10)
|
||||||
secondaryColor String? @db.VarChar(10)
|
secondaryColor String? @db.VarChar(10)
|
||||||
pictureImage String?
|
pictureImage String? @db.Text
|
||||||
badgeImage String?
|
badgeImage String? @db.Text
|
||||||
isSuperadmin Boolean @default(false)
|
isSuperadmin Boolean @default(false)
|
||||||
canEditMedia Boolean @default(false)
|
canEditMedia Boolean @default(false)
|
||||||
canManageMedia Boolean @default(false)
|
canManageMedia Boolean @default(false)
|
||||||
@ -330,22 +339,24 @@ model UserRole {
|
|||||||
canManageUser Boolean @default(false)
|
canManageUser Boolean @default(false)
|
||||||
canEditSystem Boolean @default(false)
|
canEditSystem Boolean @default(false)
|
||||||
canManageSystem Boolean @default(false)
|
canManageSystem Boolean @default(false)
|
||||||
|
creator User @relation("UserCreateRoles", fields: [createdBy], references: [id])
|
||||||
createdBy String @db.Uuid
|
createdBy String @db.Uuid
|
||||||
deletedAt DateTime?
|
deletedAt DateTime?
|
||||||
createdAt DateTime @default(now())
|
createdAt DateTime @default(now())
|
||||||
updatedAt DateTime @default(now()) @updatedAt
|
updatedAt DateTime @default(now()) @updatedAt
|
||||||
assignedUser UserRoleAssignment[]
|
|
||||||
creator User @relation("UserCreateRoles", fields: [createdBy], references: [id])
|
|
||||||
|
|
||||||
|
assignedUser UserRoleAssignment[]
|
||||||
@@map("user_roles")
|
@@map("user_roles")
|
||||||
}
|
}
|
||||||
|
|
||||||
model UserRoleAssignment {
|
model UserRoleAssignment {
|
||||||
userId String @db.Uuid
|
|
||||||
roleId String @db.Uuid
|
|
||||||
assignmentAt DateTime @default(now())
|
|
||||||
role UserRole @relation(fields: [roleId], references: [id])
|
|
||||||
user User @relation(fields: [userId], references: [id])
|
user User @relation(fields: [userId], references: [id])
|
||||||
|
userId String @db.Uuid
|
||||||
|
|
||||||
|
role UserRole @relation(fields: [roleId], references: [id])
|
||||||
|
roleId String @db.Uuid
|
||||||
|
|
||||||
|
assignmentAt DateTime @default(now())
|
||||||
|
|
||||||
@@id([userId, roleId])
|
@@id([userId, roleId])
|
||||||
@@map("user_role_assignments")
|
@@map("user_role_assignments")
|
||||||
@ -354,23 +365,23 @@ model UserRoleAssignment {
|
|||||||
model UserNotification {
|
model UserNotification {
|
||||||
id String @id @db.Uuid
|
id String @id @db.Uuid
|
||||||
title String @db.VarChar(255)
|
title String @db.VarChar(255)
|
||||||
content String
|
content String @db.Text
|
||||||
picture String
|
picture String @db.Text
|
||||||
state UserNotificationState
|
state UserNotificationState
|
||||||
ctaLink String
|
ctaLink String @db.Text
|
||||||
|
user User @relation("UserNotifications", fields: [userId], references: [id])
|
||||||
userId String @db.Uuid
|
userId String @db.Uuid
|
||||||
isReaded Boolean @default(false)
|
isReaded Boolean @default(false)
|
||||||
deletedAt DateTime?
|
deletedAt DateTime?
|
||||||
createdAt DateTime @default(now())
|
createdAt DateTime @default(now())
|
||||||
updatedAt DateTime @default(now()) @updatedAt
|
updatedAt DateTime @default(now()) @updatedAt
|
||||||
user User @relation("UserNotifications", fields: [userId], references: [id])
|
|
||||||
|
|
||||||
@@map("user_notifications")
|
@@map("user_notifications")
|
||||||
}
|
}
|
||||||
|
|
||||||
model UserSession {
|
model UserSession {
|
||||||
id String @id @db.Uuid
|
id String @id @db.Uuid
|
||||||
isAuthenticated Boolean @default(false)
|
isAuthenticated Boolean @default(false)
|
||||||
|
user User @relation("UserSession", fields: [userId], references: [id])
|
||||||
userId String @db.Uuid
|
userId String @db.Uuid
|
||||||
deviceType String @db.VarChar(255)
|
deviceType String @db.VarChar(255)
|
||||||
deviceOs String @db.VarChar(255)
|
deviceOs String @db.VarChar(255)
|
||||||
@ -382,9 +393,9 @@ model UserSession {
|
|||||||
deletedAt DateTime?
|
deletedAt DateTime?
|
||||||
createdAt DateTime @default(now())
|
createdAt DateTime @default(now())
|
||||||
updatedAt DateTime @default(now()) @updatedAt
|
updatedAt DateTime @default(now()) @updatedAt
|
||||||
episode_likes EpisodeLike[] @relation("SessionEpisodeLikes")
|
|
||||||
logs UserLog[] @relation("UserSessionLogs")
|
logs UserLog[] @relation("UserSessionLogs")
|
||||||
user User @relation("UserSession", fields: [userId], references: [id])
|
episode_likes EpisodeLike[] @relation("SessionEpisodeLikes")
|
||||||
watch_histories WatchHistory[] @relation("SessionWatchHistories")
|
watch_histories WatchHistory[] @relation("SessionWatchHistories")
|
||||||
|
|
||||||
@@index([userId, isAuthenticated, deletedAt])
|
@@index([userId, isAuthenticated, deletedAt])
|
||||||
@ -394,138 +405,119 @@ model UserSession {
|
|||||||
model UserLog {
|
model UserLog {
|
||||||
id String @id @db.Uuid
|
id String @id @db.Uuid
|
||||||
title String @db.VarChar(255)
|
title String @db.VarChar(255)
|
||||||
notes String
|
notes String @db.Text
|
||||||
|
user User @relation("UserLogs", fields: [userId], references: [id])
|
||||||
userId String @db.Uuid
|
userId String @db.Uuid
|
||||||
|
session UserSession @relation("UserSessionLogs", fields: [sessionId], references: [id])
|
||||||
sessionId String @db.Uuid
|
sessionId String @db.Uuid
|
||||||
createdAt DateTime @default(now())
|
createdAt DateTime @default(now())
|
||||||
updatedAt DateTime @default(now()) @updatedAt
|
updatedAt DateTime @default(now()) @updatedAt
|
||||||
session UserSession @relation("UserSessionLogs", fields: [sessionId], references: [id])
|
|
||||||
user User @relation("UserLogs", fields: [userId], references: [id])
|
|
||||||
|
|
||||||
@@map("user_logs")
|
@@map("user_logs")
|
||||||
}
|
}
|
||||||
|
|
||||||
model Collection {
|
model Collection {
|
||||||
id String @id @db.Uuid
|
id String @id @db.Uuid
|
||||||
name String @db.VarChar(115)
|
name String @db.VarChar(255)
|
||||||
|
medias Media[] @relation("MediaCollections")
|
||||||
|
owner User @relation("UserCollections", fields: [ownerId], references: [id])
|
||||||
ownerId String @db.Uuid
|
ownerId String @db.Uuid
|
||||||
accessStatus AccessStatus @default(private)
|
accessStatus AccessStatus @default(private)
|
||||||
password String? @db.VarChar(255)
|
password String? @db.VarChar(255)
|
||||||
|
usersAllowed User[] @relation("UserSelectedSharingCollention")
|
||||||
accessScope AccessScope @default(viewer)
|
accessScope AccessScope @default(viewer)
|
||||||
deletedAt DateTime?
|
deletedAt DateTime?
|
||||||
createdAt DateTime @default(now())
|
createdAt DateTime @default(now())
|
||||||
updatedAt DateTime @default(now()) @updatedAt
|
updatedAt DateTime @default(now()) @updatedAt
|
||||||
slug String @db.VarChar(115)
|
|
||||||
media_saved CollectionMedia[] @relation("CollectionMedia")
|
|
||||||
owner User @relation("UserCollections", fields: [ownerId], references: [id])
|
|
||||||
usersAllowed User[] @relation("UserSelectedSharingCollention")
|
|
||||||
|
|
||||||
@@unique([slug, ownerId])
|
|
||||||
@@map("collections")
|
@@map("collections")
|
||||||
}
|
}
|
||||||
|
|
||||||
model CollectionMedia {
|
|
||||||
id String @id @db.Uuid
|
|
||||||
collectionId String @db.Uuid
|
|
||||||
mediaId String @db.Uuid
|
|
||||||
savedAt DateTime @default(now())
|
|
||||||
collection Collection @relation("CollectionMedia", fields: [collectionId], references: [id])
|
|
||||||
media Media @relation("CollectionMedia", fields: [mediaId], references: [id])
|
|
||||||
|
|
||||||
@@unique([collectionId, mediaId])
|
|
||||||
}
|
|
||||||
|
|
||||||
model WatchHistory {
|
model WatchHistory {
|
||||||
id String @id @db.Uuid
|
id String @id @db.Uuid
|
||||||
|
episode Episode @relation("EpisodeWatchHistories", fields: [id], references: [id])
|
||||||
episodeId String @db.Uuid
|
episodeId String @db.Uuid
|
||||||
|
user User @relation("UserWatchHistories", fields: [userId], references: [id])
|
||||||
userId String @db.Uuid
|
userId String @db.Uuid
|
||||||
|
session UserSession @relation("SessionWatchHistories", fields: [sessionId], references: [id])
|
||||||
sessionId String @db.Uuid
|
sessionId String @db.Uuid
|
||||||
createdAt DateTime @default(now())
|
createdAt DateTime @default(now())
|
||||||
updatedAt DateTime @default(now()) @updatedAt
|
updatedAt DateTime @default(now()) @updatedAt
|
||||||
episode Episode @relation("EpisodeWatchHistories", fields: [id], references: [id])
|
|
||||||
session UserSession @relation("SessionWatchHistories", fields: [sessionId], references: [id])
|
|
||||||
user User @relation("UserWatchHistories", fields: [userId], references: [id])
|
|
||||||
|
|
||||||
@@map("watch_histories")
|
@@map("watch_histories")
|
||||||
}
|
}
|
||||||
|
|
||||||
model MediaReview {
|
model MediaReview {
|
||||||
id String @id @db.Uuid
|
id String @id @db.Uuid
|
||||||
|
media Media @relation("MediaReviews", fields: [mediaId], references:[id])
|
||||||
mediaId String @db.Uuid
|
mediaId String @db.Uuid
|
||||||
rating Int
|
rating Int
|
||||||
title String @db.VarChar(255)
|
title String @db.VarChar(255)
|
||||||
text String
|
text String @db.Text
|
||||||
reaction MediaReviewReaction
|
reaction MediaReviewReaction
|
||||||
|
creator User @relation("UserMediaReviews", fields: [createdBy], references: [id])
|
||||||
createdBy String @db.Uuid
|
createdBy String @db.Uuid
|
||||||
deletedAt DateTime?
|
deletedAt DateTime?
|
||||||
createdAt DateTime @default(now())
|
createdAt DateTime @default(now())
|
||||||
updatedAt DateTime @default(now()) @updatedAt
|
updatedAt DateTime @default(now()) @updatedAt
|
||||||
creator User @relation("UserMediaReviews", fields: [createdBy], references: [id])
|
|
||||||
media Media @relation("MediaReviews", fields: [mediaId], references: [id])
|
|
||||||
|
|
||||||
@@map("movie_reviews")
|
@@map("movie_reviews")
|
||||||
}
|
}
|
||||||
|
|
||||||
model Comment {
|
model Comment {
|
||||||
id String @id @db.Uuid
|
id String @id @db.Uuid
|
||||||
|
episode Episode @relation("EpisodeComments", fields: [episodeId], references: [id])
|
||||||
episodeId String @db.Uuid
|
episodeId String @db.Uuid
|
||||||
text String
|
text String @db.Text
|
||||||
isParent Boolean @default(false)
|
isParent Boolean @default(false)
|
||||||
|
parent Comment? @relation("ParentReplyComments", fields: [parentId], references: [id])
|
||||||
parentId String? @db.Uuid
|
parentId String? @db.Uuid
|
||||||
|
user User @relation("UserComments", fields: [userId], references: [id])
|
||||||
userId String @db.Uuid
|
userId String @db.Uuid
|
||||||
createdAt DateTime @default(now())
|
createdAt DateTime @default(now())
|
||||||
updatedAt DateTime @default(now()) @updatedAt
|
updatedAt DateTime @default(now()) @updatedAt
|
||||||
likes CommentLike[] @relation("CommentLikes")
|
|
||||||
episode Episode @relation("EpisodeComments", fields: [episodeId], references: [id])
|
|
||||||
parent Comment? @relation("ParentReplyComments", fields: [parentId], references: [id])
|
|
||||||
replies Comment[] @relation("ParentReplyComments")
|
|
||||||
user User @relation("UserComments", fields: [userId], references: [id])
|
|
||||||
|
|
||||||
|
replies Comment[] @relation("ParentReplyComments")
|
||||||
|
likes CommentLike[] @relation("CommentLikes")
|
||||||
@@map("comments")
|
@@map("comments")
|
||||||
}
|
}
|
||||||
|
|
||||||
model CommentLike {
|
model CommentLike {
|
||||||
id String @id @db.Uuid
|
id String @id @db.Uuid
|
||||||
|
comment Comment @relation("CommentLikes", fields: [commentId], references: [id])
|
||||||
commentId String @db.Uuid
|
commentId String @db.Uuid
|
||||||
|
user User @relation("UserCommentLikes", fields: [userLiked], references: [id])
|
||||||
userLiked String @db.Uuid
|
userLiked String @db.Uuid
|
||||||
createdAt DateTime @default(now())
|
createdAt DateTime @default(now())
|
||||||
updatedAt DateTime @default(now()) @updatedAt
|
updatedAt DateTime @default(now()) @updatedAt
|
||||||
comment Comment @relation("CommentLikes", fields: [commentId], references: [id])
|
|
||||||
user User @relation("UserCommentLikes", fields: [userLiked], references: [id])
|
|
||||||
|
|
||||||
@@map("comment_likes")
|
@@map("comment_likes")
|
||||||
}
|
}
|
||||||
|
|
||||||
model CommentReport {
|
model CommentReport {
|
||||||
id String @id @db.Uuid
|
id String @id @db.Uuid
|
||||||
|
reporter User @relation("UserReportComments", fields: [userReporter], references: [id])
|
||||||
userReporter String @db.Uuid
|
userReporter String @db.Uuid
|
||||||
commentReported String @db.Uuid
|
commentReported String @db.Uuid
|
||||||
isSupervisorReport Boolean @default(false)
|
isSupervisorReport Boolean @default(false)
|
||||||
reason ReportReason
|
reason ReportReason
|
||||||
status ReportStatus
|
status ReportStatus
|
||||||
description String @db.VarChar(255)
|
description String @db.VarChar(255)
|
||||||
|
approver User? @relation("ApprovedReportComments", fields: [approvedBy], references: [id])
|
||||||
approvedBy String? @db.Uuid
|
approvedBy String? @db.Uuid
|
||||||
createdAt DateTime @default(now())
|
createdAt DateTime @default(now())
|
||||||
updatedAt DateTime @default(now()) @updatedAt
|
updatedAt DateTime @default(now()) @updatedAt
|
||||||
approver User? @relation("ApprovedReportComments", fields: [approvedBy], references: [id])
|
|
||||||
reporter User @relation("UserReportComments", fields: [userReporter], references: [id])
|
|
||||||
|
|
||||||
@@map("comment_reports")
|
@@map("comment_reports")
|
||||||
}
|
}
|
||||||
|
|
||||||
model Language {
|
model Language {
|
||||||
id String @id @db.Uuid
|
id String @id @db.Uuid
|
||||||
name String @db.VarChar(255)
|
name String @db.VarChar(255)
|
||||||
code String @unique @db.VarChar(5)
|
code String @db.VarChar(5) @unique
|
||||||
countryFlag String @db.VarChar(10)
|
countryFlag String @db.VarChar(10)
|
||||||
fileLocation String
|
fileLocation String @db.Text
|
||||||
|
creator User @relation("UserCreateLanguages", fields: [craetedBy], references: [id])
|
||||||
craetedBy String @db.Uuid
|
craetedBy String @db.Uuid
|
||||||
deletedAt DateTime?
|
deletedAt DateTime?
|
||||||
createdAt DateTime @default(now())
|
createdAt DateTime @default(now())
|
||||||
updatedAt DateTime @default(now()) @updatedAt
|
updatedAt DateTime @default(now()) @updatedAt
|
||||||
creator User @relation("UserCreateLanguages", fields: [craetedBy], references: [id])
|
|
||||||
user_used UserPreference[] @relation("UserPreferenceLang")
|
|
||||||
|
|
||||||
|
user_used UserPreference[] @relation("UserPreferenceLang")
|
||||||
@@map("languages")
|
@@map("languages")
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -539,56 +531,56 @@ model EmailSystemAccount {
|
|||||||
username String @unique @db.VarChar(255)
|
username String @unique @db.VarChar(255)
|
||||||
password String @db.VarChar(255)
|
password String @db.VarChar(255)
|
||||||
purpose EmailPorpose
|
purpose EmailPorpose
|
||||||
|
creator User @relation("UserCreateSystemAccount", fields: [createdBy], references: [id])
|
||||||
createdBy String @db.Uuid
|
createdBy String @db.Uuid
|
||||||
deletedAt DateTime?
|
deletedAt DateTime?
|
||||||
createdAt DateTime @default(now())
|
createdAt DateTime @default(now())
|
||||||
updatedAt DateTime @default(now()) @updatedAt
|
updatedAt DateTime @default(now()) @updatedAt
|
||||||
creator User @relation("UserCreateSystemAccount", fields: [createdBy], references: [id])
|
|
||||||
|
|
||||||
@@map("email_system_accounts")
|
@@map("email_system_accounts")
|
||||||
}
|
}
|
||||||
|
|
||||||
model EmailSystemHistory {
|
model EmailSystemHistory {
|
||||||
id String @id @db.Uuid
|
id String @id @db.Uuid
|
||||||
purpose EmailPorpose
|
purpose EmailPorpose
|
||||||
fromEmail String
|
fromEmail String @db.Text
|
||||||
toEmail String
|
toEmail String @db.Text
|
||||||
|
user User @relation("UserEmails", fields: [userRelated], references: [id])
|
||||||
userRelated String @db.Uuid
|
userRelated String @db.Uuid
|
||||||
title String @db.VarChar(255)
|
title String @db.VarChar(255)
|
||||||
htmlContent String
|
htmlContent String @db.Text
|
||||||
deletedAt DateTime?
|
deletedAt DateTime?
|
||||||
createdAt DateTime @default(now())
|
createdAt DateTime @default(now())
|
||||||
updatedAt DateTime @default(now()) @updatedAt
|
updatedAt DateTime @default(now()) @updatedAt
|
||||||
user User @relation("UserEmails", fields: [userRelated], references: [id])
|
|
||||||
|
|
||||||
@@map("email_system_histories")
|
@@map("email_system_histories")
|
||||||
}
|
}
|
||||||
|
|
||||||
model HeroBanner {
|
model HeroBanner {
|
||||||
id String @id @db.Uuid
|
id String @id @db.Uuid
|
||||||
orderPriority Int? @unique
|
orderPriority Int? @unique
|
||||||
imageUrl String?
|
isClickable Boolean @default(false)
|
||||||
|
title String? @db.VarChar(225)
|
||||||
|
tags String[]
|
||||||
|
description String? @db.Text
|
||||||
|
buttonContent String? @db.VarChar(100)
|
||||||
|
buttonLink String? @db.Text
|
||||||
|
imageUrl String? @db.Text
|
||||||
startDate DateTime
|
startDate DateTime
|
||||||
endDate DateTime
|
endDate DateTime
|
||||||
createdAt DateTime @default(now())
|
createdAt DateTime @default(now())
|
||||||
updatedAt DateTime @default(now()) @updatedAt
|
updatedAt DateTime @default(now()) @updatedAt
|
||||||
creatorId String @db.Uuid
|
creatorId String @db.Uuid
|
||||||
mediaId String @db.Uuid
|
|
||||||
createdBy User @relation("UserHeroBanner", fields: [creatorId], references: [id])
|
createdBy User @relation("UserHeroBanner", fields: [creatorId], references: [id])
|
||||||
media Media @relation("MediaBannerPromotion", fields: [mediaId], references: [id])
|
|
||||||
|
|
||||||
@@map("hero_banner")
|
@@map("hero_banner")
|
||||||
}
|
}
|
||||||
|
|
||||||
model SystemPreference {
|
model SystemPreference {
|
||||||
id String @id @db.Uuid
|
id String @id @db.Uuid
|
||||||
key String @unique @db.VarChar(225)
|
key String @db.VarChar(225) @unique
|
||||||
value String @db.VarChar(225)
|
value String @db.VarChar(225)
|
||||||
description String
|
description String @db.Text
|
||||||
deletedAt DateTime?
|
deletedAt DateTime?
|
||||||
createdAt DateTime @default(now())
|
createdAt DateTime @default(now())
|
||||||
updatedAt DateTime @default(now()) @updatedAt
|
updatedAt DateTime @default(now()) @updatedAt
|
||||||
|
|
||||||
@@map("system_preferences")
|
@@map("system_preferences")
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -596,30 +588,35 @@ model SystemNotification {
|
|||||||
id String @id @db.Uuid
|
id String @id @db.Uuid
|
||||||
type TypeSystemNotification
|
type TypeSystemNotification
|
||||||
componentName String? @db.VarChar(255)
|
componentName String? @db.VarChar(255)
|
||||||
popupImage String?
|
popupImage String? @db.Text
|
||||||
titleToast String? @db.VarChar(255)
|
titleToast String? @db.VarChar(255)
|
||||||
contentToast String?
|
contentToast String? @db.Text
|
||||||
|
creator User @relation("UserCreatorSystemNotifications", fields: [createdBy], references: [id])
|
||||||
createdBy String @db.Uuid
|
createdBy String @db.Uuid
|
||||||
deletedAt DateTime?
|
deletedAt DateTime?
|
||||||
createdAt DateTime @default(now())
|
createdAt DateTime @default(now())
|
||||||
updatedAt DateTime @default(now()) @updatedAt
|
updatedAt DateTime @default(now()) @updatedAt
|
||||||
creator User @relation("UserCreatorSystemNotifications", fields: [createdBy], references: [id])
|
|
||||||
|
|
||||||
@@map("system_notifications")
|
@@map("system_notifications")
|
||||||
}
|
}
|
||||||
|
|
||||||
model SystemLog {
|
model SystemLog {
|
||||||
id String @id @db.Uuid
|
id String @id @db.Uuid
|
||||||
title String @db.VarChar(255)
|
title String @db.VarChar(255)
|
||||||
notes String
|
notes String @db.Text
|
||||||
|
user User? @relation("UserSystemLogs", fields: [relatedUser], references: [id])
|
||||||
relatedUser String? @db.Uuid
|
relatedUser String? @db.Uuid
|
||||||
createdAt DateTime @default(now())
|
createdAt DateTime @default(now())
|
||||||
updatedAt DateTime @default(now()) @updatedAt
|
updatedAt DateTime @default(now()) @updatedAt
|
||||||
user User? @relation("UserSystemLogs", fields: [relatedUser], references: [id])
|
|
||||||
|
|
||||||
@@map("system_logs")
|
@@map("system_logs")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//// Prisma Enum Values ////
|
||||||
|
|
||||||
|
// Media Enum
|
||||||
enum MediaType {
|
enum MediaType {
|
||||||
TV
|
TV
|
||||||
ONA
|
ONA
|
||||||
@ -628,7 +625,6 @@ enum MediaType {
|
|||||||
Special
|
Special
|
||||||
Music
|
Music
|
||||||
}
|
}
|
||||||
|
|
||||||
enum Country {
|
enum Country {
|
||||||
JP @map("Japanese")
|
JP @map("Japanese")
|
||||||
EN @map("English")
|
EN @map("English")
|
||||||
@ -636,40 +632,35 @@ enum Country {
|
|||||||
KR @map("Korea")
|
KR @map("Korea")
|
||||||
}
|
}
|
||||||
|
|
||||||
enum Season {
|
// Character Enum
|
||||||
winter
|
|
||||||
spring
|
|
||||||
summer
|
|
||||||
fall
|
|
||||||
}
|
|
||||||
|
|
||||||
enum CharacterRole {
|
enum CharacterRole {
|
||||||
Main
|
Main
|
||||||
Supporting
|
Supporting
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MediaLog Enum
|
||||||
enum MediaOperation {
|
enum MediaOperation {
|
||||||
create
|
create
|
||||||
update
|
update
|
||||||
delete
|
delete
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// User Enum
|
||||||
enum UserGender {
|
enum UserGender {
|
||||||
male
|
male
|
||||||
female
|
female
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// UserPreference Enum
|
||||||
enum AdultFiltering {
|
enum AdultFiltering {
|
||||||
hide
|
hide
|
||||||
show
|
show
|
||||||
explicit
|
explicit
|
||||||
}
|
}
|
||||||
|
|
||||||
enum AdultAlert {
|
enum AdultAlert {
|
||||||
hide
|
hide
|
||||||
show
|
show
|
||||||
}
|
}
|
||||||
|
|
||||||
enum VideoQuality {
|
enum VideoQuality {
|
||||||
Q2160
|
Q2160
|
||||||
Q1440
|
Q1440
|
||||||
@ -681,18 +672,19 @@ enum VideoQuality {
|
|||||||
Q144
|
Q144
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// userNotification Enum
|
||||||
enum UserNotificationState {
|
enum UserNotificationState {
|
||||||
info
|
info
|
||||||
warning
|
warning
|
||||||
danger
|
danger
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CommentReport Enum
|
||||||
enum ReportStatus {
|
enum ReportStatus {
|
||||||
pending
|
pending
|
||||||
resolved
|
resolved
|
||||||
rejected
|
rejected
|
||||||
}
|
}
|
||||||
|
|
||||||
enum ReportReason {
|
enum ReportReason {
|
||||||
sexualize
|
sexualize
|
||||||
violent
|
violent
|
||||||
@ -704,18 +696,19 @@ enum ReportReason {
|
|||||||
other
|
other
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Collection Enum
|
||||||
enum AccessStatus {
|
enum AccessStatus {
|
||||||
private
|
private
|
||||||
selected
|
selected
|
||||||
protected
|
protected
|
||||||
public
|
public
|
||||||
}
|
}
|
||||||
|
|
||||||
enum AccessScope {
|
enum AccessScope {
|
||||||
viewer
|
viewer
|
||||||
editor
|
editor
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MediaReview Enum
|
||||||
enum MediaReviewReaction {
|
enum MediaReviewReaction {
|
||||||
angry
|
angry
|
||||||
sad
|
sad
|
||||||
@ -727,6 +720,7 @@ enum MediaReviewReaction {
|
|||||||
disappointed
|
disappointed
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// EmailSystemHistory Enum
|
||||||
enum EmailPorpose {
|
enum EmailPorpose {
|
||||||
forgot_password
|
forgot_password
|
||||||
account_activation
|
account_activation
|
||||||
@ -734,6 +728,7 @@ enum EmailPorpose {
|
|||||||
subscribtion
|
subscribtion
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// systemNotification Enum
|
||||||
enum TypeSystemNotification {
|
enum TypeSystemNotification {
|
||||||
component
|
component
|
||||||
popup
|
popup
|
||||||
|
|||||||
@ -1,3 +1,4 @@
|
|||||||
|
import { Context } from "elysia";
|
||||||
import { UserHeaderInformation } from "./types";
|
import { UserHeaderInformation } from "./types";
|
||||||
|
|
||||||
export interface ClientInfoHeader {
|
export interface ClientInfoHeader {
|
||||||
@ -9,14 +10,25 @@ export interface ClientInfoHeader {
|
|||||||
ip: string;
|
ip: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const getUserHeaderInformation = (clientInfo: string): UserHeaderInformation => {
|
export const getUserHeaderInformation = (
|
||||||
const clientInfoHeader = (JSON.parse(clientInfo) as ClientInfoHeader) ?? ("unknown" as string);
|
ctx: Context,
|
||||||
|
): UserHeaderInformation => {
|
||||||
|
const clientInfoHeader =
|
||||||
|
(JSON.parse(
|
||||||
|
ctx.request.headers.get("x-client-info") as string,
|
||||||
|
) as ClientInfoHeader) ?? ("unknown" as string);
|
||||||
|
|
||||||
const userHeaderInformation = {
|
const userHeaderInformation = {
|
||||||
ip: clientInfoHeader.ip ?? "unknown",
|
ip: clientInfoHeader.ip ?? "unknown",
|
||||||
deviceType: clientInfoHeader.deviceType ?? "unknown",
|
deviceType: clientInfoHeader.deviceType ?? "unknown",
|
||||||
deviceOS: (clientInfoHeader.os ?? "unknown") + " " + (clientInfoHeader.osVersion ?? "unknown"),
|
deviceOS:
|
||||||
browser: (clientInfoHeader.browser ?? "unknown") + " " + (clientInfoHeader.browserVersion ?? "unknown"),
|
(clientInfoHeader.os ?? "unknown") +
|
||||||
|
" " +
|
||||||
|
(clientInfoHeader.osVersion ?? "unknown"),
|
||||||
|
browser:
|
||||||
|
(clientInfoHeader.browser ?? "unknown") +
|
||||||
|
" " +
|
||||||
|
(clientInfoHeader.browserVersion ?? "unknown"),
|
||||||
};
|
};
|
||||||
|
|
||||||
return userHeaderInformation;
|
return userHeaderInformation;
|
||||||
|
|||||||
@ -1,17 +1,14 @@
|
|||||||
import { Context, Static } from "elysia";
|
import { Context } from "elysia";
|
||||||
import { returnWriteResponse } from "../../../helpers/callback/httpResponse";
|
import { returnWriteResponse } from "../../../helpers/callback/httpResponse";
|
||||||
import { githubCallbackService } from "../services/http/githubCallback.service";
|
import { githubCallbackService } from "../services/http/githubCallback.service";
|
||||||
import { mainErrorHandler } from "../../../helpers/error/handler";
|
import { mainErrorHandler } from "../../../helpers/error/handler";
|
||||||
import { getUserHeaderInformation } from "../../../helpers/http/userHeader/getUserHeaderInformation";
|
import { getUserHeaderInformation } from "../../../helpers/http/userHeader/getUserHeaderInformation";
|
||||||
import { githubCallbackSchema } from "../schemas/githubCallback.schema";
|
|
||||||
|
|
||||||
export const githubCallbackController = async (ctx: {
|
export const githubCallbackController = async (
|
||||||
set: Context["set"];
|
ctx: Context & { query: { code: string; callbackURI: string } }
|
||||||
query: Static<typeof githubCallbackSchema.query>;
|
) => {
|
||||||
headers: Static<typeof githubCallbackSchema.headers>;
|
|
||||||
}) => {
|
|
||||||
try {
|
try {
|
||||||
const userHeaderInfo = getUserHeaderInformation(ctx.headers["x-client-info"]);
|
const userHeaderInfo = getUserHeaderInformation(ctx);
|
||||||
|
|
||||||
const authToken = await githubCallbackService(ctx.query, userHeaderInfo);
|
const authToken = await githubCallbackService(ctx.query, userHeaderInfo);
|
||||||
return returnWriteResponse(ctx.set, 200, "Authenticated successfully!", {
|
return returnWriteResponse(ctx.set, 200, "Authenticated successfully!", {
|
||||||
|
|||||||
@ -1,18 +1,21 @@
|
|||||||
import { Context, Static } from "elysia";
|
import { Context } from "elysia";
|
||||||
import { returnReadResponse } from "../../../helpers/callback/httpResponse";
|
import { returnReadResponse } from "../../../helpers/callback/httpResponse";
|
||||||
import { githubRequestService } from "../services/http/githubRequest.service";
|
import { githubRequestService } from "../services/http/githubRequest.service";
|
||||||
import { mainErrorHandler } from "../../../helpers/error/handler";
|
import { mainErrorHandler } from "../../../helpers/error/handler";
|
||||||
import { githubRequestSchema } from "../schemas/githubRequest.schema";
|
|
||||||
|
|
||||||
export const githubRequestController = async (ctx: {
|
export const githubRequestController = async (
|
||||||
set: Context["set"];
|
ctx: Context & { query: { callback?: string } },
|
||||||
query: Static<typeof githubRequestSchema.query>;
|
) => {
|
||||||
}) => {
|
|
||||||
try {
|
try {
|
||||||
const loginUrl = await githubRequestService(ctx.query.callback);
|
const loginUrl = await githubRequestService(ctx.query.callback);
|
||||||
return returnReadResponse(ctx.set, 200, "GitHub login URL created successfully.", {
|
return returnReadResponse(
|
||||||
|
ctx.set,
|
||||||
|
200,
|
||||||
|
"Login URL generated successfully",
|
||||||
|
{
|
||||||
endpointUrl: loginUrl,
|
endpointUrl: loginUrl,
|
||||||
});
|
},
|
||||||
|
);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
return mainErrorHandler(ctx.set, error);
|
return mainErrorHandler(ctx.set, error);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,20 +1,17 @@
|
|||||||
import { Context, Static } from "elysia";
|
import { Context } from "elysia";
|
||||||
import { returnReadResponse } from "../../../helpers/callback/httpResponse";
|
import { returnReadResponse } from "../../../helpers/callback/httpResponse";
|
||||||
import { mainErrorHandler } from "../../../helpers/error/handler";
|
import { mainErrorHandler } from "../../../helpers/error/handler";
|
||||||
import { googleCallbackService } from "../services/http/googleCallback.service";
|
import { googleCallbackService } from "../services/http/googleCallback.service";
|
||||||
import { getUserHeaderInformation } from "../../../helpers/http/userHeader/getUserHeaderInformation";
|
import { getUserHeaderInformation } from "../../../helpers/http/userHeader/getUserHeaderInformation";
|
||||||
import { googleCallbackSchema } from "../schemas/googleCallback.schema";
|
|
||||||
|
|
||||||
export const googleCallbackController = async (ctx: {
|
export const googleCallbackController = async (
|
||||||
set: Context["set"];
|
ctx: Context & { query: { code: string; state: string; callbackURI: string } }
|
||||||
query: Static<typeof googleCallbackSchema.query>;
|
) => {
|
||||||
headers: Static<typeof googleCallbackSchema.headers>;
|
|
||||||
}) => {
|
|
||||||
try {
|
try {
|
||||||
const userHeaderInfo = getUserHeaderInformation(ctx.headers["x-client-info"]);
|
const userHeaderInfo = getUserHeaderInformation(ctx);
|
||||||
|
|
||||||
const authToken = await googleCallbackService(ctx.query, userHeaderInfo);
|
const authToken = await googleCallbackService(ctx.query, userHeaderInfo);
|
||||||
return returnReadResponse(ctx.set, 200, "Authentication successful!", {
|
return returnReadResponse(ctx.set, 200, "Authenticated successfully!", {
|
||||||
authToken,
|
authToken,
|
||||||
});
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
|||||||
@ -1,16 +1,14 @@
|
|||||||
import { Context, Static } from "elysia";
|
import { Context } from "elysia";
|
||||||
import { mainErrorHandler } from "../../../helpers/error/handler";
|
import { mainErrorHandler } from "../../../helpers/error/handler";
|
||||||
import { googleRequestService } from "../services/http/googleRequest.service";
|
import { googleRequestService } from "../services/http/googleRequest.service";
|
||||||
import { returnReadResponse } from "../../../helpers/callback/httpResponse";
|
import { returnReadResponse } from "../../../helpers/callback/httpResponse";
|
||||||
import { googleRequestSchema } from "../schemas/googleRequest.schema";
|
|
||||||
|
|
||||||
export const googleRequestController = async (ctx: {
|
export const googleRequestController = async (
|
||||||
set: Context["set"];
|
ctx: Context & { query: { callback?: string } }
|
||||||
query: Static<typeof googleRequestSchema.query>;
|
) => {
|
||||||
}) => {
|
|
||||||
try {
|
try {
|
||||||
const loginUrl = await googleRequestService(ctx.query.callback);
|
const loginUrl = await googleRequestService(ctx.query.callback);
|
||||||
return returnReadResponse(ctx.set, 200, "Google login URL created successfully.", {
|
return returnReadResponse(ctx.set, 200, "Google login url created!", {
|
||||||
endpointUrl: loginUrl,
|
endpointUrl: loginUrl,
|
||||||
});
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
|||||||
@ -9,19 +9,13 @@ import { tokenValidationController } from "./controllers/tokenValidation.control
|
|||||||
import { logoutController } from "./controllers/logout.controller";
|
import { logoutController } from "./controllers/logout.controller";
|
||||||
import { tokenValidationSchema } from "./schemas/tokenValidation.schema";
|
import { tokenValidationSchema } from "./schemas/tokenValidation.schema";
|
||||||
import { getOauthProvidersSchema } from "./schemas/getOauthProviders.schema";
|
import { getOauthProvidersSchema } from "./schemas/getOauthProviders.schema";
|
||||||
import { getCallbackProviderUrlSchema } from "./schemas/getCallbackProviderUrl.schema";
|
|
||||||
import { googleRequestSchema } from "./schemas/googleRequest.schema";
|
|
||||||
import { googleCallbackSchema } from "./schemas/googleCallback.schema";
|
|
||||||
import { githubRequestSchema } from "./schemas/githubRequest.schema";
|
|
||||||
import { githubCallbackSchema } from "./schemas/githubCallback.schema";
|
|
||||||
import { logoutSchema } from "./schemas/logout.schema";
|
|
||||||
|
|
||||||
export const authModule = new Elysia({ prefix: "/auth", tags: ["Authentication"] })
|
export const authModule = new Elysia({ prefix: "/auth", tags: ["Authentication"] })
|
||||||
.post("/token/validate", tokenValidationController, tokenValidationSchema)
|
.post("/token/validate", tokenValidationController, tokenValidationSchema)
|
||||||
.get("/providers", getOauthProvidersController, getOauthProvidersSchema)
|
.get("/providers", getOauthProvidersController, getOauthProvidersSchema)
|
||||||
.get("/providers/:name/callback", getCallbackProviderUrlController, getCallbackProviderUrlSchema)
|
.get("/providers/:name/callback", getCallbackProviderUrlController)
|
||||||
.get("/google", googleRequestController, googleRequestSchema)
|
.get("/github", githubRequestController)
|
||||||
.get("/google/callback", googleCallbackController, googleCallbackSchema)
|
.get("/github/callback", githubCallbackController)
|
||||||
.get("/github", githubRequestController, githubRequestSchema)
|
.get("/google", googleRequestController)
|
||||||
.get("/github/callback", githubCallbackController, githubCallbackSchema)
|
.get("/google/callback", googleCallbackController)
|
||||||
.post("/logout", logoutController, logoutSchema);
|
.post("/logout", logoutController);
|
||||||
|
|||||||
@ -1,45 +0,0 @@
|
|||||||
import { AppRouteSchema } from "../../../helpers/types/AppRouteSchema";
|
|
||||||
|
|
||||||
export const getCallbackProviderUrlSchema = {
|
|
||||||
detail: {
|
|
||||||
summary: "Get the callback URL of oauth provider",
|
|
||||||
description:
|
|
||||||
"After users have successfully completed the authentication process on the OAuth provider page, they will be redirected to the callback page on the frontend. This endpoint aims to obtain the actual endpoint for each OAuth response handler.",
|
|
||||||
responses: {
|
|
||||||
200: {
|
|
||||||
description: "The callback URL on the provider has been found.",
|
|
||||||
content: {
|
|
||||||
"application/json": {
|
|
||||||
schema: {
|
|
||||||
type: "object",
|
|
||||||
properties: {
|
|
||||||
success: {
|
|
||||||
type: "boolean",
|
|
||||||
default: true,
|
|
||||||
},
|
|
||||||
status: {
|
|
||||||
type: "number",
|
|
||||||
default: 200,
|
|
||||||
},
|
|
||||||
message: {
|
|
||||||
type: "string",
|
|
||||||
default: "The callback URL on the provider has been found.",
|
|
||||||
},
|
|
||||||
data: {
|
|
||||||
type: "object",
|
|
||||||
properties: {
|
|
||||||
callback_url: {
|
|
||||||
type: "string",
|
|
||||||
description: "The callback URL on the provider.",
|
|
||||||
example: "auth/google/callback",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
} satisfies AppRouteSchema;
|
|
||||||
@ -1,3 +1,4 @@
|
|||||||
|
import { success } from "zod";
|
||||||
import { AppRouteSchema } from "../../../helpers/types/AppRouteSchema";
|
import { AppRouteSchema } from "../../../helpers/types/AppRouteSchema";
|
||||||
|
|
||||||
export const getOauthProvidersSchema = {
|
export const getOauthProvidersSchema = {
|
||||||
|
|||||||
@ -1,57 +0,0 @@
|
|||||||
import { t } from "elysia";
|
|
||||||
import { AppRouteSchema } from "../../../helpers/types/AppRouteSchema";
|
|
||||||
|
|
||||||
export const githubCallbackSchema = {
|
|
||||||
headers: t.Object({
|
|
||||||
"x-client-info": t.String({
|
|
||||||
examples: [
|
|
||||||
'{"os":"Windows","osVersion":"10","browser":"Chrome","browserVersion":"89.0.4389.82","deviceType":"Desktop","ip":"192.168.1.1"}',
|
|
||||||
],
|
|
||||||
}),
|
|
||||||
}),
|
|
||||||
query: t.Object({
|
|
||||||
code: t.String({ examples: ["4/0AY0e-xxxxxxxxx"] }),
|
|
||||||
callbackURI: t.String({ examples: ["https://example.com/auth/github/callback"] }),
|
|
||||||
}),
|
|
||||||
detail: {
|
|
||||||
summary: "GitHub OAuth callback endpoint",
|
|
||||||
description:
|
|
||||||
"Handles the callback from GitHub OAuth and processes the authentication response. This endpoint also processes the account provisioning if the user is logging in for the first time.",
|
|
||||||
responses: {
|
|
||||||
200: {
|
|
||||||
description: "Authentication successful",
|
|
||||||
content: {
|
|
||||||
"application/json": {
|
|
||||||
schema: {
|
|
||||||
type: "object",
|
|
||||||
properties: {
|
|
||||||
success: {
|
|
||||||
type: "boolean",
|
|
||||||
example: true,
|
|
||||||
},
|
|
||||||
status: {
|
|
||||||
type: "number",
|
|
||||||
example: 200,
|
|
||||||
},
|
|
||||||
message: {
|
|
||||||
type: "string",
|
|
||||||
example: "Authentication successful",
|
|
||||||
},
|
|
||||||
data: {
|
|
||||||
type: "object",
|
|
||||||
properties: {
|
|
||||||
authToken: {
|
|
||||||
type: "string",
|
|
||||||
description: "JWT token for authenticated user",
|
|
||||||
example: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
} satisfies AppRouteSchema;
|
|
||||||
@ -1,54 +0,0 @@
|
|||||||
import { t } from "elysia";
|
|
||||||
import { AppRouteSchema } from "../../../helpers/types/AppRouteSchema";
|
|
||||||
|
|
||||||
export const githubRequestSchema = {
|
|
||||||
query: t.Object({
|
|
||||||
callback: t.Optional(
|
|
||||||
t.String({
|
|
||||||
description: "The callback URL to redirect after GitHub authentication. It should be URL-encoded if provided.",
|
|
||||||
}),
|
|
||||||
),
|
|
||||||
}),
|
|
||||||
detail: {
|
|
||||||
summary: "Initiate GitHub OAuth flow",
|
|
||||||
description:
|
|
||||||
"This endpoint initiates the GitHub OAuth flow by redirecting the user to GitHub's authentication page.",
|
|
||||||
responses: {
|
|
||||||
200: {
|
|
||||||
description: "GitHub login URL created successfully.",
|
|
||||||
content: {
|
|
||||||
"application/json": {
|
|
||||||
schema: {
|
|
||||||
type: "object",
|
|
||||||
properties: {
|
|
||||||
success: {
|
|
||||||
type: "boolean",
|
|
||||||
default: true,
|
|
||||||
},
|
|
||||||
status: {
|
|
||||||
type: "number",
|
|
||||||
default: 200,
|
|
||||||
},
|
|
||||||
message: {
|
|
||||||
type: "string",
|
|
||||||
default: "GitHub login URL created successfully.",
|
|
||||||
},
|
|
||||||
data: {
|
|
||||||
type: "object",
|
|
||||||
properties: {
|
|
||||||
endpointUrl: {
|
|
||||||
type: "string",
|
|
||||||
description: "The URL to redirect the user for GitHub authentication.",
|
|
||||||
example:
|
|
||||||
"https://github.com/login/oauth/authorize?client_id=YOUR_CLIENT_ID&redirect_uri=YOUR_REDIRECT_URI&response_type=code&scope=user:email",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
} satisfies AppRouteSchema;
|
|
||||||
@ -1,58 +0,0 @@
|
|||||||
import { t } from "elysia";
|
|
||||||
import { AppRouteSchema } from "../../../helpers/types/AppRouteSchema";
|
|
||||||
|
|
||||||
export const googleCallbackSchema = {
|
|
||||||
headers: t.Object({
|
|
||||||
"x-client-info": t.String({
|
|
||||||
examples: [
|
|
||||||
'{"os":"Windows","osVersion":"10","browser":"Chrome","browserVersion":"89.0.4389.82","deviceType":"Desktop","ip":"192.168.1.1"}',
|
|
||||||
],
|
|
||||||
}),
|
|
||||||
}),
|
|
||||||
query: t.Object({
|
|
||||||
code: t.String({ examples: ["4/0AY0e-xxxxxxxxx"] }),
|
|
||||||
state: t.String({ examples: ["random_state_string"] }),
|
|
||||||
callbackURI: t.String({ examples: ["https://example.com/auth/google/callback"] }),
|
|
||||||
}),
|
|
||||||
detail: {
|
|
||||||
summary: "Google OAuth callback endpoint",
|
|
||||||
description:
|
|
||||||
"Handles the callback from Google OAuth and processes the authentication response. This endpoint also processes the account provisioning if the user is logging in for the first time.",
|
|
||||||
responses: {
|
|
||||||
200: {
|
|
||||||
description: "Authentication successful",
|
|
||||||
content: {
|
|
||||||
"application/json": {
|
|
||||||
schema: {
|
|
||||||
type: "object",
|
|
||||||
properties: {
|
|
||||||
success: {
|
|
||||||
type: "boolean",
|
|
||||||
example: true,
|
|
||||||
},
|
|
||||||
status: {
|
|
||||||
type: "number",
|
|
||||||
example: 200,
|
|
||||||
},
|
|
||||||
message: {
|
|
||||||
type: "string",
|
|
||||||
example: "Authentication successful",
|
|
||||||
},
|
|
||||||
data: {
|
|
||||||
type: "object",
|
|
||||||
properties: {
|
|
||||||
authToken: {
|
|
||||||
type: "string",
|
|
||||||
description: "JWT token for authenticated user",
|
|
||||||
example: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
} satisfies AppRouteSchema;
|
|
||||||
@ -1,54 +0,0 @@
|
|||||||
import { t } from "elysia";
|
|
||||||
import { AppRouteSchema } from "../../../helpers/types/AppRouteSchema";
|
|
||||||
|
|
||||||
export const googleRequestSchema = {
|
|
||||||
query: t.Object({
|
|
||||||
callback: t.Optional(
|
|
||||||
t.String({
|
|
||||||
description: "The callback URL to redirect after Google authentication. It should be URL-encoded if provided.",
|
|
||||||
}),
|
|
||||||
),
|
|
||||||
}),
|
|
||||||
detail: {
|
|
||||||
summary: "Initiate Google OAuth flow",
|
|
||||||
description:
|
|
||||||
"This endpoint initiates the Google OAuth flow by redirecting the user to Google's authentication page.",
|
|
||||||
responses: {
|
|
||||||
200: {
|
|
||||||
description: "Google login URL created successfully.",
|
|
||||||
content: {
|
|
||||||
"application/json": {
|
|
||||||
schema: {
|
|
||||||
type: "object",
|
|
||||||
properties: {
|
|
||||||
success: {
|
|
||||||
type: "boolean",
|
|
||||||
default: true,
|
|
||||||
},
|
|
||||||
status: {
|
|
||||||
type: "number",
|
|
||||||
default: 200,
|
|
||||||
},
|
|
||||||
message: {
|
|
||||||
type: "string",
|
|
||||||
default: "Google login URL created successfully.",
|
|
||||||
},
|
|
||||||
data: {
|
|
||||||
type: "object",
|
|
||||||
properties: {
|
|
||||||
endpointUrl: {
|
|
||||||
type: "string",
|
|
||||||
description: "The URL to redirect the user for Google authentication.",
|
|
||||||
example:
|
|
||||||
"https://accounts.google.com/o/oauth2/v2/auth?client_id=YOUR_CLIENT_ID&redirect_uri=YOUR_REDIRECT_URI&response_type=code&scope=email%20profile",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
} satisfies AppRouteSchema;
|
|
||||||
@ -1,97 +0,0 @@
|
|||||||
import { AppRouteSchema } from "../../../helpers/types/AppRouteSchema";
|
|
||||||
|
|
||||||
export const logoutSchema = {
|
|
||||||
detail: {
|
|
||||||
summary: "Logout endpoint",
|
|
||||||
description: "Logs out the authenticated user by invalidating their session or token.",
|
|
||||||
responses: {
|
|
||||||
200: {
|
|
||||||
description: "Logout successful",
|
|
||||||
content: {
|
|
||||||
"application/json": {
|
|
||||||
schema: {
|
|
||||||
type: "object",
|
|
||||||
properties: {
|
|
||||||
success: {
|
|
||||||
type: "boolean",
|
|
||||||
example: true,
|
|
||||||
},
|
|
||||||
status: {
|
|
||||||
type: "number",
|
|
||||||
example: 200,
|
|
||||||
},
|
|
||||||
message: {
|
|
||||||
type: "string",
|
|
||||||
example: "Logout successful",
|
|
||||||
},
|
|
||||||
data: {
|
|
||||||
type: "object",
|
|
||||||
description: "Details about the logout operation. This only returned in development environment.",
|
|
||||||
properties: {
|
|
||||||
id: {
|
|
||||||
type: "string",
|
|
||||||
example: "123e4567-e89b-12d3-a456-426614174000",
|
|
||||||
},
|
|
||||||
isAuthenticated: {
|
|
||||||
type: "boolean",
|
|
||||||
example: false,
|
|
||||||
},
|
|
||||||
validUntil: {
|
|
||||||
type: "string",
|
|
||||||
format: "date-time",
|
|
||||||
example: "2024-12-31T23:59:59Z",
|
|
||||||
},
|
|
||||||
userId: {
|
|
||||||
type: "string",
|
|
||||||
example: "user_12345",
|
|
||||||
},
|
|
||||||
deletedAt: {
|
|
||||||
type: "string",
|
|
||||||
format: "date-time",
|
|
||||||
example: "2024-01-02T12:00:00Z",
|
|
||||||
},
|
|
||||||
createdAt: {
|
|
||||||
type: "string",
|
|
||||||
format: "date-time",
|
|
||||||
example: "2024-01-01T12:00:00Z",
|
|
||||||
},
|
|
||||||
updatedAt: {
|
|
||||||
type: "string",
|
|
||||||
format: "date-time",
|
|
||||||
example: "2024-01-02T12:00:00Z",
|
|
||||||
},
|
|
||||||
deviceType: {
|
|
||||||
type: "string",
|
|
||||||
example: "Desktop",
|
|
||||||
},
|
|
||||||
deviceOs: {
|
|
||||||
type: "string",
|
|
||||||
example: "Windows 10",
|
|
||||||
},
|
|
||||||
deviceIp: {
|
|
||||||
type: "string",
|
|
||||||
example: "192.168.1.1",
|
|
||||||
},
|
|
||||||
browser: {
|
|
||||||
type: "string",
|
|
||||||
example: "Chrome 89.0.4389.82",
|
|
||||||
},
|
|
||||||
isOnline: {
|
|
||||||
type: "boolean",
|
|
||||||
example: false,
|
|
||||||
},
|
|
||||||
lastOnline: {
|
|
||||||
type: "string",
|
|
||||||
format: "date-time",
|
|
||||||
example: "2024-01-02T12:00:00Z",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
} satisfies AppRouteSchema;
|
|
||||||
@ -1,22 +0,0 @@
|
|||||||
import { Context, Static } from "elysia";
|
|
||||||
import { returnWriteResponse } from "../../../helpers/callback/httpResponse";
|
|
||||||
import { addItemToCollectionBySytemSchema } from "../schemas/addItemToCollectionBySytem.schema";
|
|
||||||
import { addItemToCollectionBySystemService } from "../services/addItemToCollectionBySystem.service";
|
|
||||||
import { mainErrorHandler } from "../../../helpers/error/handler";
|
|
||||||
|
|
||||||
export const addItemToCollectionBySytemController = async (ctx: {
|
|
||||||
set: Context["set"];
|
|
||||||
headers: Static<typeof addItemToCollectionBySytemSchema.headers>;
|
|
||||||
body: Static<typeof addItemToCollectionBySytemSchema.body>;
|
|
||||||
}) => {
|
|
||||||
try {
|
|
||||||
const savedItem = await addItemToCollectionBySystemService({
|
|
||||||
cookie: ctx.headers.cookie,
|
|
||||||
collectionName: ctx.body.name,
|
|
||||||
mediaId: ctx.body.itemId,
|
|
||||||
});
|
|
||||||
return returnWriteResponse(ctx.set, 200, "Item added to collection successfully", savedItem);
|
|
||||||
} catch (error) {
|
|
||||||
return mainErrorHandler(ctx.set, error);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
@ -1,22 +0,0 @@
|
|||||||
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);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
@ -1,9 +0,0 @@
|
|||||||
import Elysia from "elysia";
|
|
||||||
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", addItemToCollectionBySytemController, addItemToCollectionBySytemSchema)
|
|
||||||
.delete("/sys", removeItemFromCollectionBySytemController, removeItemFromCollectionBySytemSchema);
|
|
||||||
@ -1,31 +0,0 @@
|
|||||||
import slugify from "slugify";
|
|
||||||
import { AppError } from "../../../helpers/error/instances/app";
|
|
||||||
import { prisma } from "../../../utils/databases/prisma/connection";
|
|
||||||
|
|
||||||
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", error);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
@ -1,60 +0,0 @@
|
|||||||
import slugify from "slugify";
|
|
||||||
import { AppError } from "../../../helpers/error/instances/app";
|
|
||||||
import { prisma } from "../../../utils/databases/prisma/connection";
|
|
||||||
import { generateUUIDv7 } from "../../../helpers/databases/uuidv7";
|
|
||||||
import { Prisma } from "@prisma/client";
|
|
||||||
|
|
||||||
export interface UpsertUserCollectionRepositoryPayload {
|
|
||||||
userId: string;
|
|
||||||
collectionName: string;
|
|
||||||
mediaConnectId: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export const upsertUserCollectionBySystemRepository = async (payload: UpsertUserCollectionRepositoryPayload) => {
|
|
||||||
try {
|
|
||||||
return await prisma.collection.upsert({
|
|
||||||
where: {
|
|
||||||
slug_ownerId: {
|
|
||||||
slug: slugify(payload.collectionName, { lower: true }),
|
|
||||||
ownerId: payload.userId,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
update: {
|
|
||||||
media_saved: {
|
|
||||||
create: {
|
|
||||||
id: generateUUIDv7(),
|
|
||||||
media: {
|
|
||||||
connect: {
|
|
||||||
id: payload.mediaConnectId,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
create: {
|
|
||||||
id: generateUUIDv7(),
|
|
||||||
name: payload.collectionName,
|
|
||||||
slug: slugify(payload.collectionName, { lower: true }),
|
|
||||||
owner: {
|
|
||||||
connect: {
|
|
||||||
id: payload.userId,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
media_saved: {
|
|
||||||
create: {
|
|
||||||
id: generateUUIDv7(),
|
|
||||||
media: {
|
|
||||||
connect: {
|
|
||||||
id: payload.mediaConnectId,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
} catch (error) {
|
|
||||||
if (error instanceof Prisma.PrismaClientKnownRequestError && error.code === "P2002")
|
|
||||||
throw new AppError(400, "Media item is already in the collection");
|
|
||||||
throw new AppError(500, "Failed to upsert user collection");
|
|
||||||
}
|
|
||||||
};
|
|
||||||
@ -1,33 +0,0 @@
|
|||||||
import { t } from "elysia";
|
|
||||||
import { AppRouteSchema } from "../../../helpers/types/AppRouteSchema";
|
|
||||||
|
|
||||||
export const addItemToCollectionBySytemSchema = {
|
|
||||||
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: "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;
|
|
||||||
@ -1,33 +0,0 @@
|
|||||||
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;
|
|
||||||
@ -1,24 +0,0 @@
|
|||||||
import { parse } from "cookie";
|
|
||||||
import { tokenValidationService } from "../../auth/services/http/tokenValidation.service";
|
|
||||||
import { ErrorForwarder } from "../../../helpers/error/instances/forwarder";
|
|
||||||
import { upsertUserCollectionBySystemRepository } from "../repositories/upsertUserCollectionBySystem.repository";
|
|
||||||
|
|
||||||
export type AddItemToCollectionPayload = {
|
|
||||||
cookie: string;
|
|
||||||
collectionName: string;
|
|
||||||
mediaId: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
export const addItemToCollectionBySystemService = async (payload: AddItemToCollectionPayload) => {
|
|
||||||
try {
|
|
||||||
const { auth_token } = parse(payload.cookie);
|
|
||||||
const userData = await tokenValidationService(auth_token as string);
|
|
||||||
return await upsertUserCollectionBySystemRepository({
|
|
||||||
userId: userData.user.id,
|
|
||||||
collectionName: payload.collectionName,
|
|
||||||
mediaConnectId: payload.mediaId,
|
|
||||||
});
|
|
||||||
} catch (error) {
|
|
||||||
ErrorForwarder(error);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
@ -1,24 +0,0 @@
|
|||||||
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);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
@ -1,14 +1,17 @@
|
|||||||
import { AppError } from "../../../../helpers/error/instances/app";
|
import { AppError } from "../../../../helpers/error/instances/app";
|
||||||
import { ErrorForwarder } from "../../../../helpers/error/instances/forwarder";
|
import { ErrorForwarder } from "../../../../helpers/error/instances/forwarder";
|
||||||
import { selectMediaIdFromSlugRepository } from "../../../media/repositories/SELECT/selectMediaIdFromSlug.repository";
|
import { getMediaIdFromSlugRepository } from "../../../media/repositories/GET/getMediaIdFromSlug.repository";
|
||||||
import { GetEpisodeDetailsParams } from "../../controllers/getEpisodeDetails.controller";
|
import { GetEpisodeDetailsParams } from "../../controllers/getEpisodeDetails.controller";
|
||||||
import { getEpisodeDetailsRepository } from "../../repositories/GET/getEpisodeDetails.repository";
|
import { getEpisodeDetailsRepository } from "../../repositories/GET/getEpisodeDetails.repository";
|
||||||
|
|
||||||
export const getEpisodeDetailsService = async (params: GetEpisodeDetailsParams) => {
|
export const getEpisodeDetailsService = async (
|
||||||
|
params: GetEpisodeDetailsParams,
|
||||||
|
) => {
|
||||||
try {
|
try {
|
||||||
if (!params.mediaSlug || !params.episode) throw new AppError(400, "Media slug and episode are required.");
|
if (!params.mediaSlug || !params.episode)
|
||||||
|
throw new AppError(400, "Media slug and episode are required.");
|
||||||
|
|
||||||
const mediaId = await selectMediaIdFromSlugRepository(params.mediaSlug);
|
const mediaId = await getMediaIdFromSlugRepository(params.mediaSlug);
|
||||||
if (!mediaId?.id) throw new AppError(404, "Media not found.");
|
if (!mediaId?.id) throw new AppError(404, "Media not found.");
|
||||||
|
|
||||||
const result = await getEpisodeDetailsRepository({
|
const result = await getEpisodeDetailsRepository({
|
||||||
|
|||||||
@ -1,8 +0,0 @@
|
|||||||
import { Context } from "elysia";
|
|
||||||
import { returnWriteResponse } from "../../../helpers/callback/httpResponse";
|
|
||||||
import { clearHeroBannerService } from "../services/clearHeroBanner.service";
|
|
||||||
|
|
||||||
export const clearHeroBannerController = async (ctx: { set: Context["set"] }) => {
|
|
||||||
const cacheCleared = await clearHeroBannerService();
|
|
||||||
return returnWriteResponse(ctx.set, 200, "Hero banner cache flushed successfully", cacheCleared);
|
|
||||||
};
|
|
||||||
@ -1,4 +0,0 @@
|
|||||||
import Elysia from "elysia";
|
|
||||||
import { clearHeroBannerController } from "./controllers/clearHeroBanner.controller";
|
|
||||||
|
|
||||||
export const flushCacheModule = new Elysia({ prefix: "/flush-cache" }).put("/hero-banner", clearHeroBannerController);
|
|
||||||
@ -1,12 +0,0 @@
|
|||||||
import { redisKey } from "../../../config/redis/key";
|
|
||||||
import { AppError } from "../../../helpers/error/instances/app";
|
|
||||||
import { redis } from "../../../utils/databases/redis/connection";
|
|
||||||
|
|
||||||
export const clearHeroBannerService = async () => {
|
|
||||||
try {
|
|
||||||
const cache = await redis.del(redisKey.find((key) => key.name === "HERO_BANNER")?.key || "");
|
|
||||||
return cache > 0; // Returns true if cache was cleared, false if it was not found
|
|
||||||
} catch (error) {
|
|
||||||
throw new AppError(500, "Failed to clear hero banner cache", error);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
@ -1,16 +1,17 @@
|
|||||||
import { Context, Static } from "elysia";
|
import { Context } from "elysia";
|
||||||
import { mainErrorHandler } from "../../../helpers/error/handler";
|
import { mainErrorHandler } from "../../../helpers/error/handler";
|
||||||
import { returnReadResponse } from "../../../helpers/callback/httpResponse";
|
import { returnReadResponse } from "../../../helpers/callback/httpResponse";
|
||||||
import { getActiveHeroBannerService } from "../services/getActiveHeroBanner.service";
|
import { getActiveHeroBannerService } from "../services/getActiveHeroBanner.service";
|
||||||
import { getActiveHeroBannerSchema } from "../schemas/getActiveHeroBanner.schema";
|
|
||||||
|
|
||||||
export const getActiveHeroBannerController = async (ctx: {
|
export const getActiveHeroBannerController = async (ctx: Context) => {
|
||||||
set: Context["set"];
|
|
||||||
header: Static<typeof getActiveHeroBannerSchema.headers>;
|
|
||||||
}) => {
|
|
||||||
try {
|
try {
|
||||||
const response = await getActiveHeroBannerService({ cookie: ctx.header?.cookie });
|
const response = await getActiveHeroBannerService();
|
||||||
return returnReadResponse(ctx.set, 200, "Active hero banners fetched successfully", response);
|
return returnReadResponse(
|
||||||
|
ctx.set,
|
||||||
|
200,
|
||||||
|
"Active hero banners fetched successfully",
|
||||||
|
response,
|
||||||
|
);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
return mainErrorHandler(ctx.set, error);
|
return mainErrorHandler(ctx.set, error);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
import { AppError } from "../../../../helpers/error/instances/app";
|
import { AppError } from "../../../../helpers/error/instances/app";
|
||||||
import { prisma } from "../../../../utils/databases/prisma/connection";
|
import { prisma } from "../../../../utils/databases/prisma/connection";
|
||||||
|
|
||||||
export const findAllActiveHeroBannerRepository = async (userId?: string) => {
|
export const findAllActiveHeroBannerRepository = async () => {
|
||||||
try {
|
try {
|
||||||
return await prisma.heroBanner.findMany({
|
return await prisma.heroBanner.findMany({
|
||||||
where: {
|
where: {
|
||||||
@ -20,36 +20,6 @@ export const findAllActiveHeroBannerRepository = async (userId?: string) => {
|
|||||||
startDate: "asc",
|
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,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
_count: {
|
|
||||||
select: {
|
|
||||||
inCollections: {
|
|
||||||
where: {
|
|
||||||
collection: {
|
|
||||||
ownerId: userId,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
throw new AppError(500, "Failed to fetch active hero banners", error);
|
throw new AppError(500, "Failed to fetch active hero banners", error);
|
||||||
|
|||||||
@ -1,8 +0,0 @@
|
|||||||
import { t } from "elysia";
|
|
||||||
import { AppRouteSchema } from "../../../helpers/types/AppRouteSchema";
|
|
||||||
|
|
||||||
export const getActiveHeroBannerSchema = {
|
|
||||||
headers: t.Object({
|
|
||||||
cookie: t.Optional(t.String()),
|
|
||||||
}),
|
|
||||||
} satisfies AppRouteSchema;
|
|
||||||
@ -1,44 +1,33 @@
|
|||||||
|
import { redisKey } from "../../../config/redis/key";
|
||||||
import { AppError } from "../../../helpers/error/instances/app";
|
import { AppError } from "../../../helpers/error/instances/app";
|
||||||
import { ErrorForwarder } from "../../../helpers/error/instances/forwarder";
|
import { ErrorForwarder } from "../../../helpers/error/instances/forwarder";
|
||||||
import { tokenValidationService } from "../../auth/services/http/tokenValidation.service";
|
import { redis } from "../../../utils/databases/redis/connection";
|
||||||
import { findSystemPreferenceService } from "../../systemPreference/services/internal/findSystemPreference.service";
|
import { findSystemPreferenceService } from "../../systemPreference/services/internal/findSystemPreference.service";
|
||||||
import { findAllActiveHeroBannerRepository } from "../repositories/GET/findAllActiveHeroBanner.repository";
|
import { findAllActiveHeroBannerRepository } from "../repositories/GET/findAllActiveHeroBanner.repository";
|
||||||
|
|
||||||
export const getActiveHeroBannerService = async ({ cookie }: { cookie?: string }) => {
|
export const getActiveHeroBannerService = async () => {
|
||||||
try {
|
try {
|
||||||
const userId = cookie ? (await tokenValidationService(cookie)).user.id : undefined;
|
|
||||||
|
|
||||||
// Check if Hero Banner is enabled in system preferences
|
// Check if Hero Banner is enabled in system preferences
|
||||||
const isHeroBannerEnabled = await findSystemPreferenceService("HERO_BANNER_ENABLED", "boolean");
|
const isHeroBannerEnabled = await findSystemPreferenceService(
|
||||||
if (!isHeroBannerEnabled) throw new AppError(403, "Hero Banner is disabled");
|
"HERO_BANNER_ENABLED",
|
||||||
|
"boolean",
|
||||||
|
);
|
||||||
|
if (!isHeroBannerEnabled)
|
||||||
|
throw new AppError(403, "Hero Banner is disabled");
|
||||||
|
|
||||||
// Don’t implement caching just yet; implement collection caching first, then implement banner caching.
|
// Try to get active banners from Redis cache
|
||||||
// Please note that currently, a database query is still required to check the collections.
|
const cachedBanners = await redis.get(
|
||||||
// // Try to get active banners from Redis cache
|
`${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 (cachedBanners) return JSON.parse(cachedBanners);
|
||||||
|
|
||||||
// If not in cache, fetch from database and cache the result
|
// If not in cache, fetch from database and cache the result
|
||||||
const activeBanners = await findAllActiveHeroBannerRepository(userId);
|
const activeBanners = await findAllActiveHeroBannerRepository();
|
||||||
const constructedBanners = activeBanners.map((banner) => ({
|
await redis.set(
|
||||||
id: banner.media.id,
|
`${redisKey.filter((key) => key.name === "HERO_BANNER")[0].key}`,
|
||||||
title: banner.media.title,
|
JSON.stringify(activeBanners),
|
||||||
slug: banner.media.slug,
|
);
|
||||||
imageUrl: banner.imageUrl || banner.media.pictureLarge,
|
return activeBanners;
|
||||||
synopsis: banner.media.synopsis,
|
|
||||||
genres: banner.media.genres.map((genre) => ({
|
|
||||||
slug: genre.slug,
|
|
||||||
name: genre.name,
|
|
||||||
})),
|
|
||||||
isInCollection: banner.media._count.inCollections > 0,
|
|
||||||
}));
|
|
||||||
|
|
||||||
// await redis.set(
|
|
||||||
// `${redisKey.filter((key) => key.name === "HERO_BANNER")[0].key}`,
|
|
||||||
// JSON.stringify(constructedBanners),
|
|
||||||
// );
|
|
||||||
|
|
||||||
return constructedBanners;
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
ErrorForwarder(error);
|
ErrorForwarder(error);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,12 +1,12 @@
|
|||||||
|
import { Prisma } from "@prisma/client";
|
||||||
import { AppError } from "../../../helpers/error/instances/app";
|
import { AppError } from "../../../helpers/error/instances/app";
|
||||||
import { prisma } from "../../../utils/databases/prisma/connection";
|
import { prisma } from "../../../utils/databases/prisma/connection";
|
||||||
import { generateUUIDv7 } from "../../../helpers/databases/uuidv7";
|
import { generateUUIDv7 } from "../../../helpers/databases/uuidv7";
|
||||||
import { SystemAccountId } from "../../../config/account/system";
|
import { SystemAccountId } from "../../../config/account/system";
|
||||||
import { Static } from "elysia";
|
|
||||||
import { createHeroBannerSchema } from "../schemas/createHeroBanner.schema";
|
|
||||||
import { Prisma } from "@prisma/client";
|
|
||||||
|
|
||||||
export const insertHeroBannerRepository = async (payload: Static<typeof createHeroBannerSchema.body>) => {
|
export const insertHeroBannerRepository = async (
|
||||||
|
payload: Omit<Prisma.HeroBannerCreateInput, "id" | "createdBy">,
|
||||||
|
) => {
|
||||||
try {
|
try {
|
||||||
return await prisma.heroBanner.create({
|
return await prisma.heroBanner.create({
|
||||||
data: {
|
data: {
|
||||||
@ -16,9 +16,6 @@ export const insertHeroBannerRepository = async (payload: Static<typeof createHe
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
if (error instanceof Prisma.PrismaClientKnownRequestError && error.code === "P2002") {
|
|
||||||
throw new AppError(400, "A hero banner with the order priority already exists", error);
|
|
||||||
}
|
|
||||||
throw new AppError(500, "Failed to insert hero banner", error);
|
throw new AppError(500, "Failed to insert hero banner", error);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@ -3,18 +3,45 @@ import { AppRouteSchema } from "../../../helpers/types/AppRouteSchema";
|
|||||||
|
|
||||||
export const createHeroBannerSchema = {
|
export const createHeroBannerSchema = {
|
||||||
body: t.Object({
|
body: t.Object({
|
||||||
orderPriority: t.Optional(
|
isClickable: t.Optional(
|
||||||
t.Number({ description: "The priority order of the hero banner. Lower numbers indicate higher priority." }),
|
t.Boolean({
|
||||||
),
|
description: "Indicates whether the hero banner is clickable",
|
||||||
mediaId: t.String({ description: "The ID of the media associated with the hero banner" }),
|
|
||||||
imageUrl: t.Optional(
|
|
||||||
t.String({
|
|
||||||
description:
|
|
||||||
"The URL of the image used in the hero banner. If not provided, a thumbnail image of the media will be used.",
|
|
||||||
}),
|
}),
|
||||||
),
|
),
|
||||||
startDate: t.Date({ description: "The start date for the hero banner in ISO 8601 format" }),
|
title: t.Optional(
|
||||||
endDate: t.Date({ description: "The end date for the hero banner in ISO 8601 format" }),
|
t.String({
|
||||||
|
description: "The title of the hero banner",
|
||||||
|
}),
|
||||||
|
),
|
||||||
|
tags: t.Array(t.String(), {
|
||||||
|
description: "An array of tags associated with the hero banner",
|
||||||
|
}),
|
||||||
|
description: t.Optional(
|
||||||
|
t.String({
|
||||||
|
description: "A brief description of the hero banner",
|
||||||
|
}),
|
||||||
|
),
|
||||||
|
buttonContent: t.Optional(
|
||||||
|
t.String({
|
||||||
|
description: "The text content of the button on the hero banner",
|
||||||
|
}),
|
||||||
|
),
|
||||||
|
buttonLink: t.Optional(
|
||||||
|
t.String({
|
||||||
|
description: "The URL that the button on the hero banner links to",
|
||||||
|
}),
|
||||||
|
),
|
||||||
|
imageUrl: t.Optional(
|
||||||
|
t.String({
|
||||||
|
description: "The URL of the image used in the hero banner",
|
||||||
|
}),
|
||||||
|
),
|
||||||
|
startDate: t.String({
|
||||||
|
description: "The start date for the hero banner in ISO 8601 format",
|
||||||
|
}),
|
||||||
|
endDate: t.String({
|
||||||
|
description: "The end date for the hero banner in ISO 8601 format",
|
||||||
|
}),
|
||||||
}),
|
}),
|
||||||
detail: {
|
detail: {
|
||||||
summary: "Create a new hero banner",
|
summary: "Create a new hero banner",
|
||||||
@ -37,16 +64,17 @@ export const createHeroBannerSchema = {
|
|||||||
"The created hero banner object. This field is returned only if the environment is running in development mode.",
|
"The created hero banner object. This field is returned only if the environment is running in development mode.",
|
||||||
properties: {
|
properties: {
|
||||||
id: { type: "string", description: "The ID of the created hero banner" },
|
id: { type: "string", description: "The ID of the created hero banner" },
|
||||||
orderPriority: {
|
isClickable: { type: "boolean", description: "Indicates whether the hero banner is clickable" },
|
||||||
type: "number",
|
title: { type: "string", description: "The title of the hero banner" },
|
||||||
description: "The priority order of the hero banner. Lower numbers indicate higher priority.",
|
tags: {
|
||||||
},
|
type: "array",
|
||||||
mediaId: { type: "string", description: "The ID of the media associated with the hero banner" },
|
items: { type: "string" },
|
||||||
imageUrl: {
|
description: "An array of tags associated with the hero banner",
|
||||||
type: "string",
|
|
||||||
description:
|
|
||||||
"The URL of the image used in the hero banner. If not provided, a thumbnail image of the media will be used.",
|
|
||||||
},
|
},
|
||||||
|
description: { type: "string", description: "A brief description of the hero banner" },
|
||||||
|
buttonContent: { type: "string", description: "The text content of the button on the hero banner" },
|
||||||
|
buttonLink: { type: "string", description: "The URL that the button on the hero banner links to" },
|
||||||
|
imageUrl: { type: "string", description: "The URL of the image used in the hero banner" },
|
||||||
startDate: {
|
startDate: {
|
||||||
type: "string",
|
type: "string",
|
||||||
format: "date-time",
|
format: "date-time",
|
||||||
|
|||||||
@ -1,20 +1,27 @@
|
|||||||
import { ErrorForwarder } from "../../../../helpers/error/instances/forwarder";
|
import { ErrorForwarder } from "../../../../helpers/error/instances/forwarder";
|
||||||
import { MediaEpisodeInfoResponse } from "../../types/mediaEpisodeInfo.type";
|
import { MediaEpisodeInfoResponse } from "../../types/mediaEpisodeInfo.type";
|
||||||
|
import { getMediaByMalIdRepository } from "../../../media/repositories/GET/getMediaByMalId.repository";
|
||||||
import { AppError } from "../../../../helpers/error/instances/app";
|
import { AppError } from "../../../../helpers/error/instances/app";
|
||||||
import { SystemAccountId } from "../../../../config/account/system";
|
import { SystemAccountId } from "../../../../config/account/system";
|
||||||
import { bulkInsertEpisodesRepository } from "../../repositories/bulkInsertEpisodes.repository";
|
import { bulkInsertEpisodesRepository } from "../../repositories/bulkInsertEpisodes.repository";
|
||||||
import { getEpisodeReferenceAPI } from "../../../../config/apis/jikan/episode.reference";
|
import { getEpisodeReferenceAPI } from "../../../../config/apis/jikan/episode.reference";
|
||||||
import { selectMediaByMalIdRepository } from "../../../media/repositories/SELECT/selectMediaByMalId.repository";
|
|
||||||
|
|
||||||
export const bulkInsertEpisodeService = async (mal_id: number, page: number = 1) => {
|
export const bulkInsertEpisodeService = async (
|
||||||
|
mal_id: number,
|
||||||
|
page: number = 1,
|
||||||
|
) => {
|
||||||
try {
|
try {
|
||||||
const episodeAPI = getEpisodeReferenceAPI(mal_id);
|
const episodeAPI = getEpisodeReferenceAPI(mal_id);
|
||||||
const episodeData: MediaEpisodeInfoResponse = await fetch(
|
const episodeData: MediaEpisodeInfoResponse = await fetch(
|
||||||
`${episodeAPI.baseURL}${episodeAPI.getEpisodeList}?page=${page}`,
|
`${episodeAPI.baseURL}${episodeAPI.getEpisodeList}?page=${page}`,
|
||||||
).then((res) => res.json());
|
).then((res) => res.json());
|
||||||
|
|
||||||
const mediaData = await selectMediaByMalIdRepository(mal_id);
|
const mediaData = await getMediaByMalIdRepository(mal_id);
|
||||||
if (!mediaData) throw new AppError(404, `Media with Mal ID ${mal_id} not found in database`);
|
if (!mediaData)
|
||||||
|
throw new AppError(
|
||||||
|
404,
|
||||||
|
`Media with Mal ID ${mal_id} not found in database`,
|
||||||
|
);
|
||||||
|
|
||||||
const insertedEpisodeData = [];
|
const insertedEpisodeData = [];
|
||||||
episodeData.data.forEach(async (episode) => {
|
episodeData.data.forEach(async (episode) => {
|
||||||
|
|||||||
@ -1,9 +1,10 @@
|
|||||||
import { Static } from "elysia";
|
|
||||||
import { ErrorForwarder } from "../../../../helpers/error/instances/forwarder";
|
import { ErrorForwarder } from "../../../../helpers/error/instances/forwarder";
|
||||||
|
import { CreateHeroBannerRequestBody } from "../../controllers/createHeroBanner.controller";
|
||||||
import { insertHeroBannerRepository } from "../../repositories/insertHeroBanner.repository";
|
import { insertHeroBannerRepository } from "../../repositories/insertHeroBanner.repository";
|
||||||
import { createHeroBannerSchema } from "../../schemas/createHeroBanner.schema";
|
|
||||||
|
|
||||||
export const createHeroBannerService = async (payload: Static<typeof createHeroBannerSchema.body>) => {
|
export const createHeroBannerService = async (
|
||||||
|
payload: CreateHeroBannerRequestBody,
|
||||||
|
) => {
|
||||||
try {
|
try {
|
||||||
return await insertHeroBannerRepository(payload);
|
return await insertHeroBannerRepository(payload);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
|||||||
@ -1,16 +1,19 @@
|
|||||||
import { Context, Static } from "elysia";
|
import { Context } from "elysia";
|
||||||
import { mainErrorHandler } from "../../../helpers/error/handler";
|
import { mainErrorHandler } from "../../../helpers/error/handler";
|
||||||
import { getAllMediaService } from "../services/http/getAllMedia.service";
|
import { getAllMediaService } from "../services/http/getAllMedia.service";
|
||||||
import { returnReadResponse } from "../../../helpers/callback/httpResponse";
|
import { returnReadResponse } from "../../../helpers/callback/httpResponse";
|
||||||
import { getAllMediaSchema } from "../schemas/getAllMedia.schema";
|
|
||||||
|
|
||||||
export const getAllMediaController = async (ctx: {
|
export const getAllMediaController = async (
|
||||||
set: Context["set"];
|
ctx: Context & { query: { page: string } },
|
||||||
query: Static<typeof getAllMediaSchema.query>;
|
) => {
|
||||||
}) => {
|
|
||||||
try {
|
try {
|
||||||
const mediaData = await getAllMediaService(ctx.query.page);
|
const mediaData = await getAllMediaService(ctx.query.page);
|
||||||
return returnReadResponse(ctx.set, 200, "Media fetched successfully", mediaData);
|
return returnReadResponse(
|
||||||
|
ctx.set,
|
||||||
|
200,
|
||||||
|
"Media fetched successfully",
|
||||||
|
mediaData,
|
||||||
|
);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
return mainErrorHandler(ctx.set, error);
|
return mainErrorHandler(ctx.set, error);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,17 +0,0 @@
|
|||||||
import { Context, Static } from "elysia";
|
|
||||||
import { mainErrorHandler } from "../../../helpers/error/handler";
|
|
||||||
import { getMediaBySlugSchema } from "../schemas/getMediaBySlug.schema";
|
|
||||||
import { getMediaBySlugService } from "../services/http/getMediaBySlug.service";
|
|
||||||
import { returnReadResponse } from "../../../helpers/callback/httpResponse";
|
|
||||||
|
|
||||||
export const getMediaBySlugController = async (ctx: {
|
|
||||||
set: Context["set"];
|
|
||||||
params: Static<typeof getMediaBySlugSchema.params>;
|
|
||||||
}) => {
|
|
||||||
try {
|
|
||||||
const mediaData = await getMediaBySlugService(ctx.params.slug);
|
|
||||||
return returnReadResponse(ctx.set, 200, "Media fetched successfully", mediaData);
|
|
||||||
} catch (error) {
|
|
||||||
return mainErrorHandler(ctx.set, error);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
@ -1,9 +1,7 @@
|
|||||||
import Elysia from "elysia";
|
import Elysia from "elysia";
|
||||||
import { getAllMediaController } from "./controllers/getAllMedia.controller";
|
import { getAllMediaController } from "./controllers/getAllMedia.controller";
|
||||||
import { getMediaBySlugController } from "./controllers/getMediaBySlug.controller";
|
|
||||||
import { getMediaBySlugSchema } from "./schemas/getMediaBySlug.schema";
|
|
||||||
import { getAllMediaSchema } from "./schemas/getAllMedia.schema";
|
|
||||||
|
|
||||||
export const mediaModule = new Elysia({ prefix: "/media", tags: ["Media"] })
|
export const mediaModule = new Elysia({ prefix: "/media" }).get(
|
||||||
.get("/", getAllMediaController, getAllMediaSchema)
|
"/",
|
||||||
.get("/:slug", getMediaBySlugController, getMediaBySlugSchema);
|
getAllMediaController,
|
||||||
|
);
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
import { AppError } from "../../../../helpers/error/instances/app";
|
import { AppError } from "../../../../helpers/error/instances/app";
|
||||||
import { mediaModel } from "../../model";
|
import { mediaModel } from "../../model";
|
||||||
|
|
||||||
export const selectAllMediaRepository = async (page: number) => {
|
export const getAllMediaRepository = async (page: number) => {
|
||||||
try {
|
try {
|
||||||
const limit = 10;
|
const limit = 10;
|
||||||
return await mediaModel.findMany({
|
return await mediaModel.findMany({
|
||||||
@ -1,7 +1,7 @@
|
|||||||
import { AppError } from "../../../../helpers/error/instances/app";
|
import { AppError } from "../../../../helpers/error/instances/app";
|
||||||
import { mediaModel } from "../../model";
|
import { mediaModel } from "../../model";
|
||||||
|
|
||||||
export const selectMediaByMalIdRepository = async (mal_id: number) => {
|
export const getMediaByMalIdRepository = async (mal_id: number) => {
|
||||||
try {
|
try {
|
||||||
return await mediaModel.findUnique({
|
return await mediaModel.findUnique({
|
||||||
where: { malId: mal_id },
|
where: { malId: mal_id },
|
||||||
@ -1,7 +1,7 @@
|
|||||||
import { AppError } from "../../../../helpers/error/instances/app";
|
import { AppError } from "../../../../helpers/error/instances/app";
|
||||||
import { mediaModel } from "../../model";
|
import { mediaModel } from "../../model";
|
||||||
|
|
||||||
export const selectMediaIdFromSlugRepository = async (slug: string) => {
|
export const getMediaIdFromSlugRepository = async (slug: string) => {
|
||||||
try {
|
try {
|
||||||
return await mediaModel.findUnique({
|
return await mediaModel.findUnique({
|
||||||
where: { slug },
|
where: { slug },
|
||||||
@ -1,12 +0,0 @@
|
|||||||
import { AppError } from "../../../../helpers/error/instances/app";
|
|
||||||
import { prisma } from "../../../../utils/databases/prisma/connection";
|
|
||||||
|
|
||||||
export const selectMediaBySlugRepository = async (slug: string) => {
|
|
||||||
try {
|
|
||||||
return await prisma.media.findUnique({
|
|
||||||
where: { slug },
|
|
||||||
});
|
|
||||||
} catch (error) {
|
|
||||||
throw new AppError(500, "Failed to fetch media by slug", error);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
@ -1,58 +0,0 @@
|
|||||||
import { t } from "elysia";
|
|
||||||
import { AppRouteSchema } from "../../../helpers/types/AppRouteSchema";
|
|
||||||
|
|
||||||
export const getAllMediaSchema = {
|
|
||||||
query: t.Object({
|
|
||||||
page: t.String({ description: "The page number for pagination", default: "1" }),
|
|
||||||
}),
|
|
||||||
detail: {
|
|
||||||
summary: "Fetch all media items with pagination",
|
|
||||||
description:
|
|
||||||
"Fetch a paginated list of all media items. The 'page' query parameter can be used to specify the page number for pagination.",
|
|
||||||
responses: {
|
|
||||||
200: {
|
|
||||||
description: "Media items fetched successfully",
|
|
||||||
content: {
|
|
||||||
"application/json": {
|
|
||||||
schema: {
|
|
||||||
type: "object",
|
|
||||||
properties: {
|
|
||||||
success: { type: "boolean", example: true },
|
|
||||||
status: { type: "number", example: 200 },
|
|
||||||
message: { type: "string", example: "Media fetched successfully" },
|
|
||||||
data: {
|
|
||||||
type: "array",
|
|
||||||
items: {
|
|
||||||
type: "object",
|
|
||||||
properties: {
|
|
||||||
status: { type: "string", example: "Finished Airing" },
|
|
||||||
id: { type: "string", example: "12345" },
|
|
||||||
title: { type: "string", example: "Example Media Title" },
|
|
||||||
slug: { type: "string", example: "example-media-title" },
|
|
||||||
malId: { type: "number", example: 67890 },
|
|
||||||
pictureMedium: { type: "string", example: "https://example.com/medium.jpg" },
|
|
||||||
pictureLarge: { type: "string", example: "https://example.com/large.jpg" },
|
|
||||||
country: { type: "string", example: "JP" },
|
|
||||||
score: { type: "number", example: 8.5 },
|
|
||||||
startAiring: { type: "string", format: "date-time", example: "2023-01-01T00:00:00Z" },
|
|
||||||
endAiring: { type: "string", format: "date-time", example: "2023-12-31T23:59:59Z" },
|
|
||||||
synopsis: { type: "string", example: "This is an example synopsis of the media item." },
|
|
||||||
ageRating: { type: "string", example: "PG-13" },
|
|
||||||
mediaType: { type: "string", example: "Anime" },
|
|
||||||
source: { type: "string", example: "Manga" },
|
|
||||||
onDraft: { type: "boolean", example: false },
|
|
||||||
uploadedBy: { type: "string", example: "admin" },
|
|
||||||
deletedAt: { type: "string", format: "date-time", nullable: true, example: null },
|
|
||||||
createdAt: { type: "string", format: "date-time", example: "2023-01-01T00:00:00Z" },
|
|
||||||
updatedAt: { type: "string", format: "date-time", example: "2023-01-02T00:00:00Z" },
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
} satisfies AppRouteSchema;
|
|
||||||
@ -1,29 +0,0 @@
|
|||||||
import { t } from "elysia";
|
|
||||||
import { AppRouteSchema } from "../../../helpers/types/AppRouteSchema";
|
|
||||||
|
|
||||||
export const getMediaBySlugSchema = {
|
|
||||||
params: t.Object({
|
|
||||||
slug: t.String({ description: "The slug of the media to fetch" }),
|
|
||||||
}),
|
|
||||||
detail: {
|
|
||||||
summary: "Fetch a media item by its slug",
|
|
||||||
description: "Fetch the specified media item using its slug. This endpoint returns the media details if found.",
|
|
||||||
responses: {
|
|
||||||
200: {
|
|
||||||
description: "Media item fetched successfully",
|
|
||||||
content: {
|
|
||||||
"application/json": {
|
|
||||||
schema: {
|
|
||||||
type: "object",
|
|
||||||
properties: {
|
|
||||||
success: { type: "boolean", example: true },
|
|
||||||
status: { type: "number", example: 200 },
|
|
||||||
message: { type: "string", example: "Media fetched successfully" },
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
} satisfies AppRouteSchema;
|
|
||||||
@ -1,11 +1,14 @@
|
|||||||
import { ErrorForwarder } from "../../../../helpers/error/instances/forwarder";
|
import { ErrorForwarder } from "../../../../helpers/error/instances/forwarder";
|
||||||
import { selectAllMediaRepository } from "../../repositories/SELECT/selectAllMedia.repository";
|
import { getAllMediaRepository } from "../../repositories/GET/getAllMedia.repository";
|
||||||
|
|
||||||
export const getAllMediaService = async (pagination: string) => {
|
export const getAllMediaService = async (pagination: string) => {
|
||||||
try {
|
try {
|
||||||
const page = /^\d+$/.test(pagination) && Number(pagination) > 0 ? Number(pagination) : 1;
|
const page =
|
||||||
|
/^\d+$/.test(pagination) && Number(pagination) > 0
|
||||||
|
? Number(pagination)
|
||||||
|
: 1;
|
||||||
|
|
||||||
return selectAllMediaRepository(page);
|
return getAllMediaRepository(page);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
ErrorForwarder(error);
|
ErrorForwarder(error);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,14 +0,0 @@
|
|||||||
import { AppError } from "../../../../helpers/error/instances/app";
|
|
||||||
import { ErrorForwarder } from "../../../../helpers/error/instances/forwarder";
|
|
||||||
import { selectMediaBySlugRepository } from "../../repositories/SELECT/selectMediaBySlug.repository";
|
|
||||||
|
|
||||||
export const getMediaBySlugService = async (slug: string) => {
|
|
||||||
try {
|
|
||||||
const mediaData = await selectMediaBySlugRepository(slug);
|
|
||||||
if (!mediaData) throw new AppError(404, "Media not found with the provided slug.");
|
|
||||||
|
|
||||||
return mediaData;
|
|
||||||
} catch (error) {
|
|
||||||
ErrorForwarder(error);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
Reference in New Issue
Block a user