Compare commits
34 Commits
27b66e6d34
...
refactor-d
| Author | SHA1 | Date | |
|---|---|---|---|
| 628ff9aeb7 | |||
| e10c57da1c | |||
| a1e059a99b | |||
| d0782710a5 | |||
| 1e34793d08 | |||
| 953530a119 | |||
| c754e7f039 | |||
| 6556ac8354 | |||
| 16d8c00d75 | |||
| e61686956b | |||
| baf7ba20b1 | |||
| 697f28de60 | |||
| 72f8e9e4eb | |||
| 59228f7d1e | |||
| b27479cd3e | |||
| 17eb272b1d | |||
| 697374d6cd | |||
| 5cebd200c4 | |||
| cef6da16cb | |||
| 412b501c80 | |||
| 68d834ae6b | |||
| 86fe39f5b5 | |||
| 73b22d7f2c | |||
| f1e79945b0 | |||
| 3768ae4c26 | |||
| 56c921e800 | |||
| e798338107 | |||
| dade012888 | |||
| 4001aec6ef | |||
| dd70f9f9d4 | |||
| 26909154ab | |||
| 7f6b1373f4 | |||
| 794a130562 | |||
| 6599fa8f79 |
@ -28,10 +28,11 @@ 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 {
|
||||||
@ -368,7 +369,7 @@ Table user_logs {
|
|||||||
Table collections {
|
Table collections {
|
||||||
id String [pk]
|
id String [pk]
|
||||||
name String [not null]
|
name String [not null]
|
||||||
medias medias [not null]
|
slug String [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']
|
||||||
@ -378,6 +379,24 @@ 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 {
|
||||||
@ -496,12 +515,8 @@ Table email_system_histories {
|
|||||||
Table hero_banner {
|
Table hero_banner {
|
||||||
id String [pk]
|
id String [pk]
|
||||||
orderPriority Int [unique]
|
orderPriority Int [unique]
|
||||||
isClickable Boolean [not null, default: false]
|
mediaId String [not null]
|
||||||
title String
|
media medias [not null]
|
||||||
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]
|
||||||
@ -560,9 +575,9 @@ Table MediaCharacters {
|
|||||||
mediasId String [ref: > medias.id]
|
mediasId String [ref: > medias.id]
|
||||||
}
|
}
|
||||||
|
|
||||||
Table MediaCollections {
|
Table CollectionMedia {
|
||||||
collectionsId String [ref: > collections.id]
|
incollectionsId String [ref: > CollectionMedia.id]
|
||||||
mediasId String [ref: > medias.id]
|
media_savedId String [ref: > CollectionMedia.id]
|
||||||
}
|
}
|
||||||
|
|
||||||
Table UserFavoriteGenres {
|
Table UserFavoriteGenres {
|
||||||
@ -750,6 +765,10 @@ 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
|
||||||
@ -780,6 +799,8 @@ 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
|
||||||
|
|||||||
5812
prisma/diagram.json
Normal file
5812
prisma/diagram.json
Normal file
File diff suppressed because it is too large
Load Diff
@ -1,864 +0,0 @@
|
|||||||
-- CreateSchema
|
|
||||||
CREATE SCHEMA IF NOT EXISTS "public";
|
|
||||||
|
|
||||||
-- CreateEnum
|
|
||||||
CREATE TYPE "MediaType" AS ENUM ('TV', 'ONA', 'OVA', 'Movie', 'Special', 'Music');
|
|
||||||
|
|
||||||
-- CreateEnum
|
|
||||||
CREATE TYPE "Country" AS ENUM ('Japanese', 'English', 'Indonesia', 'Korea');
|
|
||||||
|
|
||||||
-- CreateEnum
|
|
||||||
CREATE TYPE "CharacterRole" AS ENUM ('Main', 'Supporting');
|
|
||||||
|
|
||||||
-- CreateEnum
|
|
||||||
CREATE TYPE "MediaOperation" AS ENUM ('create', 'update', 'delete');
|
|
||||||
|
|
||||||
-- CreateEnum
|
|
||||||
CREATE TYPE "UserGender" AS ENUM ('male', 'female');
|
|
||||||
|
|
||||||
-- CreateEnum
|
|
||||||
CREATE TYPE "AdultFiltering" AS ENUM ('hide', 'show', 'explicit');
|
|
||||||
|
|
||||||
-- CreateEnum
|
|
||||||
CREATE TYPE "AdultAlert" AS ENUM ('hide', 'show');
|
|
||||||
|
|
||||||
-- CreateEnum
|
|
||||||
CREATE TYPE "VideoQuality" AS ENUM ('Q2160', 'Q1440', 'Q1080', 'Q720', 'Q480', 'Q360', 'Q240', 'Q144');
|
|
||||||
|
|
||||||
-- CreateEnum
|
|
||||||
CREATE TYPE "UserNotificationState" AS ENUM ('info', 'warning', 'danger');
|
|
||||||
|
|
||||||
-- CreateEnum
|
|
||||||
CREATE TYPE "ReportStatus" AS ENUM ('pending', 'resolved', 'rejected');
|
|
||||||
|
|
||||||
-- CreateEnum
|
|
||||||
CREATE TYPE "ReportReason" AS ENUM ('sexualize', 'violent', 'explicit', 'hateful', 'political', 'racist', 'spam', 'other');
|
|
||||||
|
|
||||||
-- CreateEnum
|
|
||||||
CREATE TYPE "AccessStatus" AS ENUM ('private', 'selected', 'protected', 'public');
|
|
||||||
|
|
||||||
-- CreateEnum
|
|
||||||
CREATE TYPE "AccessScope" AS ENUM ('viewer', 'editor');
|
|
||||||
|
|
||||||
-- CreateEnum
|
|
||||||
CREATE TYPE "MediaReviewReaction" AS ENUM ('angry', 'sad', 'awesome', 'happy', 'sleepy', 'annoyed', 'disgusting', 'disappointed');
|
|
||||||
|
|
||||||
-- CreateEnum
|
|
||||||
CREATE TYPE "EmailPorpose" AS ENUM ('forgot_password', 'account_activation', 'account_notification', 'subscribtion');
|
|
||||||
|
|
||||||
-- CreateEnum
|
|
||||||
CREATE TYPE "TypeSystemNotification" AS ENUM ('component', 'popup', 'toast');
|
|
||||||
|
|
||||||
-- CreateTable
|
|
||||||
CREATE TABLE "medias" (
|
|
||||||
"id" UUID NOT NULL,
|
|
||||||
"title" TEXT NOT NULL,
|
|
||||||
"titleAlternative" JSONB NOT NULL,
|
|
||||||
"slug" TEXT NOT NULL,
|
|
||||||
"malId" INTEGER,
|
|
||||||
"pictureMedium" TEXT NOT NULL,
|
|
||||||
"pictureLarge" TEXT NOT NULL,
|
|
||||||
"country" "Country" NOT NULL DEFAULT 'Japanese',
|
|
||||||
"score" DECIMAL(4,2) NOT NULL DEFAULT 0.00,
|
|
||||||
"status" TEXT NOT NULL,
|
|
||||||
"startAiring" TIMESTAMP(3),
|
|
||||||
"endAiring" TIMESTAMP(3),
|
|
||||||
"synopsis" TEXT NOT NULL,
|
|
||||||
"ageRating" TEXT NOT NULL,
|
|
||||||
"mediaType" "MediaType" NOT NULL,
|
|
||||||
"source" TEXT,
|
|
||||||
"onDraft" BOOLEAN NOT NULL DEFAULT true,
|
|
||||||
"uploadedBy" UUID NOT NULL,
|
|
||||||
"deletedAt" TIMESTAMP(3),
|
|
||||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
||||||
"updatedAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
||||||
|
|
||||||
CONSTRAINT "medias_pkey" PRIMARY KEY ("id")
|
|
||||||
);
|
|
||||||
|
|
||||||
-- CreateTable
|
|
||||||
CREATE TABLE "media_logs" (
|
|
||||||
"id" UUID NOT NULL,
|
|
||||||
"status" "MediaOperation" NOT NULL,
|
|
||||||
"approval" BOOLEAN NOT NULL DEFAULT false,
|
|
||||||
"proposedBy" UUID NOT NULL,
|
|
||||||
"approvedBy" UUID NOT NULL,
|
|
||||||
"mediaId" UUID NOT NULL,
|
|
||||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
||||||
"updatedAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
||||||
|
|
||||||
CONSTRAINT "media_logs_pkey" PRIMARY KEY ("id")
|
|
||||||
);
|
|
||||||
|
|
||||||
-- CreateTable
|
|
||||||
CREATE TABLE "genres" (
|
|
||||||
"id" UUID NOT NULL,
|
|
||||||
"name" VARCHAR(255) NOT NULL,
|
|
||||||
"slug" VARCHAR(255) NOT NULL,
|
|
||||||
"malId" INTEGER NOT NULL,
|
|
||||||
"malUrl" VARCHAR(255) NOT NULL,
|
|
||||||
"createdBy" UUID NOT NULL,
|
|
||||||
"deletedAt" TIMESTAMP(3),
|
|
||||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
||||||
"updatedAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
||||||
|
|
||||||
CONSTRAINT "genres_pkey" PRIMARY KEY ("id")
|
|
||||||
);
|
|
||||||
|
|
||||||
-- CreateTable
|
|
||||||
CREATE TABLE "studios" (
|
|
||||||
"id" UUID NOT NULL,
|
|
||||||
"name" VARCHAR(255) NOT NULL,
|
|
||||||
"slug" VARCHAR(255) NOT NULL,
|
|
||||||
"linkAbout" TEXT NOT NULL,
|
|
||||||
"malId" INTEGER NOT NULL,
|
|
||||||
"logoUrl" TEXT,
|
|
||||||
"createdBy" UUID NOT NULL,
|
|
||||||
"deletedAt" TIMESTAMP(3),
|
|
||||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
||||||
"updatedAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
||||||
|
|
||||||
CONSTRAINT "studios_pkey" PRIMARY KEY ("id")
|
|
||||||
);
|
|
||||||
|
|
||||||
-- CreateTable
|
|
||||||
CREATE TABLE "characters" (
|
|
||||||
"id" UUID NOT NULL,
|
|
||||||
"malId" INTEGER NOT NULL,
|
|
||||||
"name" TEXT NOT NULL,
|
|
||||||
"role" "CharacterRole" NOT NULL,
|
|
||||||
"favorites" INTEGER NOT NULL DEFAULT 0,
|
|
||||||
"imageUrl" TEXT,
|
|
||||||
"smallImageUrl" TEXT,
|
|
||||||
"creatorId" UUID NOT NULL,
|
|
||||||
"deletedAt" TIMESTAMP(3),
|
|
||||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
||||||
"updatedAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
||||||
|
|
||||||
CONSTRAINT "characters_pkey" PRIMARY KEY ("id")
|
|
||||||
);
|
|
||||||
|
|
||||||
-- CreateTable
|
|
||||||
CREATE TABLE "voice_actors" (
|
|
||||||
"id" UUID NOT NULL,
|
|
||||||
"malId" INTEGER NOT NULL,
|
|
||||||
"name" TEXT NOT NULL,
|
|
||||||
"birthday" TIMESTAMP(3),
|
|
||||||
"description" TEXT,
|
|
||||||
"aboutUrl" TEXT,
|
|
||||||
"imageUrl" TEXT,
|
|
||||||
"websiteUrl" TEXT,
|
|
||||||
"creatorId" UUID NOT NULL,
|
|
||||||
"deletedAt" TIMESTAMP(3),
|
|
||||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
||||||
"updatedAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
||||||
|
|
||||||
CONSTRAINT "voice_actors_pkey" PRIMARY KEY ("id")
|
|
||||||
);
|
|
||||||
|
|
||||||
-- CreateTable
|
|
||||||
CREATE TABLE "lang_va_char" (
|
|
||||||
"id" UUID NOT NULL,
|
|
||||||
"language" TEXT NOT NULL,
|
|
||||||
"vaId" UUID NOT NULL,
|
|
||||||
"charId" UUID NOT NULL,
|
|
||||||
"creatorId" UUID NOT NULL,
|
|
||||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
||||||
"updatedAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
||||||
|
|
||||||
CONSTRAINT "lang_va_char_pkey" PRIMARY KEY ("id")
|
|
||||||
);
|
|
||||||
|
|
||||||
-- CreateTable
|
|
||||||
CREATE TABLE "episodes" (
|
|
||||||
"id" UUID NOT NULL,
|
|
||||||
"mediaId" UUID NOT NULL,
|
|
||||||
"episode" INTEGER NOT NULL,
|
|
||||||
"name" VARCHAR(255) NOT NULL,
|
|
||||||
"score" DECIMAL(4,2) NOT NULL DEFAULT 0.00,
|
|
||||||
"pictureThumbnail" TEXT,
|
|
||||||
"viewed" BIGINT NOT NULL DEFAULT 0,
|
|
||||||
"likes" BIGINT NOT NULL DEFAULT 0,
|
|
||||||
"dislikes" BIGINT NOT NULL DEFAULT 0,
|
|
||||||
"pendingUpload" BOOLEAN NOT NULL DEFAULT true,
|
|
||||||
"uploadedBy" UUID NOT NULL,
|
|
||||||
"deletedAt" TIMESTAMP(3),
|
|
||||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
||||||
"updatedAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
||||||
|
|
||||||
CONSTRAINT "episodes_pkey" PRIMARY KEY ("id")
|
|
||||||
);
|
|
||||||
|
|
||||||
-- CreateTable
|
|
||||||
CREATE TABLE "episode_likes" (
|
|
||||||
"id" UUID NOT NULL,
|
|
||||||
"userId" UUID NOT NULL,
|
|
||||||
"sessionId" UUID NOT NULL,
|
|
||||||
"episodeId" UUID NOT NULL,
|
|
||||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
||||||
"updatedAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
||||||
|
|
||||||
CONSTRAINT "episode_likes_pkey" PRIMARY KEY ("id")
|
|
||||||
);
|
|
||||||
|
|
||||||
-- CreateTable
|
|
||||||
CREATE TABLE "videos" (
|
|
||||||
"id" UUID NOT NULL,
|
|
||||||
"episodeId" UUID NOT NULL,
|
|
||||||
"serviceId" UUID NOT NULL,
|
|
||||||
"code" VARCHAR(255) NOT NULL,
|
|
||||||
"pendingUpload" BOOLEAN NOT NULL DEFAULT true,
|
|
||||||
"uploadedBy" UUID NOT NULL,
|
|
||||||
"deletedAt" TIMESTAMP(3),
|
|
||||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
||||||
"updatedAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
||||||
|
|
||||||
CONSTRAINT "videos_pkey" PRIMARY KEY ("id")
|
|
||||||
);
|
|
||||||
|
|
||||||
-- CreateTable
|
|
||||||
CREATE TABLE "video_services" (
|
|
||||||
"id" UUID NOT NULL,
|
|
||||||
"name" VARCHAR(255) NOT NULL,
|
|
||||||
"domain" VARCHAR(255) NOT NULL,
|
|
||||||
"logo" TEXT,
|
|
||||||
"hexColor" VARCHAR(10) NOT NULL,
|
|
||||||
"endpointVideo" TEXT NOT NULL,
|
|
||||||
"endpointThumbnail" TEXT,
|
|
||||||
"endpointDownload" TEXT,
|
|
||||||
"createdBy" UUID NOT NULL,
|
|
||||||
"deletedAt" TIMESTAMP(3),
|
|
||||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
||||||
"updatedAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
||||||
|
|
||||||
CONSTRAINT "video_services_pkey" PRIMARY KEY ("id")
|
|
||||||
);
|
|
||||||
|
|
||||||
-- CreateTable
|
|
||||||
CREATE TABLE "users" (
|
|
||||||
"id" UUID NOT NULL,
|
|
||||||
"name" VARCHAR(255) NOT NULL,
|
|
||||||
"username" VARCHAR(255) NOT NULL,
|
|
||||||
"email" TEXT NOT NULL,
|
|
||||||
"password" TEXT NOT NULL,
|
|
||||||
"birthDate" DATE,
|
|
||||||
"gender" "UserGender",
|
|
||||||
"phoneCC" INTEGER,
|
|
||||||
"phoneNumber" INTEGER,
|
|
||||||
"bioProfile" TEXT,
|
|
||||||
"avatar" TEXT,
|
|
||||||
"commentBackground" TEXT,
|
|
||||||
"provider" VARCHAR(255),
|
|
||||||
"providerId" VARCHAR(255),
|
|
||||||
"providerToken" TEXT,
|
|
||||||
"providerPayload" JSON,
|
|
||||||
"verifiedAt" TIMESTAMP(3),
|
|
||||||
"disabledAt" TIMESTAMP(3),
|
|
||||||
"deletedAt" TIMESTAMP(3),
|
|
||||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
||||||
"updatedAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
||||||
|
|
||||||
CONSTRAINT "users_pkey" PRIMARY KEY ("id")
|
|
||||||
);
|
|
||||||
|
|
||||||
-- CreateTable
|
|
||||||
CREATE TABLE "user_preferences" (
|
|
||||||
"id" UUID NOT NULL,
|
|
||||||
"userId" UUID NOT NULL,
|
|
||||||
"langPreference" TEXT,
|
|
||||||
"adultFiltering" "AdultFiltering" NOT NULL DEFAULT 'hide',
|
|
||||||
"adultAlert" "AdultAlert" NOT NULL DEFAULT 'show',
|
|
||||||
"videoQuality" "VideoQuality" NOT NULL DEFAULT 'Q1080',
|
|
||||||
"serviceDefaultId" UUID,
|
|
||||||
"hideContries" "Country"[],
|
|
||||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
||||||
"updatedAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
||||||
|
|
||||||
CONSTRAINT "user_preferences_pkey" PRIMARY KEY ("id")
|
|
||||||
);
|
|
||||||
|
|
||||||
-- CreateTable
|
|
||||||
CREATE TABLE "user_roles" (
|
|
||||||
"id" UUID NOT NULL,
|
|
||||||
"name" VARCHAR(255) NOT NULL,
|
|
||||||
"description" TEXT,
|
|
||||||
"primaryColor" VARCHAR(10),
|
|
||||||
"secondaryColor" VARCHAR(10),
|
|
||||||
"pictureImage" TEXT,
|
|
||||||
"badgeImage" TEXT,
|
|
||||||
"isSuperadmin" BOOLEAN NOT NULL DEFAULT false,
|
|
||||||
"canEditMedia" BOOLEAN NOT NULL DEFAULT false,
|
|
||||||
"canManageMedia" BOOLEAN NOT NULL DEFAULT false,
|
|
||||||
"canEditEpisodes" BOOLEAN NOT NULL DEFAULT false,
|
|
||||||
"canManageEpisodes" BOOLEAN NOT NULL DEFAULT false,
|
|
||||||
"canEditComment" BOOLEAN NOT NULL DEFAULT false,
|
|
||||||
"canManageComment" BOOLEAN NOT NULL DEFAULT false,
|
|
||||||
"canEditUser" BOOLEAN NOT NULL DEFAULT false,
|
|
||||||
"canManageUser" BOOLEAN NOT NULL DEFAULT false,
|
|
||||||
"canEditSystem" BOOLEAN NOT NULL DEFAULT false,
|
|
||||||
"canManageSystem" BOOLEAN NOT NULL DEFAULT false,
|
|
||||||
"createdBy" UUID NOT NULL,
|
|
||||||
"deletedAt" TIMESTAMP(3),
|
|
||||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
||||||
"updatedAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
||||||
|
|
||||||
CONSTRAINT "user_roles_pkey" PRIMARY KEY ("id")
|
|
||||||
);
|
|
||||||
|
|
||||||
-- CreateTable
|
|
||||||
CREATE TABLE "user_role_assignments" (
|
|
||||||
"userId" UUID NOT NULL,
|
|
||||||
"roleId" UUID NOT NULL,
|
|
||||||
"assignmentAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
||||||
|
|
||||||
CONSTRAINT "user_role_assignments_pkey" PRIMARY KEY ("userId","roleId")
|
|
||||||
);
|
|
||||||
|
|
||||||
-- CreateTable
|
|
||||||
CREATE TABLE "user_notifications" (
|
|
||||||
"id" UUID NOT NULL,
|
|
||||||
"title" VARCHAR(255) NOT NULL,
|
|
||||||
"content" TEXT NOT NULL,
|
|
||||||
"picture" TEXT NOT NULL,
|
|
||||||
"state" "UserNotificationState" NOT NULL,
|
|
||||||
"ctaLink" TEXT NOT NULL,
|
|
||||||
"userId" UUID NOT NULL,
|
|
||||||
"isReaded" BOOLEAN NOT NULL DEFAULT false,
|
|
||||||
"deletedAt" TIMESTAMP(3),
|
|
||||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
||||||
"updatedAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
||||||
|
|
||||||
CONSTRAINT "user_notifications_pkey" PRIMARY KEY ("id")
|
|
||||||
);
|
|
||||||
|
|
||||||
-- CreateTable
|
|
||||||
CREATE TABLE "user_sessions" (
|
|
||||||
"id" UUID NOT NULL,
|
|
||||||
"isAuthenticated" BOOLEAN NOT NULL DEFAULT false,
|
|
||||||
"userId" UUID NOT NULL,
|
|
||||||
"deviceType" VARCHAR(255) NOT NULL,
|
|
||||||
"deviceOs" VARCHAR(255) NOT NULL,
|
|
||||||
"deviceIp" VARCHAR(255) NOT NULL,
|
|
||||||
"browser" VARCHAR(255) NOT NULL,
|
|
||||||
"isOnline" BOOLEAN NOT NULL DEFAULT false,
|
|
||||||
"lastOnline" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
||||||
"validUntil" TIMESTAMP(3) NOT NULL,
|
|
||||||
"deletedAt" TIMESTAMP(3),
|
|
||||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
||||||
"updatedAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
||||||
|
|
||||||
CONSTRAINT "user_sessions_pkey" PRIMARY KEY ("id")
|
|
||||||
);
|
|
||||||
|
|
||||||
-- CreateTable
|
|
||||||
CREATE TABLE "user_logs" (
|
|
||||||
"id" UUID NOT NULL,
|
|
||||||
"title" VARCHAR(255) NOT NULL,
|
|
||||||
"notes" TEXT NOT NULL,
|
|
||||||
"userId" UUID NOT NULL,
|
|
||||||
"sessionId" UUID NOT NULL,
|
|
||||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
||||||
"updatedAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
||||||
|
|
||||||
CONSTRAINT "user_logs_pkey" PRIMARY KEY ("id")
|
|
||||||
);
|
|
||||||
|
|
||||||
-- CreateTable
|
|
||||||
CREATE TABLE "collections" (
|
|
||||||
"id" UUID NOT NULL,
|
|
||||||
"name" VARCHAR(255) NOT NULL,
|
|
||||||
"ownerId" UUID NOT NULL,
|
|
||||||
"accessStatus" "AccessStatus" NOT NULL DEFAULT 'private',
|
|
||||||
"password" VARCHAR(255),
|
|
||||||
"accessScope" "AccessScope" NOT NULL DEFAULT 'viewer',
|
|
||||||
"deletedAt" TIMESTAMP(3),
|
|
||||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
||||||
"updatedAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
||||||
|
|
||||||
CONSTRAINT "collections_pkey" PRIMARY KEY ("id")
|
|
||||||
);
|
|
||||||
|
|
||||||
-- CreateTable
|
|
||||||
CREATE TABLE "watch_histories" (
|
|
||||||
"id" UUID NOT NULL,
|
|
||||||
"episodeId" UUID NOT NULL,
|
|
||||||
"userId" UUID NOT NULL,
|
|
||||||
"sessionId" UUID NOT NULL,
|
|
||||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
||||||
"updatedAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
||||||
|
|
||||||
CONSTRAINT "watch_histories_pkey" PRIMARY KEY ("id")
|
|
||||||
);
|
|
||||||
|
|
||||||
-- CreateTable
|
|
||||||
CREATE TABLE "movie_reviews" (
|
|
||||||
"id" UUID NOT NULL,
|
|
||||||
"mediaId" UUID NOT NULL,
|
|
||||||
"rating" INTEGER NOT NULL,
|
|
||||||
"title" VARCHAR(255) NOT NULL,
|
|
||||||
"text" TEXT NOT NULL,
|
|
||||||
"reaction" "MediaReviewReaction" NOT NULL,
|
|
||||||
"createdBy" UUID NOT NULL,
|
|
||||||
"deletedAt" TIMESTAMP(3),
|
|
||||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
||||||
"updatedAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
||||||
|
|
||||||
CONSTRAINT "movie_reviews_pkey" PRIMARY KEY ("id")
|
|
||||||
);
|
|
||||||
|
|
||||||
-- CreateTable
|
|
||||||
CREATE TABLE "comments" (
|
|
||||||
"id" UUID NOT NULL,
|
|
||||||
"episodeId" UUID NOT NULL,
|
|
||||||
"text" TEXT NOT NULL,
|
|
||||||
"isParent" BOOLEAN NOT NULL DEFAULT false,
|
|
||||||
"parentId" UUID,
|
|
||||||
"userId" UUID NOT NULL,
|
|
||||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
||||||
"updatedAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
||||||
|
|
||||||
CONSTRAINT "comments_pkey" PRIMARY KEY ("id")
|
|
||||||
);
|
|
||||||
|
|
||||||
-- CreateTable
|
|
||||||
CREATE TABLE "comment_likes" (
|
|
||||||
"id" UUID NOT NULL,
|
|
||||||
"commentId" UUID NOT NULL,
|
|
||||||
"userLiked" UUID NOT NULL,
|
|
||||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
||||||
"updatedAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
||||||
|
|
||||||
CONSTRAINT "comment_likes_pkey" PRIMARY KEY ("id")
|
|
||||||
);
|
|
||||||
|
|
||||||
-- CreateTable
|
|
||||||
CREATE TABLE "comment_reports" (
|
|
||||||
"id" UUID NOT NULL,
|
|
||||||
"userReporter" UUID NOT NULL,
|
|
||||||
"commentReported" UUID NOT NULL,
|
|
||||||
"isSupervisorReport" BOOLEAN NOT NULL DEFAULT false,
|
|
||||||
"reason" "ReportReason" NOT NULL,
|
|
||||||
"status" "ReportStatus" NOT NULL,
|
|
||||||
"description" VARCHAR(255) NOT NULL,
|
|
||||||
"approvedBy" UUID,
|
|
||||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
||||||
"updatedAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
||||||
|
|
||||||
CONSTRAINT "comment_reports_pkey" PRIMARY KEY ("id")
|
|
||||||
);
|
|
||||||
|
|
||||||
-- CreateTable
|
|
||||||
CREATE TABLE "languages" (
|
|
||||||
"id" UUID NOT NULL,
|
|
||||||
"name" VARCHAR(255) NOT NULL,
|
|
||||||
"code" VARCHAR(5) NOT NULL,
|
|
||||||
"countryFlag" VARCHAR(10) NOT NULL,
|
|
||||||
"fileLocation" TEXT NOT NULL,
|
|
||||||
"craetedBy" UUID NOT NULL,
|
|
||||||
"deletedAt" TIMESTAMP(3),
|
|
||||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
||||||
"updatedAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
||||||
|
|
||||||
CONSTRAINT "languages_pkey" PRIMARY KEY ("id")
|
|
||||||
);
|
|
||||||
|
|
||||||
-- CreateTable
|
|
||||||
CREATE TABLE "email_system_accounts" (
|
|
||||||
"id" UUID NOT NULL,
|
|
||||||
"name" TEXT NOT NULL,
|
|
||||||
"host" VARCHAR(255) NOT NULL,
|
|
||||||
"port" INTEGER NOT NULL,
|
|
||||||
"secure" BOOLEAN NOT NULL,
|
|
||||||
"email" VARCHAR(255) NOT NULL,
|
|
||||||
"username" VARCHAR(255) NOT NULL,
|
|
||||||
"password" VARCHAR(255) NOT NULL,
|
|
||||||
"purpose" "EmailPorpose" NOT NULL,
|
|
||||||
"createdBy" UUID NOT NULL,
|
|
||||||
"deletedAt" TIMESTAMP(3),
|
|
||||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
||||||
"updatedAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
||||||
|
|
||||||
CONSTRAINT "email_system_accounts_pkey" PRIMARY KEY ("id")
|
|
||||||
);
|
|
||||||
|
|
||||||
-- CreateTable
|
|
||||||
CREATE TABLE "email_system_histories" (
|
|
||||||
"id" UUID NOT NULL,
|
|
||||||
"purpose" "EmailPorpose" NOT NULL,
|
|
||||||
"fromEmail" TEXT NOT NULL,
|
|
||||||
"toEmail" TEXT NOT NULL,
|
|
||||||
"userRelated" UUID NOT NULL,
|
|
||||||
"title" VARCHAR(255) NOT NULL,
|
|
||||||
"htmlContent" TEXT NOT NULL,
|
|
||||||
"deletedAt" TIMESTAMP(3),
|
|
||||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
||||||
"updatedAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
||||||
|
|
||||||
CONSTRAINT "email_system_histories_pkey" PRIMARY KEY ("id")
|
|
||||||
);
|
|
||||||
|
|
||||||
-- CreateTable
|
|
||||||
CREATE TABLE "system_preferences" (
|
|
||||||
"id" UUID NOT NULL,
|
|
||||||
"key" VARCHAR(225) NOT NULL,
|
|
||||||
"value" VARCHAR(225) NOT NULL,
|
|
||||||
"description" TEXT NOT NULL,
|
|
||||||
"deletedAt" TIMESTAMP(3),
|
|
||||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
||||||
"updatedAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
||||||
|
|
||||||
CONSTRAINT "system_preferences_pkey" PRIMARY KEY ("id")
|
|
||||||
);
|
|
||||||
|
|
||||||
-- CreateTable
|
|
||||||
CREATE TABLE "system_notifications" (
|
|
||||||
"id" UUID NOT NULL,
|
|
||||||
"type" "TypeSystemNotification" NOT NULL,
|
|
||||||
"componentName" VARCHAR(255),
|
|
||||||
"popupImage" TEXT,
|
|
||||||
"titleToast" VARCHAR(255),
|
|
||||||
"contentToast" TEXT,
|
|
||||||
"createdBy" UUID NOT NULL,
|
|
||||||
"deletedAt" TIMESTAMP(3),
|
|
||||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
||||||
"updatedAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
||||||
|
|
||||||
CONSTRAINT "system_notifications_pkey" PRIMARY KEY ("id")
|
|
||||||
);
|
|
||||||
|
|
||||||
-- CreateTable
|
|
||||||
CREATE TABLE "system_logs" (
|
|
||||||
"id" UUID NOT NULL,
|
|
||||||
"title" VARCHAR(255) NOT NULL,
|
|
||||||
"notes" TEXT NOT NULL,
|
|
||||||
"relatedUser" UUID,
|
|
||||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
||||||
"updatedAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
||||||
|
|
||||||
CONSTRAINT "system_logs_pkey" PRIMARY KEY ("id")
|
|
||||||
);
|
|
||||||
|
|
||||||
-- CreateTable
|
|
||||||
CREATE TABLE "_MediaStudios" (
|
|
||||||
"A" UUID NOT NULL,
|
|
||||||
"B" UUID NOT NULL,
|
|
||||||
|
|
||||||
CONSTRAINT "_MediaStudios_AB_pkey" PRIMARY KEY ("A","B")
|
|
||||||
);
|
|
||||||
|
|
||||||
-- CreateTable
|
|
||||||
CREATE TABLE "_MediaGenres" (
|
|
||||||
"A" UUID NOT NULL,
|
|
||||||
"B" UUID NOT NULL,
|
|
||||||
|
|
||||||
CONSTRAINT "_MediaGenres_AB_pkey" PRIMARY KEY ("A","B")
|
|
||||||
);
|
|
||||||
|
|
||||||
-- CreateTable
|
|
||||||
CREATE TABLE "_UserFavoriteGenres" (
|
|
||||||
"A" UUID NOT NULL,
|
|
||||||
"B" UUID NOT NULL,
|
|
||||||
|
|
||||||
CONSTRAINT "_UserFavoriteGenres_AB_pkey" PRIMARY KEY ("A","B")
|
|
||||||
);
|
|
||||||
|
|
||||||
-- CreateTable
|
|
||||||
CREATE TABLE "_MediaCharacters" (
|
|
||||||
"A" UUID NOT NULL,
|
|
||||||
"B" UUID NOT NULL,
|
|
||||||
|
|
||||||
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
|
|
||||||
CREATE TABLE "_UserSelectedSharingCollention" (
|
|
||||||
"A" UUID NOT NULL,
|
|
||||||
"B" UUID NOT NULL,
|
|
||||||
|
|
||||||
CONSTRAINT "_UserSelectedSharingCollention_AB_pkey" PRIMARY KEY ("A","B")
|
|
||||||
);
|
|
||||||
|
|
||||||
-- CreateIndex
|
|
||||||
CREATE UNIQUE INDEX "medias_slug_key" ON "medias"("slug");
|
|
||||||
|
|
||||||
-- CreateIndex
|
|
||||||
CREATE UNIQUE INDEX "medias_malId_key" ON "medias"("malId");
|
|
||||||
|
|
||||||
-- CreateIndex
|
|
||||||
CREATE INDEX "medias_status_onDraft_deletedAt_idx" ON "medias"("status", "onDraft", "deletedAt");
|
|
||||||
|
|
||||||
-- CreateIndex
|
|
||||||
CREATE INDEX "medias_mediaType_idx" ON "medias"("mediaType");
|
|
||||||
|
|
||||||
-- CreateIndex
|
|
||||||
CREATE INDEX "medias_uploadedBy_idx" ON "medias"("uploadedBy");
|
|
||||||
|
|
||||||
-- CreateIndex
|
|
||||||
CREATE INDEX "medias_createdAt_idx" ON "medias"("createdAt");
|
|
||||||
|
|
||||||
-- CreateIndex
|
|
||||||
CREATE UNIQUE INDEX "genres_slug_key" ON "genres"("slug");
|
|
||||||
|
|
||||||
-- CreateIndex
|
|
||||||
CREATE UNIQUE INDEX "genres_malId_key" ON "genres"("malId");
|
|
||||||
|
|
||||||
-- CreateIndex
|
|
||||||
CREATE UNIQUE INDEX "studios_slug_key" ON "studios"("slug");
|
|
||||||
|
|
||||||
-- CreateIndex
|
|
||||||
CREATE UNIQUE INDEX "studios_malId_key" ON "studios"("malId");
|
|
||||||
|
|
||||||
-- CreateIndex
|
|
||||||
CREATE UNIQUE INDEX "characters_malId_key" ON "characters"("malId");
|
|
||||||
|
|
||||||
-- CreateIndex
|
|
||||||
CREATE UNIQUE INDEX "voice_actors_malId_key" ON "voice_actors"("malId");
|
|
||||||
|
|
||||||
-- CreateIndex
|
|
||||||
CREATE UNIQUE INDEX "lang_va_char_language_vaId_charId_key" ON "lang_va_char"("language", "vaId", "charId");
|
|
||||||
|
|
||||||
-- CreateIndex
|
|
||||||
CREATE UNIQUE INDEX "episodes_mediaId_episode_key" ON "episodes"("mediaId", "episode");
|
|
||||||
|
|
||||||
-- CreateIndex
|
|
||||||
CREATE UNIQUE INDEX "videos_serviceId_code_key" ON "videos"("serviceId", "code");
|
|
||||||
|
|
||||||
-- CreateIndex
|
|
||||||
CREATE UNIQUE INDEX "video_services_name_key" ON "video_services"("name");
|
|
||||||
|
|
||||||
-- CreateIndex
|
|
||||||
CREATE UNIQUE INDEX "users_username_key" ON "users"("username");
|
|
||||||
|
|
||||||
-- CreateIndex
|
|
||||||
CREATE UNIQUE INDEX "users_email_key" ON "users"("email");
|
|
||||||
|
|
||||||
-- CreateIndex
|
|
||||||
CREATE UNIQUE INDEX "users_providerId_key" ON "users"("providerId");
|
|
||||||
|
|
||||||
-- CreateIndex
|
|
||||||
CREATE UNIQUE INDEX "user_preferences_userId_key" ON "user_preferences"("userId");
|
|
||||||
|
|
||||||
-- CreateIndex
|
|
||||||
CREATE UNIQUE INDEX "user_roles_name_key" ON "user_roles"("name");
|
|
||||||
|
|
||||||
-- CreateIndex
|
|
||||||
CREATE INDEX "user_sessions_userId_isAuthenticated_deletedAt_idx" ON "user_sessions"("userId", "isAuthenticated", "deletedAt");
|
|
||||||
|
|
||||||
-- CreateIndex
|
|
||||||
CREATE UNIQUE INDEX "languages_code_key" ON "languages"("code");
|
|
||||||
|
|
||||||
-- CreateIndex
|
|
||||||
CREATE UNIQUE INDEX "email_system_accounts_name_key" ON "email_system_accounts"("name");
|
|
||||||
|
|
||||||
-- CreateIndex
|
|
||||||
CREATE UNIQUE INDEX "email_system_accounts_email_key" ON "email_system_accounts"("email");
|
|
||||||
|
|
||||||
-- CreateIndex
|
|
||||||
CREATE UNIQUE INDEX "email_system_accounts_username_key" ON "email_system_accounts"("username");
|
|
||||||
|
|
||||||
-- CreateIndex
|
|
||||||
CREATE INDEX "_MediaStudios_B_index" ON "_MediaStudios"("B");
|
|
||||||
|
|
||||||
-- CreateIndex
|
|
||||||
CREATE INDEX "_MediaGenres_B_index" ON "_MediaGenres"("B");
|
|
||||||
|
|
||||||
-- CreateIndex
|
|
||||||
CREATE INDEX "_UserFavoriteGenres_B_index" ON "_UserFavoriteGenres"("B");
|
|
||||||
|
|
||||||
-- CreateIndex
|
|
||||||
CREATE INDEX "_MediaCharacters_B_index" ON "_MediaCharacters"("B");
|
|
||||||
|
|
||||||
-- CreateIndex
|
|
||||||
CREATE INDEX "_MediaCollections_B_index" ON "_MediaCollections"("B");
|
|
||||||
|
|
||||||
-- CreateIndex
|
|
||||||
CREATE INDEX "_UserSelectedSharingCollention_B_index" ON "_UserSelectedSharingCollention"("B");
|
|
||||||
|
|
||||||
-- AddForeignKey
|
|
||||||
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
|
|
||||||
ALTER TABLE "media_logs" ADD CONSTRAINT "media_logs_approvedBy_fkey" FOREIGN KEY ("approvedBy") REFERENCES "users"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
|
||||||
|
|
||||||
-- AddForeignKey
|
|
||||||
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 "genres" ADD CONSTRAINT "genres_createdBy_fkey" FOREIGN KEY ("createdBy") REFERENCES "users"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
|
||||||
|
|
||||||
-- AddForeignKey
|
|
||||||
ALTER TABLE "studios" ADD CONSTRAINT "studios_createdBy_fkey" FOREIGN KEY ("createdBy") REFERENCES "users"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
|
||||||
|
|
||||||
-- AddForeignKey
|
|
||||||
ALTER TABLE "characters" ADD CONSTRAINT "characters_creatorId_fkey" FOREIGN KEY ("creatorId") REFERENCES "users"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
|
||||||
|
|
||||||
-- AddForeignKey
|
|
||||||
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
|
|
||||||
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
|
|
||||||
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 "episodes" ADD CONSTRAINT "episodes_mediaId_fkey" FOREIGN KEY ("mediaId") REFERENCES "medias"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
|
||||||
|
|
||||||
-- AddForeignKey
|
|
||||||
ALTER TABLE "episodes" ADD CONSTRAINT "episodes_uploadedBy_fkey" FOREIGN KEY ("uploadedBy") REFERENCES "users"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
|
||||||
|
|
||||||
-- AddForeignKey
|
|
||||||
ALTER TABLE "episode_likes" ADD CONSTRAINT "episode_likes_userId_fkey" FOREIGN KEY ("userId") REFERENCES "users"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
|
||||||
|
|
||||||
-- AddForeignKey
|
|
||||||
ALTER TABLE "episode_likes" ADD CONSTRAINT "episode_likes_sessionId_fkey" FOREIGN KEY ("sessionId") REFERENCES "user_sessions"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
|
||||||
|
|
||||||
-- AddForeignKey
|
|
||||||
ALTER TABLE "episode_likes" ADD CONSTRAINT "episode_likes_episodeId_fkey" FOREIGN KEY ("episodeId") REFERENCES "episodes"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
|
||||||
|
|
||||||
-- AddForeignKey
|
|
||||||
ALTER TABLE "videos" ADD CONSTRAINT "videos_episodeId_fkey" FOREIGN KEY ("episodeId") REFERENCES "episodes"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
|
||||||
|
|
||||||
-- AddForeignKey
|
|
||||||
ALTER TABLE "videos" ADD CONSTRAINT "videos_serviceId_fkey" FOREIGN KEY ("serviceId") REFERENCES "video_services"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
|
||||||
|
|
||||||
-- AddForeignKey
|
|
||||||
ALTER TABLE "videos" ADD CONSTRAINT "videos_uploadedBy_fkey" FOREIGN KEY ("uploadedBy") REFERENCES "users"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
|
||||||
|
|
||||||
-- AddForeignKey
|
|
||||||
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
|
|
||||||
ALTER TABLE "user_preferences" ADD CONSTRAINT "user_preferences_langPreference_fkey" FOREIGN KEY ("langPreference") REFERENCES "languages"("code") ON DELETE SET NULL ON UPDATE CASCADE;
|
|
||||||
|
|
||||||
-- 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;
|
|
||||||
|
|
||||||
-- AddForeignKey
|
|
||||||
ALTER TABLE "user_roles" ADD CONSTRAINT "user_roles_createdBy_fkey" FOREIGN KEY ("createdBy") REFERENCES "users"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
|
||||||
|
|
||||||
-- 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;
|
|
||||||
|
|
||||||
-- 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;
|
|
||||||
|
|
||||||
-- AddForeignKey
|
|
||||||
ALTER TABLE "user_notifications" ADD CONSTRAINT "user_notifications_userId_fkey" FOREIGN KEY ("userId") REFERENCES "users"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
|
||||||
|
|
||||||
-- AddForeignKey
|
|
||||||
ALTER TABLE "user_sessions" ADD CONSTRAINT "user_sessions_userId_fkey" FOREIGN KEY ("userId") REFERENCES "users"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
|
||||||
|
|
||||||
-- AddForeignKey
|
|
||||||
ALTER TABLE "user_logs" ADD CONSTRAINT "user_logs_userId_fkey" FOREIGN KEY ("userId") REFERENCES "users"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
|
||||||
|
|
||||||
-- AddForeignKey
|
|
||||||
ALTER TABLE "user_logs" ADD CONSTRAINT "user_logs_sessionId_fkey" FOREIGN KEY ("sessionId") REFERENCES "user_sessions"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
|
||||||
|
|
||||||
-- AddForeignKey
|
|
||||||
ALTER TABLE "collections" ADD CONSTRAINT "collections_ownerId_fkey" FOREIGN KEY ("ownerId") REFERENCES "users"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
|
||||||
|
|
||||||
-- AddForeignKey
|
|
||||||
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_userId_fkey" FOREIGN KEY ("userId") REFERENCES "users"("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
|
|
||||||
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
|
|
||||||
ALTER TABLE "comments" ADD CONSTRAINT "comments_episodeId_fkey" FOREIGN KEY ("episodeId") REFERENCES "episodes"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
|
||||||
|
|
||||||
-- AddForeignKey
|
|
||||||
ALTER TABLE "comments" ADD CONSTRAINT "comments_parentId_fkey" FOREIGN KEY ("parentId") REFERENCES "comments"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|
|
||||||
|
|
||||||
-- AddForeignKey
|
|
||||||
ALTER TABLE "comments" ADD CONSTRAINT "comments_userId_fkey" FOREIGN KEY ("userId") REFERENCES "users"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
|
||||||
|
|
||||||
-- AddForeignKey
|
|
||||||
ALTER TABLE "comment_likes" ADD CONSTRAINT "comment_likes_commentId_fkey" FOREIGN KEY ("commentId") REFERENCES "comments"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
|
||||||
|
|
||||||
-- AddForeignKey
|
|
||||||
ALTER TABLE "comment_likes" ADD CONSTRAINT "comment_likes_userLiked_fkey" FOREIGN KEY ("userLiked") REFERENCES "users"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
|
||||||
|
|
||||||
-- AddForeignKey
|
|
||||||
ALTER TABLE "comment_reports" ADD CONSTRAINT "comment_reports_userReporter_fkey" FOREIGN KEY ("userReporter") REFERENCES "users"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
|
||||||
|
|
||||||
-- AddForeignKey
|
|
||||||
ALTER TABLE "comment_reports" ADD CONSTRAINT "comment_reports_approvedBy_fkey" FOREIGN KEY ("approvedBy") REFERENCES "users"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|
|
||||||
|
|
||||||
-- AddForeignKey
|
|
||||||
ALTER TABLE "languages" ADD CONSTRAINT "languages_craetedBy_fkey" FOREIGN KEY ("craetedBy") REFERENCES "users"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
|
||||||
|
|
||||||
-- AddForeignKey
|
|
||||||
ALTER TABLE "email_system_accounts" ADD CONSTRAINT "email_system_accounts_createdBy_fkey" FOREIGN KEY ("createdBy") REFERENCES "users"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
|
||||||
|
|
||||||
-- 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;
|
|
||||||
|
|
||||||
-- AddForeignKey
|
|
||||||
ALTER TABLE "system_notifications" ADD CONSTRAINT "system_notifications_createdBy_fkey" FOREIGN KEY ("createdBy") REFERENCES "users"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
|
||||||
|
|
||||||
-- AddForeignKey
|
|
||||||
ALTER TABLE "system_logs" ADD CONSTRAINT "system_logs_relatedUser_fkey" FOREIGN KEY ("relatedUser") REFERENCES "users"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|
|
||||||
|
|
||||||
-- AddForeignKey
|
|
||||||
ALTER TABLE "_MediaStudios" ADD CONSTRAINT "_MediaStudios_A_fkey" FOREIGN KEY ("A") REFERENCES "medias"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
|
||||||
|
|
||||||
-- AddForeignKey
|
|
||||||
ALTER TABLE "_MediaStudios" ADD CONSTRAINT "_MediaStudios_B_fkey" FOREIGN KEY ("B") REFERENCES "studios"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
|
||||||
|
|
||||||
-- AddForeignKey
|
|
||||||
ALTER TABLE "_MediaGenres" ADD CONSTRAINT "_MediaGenres_A_fkey" FOREIGN KEY ("A") REFERENCES "genres"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
|
||||||
|
|
||||||
-- AddForeignKey
|
|
||||||
ALTER TABLE "_MediaGenres" ADD CONSTRAINT "_MediaGenres_B_fkey" FOREIGN KEY ("B") REFERENCES "medias"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
|
||||||
|
|
||||||
-- AddForeignKey
|
|
||||||
ALTER TABLE "_UserFavoriteGenres" ADD CONSTRAINT "_UserFavoriteGenres_A_fkey" FOREIGN KEY ("A") REFERENCES "genres"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
|
||||||
|
|
||||||
-- AddForeignKey
|
|
||||||
ALTER TABLE "_UserFavoriteGenres" ADD CONSTRAINT "_UserFavoriteGenres_B_fkey" FOREIGN KEY ("B") REFERENCES "user_preferences"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
|
||||||
|
|
||||||
-- AddForeignKey
|
|
||||||
ALTER TABLE "_MediaCharacters" ADD CONSTRAINT "_MediaCharacters_A_fkey" FOREIGN KEY ("A") REFERENCES "characters"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
|
||||||
|
|
||||||
-- AddForeignKey
|
|
||||||
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
|
|
||||||
ALTER TABLE "_UserSelectedSharingCollention" ADD CONSTRAINT "_UserSelectedSharingCollention_A_fkey" FOREIGN KEY ("A") REFERENCES "collections"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
|
||||||
|
|
||||||
-- AddForeignKey
|
|
||||||
ALTER TABLE "_UserSelectedSharingCollention" ADD CONSTRAINT "_UserSelectedSharingCollention_B_fkey" FOREIGN KEY ("B") REFERENCES "users"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
|
||||||
|
|
||||||
@ -1,17 +0,0 @@
|
|||||||
/*
|
|
||||||
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");
|
|
||||||
@ -1,2 +0,0 @@
|
|||||||
-- AlterTable
|
|
||||||
ALTER TABLE "videos" ADD COLUMN "thumbnailCode" TEXT;
|
|
||||||
@ -1,20 +0,0 @@
|
|||||||
-- 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;
|
|
||||||
@ -1,32 +0,0 @@
|
|||||||
/*
|
|
||||||
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;
|
|
||||||
@ -1,11 +0,0 @@
|
|||||||
/*
|
|
||||||
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");
|
|
||||||
@ -1,16 +0,0 @@
|
|||||||
/*
|
|
||||||
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");
|
|
||||||
@ -1,2 +0,0 @@
|
|||||||
-- AlterTable
|
|
||||||
ALTER TABLE "hero_banner" ADD COLUMN "tags" TEXT[];
|
|
||||||
@ -1,8 +0,0 @@
|
|||||||
/*
|
|
||||||
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,3 +0,0 @@
|
|||||||
# Please do not edit this file manually
|
|
||||||
# It should be added in your version-control system (e.g., Git)
|
|
||||||
provider = "postgresql"
|
|
||||||
@ -1,733 +1,11 @@
|
|||||||
// This is your Prisma schema file,
|
generator client {
|
||||||
// learn more about it in the docs: https://pris.ly/d/prisma-schema
|
provider = "prisma-client-js"
|
||||||
|
}
|
||||||
// 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
|
generator dbml {
|
||||||
|
provider = "prisma-dbml-generator"
|
||||||
|
}
|
||||||
//// Prisma Configuration ////
|
|
||||||
|
datasource db {
|
||||||
generator client {
|
provider = "postgresql"
|
||||||
provider = "prisma-client-js"
|
}
|
||||||
}
|
|
||||||
datasource db {
|
|
||||||
provider = "postgresql"
|
|
||||||
}
|
|
||||||
|
|
||||||
generator dbml {
|
|
||||||
provider = "prisma-dbml-generator"
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//// Prisma Model ////
|
|
||||||
|
|
||||||
model Media {
|
|
||||||
id String @id @db.Uuid
|
|
||||||
title String @db.Text
|
|
||||||
titleAlternative Json
|
|
||||||
slug String @db.Text @unique
|
|
||||||
malId Int? @unique
|
|
||||||
pictureMedium String @db.Text
|
|
||||||
pictureLarge String @db.Text
|
|
||||||
genres Genre[] @relation("MediaGenres")
|
|
||||||
country Country @default(JP)
|
|
||||||
score Decimal @db.Decimal(4, 2) @default(0.00)
|
|
||||||
status String
|
|
||||||
startAiring DateTime?
|
|
||||||
endAiring DateTime?
|
|
||||||
synopsis String @db.Text
|
|
||||||
ageRating String
|
|
||||||
mediaType MediaType
|
|
||||||
source String?
|
|
||||||
studios Studio[] @relation("MediaStudios")
|
|
||||||
characters Character[] @relation("MediaCharacters")
|
|
||||||
onDraft Boolean @default(true)
|
|
||||||
uploader User @relation("UserUploadedMedias", fields: [uploadedBy], references: [id])
|
|
||||||
uploadedBy String @db.Uuid
|
|
||||||
deletedAt DateTime?
|
|
||||||
createdAt DateTime @default(now())
|
|
||||||
updatedAt DateTime @default(now()) @updatedAt
|
|
||||||
|
|
||||||
bannerPromotion HeroBanner[] @relation("MediaBannerPromotion")
|
|
||||||
logs MediaLog[] @relation("MediaLogs")
|
|
||||||
episodes Episode[] @relation("MediaEpisodes")
|
|
||||||
collections Collection[] @relation("MediaCollections")
|
|
||||||
reviews MediaReview[] @relation("MediaReviews")
|
|
||||||
|
|
||||||
@@index([status, onDraft, deletedAt])
|
|
||||||
@@index([mediaType])
|
|
||||||
@@index([uploadedBy])
|
|
||||||
@@index([createdAt])
|
|
||||||
@@map("medias")
|
|
||||||
}
|
|
||||||
|
|
||||||
model MediaLog {
|
|
||||||
id String @id @db.Uuid
|
|
||||||
status MediaOperation
|
|
||||||
approval Boolean @default(false)
|
|
||||||
proposer User @relation("UserProposedMedias", fields: [proposedBy], references: [id])
|
|
||||||
proposedBy String @db.Uuid
|
|
||||||
approver User @relation("UserApprovedMedias", fields: [approvedBy], references: [id])
|
|
||||||
approvedBy String @db.Uuid
|
|
||||||
media Media @relation("MediaLogs", fields: [mediaId], references: [id])
|
|
||||||
mediaId String @db.Uuid
|
|
||||||
createdAt DateTime @default(now())
|
|
||||||
updatedAt DateTime @default(now()) @updatedAt
|
|
||||||
@@map("media_logs")
|
|
||||||
}
|
|
||||||
|
|
||||||
model Genre {
|
|
||||||
id String @id @db.Uuid
|
|
||||||
name String @db.VarChar(255)
|
|
||||||
slug String @db.VarChar(255) @unique
|
|
||||||
malId Int @unique
|
|
||||||
malUrl String @db.VarChar(255)
|
|
||||||
creator User @relation("UserCreatedGenres", fields: [createdBy], references: [id])
|
|
||||||
createdBy String @db.Uuid
|
|
||||||
deletedAt DateTime?
|
|
||||||
createdAt DateTime @default(now())
|
|
||||||
updatedAt DateTime @default(now()) @updatedAt
|
|
||||||
|
|
||||||
medias Media[] @relation("MediaGenres")
|
|
||||||
user_favourite_genres UserPreference[] @relation("UserFavoriteGenres")
|
|
||||||
|
|
||||||
@@map("genres")
|
|
||||||
}
|
|
||||||
|
|
||||||
model Studio {
|
|
||||||
id String @id @db.Uuid
|
|
||||||
name String @db.VarChar(255)
|
|
||||||
slug String @db.VarChar(255) @unique
|
|
||||||
linkAbout String @db.Text
|
|
||||||
malId Int @unique
|
|
||||||
logoUrl String? @db.Text
|
|
||||||
creator User @relation("UserCreatedStudios", fields: [createdBy], references: [id])
|
|
||||||
createdBy String @db.Uuid
|
|
||||||
deletedAt DateTime?
|
|
||||||
createdAt DateTime @default(now())
|
|
||||||
updatedAt DateTime @default(now()) @updatedAt
|
|
||||||
|
|
||||||
medias Media[] @relation("MediaStudios")
|
|
||||||
@@map("studios")
|
|
||||||
}
|
|
||||||
|
|
||||||
model Character {
|
|
||||||
id String @id@db.Uuid
|
|
||||||
malId Int @unique
|
|
||||||
name String
|
|
||||||
role CharacterRole
|
|
||||||
favorites Int @default(0)
|
|
||||||
imageUrl String?
|
|
||||||
smallImageUrl String?
|
|
||||||
createdBy User @relation("UserCreatedCharacters", fields: [creatorId], references: [id])
|
|
||||||
creatorId String @db.Uuid
|
|
||||||
deletedAt DateTime?
|
|
||||||
createdAt DateTime @default(now())
|
|
||||||
updatedAt DateTime @default(now()) @updatedAt
|
|
||||||
|
|
||||||
medias Media[] @relation("MediaCharacters")
|
|
||||||
voice_actors LangVAChar[] @relation("CharVALanguage")
|
|
||||||
@@map("characters")
|
|
||||||
}
|
|
||||||
|
|
||||||
model VoiceActor {
|
|
||||||
id String @id @db.Uuid
|
|
||||||
malId Int @unique
|
|
||||||
name String
|
|
||||||
birthday DateTime?
|
|
||||||
description String? @db.Text
|
|
||||||
aboutUrl String?
|
|
||||||
imageUrl String?
|
|
||||||
websiteUrl String?
|
|
||||||
createdBy User @relation("UserCreatedVoiceActors", fields: [creatorId], references: [id])
|
|
||||||
creatorId String @db.Uuid
|
|
||||||
deletedAt DateTime?
|
|
||||||
createdAt DateTime @default(now())
|
|
||||||
updatedAt DateTime @default(now()) @updatedAt
|
|
||||||
|
|
||||||
characters LangVAChar[] @relation("VACharLanguage")
|
|
||||||
@@map("voice_actors")
|
|
||||||
}
|
|
||||||
|
|
||||||
model LangVAChar {
|
|
||||||
id String @id @db.Uuid
|
|
||||||
language String
|
|
||||||
voiceActor VoiceActor @relation("VACharLanguage", fields: [vaId], references: [id])
|
|
||||||
vaId String @db.Uuid
|
|
||||||
character Character @relation("CharVALanguage", fields: [charId], references: [id])
|
|
||||||
charId String @db.Uuid
|
|
||||||
createdBy User @relation("UserCreatedLangVAChar", fields: [creatorId], references: [id])
|
|
||||||
creatorId String @db.Uuid
|
|
||||||
createdAt DateTime @default(now())
|
|
||||||
updatedAt DateTime @default(now()) @updatedAt
|
|
||||||
|
|
||||||
@@unique([language, vaId, charId])
|
|
||||||
@@map("lang_va_char")
|
|
||||||
}
|
|
||||||
|
|
||||||
model Episode {
|
|
||||||
id String @id @db.Uuid
|
|
||||||
media Media @relation("MediaEpisodes", fields: [mediaId], references: [id])
|
|
||||||
mediaId String @db.Uuid
|
|
||||||
episode Int
|
|
||||||
name String @db.VarChar(255)
|
|
||||||
score Decimal @db.Decimal(4,2) @default(0.00)
|
|
||||||
pictureThumbnail String? @db.Text
|
|
||||||
viewed BigInt @default(0)
|
|
||||||
likes BigInt @default(0)
|
|
||||||
dislikes BigInt @default(0)
|
|
||||||
pendingUpload Boolean @default(true)
|
|
||||||
uploader User @relation("UserEpisodes", fields: [uploadedBy], references: [id])
|
|
||||||
uploadedBy String @db.Uuid
|
|
||||||
deletedAt DateTime?
|
|
||||||
createdAt DateTime @default(now())
|
|
||||||
updatedAt DateTime @default(now()) @updatedAt
|
|
||||||
|
|
||||||
user_likes EpisodeLike[] @relation("EpisodeLikes")
|
|
||||||
videos Video[] @relation("EpisodeVideos")
|
|
||||||
user_histories WatchHistory[] @relation("EpisodeWatchHistories")
|
|
||||||
comments Comment[] @relation("EpisodeComments")
|
|
||||||
|
|
||||||
@@unique([mediaId, episode])
|
|
||||||
@@map("episodes")
|
|
||||||
}
|
|
||||||
|
|
||||||
model EpisodeLike {
|
|
||||||
id String @id @db.Uuid
|
|
||||||
user User @relation("UserEpisodeLikes", fields: [userId], references: [id])
|
|
||||||
userId String @db.Uuid
|
|
||||||
session UserSession @relation("SessionEpisodeLikes", fields: [sessionId], references: [id])
|
|
||||||
sessionId String @db.Uuid
|
|
||||||
episode Episode @relation("EpisodeLikes", fields: [episodeId], references: [id])
|
|
||||||
episodeId String @db.Uuid
|
|
||||||
createdAt DateTime @default(now())
|
|
||||||
updatedAt DateTime @default(now()) @updatedAt
|
|
||||||
@@map("episode_likes")
|
|
||||||
}
|
|
||||||
|
|
||||||
model Video {
|
|
||||||
id String @id @db.Uuid
|
|
||||||
episode Episode @relation("EpisodeVideos", fields: [episodeId], references: [id])
|
|
||||||
episodeId String @db.Uuid
|
|
||||||
service VideoService @relation("VideoServices", fields: [serviceId], references: [id])
|
|
||||||
serviceId String @db.Uuid
|
|
||||||
videoCode String @db.VarChar(255)
|
|
||||||
thumbnailCode String?
|
|
||||||
pendingUpload Boolean @default(true)
|
|
||||||
uploader User @relation("UserVideos", fields: [uploadedBy], references: [id])
|
|
||||||
uploadedBy String @db.Uuid
|
|
||||||
deletedAt DateTime?
|
|
||||||
createdAt DateTime @default(now())
|
|
||||||
updatedAt DateTime @default(now()) @updatedAt
|
|
||||||
|
|
||||||
@@unique([serviceId, videoCode])
|
|
||||||
@@map("videos")
|
|
||||||
}
|
|
||||||
|
|
||||||
model VideoService {
|
|
||||||
id String @id @db.Uuid
|
|
||||||
name String @db.VarChar(255) @unique
|
|
||||||
domain String @db.VarChar(255)
|
|
||||||
logo String? @db.Text
|
|
||||||
hexColor String @db.VarChar(10)
|
|
||||||
endpointVideo String @db.Text
|
|
||||||
endpointThumbnail String? @db.Text
|
|
||||||
endpointDownload String?
|
|
||||||
creator User @relation("UserVideoServices", fields: [createdBy], references: [id])
|
|
||||||
createdBy String @db.Uuid
|
|
||||||
deletedAt DateTime?
|
|
||||||
createdAt DateTime @default(now())
|
|
||||||
updatedAt DateTime @default(now()) @updatedAt
|
|
||||||
|
|
||||||
videos Video[] @relation("VideoServices")
|
|
||||||
user_preferences UserPreference[] @relation("UserServiceDefault")
|
|
||||||
@@map("video_services")
|
|
||||||
}
|
|
||||||
|
|
||||||
model User {
|
|
||||||
id String @id @db.Uuid
|
|
||||||
name String @db.VarChar(255)
|
|
||||||
username String @unique @db.VarChar(255)
|
|
||||||
email String @unique @db.Text
|
|
||||||
password String @db.Text
|
|
||||||
birthDate DateTime? @db.Date
|
|
||||||
gender UserGender?
|
|
||||||
phoneCC Int?
|
|
||||||
phoneNumber Int?
|
|
||||||
assignedRoles UserRoleAssignment[]
|
|
||||||
bioProfile String? @db.Text
|
|
||||||
avatar String? @db.Text
|
|
||||||
commentBackground String? @db.Text
|
|
||||||
provider String? @db.VarChar(255)
|
|
||||||
providerId String? @unique @db.VarChar(255)
|
|
||||||
providerToken String? @db.Text
|
|
||||||
providerPayload Json? @db.Json
|
|
||||||
preference UserPreference?
|
|
||||||
verifiedAt DateTime?
|
|
||||||
disabledAt DateTime?
|
|
||||||
deletedAt DateTime?
|
|
||||||
createdAt DateTime @default(now())
|
|
||||||
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")
|
|
||||||
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")
|
|
||||||
allowed_collections Collection[] @relation("UserSelectedSharingCollention")
|
|
||||||
watch_histories WatchHistory[] @relation("UserWatchHistories")
|
|
||||||
media_reviews MediaReview[] @relation("UserMediaReviews")
|
|
||||||
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_emails EmailSystemHistory[] @relation("UserEmails")
|
|
||||||
user_hero_banner HeroBanner[] @relation("UserHeroBanner")
|
|
||||||
sys_notifications SystemNotification[] @relation("UserCreatorSystemNotifications")
|
|
||||||
sys_logs SystemLog[] @relation("UserSystemLogs")
|
|
||||||
@@map("users")
|
|
||||||
}
|
|
||||||
|
|
||||||
model UserPreference {
|
|
||||||
id String @id @db.Uuid
|
|
||||||
user User @relation(fields: [userId], references: [id])
|
|
||||||
userId String @unique @db.Uuid
|
|
||||||
lang Language? @relation("UserPreferenceLang", fields: [langPreference], references: [code])
|
|
||||||
langPreference String?
|
|
||||||
adultFiltering AdultFiltering @default(hide)
|
|
||||||
adultAlert AdultAlert @default(show)
|
|
||||||
videoQuality VideoQuality @default(Q1080)
|
|
||||||
serviceDefault VideoService? @relation("UserServiceDefault", fields: [serviceDefaultId], references: [id])
|
|
||||||
serviceDefaultId String? @db.Uuid
|
|
||||||
hideContries Country[]
|
|
||||||
favoriteGenres Genre[] @relation("UserFavoriteGenres")
|
|
||||||
createdAt DateTime @default(now())
|
|
||||||
updatedAt DateTime @default(now()) @updatedAt
|
|
||||||
@@map("user_preferences")
|
|
||||||
}
|
|
||||||
|
|
||||||
model UserRole {
|
|
||||||
id String @id @db.Uuid
|
|
||||||
name String @db.VarChar(255) @unique
|
|
||||||
description String? @db.Text
|
|
||||||
primaryColor String? @db.VarChar(10)
|
|
||||||
secondaryColor String? @db.VarChar(10)
|
|
||||||
pictureImage String? @db.Text
|
|
||||||
badgeImage String? @db.Text
|
|
||||||
isSuperadmin Boolean @default(false)
|
|
||||||
canEditMedia Boolean @default(false)
|
|
||||||
canManageMedia Boolean @default(false)
|
|
||||||
canEditEpisodes Boolean @default(false)
|
|
||||||
canManageEpisodes Boolean @default(false)
|
|
||||||
canEditComment Boolean @default(false)
|
|
||||||
canManageComment Boolean @default(false)
|
|
||||||
canEditUser Boolean @default(false)
|
|
||||||
canManageUser Boolean @default(false)
|
|
||||||
canEditSystem Boolean @default(false)
|
|
||||||
canManageSystem Boolean @default(false)
|
|
||||||
creator User @relation("UserCreateRoles", fields: [createdBy], references: [id])
|
|
||||||
createdBy String @db.Uuid
|
|
||||||
deletedAt DateTime?
|
|
||||||
createdAt DateTime @default(now())
|
|
||||||
updatedAt DateTime @default(now()) @updatedAt
|
|
||||||
|
|
||||||
assignedUser UserRoleAssignment[]
|
|
||||||
@@map("user_roles")
|
|
||||||
}
|
|
||||||
|
|
||||||
model UserRoleAssignment {
|
|
||||||
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])
|
|
||||||
@@map("user_role_assignments")
|
|
||||||
}
|
|
||||||
|
|
||||||
model UserNotification {
|
|
||||||
id String @id @db.Uuid
|
|
||||||
title String @db.VarChar(255)
|
|
||||||
content String @db.Text
|
|
||||||
picture String @db.Text
|
|
||||||
state UserNotificationState
|
|
||||||
ctaLink String @db.Text
|
|
||||||
user User @relation("UserNotifications", fields: [userId], references: [id])
|
|
||||||
userId String @db.Uuid
|
|
||||||
isReaded Boolean @default(false)
|
|
||||||
deletedAt DateTime?
|
|
||||||
createdAt DateTime @default(now())
|
|
||||||
updatedAt DateTime @default(now()) @updatedAt
|
|
||||||
@@map("user_notifications")
|
|
||||||
}
|
|
||||||
|
|
||||||
model UserSession {
|
|
||||||
id String @id @db.Uuid
|
|
||||||
isAuthenticated Boolean @default(false)
|
|
||||||
user User @relation("UserSession", fields: [userId], references: [id])
|
|
||||||
userId String @db.Uuid
|
|
||||||
deviceType String @db.VarChar(255)
|
|
||||||
deviceOs String @db.VarChar(255)
|
|
||||||
deviceIp String @db.VarChar(255)
|
|
||||||
browser String @db.VarChar(255)
|
|
||||||
isOnline Boolean @default(false)
|
|
||||||
lastOnline DateTime @default(now())
|
|
||||||
validUntil DateTime
|
|
||||||
deletedAt DateTime?
|
|
||||||
createdAt DateTime @default(now())
|
|
||||||
updatedAt DateTime @default(now()) @updatedAt
|
|
||||||
|
|
||||||
logs UserLog[] @relation("UserSessionLogs")
|
|
||||||
episode_likes EpisodeLike[] @relation("SessionEpisodeLikes")
|
|
||||||
watch_histories WatchHistory[] @relation("SessionWatchHistories")
|
|
||||||
|
|
||||||
@@index([userId, isAuthenticated, deletedAt])
|
|
||||||
@@map("user_sessions")
|
|
||||||
}
|
|
||||||
|
|
||||||
model UserLog {
|
|
||||||
id String @id @db.Uuid
|
|
||||||
title String @db.VarChar(255)
|
|
||||||
notes String @db.Text
|
|
||||||
user User @relation("UserLogs", fields: [userId], references: [id])
|
|
||||||
userId String @db.Uuid
|
|
||||||
session UserSession @relation("UserSessionLogs", fields: [sessionId], references: [id])
|
|
||||||
sessionId String @db.Uuid
|
|
||||||
createdAt DateTime @default(now())
|
|
||||||
updatedAt DateTime @default(now()) @updatedAt
|
|
||||||
@@map("user_logs")
|
|
||||||
}
|
|
||||||
|
|
||||||
model Collection {
|
|
||||||
id String @id @db.Uuid
|
|
||||||
name String @db.VarChar(255)
|
|
||||||
medias Media[] @relation("MediaCollections")
|
|
||||||
owner User @relation("UserCollections", fields: [ownerId], references: [id])
|
|
||||||
ownerId String @db.Uuid
|
|
||||||
accessStatus AccessStatus @default(private)
|
|
||||||
password String? @db.VarChar(255)
|
|
||||||
usersAllowed User[] @relation("UserSelectedSharingCollention")
|
|
||||||
accessScope AccessScope @default(viewer)
|
|
||||||
deletedAt DateTime?
|
|
||||||
createdAt DateTime @default(now())
|
|
||||||
updatedAt DateTime @default(now()) @updatedAt
|
|
||||||
@@map("collections")
|
|
||||||
}
|
|
||||||
|
|
||||||
model WatchHistory {
|
|
||||||
id String @id @db.Uuid
|
|
||||||
episode Episode @relation("EpisodeWatchHistories", fields: [id], references: [id])
|
|
||||||
episodeId String @db.Uuid
|
|
||||||
user User @relation("UserWatchHistories", fields: [userId], references: [id])
|
|
||||||
userId String @db.Uuid
|
|
||||||
session UserSession @relation("SessionWatchHistories", fields: [sessionId], references: [id])
|
|
||||||
sessionId String @db.Uuid
|
|
||||||
createdAt DateTime @default(now())
|
|
||||||
updatedAt DateTime @default(now()) @updatedAt
|
|
||||||
@@map("watch_histories")
|
|
||||||
}
|
|
||||||
|
|
||||||
model MediaReview {
|
|
||||||
id String @id @db.Uuid
|
|
||||||
media Media @relation("MediaReviews", fields: [mediaId], references:[id])
|
|
||||||
mediaId String @db.Uuid
|
|
||||||
rating Int
|
|
||||||
title String @db.VarChar(255)
|
|
||||||
text String @db.Text
|
|
||||||
reaction MediaReviewReaction
|
|
||||||
creator User @relation("UserMediaReviews", fields: [createdBy], references: [id])
|
|
||||||
createdBy String @db.Uuid
|
|
||||||
deletedAt DateTime?
|
|
||||||
createdAt DateTime @default(now())
|
|
||||||
updatedAt DateTime @default(now()) @updatedAt
|
|
||||||
@@map("movie_reviews")
|
|
||||||
}
|
|
||||||
|
|
||||||
model Comment {
|
|
||||||
id String @id @db.Uuid
|
|
||||||
episode Episode @relation("EpisodeComments", fields: [episodeId], references: [id])
|
|
||||||
episodeId String @db.Uuid
|
|
||||||
text String @db.Text
|
|
||||||
isParent Boolean @default(false)
|
|
||||||
parent Comment? @relation("ParentReplyComments", fields: [parentId], references: [id])
|
|
||||||
parentId String? @db.Uuid
|
|
||||||
user User @relation("UserComments", fields: [userId], references: [id])
|
|
||||||
userId String @db.Uuid
|
|
||||||
createdAt DateTime @default(now())
|
|
||||||
updatedAt DateTime @default(now()) @updatedAt
|
|
||||||
|
|
||||||
replies Comment[] @relation("ParentReplyComments")
|
|
||||||
likes CommentLike[] @relation("CommentLikes")
|
|
||||||
@@map("comments")
|
|
||||||
}
|
|
||||||
|
|
||||||
model CommentLike {
|
|
||||||
id String @id @db.Uuid
|
|
||||||
comment Comment @relation("CommentLikes", fields: [commentId], references: [id])
|
|
||||||
commentId String @db.Uuid
|
|
||||||
user User @relation("UserCommentLikes", fields: [userLiked], references: [id])
|
|
||||||
userLiked String @db.Uuid
|
|
||||||
createdAt DateTime @default(now())
|
|
||||||
updatedAt DateTime @default(now()) @updatedAt
|
|
||||||
@@map("comment_likes")
|
|
||||||
}
|
|
||||||
|
|
||||||
model CommentReport {
|
|
||||||
id String @id @db.Uuid
|
|
||||||
reporter User @relation("UserReportComments", fields: [userReporter], references: [id])
|
|
||||||
userReporter String @db.Uuid
|
|
||||||
commentReported String @db.Uuid
|
|
||||||
isSupervisorReport Boolean @default(false)
|
|
||||||
reason ReportReason
|
|
||||||
status ReportStatus
|
|
||||||
description String @db.VarChar(255)
|
|
||||||
approver User? @relation("ApprovedReportComments", fields: [approvedBy], references: [id])
|
|
||||||
approvedBy String? @db.Uuid
|
|
||||||
createdAt DateTime @default(now())
|
|
||||||
updatedAt DateTime @default(now()) @updatedAt
|
|
||||||
@@map("comment_reports")
|
|
||||||
}
|
|
||||||
|
|
||||||
model Language {
|
|
||||||
id String @id @db.Uuid
|
|
||||||
name String @db.VarChar(255)
|
|
||||||
code String @db.VarChar(5) @unique
|
|
||||||
countryFlag String @db.VarChar(10)
|
|
||||||
fileLocation String @db.Text
|
|
||||||
creator User @relation("UserCreateLanguages", fields: [craetedBy], references: [id])
|
|
||||||
craetedBy String @db.Uuid
|
|
||||||
deletedAt DateTime?
|
|
||||||
createdAt DateTime @default(now())
|
|
||||||
updatedAt DateTime @default(now()) @updatedAt
|
|
||||||
|
|
||||||
user_used UserPreference[] @relation("UserPreferenceLang")
|
|
||||||
@@map("languages")
|
|
||||||
}
|
|
||||||
|
|
||||||
model EmailSystemAccount {
|
|
||||||
id String @id @db.Uuid
|
|
||||||
name String @unique
|
|
||||||
host String @db.VarChar(255)
|
|
||||||
port Int
|
|
||||||
secure Boolean
|
|
||||||
email String @unique @db.VarChar(255)
|
|
||||||
username String @unique @db.VarChar(255)
|
|
||||||
password String @db.VarChar(255)
|
|
||||||
purpose EmailPorpose
|
|
||||||
creator User @relation("UserCreateSystemAccount", fields: [createdBy], references: [id])
|
|
||||||
createdBy String @db.Uuid
|
|
||||||
deletedAt DateTime?
|
|
||||||
createdAt DateTime @default(now())
|
|
||||||
updatedAt DateTime @default(now()) @updatedAt
|
|
||||||
@@map("email_system_accounts")
|
|
||||||
}
|
|
||||||
|
|
||||||
model EmailSystemHistory {
|
|
||||||
id String @id @db.Uuid
|
|
||||||
purpose EmailPorpose
|
|
||||||
fromEmail String @db.Text
|
|
||||||
toEmail String @db.Text
|
|
||||||
user User @relation("UserEmails", fields: [userRelated], references: [id])
|
|
||||||
userRelated String @db.Uuid
|
|
||||||
title String @db.VarChar(255)
|
|
||||||
htmlContent String @db.Text
|
|
||||||
deletedAt DateTime?
|
|
||||||
createdAt DateTime @default(now())
|
|
||||||
updatedAt DateTime @default(now()) @updatedAt
|
|
||||||
@@map("email_system_histories")
|
|
||||||
}
|
|
||||||
|
|
||||||
model HeroBanner {
|
|
||||||
id String @id @db.Uuid
|
|
||||||
orderPriority Int? @unique
|
|
||||||
mediaId String @db.Uuid
|
|
||||||
media Media @relation("MediaBannerPromotion", fields: [mediaId], references: [id])
|
|
||||||
imageUrl String? @db.Text
|
|
||||||
startDate DateTime
|
|
||||||
endDate DateTime
|
|
||||||
createdAt DateTime @default(now())
|
|
||||||
updatedAt DateTime @default(now()) @updatedAt
|
|
||||||
creatorId String @db.Uuid
|
|
||||||
createdBy User @relation("UserHeroBanner", fields: [creatorId], references: [id])
|
|
||||||
@@map("hero_banner")
|
|
||||||
}
|
|
||||||
|
|
||||||
model SystemPreference {
|
|
||||||
id String @id @db.Uuid
|
|
||||||
key String @db.VarChar(225) @unique
|
|
||||||
value String @db.VarChar(225)
|
|
||||||
description String @db.Text
|
|
||||||
deletedAt DateTime?
|
|
||||||
createdAt DateTime @default(now())
|
|
||||||
updatedAt DateTime @default(now()) @updatedAt
|
|
||||||
@@map("system_preferences")
|
|
||||||
}
|
|
||||||
|
|
||||||
model SystemNotification {
|
|
||||||
id String @id @db.Uuid
|
|
||||||
type TypeSystemNotification
|
|
||||||
componentName String? @db.VarChar(255)
|
|
||||||
popupImage String? @db.Text
|
|
||||||
titleToast String? @db.VarChar(255)
|
|
||||||
contentToast String? @db.Text
|
|
||||||
creator User @relation("UserCreatorSystemNotifications", fields: [createdBy], references: [id])
|
|
||||||
createdBy String @db.Uuid
|
|
||||||
deletedAt DateTime?
|
|
||||||
createdAt DateTime @default(now())
|
|
||||||
updatedAt DateTime @default(now()) @updatedAt
|
|
||||||
@@map("system_notifications")
|
|
||||||
}
|
|
||||||
|
|
||||||
model SystemLog {
|
|
||||||
id String @id @db.Uuid
|
|
||||||
title String @db.VarChar(255)
|
|
||||||
notes String @db.Text
|
|
||||||
user User? @relation("UserSystemLogs", fields: [relatedUser], references: [id])
|
|
||||||
relatedUser String? @db.Uuid
|
|
||||||
createdAt DateTime @default(now())
|
|
||||||
updatedAt DateTime @default(now()) @updatedAt
|
|
||||||
@@map("system_logs")
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//// Prisma Enum Values ////
|
|
||||||
|
|
||||||
// Media Enum
|
|
||||||
enum MediaType {
|
|
||||||
TV
|
|
||||||
ONA
|
|
||||||
OVA
|
|
||||||
Movie
|
|
||||||
Special
|
|
||||||
Music
|
|
||||||
}
|
|
||||||
enum Country {
|
|
||||||
JP @map("Japanese")
|
|
||||||
EN @map("English")
|
|
||||||
ID @map("Indonesia")
|
|
||||||
KR @map("Korea")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Character Enum
|
|
||||||
enum CharacterRole {
|
|
||||||
Main
|
|
||||||
Supporting
|
|
||||||
}
|
|
||||||
|
|
||||||
// MediaLog Enum
|
|
||||||
enum MediaOperation {
|
|
||||||
create
|
|
||||||
update
|
|
||||||
delete
|
|
||||||
}
|
|
||||||
|
|
||||||
// User Enum
|
|
||||||
enum UserGender {
|
|
||||||
male
|
|
||||||
female
|
|
||||||
}
|
|
||||||
|
|
||||||
// UserPreference Enum
|
|
||||||
enum AdultFiltering {
|
|
||||||
hide
|
|
||||||
show
|
|
||||||
explicit
|
|
||||||
}
|
|
||||||
enum AdultAlert {
|
|
||||||
hide
|
|
||||||
show
|
|
||||||
}
|
|
||||||
enum VideoQuality {
|
|
||||||
Q2160
|
|
||||||
Q1440
|
|
||||||
Q1080
|
|
||||||
Q720
|
|
||||||
Q480
|
|
||||||
Q360
|
|
||||||
Q240
|
|
||||||
Q144
|
|
||||||
}
|
|
||||||
|
|
||||||
// userNotification Enum
|
|
||||||
enum UserNotificationState {
|
|
||||||
info
|
|
||||||
warning
|
|
||||||
danger
|
|
||||||
}
|
|
||||||
|
|
||||||
// CommentReport Enum
|
|
||||||
enum ReportStatus {
|
|
||||||
pending
|
|
||||||
resolved
|
|
||||||
rejected
|
|
||||||
}
|
|
||||||
enum ReportReason {
|
|
||||||
sexualize
|
|
||||||
violent
|
|
||||||
explicit
|
|
||||||
hateful
|
|
||||||
political
|
|
||||||
racist
|
|
||||||
spam
|
|
||||||
other
|
|
||||||
}
|
|
||||||
|
|
||||||
// Collection Enum
|
|
||||||
enum AccessStatus {
|
|
||||||
private
|
|
||||||
selected
|
|
||||||
protected
|
|
||||||
public
|
|
||||||
}
|
|
||||||
enum AccessScope {
|
|
||||||
viewer
|
|
||||||
editor
|
|
||||||
}
|
|
||||||
|
|
||||||
// MediaReview Enum
|
|
||||||
enum MediaReviewReaction {
|
|
||||||
angry
|
|
||||||
sad
|
|
||||||
awesome
|
|
||||||
happy
|
|
||||||
sleepy
|
|
||||||
annoyed
|
|
||||||
disgusting
|
|
||||||
disappointed
|
|
||||||
}
|
|
||||||
|
|
||||||
// EmailSystemHistory Enum
|
|
||||||
enum EmailPorpose {
|
|
||||||
forgot_password
|
|
||||||
account_activation
|
|
||||||
account_notification
|
|
||||||
subscribtion
|
|
||||||
}
|
|
||||||
|
|
||||||
// systemNotification Enum
|
|
||||||
enum TypeSystemNotification {
|
|
||||||
component
|
|
||||||
popup
|
|
||||||
toast
|
|
||||||
}
|
|
||||||
|
|||||||
@ -0,0 +1,22 @@
|
|||||||
|
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);
|
||||||
|
}
|
||||||
|
};
|
||||||
@ -0,0 +1,22 @@
|
|||||||
|
import { Context, Static } from "elysia";
|
||||||
|
import { mainErrorHandler } from "../../../helpers/error/handler";
|
||||||
|
import { returnWriteResponse } from "../../../helpers/callback/httpResponse";
|
||||||
|
import { removeItemFromCollectionBySystemService } from "../services/removeItemFromCollectionBySystem.service";
|
||||||
|
import { removeItemFromCollectionBySytemSchema } from "../schemas/removeItemFromCollectionBySytem.schema";
|
||||||
|
|
||||||
|
export const removeItemFromCollectionBySytemController = async (ctx: {
|
||||||
|
set: Context["set"];
|
||||||
|
headers: Static<typeof removeItemFromCollectionBySytemSchema.headers>;
|
||||||
|
body: Static<typeof removeItemFromCollectionBySytemSchema.body>;
|
||||||
|
}) => {
|
||||||
|
try {
|
||||||
|
const removedItem = await removeItemFromCollectionBySystemService({
|
||||||
|
cookie: ctx.headers.cookie,
|
||||||
|
collectionName: ctx.body.name,
|
||||||
|
mediaId: ctx.body.itemId,
|
||||||
|
});
|
||||||
|
return returnWriteResponse(ctx.set, 200, "Item removed from collection successfully", removedItem);
|
||||||
|
} catch (error) {
|
||||||
|
return mainErrorHandler(ctx.set, error);
|
||||||
|
}
|
||||||
|
};
|
||||||
9
src/modules/collection/index.ts
Normal file
9
src/modules/collection/index.ts
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
import Elysia from "elysia";
|
||||||
|
import { 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);
|
||||||
@ -0,0 +1,31 @@
|
|||||||
|
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);
|
||||||
|
}
|
||||||
|
};
|
||||||
@ -0,0 +1,60 @@
|
|||||||
|
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");
|
||||||
|
}
|
||||||
|
};
|
||||||
@ -0,0 +1,33 @@
|
|||||||
|
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;
|
||||||
@ -0,0 +1,33 @@
|
|||||||
|
import { t } from "elysia";
|
||||||
|
import { AppRouteSchema } from "../../../helpers/types/AppRouteSchema";
|
||||||
|
|
||||||
|
export const removeItemFromCollectionBySytemSchema = {
|
||||||
|
headers: t.Object({
|
||||||
|
cookie: t.String({ description: "Authentication token in cookie format, e.g., auth_token=your_jwt_token;" }),
|
||||||
|
}),
|
||||||
|
body: t.Object({
|
||||||
|
name: t.String({ description: "Name of the collection to which the item will be added" }),
|
||||||
|
itemId: t.String({ description: "ID of the item to be added to the collection", examples: ["12345"] }),
|
||||||
|
}),
|
||||||
|
detail: {
|
||||||
|
summary: "Remove an item from a collection",
|
||||||
|
description: "Removes a specified item from a collection identified by its name.",
|
||||||
|
responses: {
|
||||||
|
200: {
|
||||||
|
description: "The item was successfully removed from the collection.",
|
||||||
|
content: {
|
||||||
|
"application/json": {
|
||||||
|
schema: {
|
||||||
|
type: "object",
|
||||||
|
properties: {
|
||||||
|
success: { type: "boolean", example: true },
|
||||||
|
status: { type: "number", example: 200 },
|
||||||
|
message: { type: "string", example: "Item removed from collection successfully" },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
} satisfies AppRouteSchema;
|
||||||
@ -0,0 +1,24 @@
|
|||||||
|
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);
|
||||||
|
}
|
||||||
|
};
|
||||||
@ -0,0 +1,24 @@
|
|||||||
|
import { parse } from "cookie";
|
||||||
|
import { ErrorForwarder } from "../../../helpers/error/instances/forwarder";
|
||||||
|
import { tokenValidationService } from "../../auth/services/http/tokenValidation.service";
|
||||||
|
import { deleteItemInUserCollectionBySystemRepository } from "../repositories/deleteItemInUserCollectionBySystem.repository";
|
||||||
|
|
||||||
|
export type RemoveItemFromCollectionPayload = {
|
||||||
|
cookie: string;
|
||||||
|
collectionName: string;
|
||||||
|
mediaId: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const removeItemFromCollectionBySystemService = async (payload: RemoveItemFromCollectionPayload) => {
|
||||||
|
try {
|
||||||
|
const { auth_token } = parse(payload.cookie);
|
||||||
|
const { user } = await tokenValidationService(auth_token as string);
|
||||||
|
return await deleteItemInUserCollectionBySystemRepository({
|
||||||
|
userId: user.id,
|
||||||
|
collectionName: payload.collectionName,
|
||||||
|
itemId: payload.mediaId,
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
ErrorForwarder(error);
|
||||||
|
}
|
||||||
|
};
|
||||||
@ -1,17 +1,14 @@
|
|||||||
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 { getMediaIdFromSlugRepository } from "../../../media/repositories/GET/getMediaIdFromSlug.repository";
|
import { selectMediaIdFromSlugRepository } from "../../../media/repositories/SELECT/selectMediaIdFromSlug.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 (
|
export const getEpisodeDetailsService = async (params: GetEpisodeDetailsParams) => {
|
||||||
params: GetEpisodeDetailsParams,
|
|
||||||
) => {
|
|
||||||
try {
|
try {
|
||||||
if (!params.mediaSlug || !params.episode)
|
if (!params.mediaSlug || !params.episode) throw new AppError(400, "Media slug and episode are required.");
|
||||||
throw new AppError(400, "Media slug and episode are required.");
|
|
||||||
|
|
||||||
const mediaId = await getMediaIdFromSlugRepository(params.mediaSlug);
|
const mediaId = await selectMediaIdFromSlugRepository(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({
|
||||||
|
|||||||
@ -0,0 +1,8 @@
|
|||||||
|
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);
|
||||||
|
};
|
||||||
4
src/modules/flushCache/index.ts
Normal file
4
src/modules/flushCache/index.ts
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
import Elysia from "elysia";
|
||||||
|
import { clearHeroBannerController } from "./controllers/clearHeroBanner.controller";
|
||||||
|
|
||||||
|
export const flushCacheModule = new Elysia({ prefix: "/flush-cache" }).put("/hero-banner", clearHeroBannerController);
|
||||||
12
src/modules/flushCache/services/clearHeroBanner.service.ts
Normal file
12
src/modules/flushCache/services/clearHeroBanner.service.ts
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
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,17 +1,16 @@
|
|||||||
import { Context } from "elysia";
|
import { Context, Static } 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: Context) => {
|
export const getActiveHeroBannerController = async (ctx: {
|
||||||
|
set: Context["set"];
|
||||||
|
header: Static<typeof getActiveHeroBannerSchema.headers>;
|
||||||
|
}) => {
|
||||||
try {
|
try {
|
||||||
const response = await getActiveHeroBannerService();
|
const response = await getActiveHeroBannerService({ cookie: ctx.header?.cookie });
|
||||||
return returnReadResponse(
|
return returnReadResponse(ctx.set, 200, "Active hero banners fetched successfully", response);
|
||||||
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 () => {
|
export const findAllActiveHeroBannerRepository = async (userId?: string) => {
|
||||||
try {
|
try {
|
||||||
return await prisma.heroBanner.findMany({
|
return await prisma.heroBanner.findMany({
|
||||||
where: {
|
where: {
|
||||||
@ -20,6 +20,36 @@ export const findAllActiveHeroBannerRepository = async () => {
|
|||||||
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);
|
||||||
|
|||||||
@ -0,0 +1,8 @@
|
|||||||
|
import { t } from "elysia";
|
||||||
|
import { AppRouteSchema } from "../../../helpers/types/AppRouteSchema";
|
||||||
|
|
||||||
|
export const getActiveHeroBannerSchema = {
|
||||||
|
headers: t.Object({
|
||||||
|
cookie: t.Optional(t.String()),
|
||||||
|
}),
|
||||||
|
} satisfies AppRouteSchema;
|
||||||
@ -1,33 +1,44 @@
|
|||||||
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 { redis } from "../../../utils/databases/redis/connection";
|
import { tokenValidationService } from "../../auth/services/http/tokenValidation.service";
|
||||||
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 () => {
|
export const getActiveHeroBannerService = async ({ cookie }: { cookie?: string }) => {
|
||||||
try {
|
try {
|
||||||
// Check if Hero Banner is enabled in system preferences
|
const userId = cookie ? (await tokenValidationService(cookie)).user.id : undefined;
|
||||||
const isHeroBannerEnabled = await findSystemPreferenceService(
|
|
||||||
"HERO_BANNER_ENABLED",
|
|
||||||
"boolean",
|
|
||||||
);
|
|
||||||
if (!isHeroBannerEnabled)
|
|
||||||
throw new AppError(403, "Hero Banner is disabled");
|
|
||||||
|
|
||||||
// Try to get active banners from Redis cache
|
// Check if Hero Banner is enabled in system preferences
|
||||||
const cachedBanners = await redis.get(
|
const isHeroBannerEnabled = await findSystemPreferenceService("HERO_BANNER_ENABLED", "boolean");
|
||||||
`${redisKey.filter((key) => key.name === "HERO_BANNER")[0].key}`,
|
if (!isHeroBannerEnabled) throw new AppError(403, "Hero Banner is disabled");
|
||||||
);
|
|
||||||
if (cachedBanners) return JSON.parse(cachedBanners);
|
// Don’t implement caching just yet; implement collection caching first, then implement banner caching.
|
||||||
|
// Please note that currently, a database query is still required to check the collections.
|
||||||
|
// // Try to get active banners from Redis cache
|
||||||
|
// const cachedBanners = await redis.get(`${redisKey.filter((key) => key.name === "HERO_BANNER")[0].key}`);
|
||||||
|
// if (cachedBanners) return JSON.parse(cachedBanners);
|
||||||
|
|
||||||
// If not in cache, fetch from database and cache the result
|
// If not in cache, fetch from database and cache the result
|
||||||
const activeBanners = await findAllActiveHeroBannerRepository();
|
const activeBanners = await findAllActiveHeroBannerRepository(userId);
|
||||||
await redis.set(
|
const constructedBanners = activeBanners.map((banner) => ({
|
||||||
`${redisKey.filter((key) => key.name === "HERO_BANNER")[0].key}`,
|
id: banner.media.id,
|
||||||
JSON.stringify(activeBanners),
|
title: banner.media.title,
|
||||||
);
|
slug: banner.media.slug,
|
||||||
return activeBanners;
|
imageUrl: banner.imageUrl || banner.media.pictureLarge,
|
||||||
|
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 (
|
export const insertHeroBannerRepository = async (payload: Static<typeof createHeroBannerSchema.body>) => {
|
||||||
payload: Omit<Prisma.HeroBannerCreateInput, "id" | "createdBy">,
|
|
||||||
) => {
|
|
||||||
try {
|
try {
|
||||||
return await prisma.heroBanner.create({
|
return await prisma.heroBanner.create({
|
||||||
data: {
|
data: {
|
||||||
@ -16,6 +16,9 @@ export const insertHeroBannerRepository = async (
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
} 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,45 +3,18 @@ import { AppRouteSchema } from "../../../helpers/types/AppRouteSchema";
|
|||||||
|
|
||||||
export const createHeroBannerSchema = {
|
export const createHeroBannerSchema = {
|
||||||
body: t.Object({
|
body: t.Object({
|
||||||
isClickable: t.Optional(
|
orderPriority: t.Optional(
|
||||||
t.Boolean({
|
t.Number({ description: "The priority order of the hero banner. Lower numbers indicate higher priority." }),
|
||||||
description: "Indicates whether the hero banner is clickable",
|
|
||||||
}),
|
|
||||||
),
|
|
||||||
title: t.Optional(
|
|
||||||
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",
|
|
||||||
}),
|
|
||||||
),
|
),
|
||||||
|
mediaId: t.String({ description: "The ID of the media associated with the hero banner" }),
|
||||||
imageUrl: t.Optional(
|
imageUrl: t.Optional(
|
||||||
t.String({
|
t.String({
|
||||||
description: "The URL of the image used in the hero banner",
|
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.String({
|
startDate: t.Date({ description: "The start date for the hero banner in ISO 8601 format" }),
|
||||||
description: "The start date for the hero banner in ISO 8601 format",
|
endDate: t.Date({ description: "The end 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",
|
||||||
@ -64,17 +37,16 @@ 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" },
|
||||||
isClickable: { type: "boolean", description: "Indicates whether the hero banner is clickable" },
|
orderPriority: {
|
||||||
title: { type: "string", description: "The title of the hero banner" },
|
type: "number",
|
||||||
tags: {
|
description: "The priority order of the hero banner. Lower numbers indicate higher priority.",
|
||||||
type: "array",
|
},
|
||||||
items: { type: "string" },
|
mediaId: { type: "string", description: "The ID of the media associated with the hero banner" },
|
||||||
description: "An array of tags associated with the hero banner",
|
imageUrl: {
|
||||||
|
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,27 +1,20 @@
|
|||||||
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 (
|
export const bulkInsertEpisodeService = async (mal_id: number, page: number = 1) => {
|
||||||
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 getMediaByMalIdRepository(mal_id);
|
const mediaData = await selectMediaByMalIdRepository(mal_id);
|
||||||
if (!mediaData)
|
if (!mediaData) throw new AppError(404, `Media with Mal ID ${mal_id} not found in database`);
|
||||||
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,10 +1,9 @@
|
|||||||
|
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 (
|
export const createHeroBannerService = async (payload: Static<typeof createHeroBannerSchema.body>) => {
|
||||||
payload: CreateHeroBannerRequestBody,
|
|
||||||
) => {
|
|
||||||
try {
|
try {
|
||||||
return await insertHeroBannerRepository(payload);
|
return await insertHeroBannerRepository(payload);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
|||||||
@ -1,19 +1,16 @@
|
|||||||
import { Context } from "elysia";
|
import { Context, Static } 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 (
|
export const getAllMediaController = async (ctx: {
|
||||||
ctx: Context & { query: { page: string } },
|
set: Context["set"];
|
||||||
) => {
|
query: Static<typeof getAllMediaSchema.query>;
|
||||||
|
}) => {
|
||||||
try {
|
try {
|
||||||
const mediaData = await getAllMediaService(ctx.query.page);
|
const mediaData = await getAllMediaService(ctx.query.page);
|
||||||
return returnReadResponse(
|
return returnReadResponse(ctx.set, 200, "Media fetched successfully", mediaData);
|
||||||
ctx.set,
|
|
||||||
200,
|
|
||||||
"Media fetched successfully",
|
|
||||||
mediaData,
|
|
||||||
);
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
return mainErrorHandler(ctx.set, error);
|
return mainErrorHandler(ctx.set, error);
|
||||||
}
|
}
|
||||||
|
|||||||
17
src/modules/media/controllers/getMediaBySlug.controller.ts
Normal file
17
src/modules/media/controllers/getMediaBySlug.controller.ts
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
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,7 +1,9 @@
|
|||||||
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" }).get(
|
export const mediaModule = new Elysia({ prefix: "/media", tags: ["Media"] })
|
||||||
"/",
|
.get("/", getAllMediaController, getAllMediaSchema)
|
||||||
getAllMediaController,
|
.get("/:slug", getMediaBySlugController, getMediaBySlugSchema);
|
||||||
);
|
|
||||||
|
|||||||
@ -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 getAllMediaRepository = async (page: number) => {
|
export const selectAllMediaRepository = 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 getMediaByMalIdRepository = async (mal_id: number) => {
|
export const selectMediaByMalIdRepository = async (mal_id: number) => {
|
||||||
try {
|
try {
|
||||||
return await mediaModel.findUnique({
|
return await mediaModel.findUnique({
|
||||||
where: { malId: mal_id },
|
where: { malId: mal_id },
|
||||||
@ -0,0 +1,12 @@
|
|||||||
|
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,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 getMediaIdFromSlugRepository = async (slug: string) => {
|
export const selectMediaIdFromSlugRepository = async (slug: string) => {
|
||||||
try {
|
try {
|
||||||
return await mediaModel.findUnique({
|
return await mediaModel.findUnique({
|
||||||
where: { slug },
|
where: { slug },
|
||||||
58
src/modules/media/schemas/getAllMedia.schema.ts
Normal file
58
src/modules/media/schemas/getAllMedia.schema.ts
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
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;
|
||||||
29
src/modules/media/schemas/getMediaBySlug.schema.ts
Normal file
29
src/modules/media/schemas/getMediaBySlug.schema.ts
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
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,14 +1,11 @@
|
|||||||
import { ErrorForwarder } from "../../../../helpers/error/instances/forwarder";
|
import { ErrorForwarder } from "../../../../helpers/error/instances/forwarder";
|
||||||
import { getAllMediaRepository } from "../../repositories/GET/getAllMedia.repository";
|
import { selectAllMediaRepository } from "../../repositories/SELECT/selectAllMedia.repository";
|
||||||
|
|
||||||
export const getAllMediaService = async (pagination: string) => {
|
export const getAllMediaService = async (pagination: string) => {
|
||||||
try {
|
try {
|
||||||
const page =
|
const page = /^\d+$/.test(pagination) && Number(pagination) > 0 ? Number(pagination) : 1;
|
||||||
/^\d+$/.test(pagination) && Number(pagination) > 0
|
|
||||||
? Number(pagination)
|
|
||||||
: 1;
|
|
||||||
|
|
||||||
return getAllMediaRepository(page);
|
return selectAllMediaRepository(page);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
ErrorForwarder(error);
|
ErrorForwarder(error);
|
||||||
}
|
}
|
||||||
|
|||||||
14
src/modules/media/services/http/getMediaBySlug.service.ts
Normal file
14
src/modules/media/services/http/getMediaBySlug.service.ts
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
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