Compare commits
16 Commits
main
...
a46b465409
| Author | SHA1 | Date | |
|---|---|---|---|
| a46b465409 | |||
| 9cfb793e59 | |||
| 51693959b6 | |||
| d914046288 | |||
| 7387386aee | |||
| 7a63b43c9f | |||
| 107582dd32 | |||
| 502e7b10c6 | |||
| 73f1f87695 | |||
| 28b3de29d8 | |||
| a04d1ffdf1 | |||
| dcfa4350d6 | |||
| 9de535f541 | |||
| 00ca1ba8fb | |||
| 0057f0c63b | |||
| 1694035dc4 |
3
.gitignore
vendored
3
.gitignore
vendored
@ -63,3 +63,6 @@ server.exe
|
|||||||
/uploads
|
/uploads
|
||||||
|
|
||||||
/scripts/git-multipush.ts
|
/scripts/git-multipush.ts
|
||||||
|
|
||||||
|
# IDE configuration
|
||||||
|
/.idea
|
||||||
8
.idea/.gitignore
generated
vendored
8
.idea/.gitignore
generated
vendored
@ -1,8 +0,0 @@
|
|||||||
# Default ignored files
|
|
||||||
/shelf/
|
|
||||||
/workspace.xml
|
|
||||||
# Editor-based HTTP Client requests
|
|
||||||
/httpRequests/
|
|
||||||
# Datasource local storage ignored files
|
|
||||||
/dataSources/
|
|
||||||
/dataSources.local.xml
|
|
||||||
12
.idea/backend.iml
generated
12
.idea/backend.iml
generated
@ -1,12 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<module type="WEB_MODULE" version="4">
|
|
||||||
<component name="NewModuleRootManager">
|
|
||||||
<content url="file://$MODULE_DIR$">
|
|
||||||
<excludeFolder url="file://$MODULE_DIR$/.tmp" />
|
|
||||||
<excludeFolder url="file://$MODULE_DIR$/temp" />
|
|
||||||
<excludeFolder url="file://$MODULE_DIR$/tmp" />
|
|
||||||
</content>
|
|
||||||
<orderEntry type="inheritedJdk" />
|
|
||||||
<orderEntry type="sourceFolder" forTests="false" />
|
|
||||||
</component>
|
|
||||||
</module>
|
|
||||||
8
.idea/modules.xml
generated
8
.idea/modules.xml
generated
@ -1,8 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project version="4">
|
|
||||||
<component name="ProjectModuleManager">
|
|
||||||
<modules>
|
|
||||||
<module fileurl="file://$PROJECT_DIR$/.idea/backend.iml" filepath="$PROJECT_DIR$/.idea/backend.iml" />
|
|
||||||
</modules>
|
|
||||||
</component>
|
|
||||||
</project>
|
|
||||||
6
.idea/vcs.xml
generated
6
.idea/vcs.xml
generated
@ -1,6 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project version="4">
|
|
||||||
<component name="VcsDirectoryMappings">
|
|
||||||
<mapping directory="" vcs="Git" />
|
|
||||||
</component>
|
|
||||||
</project>
|
|
||||||
@ -169,10 +169,11 @@ Table user_watch_histories {
|
|||||||
episode episodes [not null]
|
episode episodes [not null]
|
||||||
updated_at DateTime [not null]
|
updated_at DateTime [not null]
|
||||||
user_id String [not null]
|
user_id String [not null]
|
||||||
episode_id String [not null]
|
episode_number Int [not null]
|
||||||
|
media_id String [not null]
|
||||||
|
|
||||||
indexes {
|
indexes {
|
||||||
(user_id, episode_id) [pk]
|
(user_id, episode_number, media_id) [pk]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -252,10 +253,9 @@ Table medias {
|
|||||||
age_rating_id String
|
age_rating_id String
|
||||||
country_id String
|
country_id String
|
||||||
related_media media_relations [not null]
|
related_media media_relations [not null]
|
||||||
approver_id String
|
|
||||||
created_by_id String
|
|
||||||
updated_by_id String
|
updated_by_id String
|
||||||
deleted_by_id String
|
deleted_by_id String
|
||||||
|
episodes episodes [not null]
|
||||||
home_media_banners home_media_banners [not null]
|
home_media_banners home_media_banners [not null]
|
||||||
saved_to_collections media_collections [not null]
|
saved_to_collections media_collections [not null]
|
||||||
|
|
||||||
@ -296,7 +296,7 @@ Table media_collections {
|
|||||||
Table media_trailers {
|
Table media_trailers {
|
||||||
media_id String [pk]
|
media_id String [pk]
|
||||||
url String
|
url String
|
||||||
embed_url String
|
embed_url String [unique]
|
||||||
small_image_url String
|
small_image_url String
|
||||||
large_image_url String
|
large_image_url String
|
||||||
maximum_image_url String
|
maximum_image_url String
|
||||||
@ -456,13 +456,16 @@ Table media_external_links {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Table media_characters {
|
Table media_characters {
|
||||||
id String [pk]
|
|
||||||
media medias [not null]
|
media medias [not null]
|
||||||
character characters [not null]
|
character characters [not null]
|
||||||
voice_actors voice_actors [not null]
|
voice_actors voice_actors [not null]
|
||||||
role character_role [not null]
|
role character_role [not null]
|
||||||
media_id String [not null]
|
media_id String [not null]
|
||||||
character_id String [not null]
|
character_id String [not null]
|
||||||
|
|
||||||
|
indexes {
|
||||||
|
(character_id, media_id) [pk]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Table characters {
|
Table characters {
|
||||||
@ -482,11 +485,16 @@ Table characters {
|
|||||||
|
|
||||||
Table voice_actors {
|
Table voice_actors {
|
||||||
id String [pk]
|
id String [pk]
|
||||||
media_character_id String [not null]
|
|
||||||
language String [not null]
|
language String [not null]
|
||||||
actor_staff staff [not null]
|
actor_staff staff [not null]
|
||||||
staff_id String [not null]
|
staff_id String [not null]
|
||||||
|
media_id String [not null]
|
||||||
|
character_id String [not null]
|
||||||
media_character media_characters [not null]
|
media_character media_characters [not null]
|
||||||
|
|
||||||
|
indexes {
|
||||||
|
(media_id, character_id, staff_id, language) [unique]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Table staff {
|
Table staff {
|
||||||
@ -501,9 +509,7 @@ Table staff {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Table episodes {
|
Table episodes {
|
||||||
id String [pk]
|
episode_number Int [not null]
|
||||||
media_id String [not null]
|
|
||||||
episode Int [not null]
|
|
||||||
mal_url String
|
mal_url String
|
||||||
forum_url String
|
forum_url String
|
||||||
title String [not null]
|
title String [not null]
|
||||||
@ -522,12 +528,19 @@ Table episodes {
|
|||||||
created_by_id String [not null]
|
created_by_id String [not null]
|
||||||
comments comments [not null]
|
comments comments [not null]
|
||||||
watch_histories user_watch_histories [not null]
|
watch_histories user_watch_histories [not null]
|
||||||
|
media medias [not null]
|
||||||
|
media_id String [not null]
|
||||||
|
|
||||||
|
indexes {
|
||||||
|
(media_id, episode_number) [pk]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Table videos {
|
Table videos {
|
||||||
id String [pk]
|
id String [pk]
|
||||||
service video_services [not null]
|
video_service video_services [not null]
|
||||||
Episode episodes [not null]
|
episode episodes [not null]
|
||||||
|
priority Int
|
||||||
video_code String [not null]
|
video_code String [not null]
|
||||||
short_code String
|
short_code String
|
||||||
thumbnail_code String
|
thumbnail_code String
|
||||||
@ -535,9 +548,15 @@ Table videos {
|
|||||||
created_at DateTime [default: `now()`, not null]
|
created_at DateTime [default: `now()`, not null]
|
||||||
deleted_at DateTime
|
deleted_at DateTime
|
||||||
updated_at DateTime [not null]
|
updated_at DateTime [not null]
|
||||||
episode_id String [not null]
|
episode_number Int [not null]
|
||||||
|
media_id String [not null]
|
||||||
created_by_id String [not null]
|
created_by_id String [not null]
|
||||||
video_submission video_submissions
|
video_submission video_submissions
|
||||||
|
video_service_id String [not null]
|
||||||
|
|
||||||
|
indexes {
|
||||||
|
(media_id, episode_number, priority) [unique]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Table video_submissions {
|
Table video_submissions {
|
||||||
@ -597,7 +616,8 @@ Table comments {
|
|||||||
updated_at DateTime [not null]
|
updated_at DateTime [not null]
|
||||||
deleted_at DateTime
|
deleted_at DateTime
|
||||||
user_id String [not null]
|
user_id String [not null]
|
||||||
episode_id String [not null]
|
episode_number Int [not null]
|
||||||
|
media_id String [not null]
|
||||||
likes comment_likes [not null]
|
likes comment_likes [not null]
|
||||||
audit_logs comment_audit_logs [not null]
|
audit_logs comment_audit_logs [not null]
|
||||||
reports comment_reports [not null]
|
reports comment_reports [not null]
|
||||||
@ -661,7 +681,7 @@ Table countries {
|
|||||||
id String [pk]
|
id String [pk]
|
||||||
name String [not null]
|
name String [not null]
|
||||||
slug String [not null]
|
slug String [not null]
|
||||||
code String [not null]
|
code String [unique, not null]
|
||||||
flag String
|
flag String
|
||||||
banner String
|
banner String
|
||||||
UserCountry users [not null]
|
UserCountry users [not null]
|
||||||
@ -681,11 +701,6 @@ Table home_media_banners {
|
|||||||
created_by_id String [not null]
|
created_by_id String [not null]
|
||||||
}
|
}
|
||||||
|
|
||||||
Table VideoToVideoService {
|
|
||||||
serviceId String [ref: > video_services.id]
|
|
||||||
videosId String [ref: > videos.id]
|
|
||||||
}
|
|
||||||
|
|
||||||
Enum user_role {
|
Enum user_role {
|
||||||
user
|
user
|
||||||
contributor
|
contributor
|
||||||
@ -789,7 +804,7 @@ Ref: user_follows.following_id > users.id
|
|||||||
|
|
||||||
Ref: user_watch_histories.user_id > users.id
|
Ref: user_watch_histories.user_id > users.id
|
||||||
|
|
||||||
Ref: user_watch_histories.episode_id > episodes.id
|
Ref: user_watch_histories.(episode_number, media_id) > episodes.(episode_number, media_id)
|
||||||
|
|
||||||
Ref: collection_members.collection_id > collections.id
|
Ref: collection_members.collection_id > collections.id
|
||||||
|
|
||||||
@ -867,11 +882,15 @@ Ref: media_characters.character_id > characters.id
|
|||||||
|
|
||||||
Ref: voice_actors.staff_id > staff.id
|
Ref: voice_actors.staff_id > staff.id
|
||||||
|
|
||||||
Ref: voice_actors.media_character_id > media_characters.id
|
Ref: voice_actors.(media_id, character_id) > media_characters.(media_id, character_id)
|
||||||
|
|
||||||
Ref: episodes.created_by_id > users.id
|
Ref: episodes.created_by_id > users.id
|
||||||
|
|
||||||
Ref: videos.episode_id > episodes.id
|
Ref: episodes.media_id > medias.id
|
||||||
|
|
||||||
|
Ref: videos.video_service_id > video_services.id
|
||||||
|
|
||||||
|
Ref: videos.(episode_number, media_id) > episodes.(episode_number, media_id)
|
||||||
|
|
||||||
Ref: video_submissions.created_by_id > users.id
|
Ref: video_submissions.created_by_id > users.id
|
||||||
|
|
||||||
@ -887,7 +906,7 @@ Ref: video_service_submissions.video_service_id - video_services.id
|
|||||||
|
|
||||||
Ref: comments.user_id > users.id
|
Ref: comments.user_id > users.id
|
||||||
|
|
||||||
Ref: comments.episode_id > episodes.id
|
Ref: comments.(episode_number, media_id) > episodes.(episode_number, media_id)
|
||||||
|
|
||||||
Ref: comment_likes.user_id > users.id
|
Ref: comment_likes.user_id > users.id
|
||||||
|
|
||||||
|
|||||||
@ -1,911 +0,0 @@
|
|||||||
-- CreateEnum
|
|
||||||
CREATE TYPE "user_role" AS ENUM ('user', 'contributor', 'curator', 'admin');
|
|
||||||
|
|
||||||
-- CreateEnum
|
|
||||||
CREATE TYPE "user_sex" AS ENUM ('male', 'female');
|
|
||||||
|
|
||||||
-- CreateEnum
|
|
||||||
CREATE TYPE "auth_provider" AS ENUM ('google', 'github');
|
|
||||||
|
|
||||||
-- CreateEnum
|
|
||||||
CREATE TYPE "device_type" AS ENUM ('mobile', 'tablet', 'desktop', 'unknown');
|
|
||||||
|
|
||||||
-- CreateEnum
|
|
||||||
CREATE TYPE "user_preference_state" AS ENUM ('exclude', 'include');
|
|
||||||
|
|
||||||
-- CreateEnum
|
|
||||||
CREATE TYPE "media_season" AS ENUM ('winter', 'spring', 'summer', 'fall');
|
|
||||||
|
|
||||||
-- CreateEnum
|
|
||||||
CREATE TYPE "character_role" AS ENUM ('main', 'supporting', 'background');
|
|
||||||
|
|
||||||
-- CreateEnum
|
|
||||||
CREATE TYPE "status_submission" AS ENUM ('pending', 'approved', 'rejected');
|
|
||||||
|
|
||||||
-- CreateEnum
|
|
||||||
CREATE TYPE "like_type" AS ENUM ('like', 'dislike');
|
|
||||||
|
|
||||||
-- CreateEnum
|
|
||||||
CREATE TYPE "audit_action" AS ENUM ('delete', 'restore', 'edit', 'flag');
|
|
||||||
|
|
||||||
-- CreateEnum
|
|
||||||
CREATE TYPE "privacy_level" AS ENUM ('public', 'unlisted', 'private');
|
|
||||||
|
|
||||||
-- CreateEnum
|
|
||||||
CREATE TYPE "collection_access_level" AS ENUM ('owner', 'moderator', 'contributor', 'viewer');
|
|
||||||
|
|
||||||
-- CreateTable
|
|
||||||
CREATE TABLE "users" (
|
|
||||||
"id" UUID NOT NULL,
|
|
||||||
"email" TEXT NOT NULL,
|
|
||||||
"password" VARCHAR(255),
|
|
||||||
"username" VARCHAR(28) NOT NULL,
|
|
||||||
"fullname" VARCHAR(32) NOT NULL,
|
|
||||||
"avatar" VARCHAR(255),
|
|
||||||
"bio" TEXT,
|
|
||||||
"datebirth" DATE,
|
|
||||||
"role" "user_role" NOT NULL DEFAULT 'user',
|
|
||||||
"sex" "user_sex",
|
|
||||||
"phone_number" VARCHAR(20),
|
|
||||||
"auth_provider" VARCHAR(64),
|
|
||||||
"provider_token" VARCHAR(255),
|
|
||||||
"created_at" TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
||||||
"updated_at" TIMESTAMPTZ NOT NULL,
|
|
||||||
"deleted_at" TIMESTAMPTZ,
|
|
||||||
"countryId" UUID,
|
|
||||||
|
|
||||||
CONSTRAINT "users_pkey" PRIMARY KEY ("id")
|
|
||||||
);
|
|
||||||
|
|
||||||
-- CreateTable
|
|
||||||
CREATE TABLE "user_addresses" (
|
|
||||||
"user_id" UUID NOT NULL,
|
|
||||||
"address" VARCHAR(255) NOT NULL,
|
|
||||||
"district" VARCHAR(100) NOT NULL,
|
|
||||||
"city" VARCHAR(100) NOT NULL,
|
|
||||||
"province" VARCHAR(100) NOT NULL,
|
|
||||||
"postal_code" VARCHAR(20) NOT NULL,
|
|
||||||
"coordinate" VARCHAR(50),
|
|
||||||
"updated_at" TIMESTAMPTZ NOT NULL,
|
|
||||||
|
|
||||||
CONSTRAINT "user_addresses_pkey" PRIMARY KEY ("user_id")
|
|
||||||
);
|
|
||||||
|
|
||||||
-- CreateTable
|
|
||||||
CREATE TABLE "user_oauth_accounts" (
|
|
||||||
"id" UUID NOT NULL,
|
|
||||||
"provider_name" "auth_provider" NOT NULL,
|
|
||||||
"provider_sub" VARCHAR(255),
|
|
||||||
"provider_email" VARCHAR(255),
|
|
||||||
"provider_token" VARCHAR(255),
|
|
||||||
"refresh_token" VARCHAR(255),
|
|
||||||
"expires_at" TIMESTAMPTZ,
|
|
||||||
"last_login" TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
||||||
"created_at" TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
||||||
"updated_at" TIMESTAMPTZ NOT NULL,
|
|
||||||
"user_id" UUID NOT NULL,
|
|
||||||
|
|
||||||
CONSTRAINT "user_oauth_accounts_pkey" PRIMARY KEY ("id")
|
|
||||||
);
|
|
||||||
|
|
||||||
-- CreateTable
|
|
||||||
CREATE TABLE "user_sessions" (
|
|
||||||
"id" UUID NOT NULL,
|
|
||||||
"device_type" "device_type" NOT NULL,
|
|
||||||
"os_type" VARCHAR(50),
|
|
||||||
"os_version" VARCHAR(50),
|
|
||||||
"browser_name" VARCHAR(50),
|
|
||||||
"browser_version" VARCHAR(50),
|
|
||||||
"ip_login" INET,
|
|
||||||
"login_at" TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
||||||
"logout_at" TIMESTAMPTZ,
|
|
||||||
"user_id" UUID NOT NULL,
|
|
||||||
|
|
||||||
CONSTRAINT "user_sessions_pkey" PRIMARY KEY ("id")
|
|
||||||
);
|
|
||||||
|
|
||||||
-- CreateTable
|
|
||||||
CREATE TABLE "user_preferences" (
|
|
||||||
"comment_picture" VARCHAR(255),
|
|
||||||
"enable_watch_history" BOOLEAN NOT NULL DEFAULT true,
|
|
||||||
"enable_search_history" BOOLEAN NOT NULL DEFAULT false,
|
|
||||||
"is_private_account" BOOLEAN NOT NULL DEFAULT false,
|
|
||||||
"can_message_me" BOOLEAN NOT NULL DEFAULT true,
|
|
||||||
"publish_birthday" BOOLEAN NOT NULL DEFAULT false,
|
|
||||||
"publish_email" BOOLEAN NOT NULL DEFAULT false,
|
|
||||||
"publish_phone_number" BOOLEAN NOT NULL DEFAULT false,
|
|
||||||
"publish_country" BOOLEAN NOT NULL DEFAULT false,
|
|
||||||
"publish_partner" BOOLEAN NOT NULL DEFAULT true,
|
|
||||||
"subscribe_to_newsletter" BOOLEAN NOT NULL DEFAULT true,
|
|
||||||
"enable_security_alerts" BOOLEAN NOT NULL DEFAULT true,
|
|
||||||
"user_id" UUID NOT NULL,
|
|
||||||
"char_as_partner_id" UUID NOT NULL,
|
|
||||||
|
|
||||||
CONSTRAINT "user_preferences_pkey" PRIMARY KEY ("user_id")
|
|
||||||
);
|
|
||||||
|
|
||||||
-- CreateTable
|
|
||||||
CREATE TABLE "user_genre_preferences" (
|
|
||||||
"state" "user_preference_state" NOT NULL,
|
|
||||||
"user_id" UUID NOT NULL,
|
|
||||||
"genre_id" UUID NOT NULL,
|
|
||||||
|
|
||||||
CONSTRAINT "user_genre_preferences_pkey" PRIMARY KEY ("user_id","genre_id")
|
|
||||||
);
|
|
||||||
|
|
||||||
-- CreateTable
|
|
||||||
CREATE TABLE "user_rating_preferences" (
|
|
||||||
"state" "user_preference_state" NOT NULL,
|
|
||||||
"user_id" UUID NOT NULL,
|
|
||||||
"rating_id" UUID NOT NULL,
|
|
||||||
|
|
||||||
CONSTRAINT "user_rating_preferences_pkey" PRIMARY KEY ("user_id","rating_id")
|
|
||||||
);
|
|
||||||
|
|
||||||
-- CreateTable
|
|
||||||
CREATE TABLE "user_country_preferences" (
|
|
||||||
"state" "user_preference_state" NOT NULL,
|
|
||||||
"user_id" UUID NOT NULL,
|
|
||||||
"country_id" UUID NOT NULL,
|
|
||||||
|
|
||||||
CONSTRAINT "user_country_preferences_pkey" PRIMARY KEY ("user_id","country_id")
|
|
||||||
);
|
|
||||||
|
|
||||||
-- CreateTable
|
|
||||||
CREATE TABLE "user_follows" (
|
|
||||||
"created_at" TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
||||||
"follower_id" UUID NOT NULL,
|
|
||||||
"following_id" UUID NOT NULL,
|
|
||||||
|
|
||||||
CONSTRAINT "user_follows_pkey" PRIMARY KEY ("follower_id","following_id")
|
|
||||||
);
|
|
||||||
|
|
||||||
-- CreateTable
|
|
||||||
CREATE TABLE "user_watch_histories" (
|
|
||||||
"updated_at" TIMESTAMPTZ NOT NULL,
|
|
||||||
"user_id" UUID NOT NULL,
|
|
||||||
"episode_id" UUID NOT NULL,
|
|
||||||
|
|
||||||
CONSTRAINT "user_watch_histories_pkey" PRIMARY KEY ("user_id","episode_id")
|
|
||||||
);
|
|
||||||
|
|
||||||
-- CreateTable
|
|
||||||
CREATE TABLE "collections" (
|
|
||||||
"id" UUID NOT NULL,
|
|
||||||
"name" VARCHAR(64) NOT NULL,
|
|
||||||
"code" VARCHAR(12),
|
|
||||||
"cover_url" VARCHAR(255),
|
|
||||||
"privacy" "privacy_level" NOT NULL DEFAULT 'private',
|
|
||||||
"created_at" TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
||||||
"updated_at" TIMESTAMPTZ NOT NULL,
|
|
||||||
|
|
||||||
CONSTRAINT "collections_pkey" PRIMARY KEY ("id")
|
|
||||||
);
|
|
||||||
|
|
||||||
-- CreateTable
|
|
||||||
CREATE TABLE "collection_members" (
|
|
||||||
"access_level" "collection_access_level" NOT NULL,
|
|
||||||
"invited_at" TIMESTAMPTZ,
|
|
||||||
"collection_id" UUID NOT NULL,
|
|
||||||
"user_id" UUID NOT NULL,
|
|
||||||
"invited_by_id" UUID,
|
|
||||||
|
|
||||||
CONSTRAINT "collection_members_pkey" PRIMARY KEY ("collection_id","user_id")
|
|
||||||
);
|
|
||||||
|
|
||||||
-- CreateTable
|
|
||||||
CREATE TABLE "medias" (
|
|
||||||
"id" UUID NOT NULL,
|
|
||||||
"mal_id" INTEGER NOT NULL,
|
|
||||||
"title" VARCHAR(255) NOT NULL,
|
|
||||||
"title_secondary" VARCHAR(255),
|
|
||||||
"title_original" VARCHAR(255),
|
|
||||||
"title_synonyms" VARCHAR(255)[],
|
|
||||||
"synopsis" TEXT,
|
|
||||||
"small_image_url" VARCHAR(255),
|
|
||||||
"medium_image_url" VARCHAR(255) NOT NULL,
|
|
||||||
"large_image_url" VARCHAR(255),
|
|
||||||
"airing" BOOLEAN NOT NULL,
|
|
||||||
"start_airing" DATE,
|
|
||||||
"end_airing" DATE,
|
|
||||||
"score" DECIMAL(2,2),
|
|
||||||
"score_total" INTEGER NOT NULL DEFAULT 0,
|
|
||||||
"score_count" INTEGER NOT NULL DEFAULT 0,
|
|
||||||
"background" TEXT,
|
|
||||||
"season" "media_season" NOT NULL,
|
|
||||||
"year" SMALLINT,
|
|
||||||
"broadcast_day" VARCHAR(20),
|
|
||||||
"created_at" TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
||||||
"updated_at" TIMESTAMPTZ NOT NULL,
|
|
||||||
"deleted_at" TIMESTAMPTZ,
|
|
||||||
"type_id" UUID NOT NULL,
|
|
||||||
"source_id" UUID NOT NULL,
|
|
||||||
"status_id" UUID NOT NULL,
|
|
||||||
"age_rating_id" UUID,
|
|
||||||
"country_id" UUID,
|
|
||||||
"approver_id" UUID,
|
|
||||||
"created_by_id" UUID,
|
|
||||||
"updated_by_id" UUID,
|
|
||||||
"deleted_by_id" UUID,
|
|
||||||
|
|
||||||
CONSTRAINT "medias_pkey" PRIMARY KEY ("id")
|
|
||||||
);
|
|
||||||
|
|
||||||
-- CreateTable
|
|
||||||
CREATE TABLE "media_submissions" (
|
|
||||||
"id" UUID NOT NULL,
|
|
||||||
"status" "status_submission" NOT NULL DEFAULT 'pending',
|
|
||||||
"reviewed_at" TIMESTAMPTZ,
|
|
||||||
"reason" TEXT,
|
|
||||||
"created_at" TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
||||||
"media_id" UUID NOT NULL,
|
|
||||||
"submitter_id" UUID NOT NULL,
|
|
||||||
"reviewer_id" UUID,
|
|
||||||
|
|
||||||
CONSTRAINT "media_submissions_pkey" PRIMARY KEY ("id")
|
|
||||||
);
|
|
||||||
|
|
||||||
-- CreateTable
|
|
||||||
CREATE TABLE "media_collections" (
|
|
||||||
"added_at" TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
||||||
"media_id" UUID NOT NULL,
|
|
||||||
"collection_id" UUID NOT NULL,
|
|
||||||
"added_by_id" UUID NOT NULL,
|
|
||||||
|
|
||||||
CONSTRAINT "media_collections_pkey" PRIMARY KEY ("media_id","collection_id")
|
|
||||||
);
|
|
||||||
|
|
||||||
-- CreateTable
|
|
||||||
CREATE TABLE "media_trailers" (
|
|
||||||
"media_id" UUID NOT NULL,
|
|
||||||
"url" VARCHAR(255),
|
|
||||||
"embed_url" VARCHAR(255),
|
|
||||||
"small_image_url" VARCHAR(255),
|
|
||||||
"large_image_url" VARCHAR(255),
|
|
||||||
"maximum_image_url" VARCHAR(255),
|
|
||||||
|
|
||||||
CONSTRAINT "media_trailers_pkey" PRIMARY KEY ("media_id")
|
|
||||||
);
|
|
||||||
|
|
||||||
-- CreateTable
|
|
||||||
CREATE TABLE "media_types" (
|
|
||||||
"id" UUID NOT NULL,
|
|
||||||
"name" VARCHAR(100) NOT NULL,
|
|
||||||
|
|
||||||
CONSTRAINT "media_types_pkey" PRIMARY KEY ("id")
|
|
||||||
);
|
|
||||||
|
|
||||||
-- CreateTable
|
|
||||||
CREATE TABLE "media_sources" (
|
|
||||||
"id" UUID NOT NULL,
|
|
||||||
"name" VARCHAR(100) NOT NULL,
|
|
||||||
|
|
||||||
CONSTRAINT "media_sources_pkey" PRIMARY KEY ("id")
|
|
||||||
);
|
|
||||||
|
|
||||||
-- CreateTable
|
|
||||||
CREATE TABLE "media_statuses" (
|
|
||||||
"id" UUID NOT NULL,
|
|
||||||
"name" VARCHAR(100) NOT NULL,
|
|
||||||
|
|
||||||
CONSTRAINT "media_statuses_pkey" PRIMARY KEY ("id")
|
|
||||||
);
|
|
||||||
|
|
||||||
-- CreateTable
|
|
||||||
CREATE TABLE "media_age_ratings" (
|
|
||||||
"id" UUID NOT NULL,
|
|
||||||
"name" VARCHAR(100) NOT NULL,
|
|
||||||
"min_age" SMALLINT NOT NULL,
|
|
||||||
|
|
||||||
CONSTRAINT "media_age_ratings_pkey" PRIMARY KEY ("id")
|
|
||||||
);
|
|
||||||
|
|
||||||
-- CreateTable
|
|
||||||
CREATE TABLE "media_producers" (
|
|
||||||
"media_id" UUID NOT NULL,
|
|
||||||
"producer_id" UUID NOT NULL,
|
|
||||||
|
|
||||||
CONSTRAINT "media_producers_pkey" PRIMARY KEY ("media_id","producer_id")
|
|
||||||
);
|
|
||||||
|
|
||||||
-- CreateTable
|
|
||||||
CREATE TABLE "media_licensors" (
|
|
||||||
"media_id" UUID NOT NULL,
|
|
||||||
"licensor_id" UUID NOT NULL,
|
|
||||||
|
|
||||||
CONSTRAINT "media_licensors_pkey" PRIMARY KEY ("media_id","licensor_id")
|
|
||||||
);
|
|
||||||
|
|
||||||
-- CreateTable
|
|
||||||
CREATE TABLE "media_studios" (
|
|
||||||
"media_id" UUID NOT NULL,
|
|
||||||
"studio_id" UUID NOT NULL,
|
|
||||||
|
|
||||||
CONSTRAINT "media_studios_pkey" PRIMARY KEY ("media_id","studio_id")
|
|
||||||
);
|
|
||||||
|
|
||||||
-- CreateTable
|
|
||||||
CREATE TABLE "producers" (
|
|
||||||
"id" UUID NOT NULL,
|
|
||||||
"mal_id" INTEGER NOT NULL,
|
|
||||||
"type" VARCHAR(24) NOT NULL,
|
|
||||||
"name" VARCHAR(255) NOT NULL,
|
|
||||||
"url" VARCHAR(255),
|
|
||||||
"created_at" TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
||||||
"updated_at" TIMESTAMPTZ NOT NULL,
|
|
||||||
"deleted_at" TIMESTAMPTZ,
|
|
||||||
"created_by_id" UUID NOT NULL,
|
|
||||||
|
|
||||||
CONSTRAINT "producers_pkey" PRIMARY KEY ("id")
|
|
||||||
);
|
|
||||||
|
|
||||||
-- CreateTable
|
|
||||||
CREATE TABLE "media_genres" (
|
|
||||||
"media_id" UUID NOT NULL,
|
|
||||||
"genre_id" UUID NOT NULL,
|
|
||||||
|
|
||||||
CONSTRAINT "media_genres_pkey" PRIMARY KEY ("media_id","genre_id")
|
|
||||||
);
|
|
||||||
|
|
||||||
-- CreateTable
|
|
||||||
CREATE TABLE "media_explicit_genres" (
|
|
||||||
"media_id" UUID NOT NULL,
|
|
||||||
"genre_id" UUID NOT NULL,
|
|
||||||
|
|
||||||
CONSTRAINT "media_explicit_genres_pkey" PRIMARY KEY ("media_id","genre_id")
|
|
||||||
);
|
|
||||||
|
|
||||||
-- CreateTable
|
|
||||||
CREATE TABLE "media_themes" (
|
|
||||||
"media_id" UUID NOT NULL,
|
|
||||||
"genre_id" UUID NOT NULL,
|
|
||||||
|
|
||||||
CONSTRAINT "media_themes_pkey" PRIMARY KEY ("media_id","genre_id")
|
|
||||||
);
|
|
||||||
|
|
||||||
-- CreateTable
|
|
||||||
CREATE TABLE "media_demographics" (
|
|
||||||
"media_id" UUID NOT NULL,
|
|
||||||
"demographic_id" UUID NOT NULL,
|
|
||||||
|
|
||||||
CONSTRAINT "media_demographics_pkey" PRIMARY KEY ("media_id","demographic_id")
|
|
||||||
);
|
|
||||||
|
|
||||||
-- CreateTable
|
|
||||||
CREATE TABLE "genres" (
|
|
||||||
"id" UUID NOT NULL,
|
|
||||||
"mal_id" SMALLINT NOT NULL,
|
|
||||||
"name" VARCHAR(100) NOT NULL,
|
|
||||||
"slug" VARCHAR(115) NOT NULL,
|
|
||||||
"thumbnail_url" VARCHAR(255),
|
|
||||||
|
|
||||||
CONSTRAINT "genres_pkey" PRIMARY KEY ("id")
|
|
||||||
);
|
|
||||||
|
|
||||||
-- CreateTable
|
|
||||||
CREATE TABLE "media_relations" (
|
|
||||||
"relation_type" VARCHAR(50) NOT NULL,
|
|
||||||
"media_id" UUID NOT NULL,
|
|
||||||
"related_media_id" UUID NOT NULL,
|
|
||||||
|
|
||||||
CONSTRAINT "media_relations_pkey" PRIMARY KEY ("media_id","related_media_id")
|
|
||||||
);
|
|
||||||
|
|
||||||
-- CreateTable
|
|
||||||
CREATE TABLE "media_external_links" (
|
|
||||||
"id" UUID NOT NULL,
|
|
||||||
"url" VARCHAR(255) NOT NULL,
|
|
||||||
"site_name" VARCHAR(100),
|
|
||||||
"media_id" UUID NOT NULL,
|
|
||||||
|
|
||||||
CONSTRAINT "media_external_links_pkey" PRIMARY KEY ("id")
|
|
||||||
);
|
|
||||||
|
|
||||||
-- CreateTable
|
|
||||||
CREATE TABLE "media_characters" (
|
|
||||||
"id" UUID NOT NULL,
|
|
||||||
"role" "character_role" NOT NULL,
|
|
||||||
"media_id" UUID NOT NULL,
|
|
||||||
"character_id" UUID NOT NULL,
|
|
||||||
|
|
||||||
CONSTRAINT "media_characters_pkey" PRIMARY KEY ("id")
|
|
||||||
);
|
|
||||||
|
|
||||||
-- CreateTable
|
|
||||||
CREATE TABLE "characters" (
|
|
||||||
"id" UUID NOT NULL,
|
|
||||||
"name" VARCHAR(255) NOT NULL,
|
|
||||||
"image" VARCHAR(255),
|
|
||||||
"small_image" VARCHAR(255),
|
|
||||||
"mal_id" INTEGER,
|
|
||||||
"fanpage_url" VARCHAR(255),
|
|
||||||
"liked" INTEGER NOT NULL DEFAULT 0,
|
|
||||||
"deleted_at" TIMESTAMPTZ,
|
|
||||||
"updated_at" TIMESTAMPTZ NOT NULL,
|
|
||||||
"created_at" TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
||||||
|
|
||||||
CONSTRAINT "characters_pkey" PRIMARY KEY ("id")
|
|
||||||
);
|
|
||||||
|
|
||||||
-- CreateTable
|
|
||||||
CREATE TABLE "voice_actors" (
|
|
||||||
"id" UUID NOT NULL,
|
|
||||||
"media_character_id" UUID NOT NULL,
|
|
||||||
"language" VARCHAR(115) NOT NULL,
|
|
||||||
"staff_id" UUID NOT NULL,
|
|
||||||
|
|
||||||
CONSTRAINT "voice_actors_pkey" PRIMARY KEY ("id")
|
|
||||||
);
|
|
||||||
|
|
||||||
-- CreateTable
|
|
||||||
CREATE TABLE "staff" (
|
|
||||||
"id" UUID NOT NULL,
|
|
||||||
"name" VARCHAR(255) NOT NULL,
|
|
||||||
"image" VARCHAR(255),
|
|
||||||
"mal_id" INTEGER,
|
|
||||||
"deleted_at" TIMESTAMPTZ,
|
|
||||||
"updated_at" TIMESTAMPTZ NOT NULL,
|
|
||||||
"created_at" TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
||||||
|
|
||||||
CONSTRAINT "staff_pkey" PRIMARY KEY ("id")
|
|
||||||
);
|
|
||||||
|
|
||||||
-- CreateTable
|
|
||||||
CREATE TABLE "episodes" (
|
|
||||||
"id" UUID NOT NULL,
|
|
||||||
"media_id" UUID NOT NULL,
|
|
||||||
"episode" SMALLINT NOT NULL,
|
|
||||||
"mal_url" VARCHAR(255),
|
|
||||||
"forum_url" VARCHAR(255),
|
|
||||||
"title" VARCHAR(155) NOT NULL,
|
|
||||||
"title_origin" VARCHAR(155),
|
|
||||||
"title_romanji" VARCHAR(155),
|
|
||||||
"aired_at" DATE,
|
|
||||||
"filler" BOOLEAN NOT NULL,
|
|
||||||
"recap" BOOLEAN NOT NULL,
|
|
||||||
"total_score" INTEGER NOT NULL DEFAULT 0,
|
|
||||||
"score_count" INTEGER NOT NULL DEFAULT 0,
|
|
||||||
"deleted_at" TIMESTAMPTZ,
|
|
||||||
"updated_at" TIMESTAMPTZ NOT NULL,
|
|
||||||
"created_at" TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
||||||
"created_by_id" UUID NOT NULL,
|
|
||||||
|
|
||||||
CONSTRAINT "episodes_pkey" PRIMARY KEY ("id")
|
|
||||||
);
|
|
||||||
|
|
||||||
-- CreateTable
|
|
||||||
CREATE TABLE "videos" (
|
|
||||||
"id" UUID NOT NULL,
|
|
||||||
"video_code" VARCHAR(255) NOT NULL,
|
|
||||||
"short_code" VARCHAR(255),
|
|
||||||
"thumbnail_code" VARCHAR(255),
|
|
||||||
"download_code" VARCHAR(255),
|
|
||||||
"created_at" TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
||||||
"deleted_at" TIMESTAMPTZ,
|
|
||||||
"updated_at" TIMESTAMPTZ NOT NULL,
|
|
||||||
"episode_id" UUID NOT NULL,
|
|
||||||
"created_by_id" UUID NOT NULL,
|
|
||||||
|
|
||||||
CONSTRAINT "videos_pkey" PRIMARY KEY ("id")
|
|
||||||
);
|
|
||||||
|
|
||||||
-- CreateTable
|
|
||||||
CREATE TABLE "video_submissions" (
|
|
||||||
"video_id" UUID NOT NULL,
|
|
||||||
"status" "status_submission" NOT NULL DEFAULT 'pending',
|
|
||||||
"reviewed_at" TIMESTAMPTZ,
|
|
||||||
"reason" TEXT,
|
|
||||||
"created_at" TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
||||||
"created_by_id" UUID NOT NULL,
|
|
||||||
"reviewer_id" UUID,
|
|
||||||
|
|
||||||
CONSTRAINT "video_submissions_pkey" PRIMARY KEY ("video_id")
|
|
||||||
);
|
|
||||||
|
|
||||||
-- CreateTable
|
|
||||||
CREATE TABLE "video_services" (
|
|
||||||
"id" UUID NOT NULL,
|
|
||||||
"name" VARCHAR(155) NOT NULL,
|
|
||||||
"resolution" SMALLINT NOT NULL,
|
|
||||||
"domain" VARCHAR(255) NOT NULL,
|
|
||||||
"image_url" VARCHAR(255),
|
|
||||||
"hex_color" VARCHAR(10),
|
|
||||||
"endpoint_video" VARCHAR(255) NOT NULL,
|
|
||||||
"endpoint_short" VARCHAR(255),
|
|
||||||
"endpoint_image" VARCHAR(255),
|
|
||||||
"endpoint_download" VARCHAR(255),
|
|
||||||
"deleted_at" TIMESTAMPTZ,
|
|
||||||
"updated_at" TIMESTAMPTZ NOT NULL,
|
|
||||||
"created_at" TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
||||||
|
|
||||||
CONSTRAINT "video_services_pkey" PRIMARY KEY ("id")
|
|
||||||
);
|
|
||||||
|
|
||||||
-- CreateTable
|
|
||||||
CREATE TABLE "video_service_submissions" (
|
|
||||||
"video_service_id" UUID NOT NULL,
|
|
||||||
"status" "status_submission" NOT NULL DEFAULT 'pending',
|
|
||||||
"reviewed_at" TIMESTAMPTZ,
|
|
||||||
"reason" TEXT,
|
|
||||||
"created_at" TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
||||||
"created_by_id" UUID NOT NULL,
|
|
||||||
"reviewer_id" UUID,
|
|
||||||
|
|
||||||
CONSTRAINT "video_service_submissions_pkey" PRIMARY KEY ("video_service_id")
|
|
||||||
);
|
|
||||||
|
|
||||||
-- CreateTable
|
|
||||||
CREATE TABLE "comments" (
|
|
||||||
"id" UUID NOT NULL,
|
|
||||||
"content" TEXT NOT NULL,
|
|
||||||
"created_at" TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
||||||
"updated_at" TIMESTAMPTZ NOT NULL,
|
|
||||||
"deleted_at" TIMESTAMPTZ,
|
|
||||||
"user_id" UUID NOT NULL,
|
|
||||||
"episode_id" UUID NOT NULL,
|
|
||||||
|
|
||||||
CONSTRAINT "comments_pkey" PRIMARY KEY ("id")
|
|
||||||
);
|
|
||||||
|
|
||||||
-- CreateTable
|
|
||||||
CREATE TABLE "comment_likes" (
|
|
||||||
"user_id" UUID NOT NULL,
|
|
||||||
"comment_id" UUID NOT NULL,
|
|
||||||
"type" "like_type" NOT NULL,
|
|
||||||
"created_at" TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
||||||
|
|
||||||
CONSTRAINT "comment_likes_pkey" PRIMARY KEY ("user_id","comment_id")
|
|
||||||
);
|
|
||||||
|
|
||||||
-- CreateTable
|
|
||||||
CREATE TABLE "comment_audit_logs" (
|
|
||||||
"id" UUID NOT NULL,
|
|
||||||
"action" "audit_action" NOT NULL,
|
|
||||||
"created_at" TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
||||||
"comment_id" UUID NOT NULL,
|
|
||||||
"performed_by_id" UUID NOT NULL,
|
|
||||||
|
|
||||||
CONSTRAINT "comment_audit_logs_pkey" PRIMARY KEY ("id")
|
|
||||||
);
|
|
||||||
|
|
||||||
-- CreateTable
|
|
||||||
CREATE TABLE "comment_reports" (
|
|
||||||
"id" UUID NOT NULL,
|
|
||||||
"title" VARCHAR(115) NOT NULL,
|
|
||||||
"status" "status_submission" NOT NULL,
|
|
||||||
"description" TEXT,
|
|
||||||
"reported_at" TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
||||||
"closed_at" TIMESTAMPTZ,
|
|
||||||
"reporter_id" UUID NOT NULL,
|
|
||||||
"comment_id" UUID NOT NULL,
|
|
||||||
|
|
||||||
CONSTRAINT "comment_reports_pkey" PRIMARY KEY ("id")
|
|
||||||
);
|
|
||||||
|
|
||||||
-- CreateTable
|
|
||||||
CREATE TABLE "provisioned_users" (
|
|
||||||
"provisioned_at" TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
||||||
"reason" VARCHAR(255),
|
|
||||||
"admin_id" UUID NOT NULL,
|
|
||||||
"user_id" UUID NOT NULL,
|
|
||||||
|
|
||||||
CONSTRAINT "provisioned_users_pkey" PRIMARY KEY ("admin_id","user_id")
|
|
||||||
);
|
|
||||||
|
|
||||||
-- CreateTable
|
|
||||||
CREATE TABLE "countries" (
|
|
||||||
"id" UUID NOT NULL,
|
|
||||||
"name" VARCHAR(155) NOT NULL,
|
|
||||||
"slug" VARCHAR(165) NOT NULL,
|
|
||||||
"code" VARCHAR(3) NOT NULL,
|
|
||||||
"flag" VARCHAR(255),
|
|
||||||
"banner" VARCHAR(255),
|
|
||||||
|
|
||||||
CONSTRAINT "countries_pkey" PRIMARY KEY ("id")
|
|
||||||
);
|
|
||||||
|
|
||||||
-- CreateTable
|
|
||||||
CREATE TABLE "home_media_banners" (
|
|
||||||
"id" UUID NOT NULL,
|
|
||||||
"priority" SMALLINT NOT NULL,
|
|
||||||
"start_show" DATE NOT NULL,
|
|
||||||
"end_show" DATE NOT NULL,
|
|
||||||
"created_at" TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
||||||
"media_id" UUID NOT NULL,
|
|
||||||
"created_by_id" UUID NOT NULL,
|
|
||||||
|
|
||||||
CONSTRAINT "home_media_banners_pkey" PRIMARY KEY ("id")
|
|
||||||
);
|
|
||||||
|
|
||||||
-- CreateTable
|
|
||||||
CREATE TABLE "_VideoToVideoService" (
|
|
||||||
"A" UUID NOT NULL,
|
|
||||||
"B" UUID NOT NULL,
|
|
||||||
|
|
||||||
CONSTRAINT "_VideoToVideoService_AB_pkey" PRIMARY KEY ("A","B")
|
|
||||||
);
|
|
||||||
|
|
||||||
-- CreateIndex
|
|
||||||
CREATE UNIQUE INDEX "users_email_key" ON "users"("email");
|
|
||||||
|
|
||||||
-- CreateIndex
|
|
||||||
CREATE UNIQUE INDEX "users_username_key" ON "users"("username");
|
|
||||||
|
|
||||||
-- CreateIndex
|
|
||||||
CREATE INDEX "users_email_idx" ON "users"("email");
|
|
||||||
|
|
||||||
-- CreateIndex
|
|
||||||
CREATE INDEX "users_username_idx" ON "users"("username");
|
|
||||||
|
|
||||||
-- CreateIndex
|
|
||||||
CREATE UNIQUE INDEX "medias_mal_id_key" ON "medias"("mal_id");
|
|
||||||
|
|
||||||
-- CreateIndex
|
|
||||||
CREATE UNIQUE INDEX "media_submissions_media_id_key" ON "media_submissions"("media_id");
|
|
||||||
|
|
||||||
-- CreateIndex
|
|
||||||
CREATE UNIQUE INDEX "media_types_name_key" ON "media_types"("name");
|
|
||||||
|
|
||||||
-- CreateIndex
|
|
||||||
CREATE UNIQUE INDEX "media_sources_name_key" ON "media_sources"("name");
|
|
||||||
|
|
||||||
-- CreateIndex
|
|
||||||
CREATE UNIQUE INDEX "media_statuses_name_key" ON "media_statuses"("name");
|
|
||||||
|
|
||||||
-- CreateIndex
|
|
||||||
CREATE UNIQUE INDEX "media_age_ratings_name_key" ON "media_age_ratings"("name");
|
|
||||||
|
|
||||||
-- CreateIndex
|
|
||||||
CREATE UNIQUE INDEX "producers_mal_id_key" ON "producers"("mal_id");
|
|
||||||
|
|
||||||
-- CreateIndex
|
|
||||||
CREATE UNIQUE INDEX "genres_mal_id_key" ON "genres"("mal_id");
|
|
||||||
|
|
||||||
-- CreateIndex
|
|
||||||
CREATE UNIQUE INDEX "characters_mal_id_key" ON "characters"("mal_id");
|
|
||||||
|
|
||||||
-- CreateIndex
|
|
||||||
CREATE UNIQUE INDEX "staff_mal_id_key" ON "staff"("mal_id");
|
|
||||||
|
|
||||||
-- CreateIndex
|
|
||||||
CREATE INDEX "episodes_media_id_episode_idx" ON "episodes"("media_id", "episode");
|
|
||||||
|
|
||||||
-- CreateIndex
|
|
||||||
CREATE UNIQUE INDEX "video_services_name_resolution_key" ON "video_services"("name", "resolution");
|
|
||||||
|
|
||||||
-- CreateIndex
|
|
||||||
CREATE UNIQUE INDEX "home_media_banners_priority_key" ON "home_media_banners"("priority");
|
|
||||||
|
|
||||||
-- CreateIndex
|
|
||||||
CREATE INDEX "_VideoToVideoService_B_index" ON "_VideoToVideoService"("B");
|
|
||||||
|
|
||||||
-- AddForeignKey
|
|
||||||
ALTER TABLE "users" ADD CONSTRAINT "users_countryId_fkey" FOREIGN KEY ("countryId") REFERENCES "countries"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|
|
||||||
|
|
||||||
-- AddForeignKey
|
|
||||||
ALTER TABLE "user_addresses" ADD CONSTRAINT "user_addresses_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "users"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
|
||||||
|
|
||||||
-- AddForeignKey
|
|
||||||
ALTER TABLE "user_oauth_accounts" ADD CONSTRAINT "user_oauth_accounts_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "users"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
|
||||||
|
|
||||||
-- AddForeignKey
|
|
||||||
ALTER TABLE "user_sessions" ADD CONSTRAINT "user_sessions_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "users"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
|
||||||
|
|
||||||
-- AddForeignKey
|
|
||||||
ALTER TABLE "user_preferences" ADD CONSTRAINT "user_preferences_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "users"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
|
||||||
|
|
||||||
-- AddForeignKey
|
|
||||||
ALTER TABLE "user_preferences" ADD CONSTRAINT "user_preferences_char_as_partner_id_fkey" FOREIGN KEY ("char_as_partner_id") REFERENCES "characters"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
|
||||||
|
|
||||||
-- AddForeignKey
|
|
||||||
ALTER TABLE "user_genre_preferences" ADD CONSTRAINT "user_genre_preferences_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "user_preferences"("user_id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
|
||||||
|
|
||||||
-- AddForeignKey
|
|
||||||
ALTER TABLE "user_genre_preferences" ADD CONSTRAINT "user_genre_preferences_genre_id_fkey" FOREIGN KEY ("genre_id") REFERENCES "genres"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
|
||||||
|
|
||||||
-- AddForeignKey
|
|
||||||
ALTER TABLE "user_rating_preferences" ADD CONSTRAINT "user_rating_preferences_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "user_preferences"("user_id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
|
||||||
|
|
||||||
-- AddForeignKey
|
|
||||||
ALTER TABLE "user_rating_preferences" ADD CONSTRAINT "user_rating_preferences_rating_id_fkey" FOREIGN KEY ("rating_id") REFERENCES "media_age_ratings"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
|
||||||
|
|
||||||
-- AddForeignKey
|
|
||||||
ALTER TABLE "user_country_preferences" ADD CONSTRAINT "user_country_preferences_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "user_preferences"("user_id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
|
||||||
|
|
||||||
-- AddForeignKey
|
|
||||||
ALTER TABLE "user_country_preferences" ADD CONSTRAINT "user_country_preferences_country_id_fkey" FOREIGN KEY ("country_id") REFERENCES "countries"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
|
||||||
|
|
||||||
-- AddForeignKey
|
|
||||||
ALTER TABLE "user_follows" ADD CONSTRAINT "user_follows_follower_id_fkey" FOREIGN KEY ("follower_id") REFERENCES "users"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
|
||||||
|
|
||||||
-- AddForeignKey
|
|
||||||
ALTER TABLE "user_follows" ADD CONSTRAINT "user_follows_following_id_fkey" FOREIGN KEY ("following_id") REFERENCES "users"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
|
||||||
|
|
||||||
-- AddForeignKey
|
|
||||||
ALTER TABLE "user_watch_histories" ADD CONSTRAINT "user_watch_histories_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "users"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
|
||||||
|
|
||||||
-- AddForeignKey
|
|
||||||
ALTER TABLE "user_watch_histories" ADD CONSTRAINT "user_watch_histories_episode_id_fkey" FOREIGN KEY ("episode_id") REFERENCES "episodes"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
|
||||||
|
|
||||||
-- AddForeignKey
|
|
||||||
ALTER TABLE "collection_members" ADD CONSTRAINT "collection_members_collection_id_fkey" FOREIGN KEY ("collection_id") REFERENCES "collections"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
|
||||||
|
|
||||||
-- AddForeignKey
|
|
||||||
ALTER TABLE "collection_members" ADD CONSTRAINT "collection_members_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "users"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
|
||||||
|
|
||||||
-- AddForeignKey
|
|
||||||
ALTER TABLE "collection_members" ADD CONSTRAINT "collection_members_invited_by_id_fkey" FOREIGN KEY ("invited_by_id") REFERENCES "users"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|
|
||||||
|
|
||||||
-- AddForeignKey
|
|
||||||
ALTER TABLE "medias" ADD CONSTRAINT "medias_type_id_fkey" FOREIGN KEY ("type_id") REFERENCES "media_types"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
|
||||||
|
|
||||||
-- AddForeignKey
|
|
||||||
ALTER TABLE "medias" ADD CONSTRAINT "medias_source_id_fkey" FOREIGN KEY ("source_id") REFERENCES "media_sources"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
|
||||||
|
|
||||||
-- AddForeignKey
|
|
||||||
ALTER TABLE "medias" ADD CONSTRAINT "medias_status_id_fkey" FOREIGN KEY ("status_id") REFERENCES "media_statuses"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
|
||||||
|
|
||||||
-- AddForeignKey
|
|
||||||
ALTER TABLE "medias" ADD CONSTRAINT "medias_age_rating_id_fkey" FOREIGN KEY ("age_rating_id") REFERENCES "media_age_ratings"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|
|
||||||
|
|
||||||
-- AddForeignKey
|
|
||||||
ALTER TABLE "medias" ADD CONSTRAINT "medias_country_id_fkey" FOREIGN KEY ("country_id") REFERENCES "countries"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|
|
||||||
|
|
||||||
-- AddForeignKey
|
|
||||||
ALTER TABLE "medias" ADD CONSTRAINT "medias_updated_by_id_fkey" FOREIGN KEY ("updated_by_id") REFERENCES "users"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|
|
||||||
|
|
||||||
-- AddForeignKey
|
|
||||||
ALTER TABLE "medias" ADD CONSTRAINT "medias_deleted_by_id_fkey" FOREIGN KEY ("deleted_by_id") REFERENCES "users"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|
|
||||||
|
|
||||||
-- AddForeignKey
|
|
||||||
ALTER TABLE "media_submissions" ADD CONSTRAINT "media_submissions_media_id_fkey" FOREIGN KEY ("media_id") REFERENCES "medias"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
|
||||||
|
|
||||||
-- AddForeignKey
|
|
||||||
ALTER TABLE "media_submissions" ADD CONSTRAINT "media_submissions_submitter_id_fkey" FOREIGN KEY ("submitter_id") REFERENCES "users"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
|
||||||
|
|
||||||
-- AddForeignKey
|
|
||||||
ALTER TABLE "media_submissions" ADD CONSTRAINT "media_submissions_reviewer_id_fkey" FOREIGN KEY ("reviewer_id") REFERENCES "users"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|
|
||||||
|
|
||||||
-- AddForeignKey
|
|
||||||
ALTER TABLE "media_collections" ADD CONSTRAINT "media_collections_media_id_fkey" FOREIGN KEY ("media_id") REFERENCES "medias"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
|
||||||
|
|
||||||
-- AddForeignKey
|
|
||||||
ALTER TABLE "media_collections" ADD CONSTRAINT "media_collections_collection_id_fkey" FOREIGN KEY ("collection_id") REFERENCES "collections"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
|
||||||
|
|
||||||
-- AddForeignKey
|
|
||||||
ALTER TABLE "media_collections" ADD CONSTRAINT "media_collections_added_by_id_fkey" FOREIGN KEY ("added_by_id") REFERENCES "users"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
|
||||||
|
|
||||||
-- AddForeignKey
|
|
||||||
ALTER TABLE "media_trailers" ADD CONSTRAINT "media_trailers_media_id_fkey" FOREIGN KEY ("media_id") REFERENCES "medias"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
|
||||||
|
|
||||||
-- AddForeignKey
|
|
||||||
ALTER TABLE "media_producers" ADD CONSTRAINT "media_producers_media_id_fkey" FOREIGN KEY ("media_id") REFERENCES "medias"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
|
||||||
|
|
||||||
-- AddForeignKey
|
|
||||||
ALTER TABLE "media_producers" ADD CONSTRAINT "media_producers_producer_id_fkey" FOREIGN KEY ("producer_id") REFERENCES "producers"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
|
||||||
|
|
||||||
-- AddForeignKey
|
|
||||||
ALTER TABLE "media_licensors" ADD CONSTRAINT "media_licensors_media_id_fkey" FOREIGN KEY ("media_id") REFERENCES "medias"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
|
||||||
|
|
||||||
-- AddForeignKey
|
|
||||||
ALTER TABLE "media_licensors" ADD CONSTRAINT "media_licensors_licensor_id_fkey" FOREIGN KEY ("licensor_id") REFERENCES "producers"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
|
||||||
|
|
||||||
-- AddForeignKey
|
|
||||||
ALTER TABLE "media_studios" ADD CONSTRAINT "media_studios_media_id_fkey" FOREIGN KEY ("media_id") REFERENCES "medias"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
|
||||||
|
|
||||||
-- AddForeignKey
|
|
||||||
ALTER TABLE "media_studios" ADD CONSTRAINT "media_studios_studio_id_fkey" FOREIGN KEY ("studio_id") REFERENCES "producers"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
|
||||||
|
|
||||||
-- AddForeignKey
|
|
||||||
ALTER TABLE "producers" ADD CONSTRAINT "producers_created_by_id_fkey" FOREIGN KEY ("created_by_id") REFERENCES "users"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
|
||||||
|
|
||||||
-- AddForeignKey
|
|
||||||
ALTER TABLE "media_genres" ADD CONSTRAINT "media_genres_media_id_fkey" FOREIGN KEY ("media_id") REFERENCES "medias"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
|
||||||
|
|
||||||
-- AddForeignKey
|
|
||||||
ALTER TABLE "media_genres" ADD CONSTRAINT "media_genres_genre_id_fkey" FOREIGN KEY ("genre_id") REFERENCES "genres"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
|
||||||
|
|
||||||
-- AddForeignKey
|
|
||||||
ALTER TABLE "media_explicit_genres" ADD CONSTRAINT "media_explicit_genres_media_id_fkey" FOREIGN KEY ("media_id") REFERENCES "medias"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
|
||||||
|
|
||||||
-- AddForeignKey
|
|
||||||
ALTER TABLE "media_explicit_genres" ADD CONSTRAINT "media_explicit_genres_genre_id_fkey" FOREIGN KEY ("genre_id") REFERENCES "genres"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
|
||||||
|
|
||||||
-- AddForeignKey
|
|
||||||
ALTER TABLE "media_themes" ADD CONSTRAINT "media_themes_media_id_fkey" FOREIGN KEY ("media_id") REFERENCES "medias"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
|
||||||
|
|
||||||
-- AddForeignKey
|
|
||||||
ALTER TABLE "media_themes" ADD CONSTRAINT "media_themes_genre_id_fkey" FOREIGN KEY ("genre_id") REFERENCES "genres"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
|
||||||
|
|
||||||
-- AddForeignKey
|
|
||||||
ALTER TABLE "media_demographics" ADD CONSTRAINT "media_demographics_media_id_fkey" FOREIGN KEY ("media_id") REFERENCES "medias"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
|
||||||
|
|
||||||
-- AddForeignKey
|
|
||||||
ALTER TABLE "media_demographics" ADD CONSTRAINT "media_demographics_demographic_id_fkey" FOREIGN KEY ("demographic_id") REFERENCES "genres"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
|
||||||
|
|
||||||
-- AddForeignKey
|
|
||||||
ALTER TABLE "media_relations" ADD CONSTRAINT "media_relations_media_id_fkey" FOREIGN KEY ("media_id") REFERENCES "medias"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
|
||||||
|
|
||||||
-- AddForeignKey
|
|
||||||
ALTER TABLE "media_relations" ADD CONSTRAINT "media_relations_related_media_id_fkey" FOREIGN KEY ("related_media_id") REFERENCES "medias"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
|
||||||
|
|
||||||
-- AddForeignKey
|
|
||||||
ALTER TABLE "media_external_links" ADD CONSTRAINT "media_external_links_media_id_fkey" FOREIGN KEY ("media_id") REFERENCES "medias"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
|
||||||
|
|
||||||
-- AddForeignKey
|
|
||||||
ALTER TABLE "media_characters" ADD CONSTRAINT "media_characters_media_id_fkey" FOREIGN KEY ("media_id") REFERENCES "medias"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
|
||||||
|
|
||||||
-- AddForeignKey
|
|
||||||
ALTER TABLE "media_characters" ADD CONSTRAINT "media_characters_character_id_fkey" FOREIGN KEY ("character_id") REFERENCES "characters"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
|
||||||
|
|
||||||
-- AddForeignKey
|
|
||||||
ALTER TABLE "voice_actors" ADD CONSTRAINT "voice_actors_staff_id_fkey" FOREIGN KEY ("staff_id") REFERENCES "staff"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
|
||||||
|
|
||||||
-- AddForeignKey
|
|
||||||
ALTER TABLE "voice_actors" ADD CONSTRAINT "voice_actors_media_character_id_fkey" FOREIGN KEY ("media_character_id") REFERENCES "media_characters"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
|
||||||
|
|
||||||
-- AddForeignKey
|
|
||||||
ALTER TABLE "episodes" ADD CONSTRAINT "episodes_created_by_id_fkey" FOREIGN KEY ("created_by_id") REFERENCES "users"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
|
||||||
|
|
||||||
-- AddForeignKey
|
|
||||||
ALTER TABLE "videos" ADD CONSTRAINT "videos_episode_id_fkey" FOREIGN KEY ("episode_id") REFERENCES "episodes"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
|
||||||
|
|
||||||
-- AddForeignKey
|
|
||||||
ALTER TABLE "video_submissions" ADD CONSTRAINT "video_submissions_created_by_id_fkey" FOREIGN KEY ("created_by_id") REFERENCES "users"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
|
||||||
|
|
||||||
-- AddForeignKey
|
|
||||||
ALTER TABLE "video_submissions" ADD CONSTRAINT "video_submissions_reviewer_id_fkey" FOREIGN KEY ("reviewer_id") REFERENCES "users"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|
|
||||||
|
|
||||||
-- AddForeignKey
|
|
||||||
ALTER TABLE "video_submissions" ADD CONSTRAINT "video_submissions_video_id_fkey" FOREIGN KEY ("video_id") REFERENCES "videos"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
|
||||||
|
|
||||||
-- AddForeignKey
|
|
||||||
ALTER TABLE "video_service_submissions" ADD CONSTRAINT "video_service_submissions_created_by_id_fkey" FOREIGN KEY ("created_by_id") REFERENCES "users"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
|
||||||
|
|
||||||
-- AddForeignKey
|
|
||||||
ALTER TABLE "video_service_submissions" ADD CONSTRAINT "video_service_submissions_reviewer_id_fkey" FOREIGN KEY ("reviewer_id") REFERENCES "users"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|
|
||||||
|
|
||||||
-- AddForeignKey
|
|
||||||
ALTER TABLE "video_service_submissions" ADD CONSTRAINT "video_service_submissions_video_service_id_fkey" FOREIGN KEY ("video_service_id") REFERENCES "video_services"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
|
||||||
|
|
||||||
-- AddForeignKey
|
|
||||||
ALTER TABLE "comments" ADD CONSTRAINT "comments_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "users"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
|
||||||
|
|
||||||
-- AddForeignKey
|
|
||||||
ALTER TABLE "comments" ADD CONSTRAINT "comments_episode_id_fkey" FOREIGN KEY ("episode_id") REFERENCES "episodes"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
|
||||||
|
|
||||||
-- AddForeignKey
|
|
||||||
ALTER TABLE "comment_likes" ADD CONSTRAINT "comment_likes_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "users"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
|
||||||
|
|
||||||
-- AddForeignKey
|
|
||||||
ALTER TABLE "comment_likes" ADD CONSTRAINT "comment_likes_comment_id_fkey" FOREIGN KEY ("comment_id") REFERENCES "comments"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
|
||||||
|
|
||||||
-- AddForeignKey
|
|
||||||
ALTER TABLE "comment_audit_logs" ADD CONSTRAINT "comment_audit_logs_comment_id_fkey" FOREIGN KEY ("comment_id") REFERENCES "comments"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
|
||||||
|
|
||||||
-- AddForeignKey
|
|
||||||
ALTER TABLE "comment_audit_logs" ADD CONSTRAINT "comment_audit_logs_performed_by_id_fkey" FOREIGN KEY ("performed_by_id") REFERENCES "users"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
|
||||||
|
|
||||||
-- AddForeignKey
|
|
||||||
ALTER TABLE "comment_reports" ADD CONSTRAINT "comment_reports_reporter_id_fkey" FOREIGN KEY ("reporter_id") REFERENCES "users"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
|
||||||
|
|
||||||
-- AddForeignKey
|
|
||||||
ALTER TABLE "comment_reports" ADD CONSTRAINT "comment_reports_comment_id_fkey" FOREIGN KEY ("comment_id") REFERENCES "comments"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
|
||||||
|
|
||||||
-- AddForeignKey
|
|
||||||
ALTER TABLE "provisioned_users" ADD CONSTRAINT "provisioned_users_admin_id_fkey" FOREIGN KEY ("admin_id") REFERENCES "users"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
|
||||||
|
|
||||||
-- AddForeignKey
|
|
||||||
ALTER TABLE "provisioned_users" ADD CONSTRAINT "provisioned_users_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "users"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
|
||||||
|
|
||||||
-- AddForeignKey
|
|
||||||
ALTER TABLE "home_media_banners" ADD CONSTRAINT "home_media_banners_media_id_fkey" FOREIGN KEY ("media_id") REFERENCES "medias"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
|
||||||
|
|
||||||
-- AddForeignKey
|
|
||||||
ALTER TABLE "home_media_banners" ADD CONSTRAINT "home_media_banners_created_by_id_fkey" FOREIGN KEY ("created_by_id") REFERENCES "users"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
|
||||||
|
|
||||||
-- AddForeignKey
|
|
||||||
ALTER TABLE "_VideoToVideoService" ADD CONSTRAINT "_VideoToVideoService_A_fkey" FOREIGN KEY ("A") REFERENCES "videos"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
|
||||||
|
|
||||||
-- AddForeignKey
|
|
||||||
ALTER TABLE "_VideoToVideoService" ADD CONSTRAINT "_VideoToVideoService_B_fkey" FOREIGN KEY ("B") REFERENCES "video_services"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
|
||||||
@ -1,10 +0,0 @@
|
|||||||
/*
|
|
||||||
Warnings:
|
|
||||||
|
|
||||||
- You are about to drop the column `auth_provider` on the `users` table. All the data in the column will be lost.
|
|
||||||
- You are about to drop the column `provider_token` on the `users` table. All the data in the column will be lost.
|
|
||||||
|
|
||||||
*/
|
|
||||||
-- AlterTable
|
|
||||||
ALTER TABLE "users" DROP COLUMN "auth_provider",
|
|
||||||
DROP COLUMN "provider_token";
|
|
||||||
@ -1,8 +0,0 @@
|
|||||||
/*
|
|
||||||
Warnings:
|
|
||||||
|
|
||||||
- You are about to drop the column `last_login` on the `user_oauth_accounts` table. All the data in the column will be lost.
|
|
||||||
|
|
||||||
*/
|
|
||||||
-- AlterTable
|
|
||||||
ALTER TABLE "user_oauth_accounts" DROP COLUMN "last_login";
|
|
||||||
@ -1,12 +0,0 @@
|
|||||||
-- DropForeignKey
|
|
||||||
ALTER TABLE "user_preferences" DROP CONSTRAINT "user_preferences_char_as_partner_id_fkey";
|
|
||||||
|
|
||||||
-- AlterTable
|
|
||||||
ALTER TABLE "user_oauth_accounts" ALTER COLUMN "provider_token" SET DATA TYPE TEXT,
|
|
||||||
ALTER COLUMN "refresh_token" SET DATA TYPE TEXT;
|
|
||||||
|
|
||||||
-- AlterTable
|
|
||||||
ALTER TABLE "user_preferences" ALTER COLUMN "char_as_partner_id" DROP NOT NULL;
|
|
||||||
|
|
||||||
-- AddForeignKey
|
|
||||||
ALTER TABLE "user_preferences" ADD CONSTRAINT "user_preferences_char_as_partner_id_fkey" FOREIGN KEY ("char_as_partner_id") REFERENCES "characters"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|
|
||||||
@ -1,8 +0,0 @@
|
|||||||
/*
|
|
||||||
Warnings:
|
|
||||||
|
|
||||||
- Added the required column `valid_until` to the `user_sessions` table without a default value. This is not possible if the table is not empty.
|
|
||||||
|
|
||||||
*/
|
|
||||||
-- AlterTable
|
|
||||||
ALTER TABLE "user_sessions" ADD COLUMN "valid_until" TIMESTAMPTZ NOT NULL;
|
|
||||||
@ -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"
|
|
||||||
@ -11,15 +11,15 @@
|
|||||||
generator client {
|
generator client {
|
||||||
provider = "prisma-client-js"
|
provider = "prisma-client-js"
|
||||||
}
|
}
|
||||||
|
|
||||||
generator dbml {
|
generator dbml {
|
||||||
provider = "prisma-dbml-generator"
|
provider = "prisma-dbml-generator"
|
||||||
}
|
}
|
||||||
|
|
||||||
datasource db {
|
datasource db {
|
||||||
provider = "postgresql"
|
provider = "postgresql"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ----------------------------------
|
* ----------------------------------
|
||||||
* Enum Definitions
|
* Enum Definitions
|
||||||
@ -98,15 +98,13 @@ enum collection_access_level {
|
|||||||
viewer
|
viewer
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ----------------------------------
|
* ----------------------------------
|
||||||
* Model for User and related entities
|
* Model for User and related entities
|
||||||
* ----------------------------------
|
* ----------------------------------
|
||||||
*/
|
*/
|
||||||
model User {
|
model User {
|
||||||
id String @id @db.Uuid @default(uuid(7))
|
id String @id @default(uuid(7)) @db.Uuid
|
||||||
email String @unique
|
email String @unique
|
||||||
password String? @db.VarChar(255)
|
password String? @db.VarChar(255)
|
||||||
username String @unique @db.VarChar(28)
|
username String @unique @db.VarChar(28)
|
||||||
@ -150,6 +148,7 @@ model User {
|
|||||||
saved_collections CollectionMember[] @relation("CollectionMemberUser")
|
saved_collections CollectionMember[] @relation("CollectionMemberUser")
|
||||||
invited_collections CollectionMember[] @relation("CollectionMemberInviter")
|
invited_collections CollectionMember[] @relation("CollectionMemberInviter")
|
||||||
contributed_collections MediaCollection[] @relation("MediaCollectionAdder")
|
contributed_collections MediaCollection[] @relation("MediaCollectionAdder")
|
||||||
|
|
||||||
@@index([email])
|
@@index([email])
|
||||||
@@index([username])
|
@@index([username])
|
||||||
@@map("users")
|
@@map("users")
|
||||||
@ -166,11 +165,12 @@ model UserAddress {
|
|||||||
updated_at DateTime @updatedAt @db.Timestamptz()
|
updated_at DateTime @updatedAt @db.Timestamptz()
|
||||||
|
|
||||||
user User @relation(fields: [user_id], references: [id])
|
user User @relation(fields: [user_id], references: [id])
|
||||||
|
|
||||||
@@map("user_addresses")
|
@@map("user_addresses")
|
||||||
}
|
}
|
||||||
|
|
||||||
model UserOauthAccounts {
|
model UserOauthAccounts {
|
||||||
id String @id @db.Uuid @default(uuid(7))
|
id String @id @default(uuid(7)) @db.Uuid
|
||||||
user User @relation(fields: [user_id], references: [id])
|
user User @relation(fields: [user_id], references: [id])
|
||||||
provider_name auth_provider
|
provider_name auth_provider
|
||||||
provider_sub String? @db.VarChar(255)
|
provider_sub String? @db.VarChar(255)
|
||||||
@ -182,11 +182,12 @@ model UserOauthAccounts {
|
|||||||
updated_at DateTime @updatedAt @db.Timestamptz()
|
updated_at DateTime @updatedAt @db.Timestamptz()
|
||||||
|
|
||||||
user_id String @db.Uuid
|
user_id String @db.Uuid
|
||||||
|
|
||||||
@@map("user_oauth_accounts")
|
@@map("user_oauth_accounts")
|
||||||
}
|
}
|
||||||
|
|
||||||
model UserSession {
|
model UserSession {
|
||||||
id String @id @db.Uuid @default(uuid(7))
|
id String @id @default(uuid(7)) @db.Uuid
|
||||||
user User @relation(fields: [user_id], references: [id])
|
user User @relation(fields: [user_id], references: [id])
|
||||||
device_type device_type
|
device_type device_type
|
||||||
os_type String? @db.VarChar(50)
|
os_type String? @db.VarChar(50)
|
||||||
@ -199,6 +200,7 @@ model UserSession {
|
|||||||
logout_at DateTime? @db.Timestamptz()
|
logout_at DateTime? @db.Timestamptz()
|
||||||
|
|
||||||
user_id String @db.Uuid
|
user_id String @db.Uuid
|
||||||
|
|
||||||
@@map("user_sessions")
|
@@map("user_sessions")
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -223,6 +225,7 @@ model UserPreference {
|
|||||||
|
|
||||||
user_id String @id @db.Uuid
|
user_id String @id @db.Uuid
|
||||||
char_as_partner_id String? @db.Uuid
|
char_as_partner_id String? @db.Uuid
|
||||||
|
|
||||||
@@map("user_preferences")
|
@@map("user_preferences")
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -233,6 +236,7 @@ model UserGenrePreference {
|
|||||||
|
|
||||||
user_id String @db.Uuid
|
user_id String @db.Uuid
|
||||||
genre_id String @db.Uuid
|
genre_id String @db.Uuid
|
||||||
|
|
||||||
@@id([user_id, genre_id])
|
@@id([user_id, genre_id])
|
||||||
@@map("user_genre_preferences")
|
@@map("user_genre_preferences")
|
||||||
}
|
}
|
||||||
@ -244,6 +248,7 @@ model UserRatingPreference {
|
|||||||
|
|
||||||
user_id String @db.Uuid
|
user_id String @db.Uuid
|
||||||
rating_id String @db.Uuid
|
rating_id String @db.Uuid
|
||||||
|
|
||||||
@@id([user_id, rating_id])
|
@@id([user_id, rating_id])
|
||||||
@@map("user_rating_preferences")
|
@@map("user_rating_preferences")
|
||||||
}
|
}
|
||||||
@ -255,6 +260,7 @@ model UserCountryPreference {
|
|||||||
|
|
||||||
user_id String @db.Uuid
|
user_id String @db.Uuid
|
||||||
country_id String @db.Uuid
|
country_id String @db.Uuid
|
||||||
|
|
||||||
@@id([user_id, country_id])
|
@@id([user_id, country_id])
|
||||||
@@map("user_country_preferences")
|
@@map("user_country_preferences")
|
||||||
}
|
}
|
||||||
@ -266,23 +272,26 @@ model UserFollow {
|
|||||||
|
|
||||||
follower_id String @db.Uuid
|
follower_id String @db.Uuid
|
||||||
following_id String @db.Uuid
|
following_id String @db.Uuid
|
||||||
|
|
||||||
@@id([follower_id, following_id])
|
@@id([follower_id, following_id])
|
||||||
@@map("user_follows")
|
@@map("user_follows")
|
||||||
}
|
}
|
||||||
|
|
||||||
model UserWatchHistory {
|
model UserWatchHistory {
|
||||||
user User @relation(fields: [user_id], references: [id])
|
user User @relation(fields: [user_id], references: [id])
|
||||||
episode Episode @relation(fields: [episode_id], references: [id])
|
episode Episode @relation(fields: [episode_number, media_id], references: [episode_number, media_id])
|
||||||
updated_at DateTime @updatedAt @db.Timestamptz()
|
updated_at DateTime @updatedAt @db.Timestamptz()
|
||||||
|
|
||||||
user_id String @db.Uuid
|
user_id String @db.Uuid
|
||||||
episode_id String @db.Uuid
|
episode_number Int @db.SmallInt
|
||||||
@@id([user_id, episode_id])
|
media_id String @db.Uuid
|
||||||
|
|
||||||
|
@@id([user_id, episode_number, media_id])
|
||||||
@@map("user_watch_histories")
|
@@map("user_watch_histories")
|
||||||
}
|
}
|
||||||
|
|
||||||
model Collection {
|
model Collection {
|
||||||
id String @id @db.Uuid @default(uuid(7))
|
id String @id @default(uuid(7)) @db.Uuid
|
||||||
name String @db.VarChar(64)
|
name String @db.VarChar(64)
|
||||||
code String? @db.VarChar(12)
|
code String? @db.VarChar(12)
|
||||||
cover_url String? @db.VarChar(255)
|
cover_url String? @db.VarChar(255)
|
||||||
@ -292,6 +301,7 @@ model Collection {
|
|||||||
|
|
||||||
saved_media MediaCollection[]
|
saved_media MediaCollection[]
|
||||||
members CollectionMember[]
|
members CollectionMember[]
|
||||||
|
|
||||||
@@map("collections")
|
@@map("collections")
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -305,19 +315,18 @@ model CollectionMember {
|
|||||||
collection_id String @db.Uuid
|
collection_id String @db.Uuid
|
||||||
user_id String @db.Uuid
|
user_id String @db.Uuid
|
||||||
invited_by_id String? @db.Uuid
|
invited_by_id String? @db.Uuid
|
||||||
|
|
||||||
@@id([collection_id, user_id])
|
@@id([collection_id, user_id])
|
||||||
@@map("collection_members")
|
@@map("collection_members")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ----------------------------------
|
* ----------------------------------
|
||||||
* Model for Media and related entities
|
* Model for Media and related entities
|
||||||
* ----------------------------------
|
* ----------------------------------
|
||||||
*/
|
*/
|
||||||
model Media {
|
model Media {
|
||||||
id String @id @db.Uuid @default(uuid(7))
|
id String @id @default(uuid(7)) @db.Uuid
|
||||||
mal_id Int @unique
|
mal_id Int @unique
|
||||||
title String @db.VarChar(255)
|
title String @db.VarChar(255)
|
||||||
title_secondary String? @db.VarChar(255)
|
title_secondary String? @db.VarChar(255)
|
||||||
@ -366,17 +375,17 @@ model Media {
|
|||||||
age_rating_id String? @db.Uuid
|
age_rating_id String? @db.Uuid
|
||||||
country_id String? @db.Uuid
|
country_id String? @db.Uuid
|
||||||
related_media MediaRelation[] @relation("MediaRelationRelatedMedia")
|
related_media MediaRelation[] @relation("MediaRelationRelatedMedia")
|
||||||
approver_id String? @db.Uuid
|
|
||||||
created_by_id String? @db.Uuid
|
|
||||||
updated_by_id String? @db.Uuid
|
updated_by_id String? @db.Uuid
|
||||||
deleted_by_id String? @db.Uuid
|
deleted_by_id String? @db.Uuid
|
||||||
|
episodes Episode[]
|
||||||
home_media_banners HomeMediaBanner[]
|
home_media_banners HomeMediaBanner[]
|
||||||
saved_to_collections MediaCollection[]
|
saved_to_collections MediaCollection[]
|
||||||
|
|
||||||
@@map("medias")
|
@@map("medias")
|
||||||
}
|
}
|
||||||
|
|
||||||
model MediaSubmission {
|
model MediaSubmission {
|
||||||
id String @id @db.Uuid @default(uuid(7))
|
id String @id @default(uuid(7)) @db.Uuid
|
||||||
media Media @relation(fields: [media_id], references: [id])
|
media Media @relation(fields: [media_id], references: [id])
|
||||||
submitter User @relation(fields: [submitter_id], references: [id], name: "MediaSubmissionSubmitter")
|
submitter User @relation(fields: [submitter_id], references: [id], name: "MediaSubmissionSubmitter")
|
||||||
status status_submission @default(pending)
|
status status_submission @default(pending)
|
||||||
@ -385,9 +394,10 @@ model MediaSubmission {
|
|||||||
reason String? @db.Text
|
reason String? @db.Text
|
||||||
created_at DateTime @default(now()) @db.Timestamptz()
|
created_at DateTime @default(now()) @db.Timestamptz()
|
||||||
|
|
||||||
media_id String @db.Uuid @unique
|
media_id String @unique @db.Uuid
|
||||||
submitter_id String @db.Uuid
|
submitter_id String @db.Uuid
|
||||||
reviewer_id String? @db.Uuid
|
reviewer_id String? @db.Uuid
|
||||||
|
|
||||||
@@map("media_submissions")
|
@@map("media_submissions")
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -400,6 +410,7 @@ model MediaCollection {
|
|||||||
media_id String @db.Uuid
|
media_id String @db.Uuid
|
||||||
collection_id String @db.Uuid
|
collection_id String @db.Uuid
|
||||||
added_by_id String @db.Uuid
|
added_by_id String @db.Uuid
|
||||||
|
|
||||||
@@id([media_id, collection_id])
|
@@id([media_id, collection_id])
|
||||||
@@map("media_collections")
|
@@map("media_collections")
|
||||||
}
|
}
|
||||||
@ -407,46 +418,51 @@ model MediaCollection {
|
|||||||
model MediaTrailer {
|
model MediaTrailer {
|
||||||
media_id String @id @db.Uuid
|
media_id String @id @db.Uuid
|
||||||
url String? @db.VarChar(255)
|
url String? @db.VarChar(255)
|
||||||
embed_url String? @db.VarChar(255)
|
embed_url String? @unique @db.VarChar(255)
|
||||||
small_image_url String? @db.VarChar(255)
|
small_image_url String? @db.VarChar(255)
|
||||||
large_image_url String? @db.VarChar(255)
|
large_image_url String? @db.VarChar(255)
|
||||||
maximum_image_url String? @db.VarChar(255)
|
maximum_image_url String? @db.VarChar(255)
|
||||||
|
|
||||||
media Media @relation(fields: [media_id], references: [id])
|
media Media @relation(fields: [media_id], references: [id])
|
||||||
|
|
||||||
@@map("media_trailers")
|
@@map("media_trailers")
|
||||||
}
|
}
|
||||||
|
|
||||||
model MediaType {
|
model MediaType {
|
||||||
id String @id @db.Uuid @default(uuid(7))
|
id String @id @default(uuid(7)) @db.Uuid
|
||||||
name String @db.VarChar(100) @unique
|
name String @unique @db.VarChar(100)
|
||||||
|
|
||||||
Media Media[]
|
Media Media[]
|
||||||
|
|
||||||
@@map("media_types")
|
@@map("media_types")
|
||||||
}
|
}
|
||||||
|
|
||||||
model MediaSource {
|
model MediaSource {
|
||||||
id String @id @db.Uuid @default(uuid(7))
|
id String @id @default(uuid(7)) @db.Uuid
|
||||||
name String @db.VarChar(100) @unique
|
name String @unique @db.VarChar(100)
|
||||||
|
|
||||||
media Media[]
|
media Media[]
|
||||||
|
|
||||||
@@map("media_sources")
|
@@map("media_sources")
|
||||||
}
|
}
|
||||||
|
|
||||||
model MediaStatus {
|
model MediaStatus {
|
||||||
id String @id @db.Uuid @default(uuid(7))
|
id String @id @default(uuid(7)) @db.Uuid
|
||||||
name String @db.VarChar(100) @unique
|
name String @unique @db.VarChar(100)
|
||||||
|
|
||||||
media Media[]
|
media Media[]
|
||||||
|
|
||||||
@@map("media_statuses")
|
@@map("media_statuses")
|
||||||
}
|
}
|
||||||
|
|
||||||
model MediaAgeRating {
|
model MediaAgeRating {
|
||||||
id String @id @db.Uuid @default(uuid(7))
|
id String @id @default(uuid(7)) @db.Uuid
|
||||||
name String @db.VarChar(100) @unique
|
name String @unique @db.VarChar(100)
|
||||||
min_age Int @db.SmallInt
|
min_age Int @db.SmallInt
|
||||||
|
|
||||||
media Media[]
|
media Media[]
|
||||||
user_rating_preferences UserRatingPreference[]
|
user_rating_preferences UserRatingPreference[]
|
||||||
|
|
||||||
@@map("media_age_ratings")
|
@@map("media_age_ratings")
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -456,6 +472,7 @@ model MediaProducer {
|
|||||||
|
|
||||||
media_id String @db.Uuid
|
media_id String @db.Uuid
|
||||||
producer_id String @db.Uuid
|
producer_id String @db.Uuid
|
||||||
|
|
||||||
@@id([media_id, producer_id])
|
@@id([media_id, producer_id])
|
||||||
@@map("media_producers")
|
@@map("media_producers")
|
||||||
}
|
}
|
||||||
@ -466,6 +483,7 @@ model MediaLicensor {
|
|||||||
|
|
||||||
media_id String @db.Uuid
|
media_id String @db.Uuid
|
||||||
licensor_id String @db.Uuid
|
licensor_id String @db.Uuid
|
||||||
|
|
||||||
@@id([media_id, licensor_id])
|
@@id([media_id, licensor_id])
|
||||||
@@map("media_licensors")
|
@@map("media_licensors")
|
||||||
}
|
}
|
||||||
@ -476,12 +494,13 @@ model MediaStudio {
|
|||||||
|
|
||||||
media_id String @db.Uuid
|
media_id String @db.Uuid
|
||||||
studio_id String @db.Uuid
|
studio_id String @db.Uuid
|
||||||
|
|
||||||
@@id([media_id, studio_id])
|
@@id([media_id, studio_id])
|
||||||
@@map("media_studios")
|
@@map("media_studios")
|
||||||
}
|
}
|
||||||
|
|
||||||
model Producer {
|
model Producer {
|
||||||
id String @id @db.Uuid @default(uuid(7))
|
id String @id @default(uuid(7)) @db.Uuid
|
||||||
mal_id Int @unique
|
mal_id Int @unique
|
||||||
type String @db.VarChar(24)
|
type String @db.VarChar(24)
|
||||||
name String @db.VarChar(255)
|
name String @db.VarChar(255)
|
||||||
@ -495,6 +514,7 @@ model Producer {
|
|||||||
media_producers MediaProducer[]
|
media_producers MediaProducer[]
|
||||||
media_licensors MediaLicensor[]
|
media_licensors MediaLicensor[]
|
||||||
media_studios MediaStudio[]
|
media_studios MediaStudio[]
|
||||||
|
|
||||||
@@map("producers")
|
@@map("producers")
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -504,6 +524,7 @@ model MediaGenre {
|
|||||||
|
|
||||||
media_id String @db.Uuid
|
media_id String @db.Uuid
|
||||||
genre_id String @db.Uuid
|
genre_id String @db.Uuid
|
||||||
|
|
||||||
@@id([media_id, genre_id])
|
@@id([media_id, genre_id])
|
||||||
@@map("media_genres")
|
@@map("media_genres")
|
||||||
}
|
}
|
||||||
@ -514,6 +535,7 @@ model MediaExplicitGenre {
|
|||||||
|
|
||||||
media_id String @db.Uuid
|
media_id String @db.Uuid
|
||||||
genre_id String @db.Uuid
|
genre_id String @db.Uuid
|
||||||
|
|
||||||
@@id([media_id, genre_id])
|
@@id([media_id, genre_id])
|
||||||
@@map("media_explicit_genres")
|
@@map("media_explicit_genres")
|
||||||
}
|
}
|
||||||
@ -524,6 +546,7 @@ model MediaTheme {
|
|||||||
|
|
||||||
media_id String @db.Uuid
|
media_id String @db.Uuid
|
||||||
genre_id String @db.Uuid
|
genre_id String @db.Uuid
|
||||||
|
|
||||||
@@id([media_id, genre_id])
|
@@id([media_id, genre_id])
|
||||||
@@map("media_themes")
|
@@map("media_themes")
|
||||||
}
|
}
|
||||||
@ -534,12 +557,13 @@ model MediaDemographic {
|
|||||||
|
|
||||||
media_id String @db.Uuid
|
media_id String @db.Uuid
|
||||||
demographic_id String @db.Uuid
|
demographic_id String @db.Uuid
|
||||||
|
|
||||||
@@id([media_id, demographic_id])
|
@@id([media_id, demographic_id])
|
||||||
@@map("media_demographics")
|
@@map("media_demographics")
|
||||||
}
|
}
|
||||||
|
|
||||||
model Genre {
|
model Genre {
|
||||||
id String @id @db.Uuid @default(uuid(7))
|
id String @id @default(uuid(7)) @db.Uuid
|
||||||
mal_id Int @unique @db.SmallInt
|
mal_id Int @unique @db.SmallInt
|
||||||
name String @db.VarChar(100)
|
name String @db.VarChar(100)
|
||||||
slug String @db.VarChar(115)
|
slug String @db.VarChar(115)
|
||||||
@ -550,6 +574,7 @@ model Genre {
|
|||||||
media_themes MediaTheme[]
|
media_themes MediaTheme[]
|
||||||
media_demographics MediaDemographic[]
|
media_demographics MediaDemographic[]
|
||||||
user_genre_preferences UserGenrePreference[]
|
user_genre_preferences UserGenrePreference[]
|
||||||
|
|
||||||
@@map("genres")
|
@@map("genres")
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -560,22 +585,23 @@ model MediaRelation {
|
|||||||
|
|
||||||
media_id String @db.Uuid
|
media_id String @db.Uuid
|
||||||
related_media_id String @db.Uuid
|
related_media_id String @db.Uuid
|
||||||
|
|
||||||
@@id([media_id, related_media_id])
|
@@id([media_id, related_media_id])
|
||||||
@@map("media_relations")
|
@@map("media_relations")
|
||||||
}
|
}
|
||||||
|
|
||||||
model MediaExternalLink {
|
model MediaExternalLink {
|
||||||
id String @id @db.Uuid @default(uuid(7))
|
id String @id @default(uuid(7)) @db.Uuid
|
||||||
media Media @relation(fields: [media_id], references: [id])
|
media Media @relation(fields: [media_id], references: [id])
|
||||||
url String @db.VarChar(255)
|
url String @db.VarChar(255)
|
||||||
site_name String? @db.VarChar(100)
|
site_name String? @db.VarChar(100)
|
||||||
|
|
||||||
media_id String @db.Uuid
|
media_id String @db.Uuid
|
||||||
|
|
||||||
@@map("media_external_links")
|
@@map("media_external_links")
|
||||||
}
|
}
|
||||||
|
|
||||||
model MediaCharacter {
|
model MediaCharacter {
|
||||||
id String @id @db.Uuid @default(uuid(7))
|
|
||||||
media Media @relation(fields: [media_id], references: [id])
|
media Media @relation(fields: [media_id], references: [id])
|
||||||
character Character @relation(fields: [character_id], references: [id])
|
character Character @relation(fields: [character_id], references: [id])
|
||||||
voice_actors VoiceActor[]
|
voice_actors VoiceActor[]
|
||||||
@ -583,11 +609,13 @@ model MediaCharacter {
|
|||||||
|
|
||||||
media_id String @db.Uuid
|
media_id String @db.Uuid
|
||||||
character_id String @db.Uuid
|
character_id String @db.Uuid
|
||||||
|
|
||||||
|
@@id([character_id, media_id])
|
||||||
@@map("media_characters")
|
@@map("media_characters")
|
||||||
}
|
}
|
||||||
|
|
||||||
model Character {
|
model Character {
|
||||||
id String @id @db.Uuid @default(uuid(7))
|
id String @id @default(uuid(7)) @db.Uuid
|
||||||
name String @db.VarChar(255)
|
name String @db.VarChar(255)
|
||||||
image String? @db.VarChar(255)
|
image String? @db.VarChar(255)
|
||||||
small_image String? @db.VarChar(255)
|
small_image String? @db.VarChar(255)
|
||||||
@ -600,22 +628,26 @@ model Character {
|
|||||||
|
|
||||||
partnered_user UserPreference[]
|
partnered_user UserPreference[]
|
||||||
media_characters MediaCharacter[]
|
media_characters MediaCharacter[]
|
||||||
|
|
||||||
@@map("characters")
|
@@map("characters")
|
||||||
}
|
}
|
||||||
|
|
||||||
model VoiceActor {
|
model VoiceActor {
|
||||||
id String @id @db.Uuid @default(uuid(7))
|
id String @id @default(uuid(7)) @db.Uuid
|
||||||
media_character_id String @db.Uuid
|
|
||||||
language String @db.VarChar(115)
|
language String @db.VarChar(115)
|
||||||
actor_staff Staff @relation(fields: [staff_id], references: [id])
|
actor_staff Staff @relation(fields: [staff_id], references: [id])
|
||||||
|
|
||||||
staff_id String @db.Uuid
|
staff_id String @db.Uuid
|
||||||
media_character MediaCharacter @relation(fields: [media_character_id], references: [id])
|
|
||||||
|
media_id String @db.Uuid
|
||||||
|
character_id String @db.Uuid
|
||||||
|
media_character MediaCharacter @relation(fields: [media_id, character_id], references: [media_id, character_id])
|
||||||
|
|
||||||
|
@@unique([media_id, character_id, staff_id, language])
|
||||||
@@map("voice_actors")
|
@@map("voice_actors")
|
||||||
}
|
}
|
||||||
|
|
||||||
model Staff {
|
model Staff {
|
||||||
id String @id @db.Uuid @default(uuid(7))
|
id String @id @default(uuid(7)) @db.Uuid
|
||||||
name String @db.VarChar(255)
|
name String @db.VarChar(255)
|
||||||
image String? @db.VarChar(255)
|
image String? @db.VarChar(255)
|
||||||
mal_id Int? @unique
|
mal_id Int? @unique
|
||||||
@ -624,13 +656,12 @@ model Staff {
|
|||||||
created_at DateTime @default(now()) @db.Timestamptz()
|
created_at DateTime @default(now()) @db.Timestamptz()
|
||||||
|
|
||||||
voice_actors VoiceActor[]
|
voice_actors VoiceActor[]
|
||||||
|
|
||||||
@@map("staff")
|
@@map("staff")
|
||||||
}
|
}
|
||||||
|
|
||||||
model Episode {
|
model Episode {
|
||||||
id String @id @db.Uuid @default(uuid(7))
|
episode_number Int @db.SmallInt
|
||||||
media_id String @db.Uuid
|
|
||||||
episode Int @db.SmallInt
|
|
||||||
mal_url String? @db.VarChar(255)
|
mal_url String? @db.VarChar(255)
|
||||||
forum_url String? @db.VarChar(255)
|
forum_url String? @db.VarChar(255)
|
||||||
title String @db.VarChar(155)
|
title String @db.VarChar(155)
|
||||||
@ -650,14 +681,18 @@ model Episode {
|
|||||||
created_by_id String @db.Uuid
|
created_by_id String @db.Uuid
|
||||||
comments Comment[]
|
comments Comment[]
|
||||||
watch_histories UserWatchHistory[]
|
watch_histories UserWatchHistory[]
|
||||||
@@index([media_id, episode])
|
media Media @relation(fields: [media_id], references: [id])
|
||||||
|
media_id String @db.Uuid
|
||||||
|
|
||||||
|
@@id([media_id, episode_number])
|
||||||
@@map("episodes")
|
@@map("episodes")
|
||||||
}
|
}
|
||||||
|
|
||||||
model Video {
|
model Video {
|
||||||
id String @id @db.Uuid @default(uuid(7))
|
id String @id @default(uuid(7)) @db.Uuid
|
||||||
service VideoService[]
|
video_service VideoService @relation(fields: [video_service_id], references: [id])
|
||||||
Episode Episode @relation(fields: [episode_id], references: [id])
|
episode Episode @relation(fields: [episode_number, media_id], references: [episode_number, media_id])
|
||||||
|
priority Int? @db.SmallInt
|
||||||
video_code String @db.VarChar(255)
|
video_code String @db.VarChar(255)
|
||||||
short_code String? @db.VarChar(255)
|
short_code String? @db.VarChar(255)
|
||||||
thumbnail_code String? @db.VarChar(255)
|
thumbnail_code String? @db.VarChar(255)
|
||||||
@ -666,9 +701,13 @@ model Video {
|
|||||||
deleted_at DateTime? @db.Timestamptz()
|
deleted_at DateTime? @db.Timestamptz()
|
||||||
updated_at DateTime @updatedAt @db.Timestamptz()
|
updated_at DateTime @updatedAt @db.Timestamptz()
|
||||||
|
|
||||||
episode_id String @db.Uuid
|
episode_number Int @db.SmallInt
|
||||||
|
media_id String @db.Uuid
|
||||||
created_by_id String @db.Uuid
|
created_by_id String @db.Uuid
|
||||||
video_submission VideoSubmission?
|
video_submission VideoSubmission?
|
||||||
|
video_service_id String @db.Uuid
|
||||||
|
|
||||||
|
@@unique([media_id, episode_number, priority])
|
||||||
@@map("videos")
|
@@map("videos")
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -684,11 +723,12 @@ model VideoSubmission {
|
|||||||
created_by_id String @db.Uuid
|
created_by_id String @db.Uuid
|
||||||
reviewer_id String? @db.Uuid
|
reviewer_id String? @db.Uuid
|
||||||
video Video @relation(fields: [video_id], references: [id])
|
video Video @relation(fields: [video_id], references: [id])
|
||||||
|
|
||||||
@@map("video_submissions")
|
@@map("video_submissions")
|
||||||
}
|
}
|
||||||
|
|
||||||
model VideoService {
|
model VideoService {
|
||||||
id String @id @db.Uuid @default(uuid(7))
|
id String @id @default(uuid(7)) @db.Uuid
|
||||||
name String @db.VarChar(155)
|
name String @db.VarChar(155)
|
||||||
resolution Int @db.SmallInt
|
resolution Int @db.SmallInt
|
||||||
domain String @db.VarChar(255)
|
domain String @db.VarChar(255)
|
||||||
@ -704,6 +744,7 @@ model VideoService {
|
|||||||
|
|
||||||
videos Video[]
|
videos Video[]
|
||||||
video_service_submissions VideoServiceSubmission?
|
video_service_submissions VideoServiceSubmission?
|
||||||
|
|
||||||
@@unique([name, resolution])
|
@@unique([name, resolution])
|
||||||
@@map("video_services")
|
@@map("video_services")
|
||||||
}
|
}
|
||||||
@ -720,23 +761,26 @@ model VideoServiceSubmission {
|
|||||||
video_service VideoService @relation(fields: [video_service_id], references: [id])
|
video_service VideoService @relation(fields: [video_service_id], references: [id])
|
||||||
created_by_id String @db.Uuid
|
created_by_id String @db.Uuid
|
||||||
reviewer_id String? @db.Uuid
|
reviewer_id String? @db.Uuid
|
||||||
|
|
||||||
@@map("video_service_submissions")
|
@@map("video_service_submissions")
|
||||||
}
|
}
|
||||||
|
|
||||||
model Comment {
|
model Comment {
|
||||||
id String @id @db.Uuid @default(uuid(7))
|
id String @id @default(uuid(7)) @db.Uuid
|
||||||
user User @relation(fields: [user_id], references: [id])
|
user User @relation(fields: [user_id], references: [id])
|
||||||
episode Episode @relation(fields: [episode_id], references: [id])
|
episode Episode @relation(fields: [episode_number, media_id], references: [episode_number, media_id])
|
||||||
content String @db.Text
|
content String @db.Text
|
||||||
created_at DateTime @default(now()) @db.Timestamptz()
|
created_at DateTime @default(now()) @db.Timestamptz()
|
||||||
updated_at DateTime @updatedAt @db.Timestamptz()
|
updated_at DateTime @updatedAt @db.Timestamptz()
|
||||||
deleted_at DateTime? @db.Timestamptz()
|
deleted_at DateTime? @db.Timestamptz()
|
||||||
|
|
||||||
user_id String @db.Uuid
|
user_id String @db.Uuid
|
||||||
episode_id String @db.Uuid
|
episode_number Int @db.SmallInt
|
||||||
|
media_id String @db.Uuid
|
||||||
likes CommentLike[]
|
likes CommentLike[]
|
||||||
audit_logs CommentAuditLog[]
|
audit_logs CommentAuditLog[]
|
||||||
reports CommentReport[]
|
reports CommentReport[]
|
||||||
|
|
||||||
@@map("comments")
|
@@map("comments")
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -748,12 +792,13 @@ model CommentLike {
|
|||||||
|
|
||||||
user User @relation(fields: [user_id], references: [id])
|
user User @relation(fields: [user_id], references: [id])
|
||||||
comment Comment @relation(fields: [comment_id], references: [id])
|
comment Comment @relation(fields: [comment_id], references: [id])
|
||||||
|
|
||||||
@@id([user_id, comment_id])
|
@@id([user_id, comment_id])
|
||||||
@@map("comment_likes")
|
@@map("comment_likes")
|
||||||
}
|
}
|
||||||
|
|
||||||
model CommentAuditLog {
|
model CommentAuditLog {
|
||||||
id String @id @db.Uuid @default(uuid(7))
|
id String @id @default(uuid(7)) @db.Uuid
|
||||||
comment Comment @relation(fields: [comment_id], references: [id])
|
comment Comment @relation(fields: [comment_id], references: [id])
|
||||||
performed_by User @relation(fields: [performed_by_id], references: [id])
|
performed_by User @relation(fields: [performed_by_id], references: [id])
|
||||||
action audit_action
|
action audit_action
|
||||||
@ -761,11 +806,12 @@ model CommentAuditLog {
|
|||||||
|
|
||||||
comment_id String @db.Uuid
|
comment_id String @db.Uuid
|
||||||
performed_by_id String @db.Uuid
|
performed_by_id String @db.Uuid
|
||||||
|
|
||||||
@@map("comment_audit_logs")
|
@@map("comment_audit_logs")
|
||||||
}
|
}
|
||||||
|
|
||||||
model CommentReport {
|
model CommentReport {
|
||||||
id String @id @db.Uuid @default(uuid(7))
|
id String @id @default(uuid(7)) @db.Uuid
|
||||||
reporter User @relation(fields: [reporter_id], references: [id])
|
reporter User @relation(fields: [reporter_id], references: [id])
|
||||||
comment Comment @relation(fields: [comment_id], references: [id])
|
comment Comment @relation(fields: [comment_id], references: [id])
|
||||||
title String @db.VarChar(115)
|
title String @db.VarChar(115)
|
||||||
@ -776,11 +822,10 @@ model CommentReport {
|
|||||||
|
|
||||||
reporter_id String @db.Uuid
|
reporter_id String @db.Uuid
|
||||||
comment_id String @db.Uuid
|
comment_id String @db.Uuid
|
||||||
|
|
||||||
@@map("comment_reports")
|
@@map("comment_reports")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ----------------------------------
|
* ----------------------------------
|
||||||
* Model for System Apps and related entities
|
* Model for System Apps and related entities
|
||||||
@ -794,34 +839,37 @@ model ProvisionedUser {
|
|||||||
|
|
||||||
admin_id String @db.Uuid
|
admin_id String @db.Uuid
|
||||||
user_id String @db.Uuid
|
user_id String @db.Uuid
|
||||||
|
|
||||||
@@id([admin_id, user_id])
|
@@id([admin_id, user_id])
|
||||||
@@map("provisioned_users")
|
@@map("provisioned_users")
|
||||||
}
|
}
|
||||||
|
|
||||||
model Country {
|
model Country {
|
||||||
id String @id @db.Uuid @default(uuid(7))
|
id String @id @default(uuid(7)) @db.Uuid
|
||||||
name String @db.VarChar(155)
|
name String @db.VarChar(155)
|
||||||
slug String @db.VarChar(165)
|
slug String @db.VarChar(165)
|
||||||
code String @db.VarChar(3)
|
code String @unique @db.VarChar(3)
|
||||||
flag String? @db.VarChar(255)
|
flag String? @db.VarChar(255)
|
||||||
banner String? @db.VarChar(255)
|
banner String? @db.VarChar(255)
|
||||||
|
|
||||||
UserCountry User[] @relation("UserCountry")
|
UserCountry User[] @relation("UserCountry")
|
||||||
UserCountryPreference UserCountryPreference[]
|
UserCountryPreference UserCountryPreference[]
|
||||||
Media Media[]
|
Media Media[]
|
||||||
|
|
||||||
@@map("countries")
|
@@map("countries")
|
||||||
}
|
}
|
||||||
|
|
||||||
model HomeMediaBanner {
|
model HomeMediaBanner {
|
||||||
id String @id @db.Uuid @default(uuid(7))
|
id String @id @default(uuid(7)) @db.Uuid
|
||||||
media Media @relation(fields: [media_id], references: [id])
|
media Media @relation(fields: [media_id], references: [id])
|
||||||
created_by User @relation(fields: [created_by_id], references: [id])
|
created_by User @relation(fields: [created_by_id], references: [id])
|
||||||
priority Int @db.SmallInt @unique
|
priority Int @unique @db.SmallInt
|
||||||
start_show DateTime @db.Date
|
start_show DateTime @db.Date
|
||||||
end_show DateTime @db.Date
|
end_show DateTime @db.Date
|
||||||
created_at DateTime @default(now()) @db.Timestamptz()
|
created_at DateTime @default(now()) @db.Timestamptz()
|
||||||
|
|
||||||
media_id String @db.Uuid
|
media_id String @db.Uuid
|
||||||
created_by_id String @db.Uuid
|
created_by_id String @db.Uuid
|
||||||
|
|
||||||
@@map("home_media_banners")
|
@@map("home_media_banners")
|
||||||
}
|
}
|
||||||
@ -1,15 +1,11 @@
|
|||||||
import { prisma } from "../../src/utils/databases/prisma/connection";
|
import { prisma } from "../../src/utils/databases/prisma/connection";
|
||||||
import { systemPreferenceSeed } from "./systemPreference.seed";
|
|
||||||
import { userRoleSeed } from "./userRole.seed";
|
|
||||||
import { userSystemSeed } from "./userSystem.seed";
|
import { userSystemSeed } from "./userSystem.seed";
|
||||||
|
|
||||||
async function main() {
|
async function main() {
|
||||||
console.log("🌱 Running all seeds...");
|
console.log("🌱 Running all seeds...");
|
||||||
console.log("🔌 Connecting to database...");
|
console.log("🔌 Connecting to database...");
|
||||||
|
|
||||||
const userSystemSeedResult = await userSystemSeed();
|
await userSystemSeed();
|
||||||
await userRoleSeed(userSystemSeedResult.id);
|
|
||||||
await systemPreferenceSeed();
|
|
||||||
|
|
||||||
console.log("🌳 All seeds completed");
|
console.log("🌳 All seeds completed");
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,35 +0,0 @@
|
|||||||
import { Prisma } from "@prisma/client";
|
|
||||||
import { generateUUIDv7 } from "../../src/helpers/databases/uuidv7";
|
|
||||||
import { prisma } from "../../src/utils/databases/prisma/connection";
|
|
||||||
|
|
||||||
export const systemPreferenceSeed = async () => {
|
|
||||||
const preferences: Prisma.SystemPreferenceUpsertArgs["create"][] = [
|
|
||||||
{
|
|
||||||
id: generateUUIDv7(),
|
|
||||||
key: "REGISTRATION_ENABLED",
|
|
||||||
value: process.env.ENABLE_REGISTRATION === "true" ? "true" : "false",
|
|
||||||
description: "Enable or disable user registration",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: generateUUIDv7(),
|
|
||||||
key: "HERO_BANNER_ENABLED",
|
|
||||||
value: process.env.ENABLE_HERO_BANNER === "true" ? "true" : "false",
|
|
||||||
description: "Enable or disable hero banner feature",
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
await prisma.$transaction(async (tx) => {
|
|
||||||
return await Promise.all(
|
|
||||||
preferences.map(
|
|
||||||
async (pref) =>
|
|
||||||
await tx.systemPreference.upsert({
|
|
||||||
where: {
|
|
||||||
key: pref.key,
|
|
||||||
},
|
|
||||||
update: pref,
|
|
||||||
create: pref,
|
|
||||||
}),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
});
|
|
||||||
};
|
|
||||||
@ -1,73 +0,0 @@
|
|||||||
import { generateUUIDv7 } from "../../src/helpers/databases/uuidv7";
|
|
||||||
import { prisma } from "../../src/utils/databases/prisma/connection";
|
|
||||||
|
|
||||||
export const userRoleSeed = async (SystemAccountId: string) => {
|
|
||||||
console.log("🔃 Seeding user roles...");
|
|
||||||
const roles = [
|
|
||||||
{
|
|
||||||
name: "ADMIN",
|
|
||||||
description: "Administrator with full access",
|
|
||||||
isSuperadmin: true,
|
|
||||||
canEditMedia: true,
|
|
||||||
canManageMedia: true,
|
|
||||||
canEditEpisodes: true,
|
|
||||||
canManageEpisodes: true,
|
|
||||||
canEditComment: true,
|
|
||||||
canManageComment: true,
|
|
||||||
canEditUser: true,
|
|
||||||
canManageUser: true,
|
|
||||||
canEditSystem: true,
|
|
||||||
canManageSystem: true,
|
|
||||||
createdBy: SystemAccountId,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "USER",
|
|
||||||
description: "Regular user with limited access",
|
|
||||||
isSuperadmin: false,
|
|
||||||
canEditMedia: false,
|
|
||||||
canManageMedia: false,
|
|
||||||
canEditEpisodes: false,
|
|
||||||
canManageEpisodes: false,
|
|
||||||
canEditComment: false,
|
|
||||||
canManageComment: false,
|
|
||||||
canEditUser: false,
|
|
||||||
canManageUser: false,
|
|
||||||
canEditSystem: false,
|
|
||||||
canManageSystem: false,
|
|
||||||
createdBy: SystemAccountId,
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
await prisma.$transaction(async (tx) => {
|
|
||||||
const createdRoles = await Promise.all(
|
|
||||||
roles.map(
|
|
||||||
async (role) =>
|
|
||||||
await tx.userRole.upsert({
|
|
||||||
where: { name: role.name },
|
|
||||||
update: role,
|
|
||||||
create: {
|
|
||||||
id: generateUUIDv7(),
|
|
||||||
...role,
|
|
||||||
},
|
|
||||||
}),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
|
|
||||||
await tx.userRoleAssignment.upsert({
|
|
||||||
where: {
|
|
||||||
userId_roleId: {
|
|
||||||
userId: SystemAccountId,
|
|
||||||
roleId: createdRoles.find((r) => r.name === "ADMIN")!.id,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
create: {
|
|
||||||
userId: SystemAccountId,
|
|
||||||
roleId: createdRoles.find((r) => r.name === "ADMIN")!.id,
|
|
||||||
},
|
|
||||||
update: {
|
|
||||||
userId: SystemAccountId,
|
|
||||||
roleId: createdRoles.find((r) => r.name === "ADMIN")!.id,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
});
|
|
||||||
};
|
|
||||||
@ -1,21 +1,21 @@
|
|||||||
import { generateUUIDv7 } from "../../src/helpers/databases/uuidv7";
|
|
||||||
import { createFile } from "../../src/helpers/files/createFile";
|
import { createFile } from "../../src/helpers/files/createFile";
|
||||||
import { hashPassword } from "../../src/helpers/security/password/hash";
|
import { hashPassword } from "../../src/helpers/security/password/hash";
|
||||||
import { prisma } from "../../src/utils/databases/prisma/connection";
|
import { prisma } from "../../src/utils/databases/prisma/connection";
|
||||||
|
import {Prisma} from "@prisma/client";
|
||||||
|
|
||||||
export const userSystemSeed = async () => {
|
export const userSystemSeed = async () => {
|
||||||
const payload = {
|
const payload = {
|
||||||
name: "SYSTEM",
|
|
||||||
username: process.env.DEFAULT_ADMIN_USERNAME!,
|
username: process.env.DEFAULT_ADMIN_USERNAME!,
|
||||||
|
fullname: "SYSTEM",
|
||||||
email: process.env.DEFAULT_ADMIN_EMAIL!,
|
email: process.env.DEFAULT_ADMIN_EMAIL!,
|
||||||
password: await hashPassword(process.env.DEFAULT_ADMIN_PASSWORD!),
|
password: await hashPassword(process.env.DEFAULT_ADMIN_PASSWORD!),
|
||||||
};
|
role: "admin"
|
||||||
|
} as Prisma.UserCreateInput;
|
||||||
|
|
||||||
const insertedUserSystem = await prisma.user.upsert({
|
const insertedUserSystem = await prisma.user.upsert({
|
||||||
where: { username: payload.username },
|
where: { username: payload.username },
|
||||||
update: payload,
|
update: payload,
|
||||||
create: {
|
create: {
|
||||||
id: generateUUIDv7(),
|
|
||||||
...payload,
|
...payload,
|
||||||
},
|
},
|
||||||
select: { id: true },
|
select: { id: true },
|
||||||
|
|||||||
@ -4,6 +4,6 @@ export const getContentReferenceAPI = (malId: number) => {
|
|||||||
return {
|
return {
|
||||||
baseURL,
|
baseURL,
|
||||||
getMediaFullInfo: `/anime/${malId}/full`,
|
getMediaFullInfo: `/anime/${malId}/full`,
|
||||||
getMediaCharactersWithVA: `/anime/${malId}/characters`,
|
getMediaCharacters: `/anime/${malId}/characters`,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|||||||
@ -1,25 +0,0 @@
|
|||||||
import { Context, Static } from "elysia";
|
|
||||||
import { mainErrorHandler } from "../../../helpers/error/handler";
|
|
||||||
import { returnWriteResponse } from "../../../helpers/callback/httpResponse";
|
|
||||||
import { updateAllEpisodeThumbnailService } from "../services/http/updateAllEpisodeThumbnail.service";
|
|
||||||
import { updateAllEpisodeThumbnailSchema } from "../schemas/updateAllEpisodeThumbnail.schema";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Updating all episode thumbnails for a specific target service reference ID.
|
|
||||||
*
|
|
||||||
* This controller handles the bulk update of episode thumbnails for all episodes associated with a specific service reference ID.
|
|
||||||
* It fetches the latest thumbnail data from external sources and updates the existing episode records in the database accordingly.
|
|
||||||
*
|
|
||||||
* See OpenAPI documentation for request/response schema.
|
|
||||||
*/
|
|
||||||
export const updateAllEpisodeThumbnailController = async (ctx: {
|
|
||||||
set: Context["set"];
|
|
||||||
body: Static<typeof updateAllEpisodeThumbnailSchema.body>;
|
|
||||||
}) => {
|
|
||||||
try {
|
|
||||||
const newEpisodeThumbnailsCount = await updateAllEpisodeThumbnailService(ctx.body.service_reference_id);
|
|
||||||
return returnWriteResponse(ctx.set, 204, `Updating ${newEpisodeThumbnailsCount} episode thumbnails successfully.`);
|
|
||||||
} catch (error) {
|
|
||||||
return mainErrorHandler(ctx.set, error);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
@ -3,12 +3,10 @@ import { bulkInsertEpisodeController } from "./controllers/bulkInsertEpisode.con
|
|||||||
import {bulkInsertMediaController} from "./controllers/bulkInsertMedia.controller";
|
import {bulkInsertMediaController} from "./controllers/bulkInsertMedia.controller";
|
||||||
import {createVideoServiceInternalController} from "./controllers/createVideoService.controller";
|
import {createVideoServiceInternalController} from "./controllers/createVideoService.controller";
|
||||||
import {bulkInsertVideoController} from "./controllers/bulkInsertVideo.controller";
|
import {bulkInsertVideoController} from "./controllers/bulkInsertVideo.controller";
|
||||||
import { updateAllEpisodeThumbnailController } from "./controllers/updateAllEpisodeThumbnail.controller";
|
|
||||||
import {purgeUnusedSessionController} from "./controllers/purgeUnusedSession.controller";
|
import {purgeUnusedSessionController} from "./controllers/purgeUnusedSession.controller";
|
||||||
import {createHeroBannerController} from "./controllers/createHeroBanner.controller";
|
import {createHeroBannerController} from "./controllers/createHeroBanner.controller";
|
||||||
import {bulkInsertMediaSchema} from "./schemas/bulkInsertMedia.schema";
|
import {bulkInsertMediaSchema} from "./schemas/bulkInsertMedia.schema";
|
||||||
import {bulkInsertEpisodeSchema} from "./schemas/bulkInsertEpisode.schema";
|
import {bulkInsertEpisodeSchema} from "./schemas/bulkInsertEpisode.schema";
|
||||||
import { updateAllEpisodeThumbnailSchema } from "./schemas/updateAllEpisodeThumbnail.schema";
|
|
||||||
import {bulkInsertVideoSchema} from "./schemas/bulkInsertVideo.schema";
|
import {bulkInsertVideoSchema} from "./schemas/bulkInsertVideo.schema";
|
||||||
import {createVideoServiceInternalSchema} from "./schemas/createVideoServiceInternal.schema";
|
import {createVideoServiceInternalSchema} from "./schemas/createVideoServiceInternal.schema";
|
||||||
import {purgeUnusedSessionSchema} from "./schemas/purgeUnusedSession.schema";
|
import {purgeUnusedSessionSchema} from "./schemas/purgeUnusedSession.schema";
|
||||||
@ -20,7 +18,6 @@ export const internalModule = new Elysia({
|
|||||||
})
|
})
|
||||||
.post("/media/bulk-insert", bulkInsertMediaController, bulkInsertMediaSchema)
|
.post("/media/bulk-insert", bulkInsertMediaController, bulkInsertMediaSchema)
|
||||||
.post("/episode/bulk-insert", bulkInsertEpisodeController, bulkInsertEpisodeSchema)
|
.post("/episode/bulk-insert", bulkInsertEpisodeController, bulkInsertEpisodeSchema)
|
||||||
.put("/episode/update-thumbnails", updateAllEpisodeThumbnailController, updateAllEpisodeThumbnailSchema)
|
|
||||||
.post("/video/bulk-insert", bulkInsertVideoController, bulkInsertVideoSchema)
|
.post("/video/bulk-insert", bulkInsertVideoController, bulkInsertVideoSchema)
|
||||||
.post("/video-service", createVideoServiceInternalController, createVideoServiceInternalSchema)
|
.post("/video-service", createVideoServiceInternalController, createVideoServiceInternalSchema)
|
||||||
.post("/user-session/purge-unused", purgeUnusedSessionController, purgeUnusedSessionSchema)
|
.post("/user-session/purge-unused", purgeUnusedSessionController, purgeUnusedSessionSchema)
|
||||||
|
|||||||
@ -1,25 +1,45 @@
|
|||||||
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 {SystemAccountId} from "../../../config/account/system";
|
||||||
|
|
||||||
|
|
||||||
|
export interface BulkInsertEpisodesPayload {
|
||||||
|
media_id: string
|
||||||
|
episode_number: number
|
||||||
|
title: string
|
||||||
|
title_romanji: string
|
||||||
|
title_origin: string
|
||||||
|
aired_at: Date
|
||||||
|
score: number
|
||||||
|
filler: boolean
|
||||||
|
recap: boolean
|
||||||
|
forum_url: string
|
||||||
|
created_by_id: string
|
||||||
|
}
|
||||||
|
|
||||||
export const bulkInsertEpisodesRepository = async (
|
export const bulkInsertEpisodesRepository = async (
|
||||||
payload: Omit<Prisma.EpisodeUncheckedCreateInput, "id">,
|
payload: BulkInsertEpisodesPayload[]
|
||||||
) => {
|
) => {
|
||||||
try {
|
try {
|
||||||
return await prisma.episode.upsert({
|
await prisma.$transaction(async (tx) => {
|
||||||
|
await Promise.all(
|
||||||
|
payload.map(async (episode) =>
|
||||||
|
await tx.episode.upsert({
|
||||||
where: {
|
where: {
|
||||||
mediaId_episode: {
|
media_id_episode_number: {
|
||||||
mediaId: payload.mediaId as string,
|
media_id: episode.media_id,
|
||||||
episode: payload.episode as number,
|
episode_number: episode.episode_number
|
||||||
|
}
|
||||||
},
|
},
|
||||||
},
|
update: episode,
|
||||||
update: payload,
|
|
||||||
create: {
|
create: {
|
||||||
id: generateUUIDv7(),
|
...episode,
|
||||||
...payload,
|
created_by_id: SystemAccountId
|
||||||
},
|
}
|
||||||
});
|
})
|
||||||
|
)
|
||||||
|
)
|
||||||
|
})
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
throw new AppError(500, "Failed to bulk insert episodes", err);
|
throw new AppError(500, "Failed to bulk insert episodes", err);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -0,0 +1,123 @@
|
|||||||
|
import {AppError} from "../../../helpers/error/instances/app";
|
||||||
|
import {MediaChar} from "../types/mediaCharacters";
|
||||||
|
import {prisma} from "../../../utils/databases/prisma/connection";
|
||||||
|
import {character_role} from "@prisma/client";
|
||||||
|
|
||||||
|
export const bulkInsertMediaCharacterRepository = async (
|
||||||
|
mediaId: string,
|
||||||
|
characters: MediaChar[]
|
||||||
|
) => {
|
||||||
|
try {
|
||||||
|
const chars = characters.map(c => ({
|
||||||
|
mal_id: c.character.mal_id,
|
||||||
|
name: c.character.name,
|
||||||
|
image: c.character.images.webp.image_url,
|
||||||
|
small_image: c.character.images.webp.small_image_url,
|
||||||
|
fanpage_url: c.character.url
|
||||||
|
}));
|
||||||
|
|
||||||
|
const staffs = characters.flatMap(c =>
|
||||||
|
c.voice_actors.map(v => ({
|
||||||
|
mal_id: v.person.mal_id,
|
||||||
|
name: v.person.name,
|
||||||
|
image: v.person.images.jpg.image_url
|
||||||
|
}))
|
||||||
|
);
|
||||||
|
|
||||||
|
await prisma.$transaction(async (tx) => {
|
||||||
|
|
||||||
|
// Insert Character
|
||||||
|
await tx.character.createMany({
|
||||||
|
data: chars,
|
||||||
|
skipDuplicates: true
|
||||||
|
});
|
||||||
|
|
||||||
|
// Insert Staff
|
||||||
|
await tx.staff.createMany({
|
||||||
|
data: staffs,
|
||||||
|
skipDuplicates: true
|
||||||
|
});
|
||||||
|
|
||||||
|
// Get inserted characters
|
||||||
|
const insertedChar = await tx.character.findMany({
|
||||||
|
where: {
|
||||||
|
mal_id: {
|
||||||
|
in: chars.map(c => c.mal_id)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
select: {
|
||||||
|
id: true,
|
||||||
|
mal_id: true
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Get inserted staffs
|
||||||
|
const insertedStaff = await tx.staff.findMany({
|
||||||
|
where: {
|
||||||
|
mal_id: {
|
||||||
|
in: staffs.map(s => s.mal_id)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
select: {
|
||||||
|
id: true,
|
||||||
|
mal_id: true
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Build lookup map
|
||||||
|
const characterMap = new Map(
|
||||||
|
insertedChar.map(c => [c.mal_id!, c.id])
|
||||||
|
);
|
||||||
|
const staffMap = new Map(
|
||||||
|
insertedStaff.map(s => [s.mal_id!, s.id])
|
||||||
|
);
|
||||||
|
|
||||||
|
// Connect media with characters
|
||||||
|
const mediaCharacters = characters.map(c => {
|
||||||
|
const characterId = characterMap.get(c.character.mal_id);
|
||||||
|
if (!characterId)
|
||||||
|
throw new AppError(500, `Character ${c.character.mal_id} not found`);
|
||||||
|
|
||||||
|
return {
|
||||||
|
media_id: mediaId,
|
||||||
|
character_id: characterId,
|
||||||
|
role: c.role.toLowerCase() as character_role
|
||||||
|
};
|
||||||
|
});
|
||||||
|
await tx.mediaCharacter.createMany({
|
||||||
|
data: mediaCharacters,
|
||||||
|
skipDuplicates: true
|
||||||
|
});
|
||||||
|
|
||||||
|
// Insert all voice actor of characters
|
||||||
|
const voiceActors = characters.flatMap(c => {
|
||||||
|
const characterId = characterMap.get(c.character.mal_id);
|
||||||
|
if (!characterId)
|
||||||
|
throw new AppError(500, `Character ${c.character.mal_id} not found`);
|
||||||
|
|
||||||
|
return c.voice_actors.map(v => {
|
||||||
|
const staffId = staffMap.get(v.person.mal_id);
|
||||||
|
if (!staffId) throw new AppError(500, `Staff ${v.person.mal_id} not found`);
|
||||||
|
|
||||||
|
return {
|
||||||
|
media_id: mediaId,
|
||||||
|
character_id: characterId,
|
||||||
|
staff_id: staffId,
|
||||||
|
language: v.language
|
||||||
|
};
|
||||||
|
});
|
||||||
|
});
|
||||||
|
await tx.voiceActor.createMany({
|
||||||
|
data: voiceActors,
|
||||||
|
skipDuplicates: true
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
throw new AppError(
|
||||||
|
500,
|
||||||
|
"Failed to bulk insert media characters",
|
||||||
|
error
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
@ -0,0 +1,36 @@
|
|||||||
|
import {AppError} from "../../../helpers/error/instances/app";
|
||||||
|
import {MediaFullInfoResponse} from "../types/mediaFullInfo.type";
|
||||||
|
import {prisma} from "../../../utils/databases/prisma/connection";
|
||||||
|
import slugify from "slugify";
|
||||||
|
|
||||||
|
export const bulkInsertMediaGenreRepository = async (mediaData: MediaFullInfoResponse, mediaId: string) => {
|
||||||
|
try {
|
||||||
|
await prisma.$transaction(async (tx) => {
|
||||||
|
const createdGenres = await tx.genre.createManyAndReturn({
|
||||||
|
data: mediaData.data.genres.map((genre) => ({
|
||||||
|
name: genre.name,
|
||||||
|
mal_id: genre.mal_id,
|
||||||
|
slug: slugify(genre.name, {
|
||||||
|
lower: true,
|
||||||
|
strict: true,
|
||||||
|
})
|
||||||
|
})),
|
||||||
|
skipDuplicates: true,
|
||||||
|
select: {
|
||||||
|
mal_id: true,
|
||||||
|
id: true
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
await tx.mediaGenre.createMany({
|
||||||
|
data: createdGenres.map((genre) => ({
|
||||||
|
media_id: mediaId,
|
||||||
|
genre_id: genre.id
|
||||||
|
})),
|
||||||
|
skipDuplicates: true
|
||||||
|
})
|
||||||
|
})
|
||||||
|
} catch (error) {
|
||||||
|
throw new AppError(500, "Failed to bulk insert media genre", error);
|
||||||
|
}
|
||||||
|
};
|
||||||
@ -0,0 +1,80 @@
|
|||||||
|
import { Prisma } from "@prisma/client";
|
||||||
|
import { GenreOrProducer } from "../types/mediaFullInfo.type";
|
||||||
|
import { SystemAccountId } from "../../../config/account/system";
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Bulk Insert Producer, Studio, Licensor
|
||||||
|
*
|
||||||
|
* This function handles the bulk insertion of producers, studios, and licensors.
|
||||||
|
* It takes a transaction client, the ID of the media, and an array of producer, studio, and licensor objects.
|
||||||
|
* */
|
||||||
|
export const bulkInsertMediaProducerStudioLicensorRepository = async (
|
||||||
|
tx: Prisma.TransactionClient,
|
||||||
|
media_id: string,
|
||||||
|
payload: (GenreOrProducer & { status: "producer" | "licensor" | "studio" })[],
|
||||||
|
) => {
|
||||||
|
await tx.producer.createMany({
|
||||||
|
data: payload.map((p) => ({
|
||||||
|
mal_id: p.mal_id,
|
||||||
|
type: p.type,
|
||||||
|
name: p.name,
|
||||||
|
url: p.url,
|
||||||
|
created_by_id: SystemAccountId,
|
||||||
|
})),
|
||||||
|
skipDuplicates: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
const insertedProducers = (
|
||||||
|
await tx.producer.findMany({
|
||||||
|
where: {
|
||||||
|
mal_id: {
|
||||||
|
in: payload.map((p) => p.mal_id),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
select: {
|
||||||
|
id: true,
|
||||||
|
mal_id: true,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
).map((producer) => {
|
||||||
|
const statusProducer = payload.find((p) => p.mal_id === producer.mal_id)?.status;
|
||||||
|
return {
|
||||||
|
id: producer.id,
|
||||||
|
mal_id: producer.mal_id,
|
||||||
|
status: statusProducer,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
await tx.mediaProducer.createMany({
|
||||||
|
data: insertedProducers
|
||||||
|
.filter((p) => p.status === "producer")
|
||||||
|
.map((producer) => ({
|
||||||
|
media_id,
|
||||||
|
producer_id: producer.id,
|
||||||
|
})),
|
||||||
|
skipDuplicates: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
await tx.mediaLicensor.createMany({
|
||||||
|
data: insertedProducers
|
||||||
|
.filter((p) => p.status === "licensor")
|
||||||
|
.map((producer) => ({
|
||||||
|
media_id,
|
||||||
|
licensor_id: producer.id,
|
||||||
|
})),
|
||||||
|
skipDuplicates: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
await tx.mediaStudio.createMany({
|
||||||
|
data: insertedProducers
|
||||||
|
.filter((p) => p.status === "studio")
|
||||||
|
.map((producer) => ({
|
||||||
|
media_id,
|
||||||
|
studio_id: producer.id,
|
||||||
|
})),
|
||||||
|
skipDuplicates: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
return insertedProducers;
|
||||||
|
};
|
||||||
@ -1,69 +0,0 @@
|
|||||||
import { SystemAccountId } from "../../../config/account/system";
|
|
||||||
import { generateSlug } from "../../../helpers/characters/generateSlug";
|
|
||||||
import { generateUUIDv7 } from "../../../helpers/databases/uuidv7";
|
|
||||||
import { AppError } from "../../../helpers/error/instances/app";
|
|
||||||
import { prisma } from "../../../utils/databases/prisma/connection";
|
|
||||||
import { MediaFullInfoResponse } from "../types/mediaFullInfo.type";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Studios Insertion
|
|
||||||
*
|
|
||||||
* This section manages the insertion of studios associated with the media.
|
|
||||||
* It processes each studio listed in the media data, generating a slug for
|
|
||||||
* each and performing an upsert operation to either create or update the
|
|
||||||
* studio record in the database. The IDs of the inserted or updated studios
|
|
||||||
* are collected for later association with the media.
|
|
||||||
*
|
|
||||||
* @param data - The full media data containing studios information.
|
|
||||||
* @returns An array of IDs of the inserted or updated studios.
|
|
||||||
*/
|
|
||||||
export const bulkInsertStudiosRepository = async (
|
|
||||||
data: MediaFullInfoResponse,
|
|
||||||
) => {
|
|
||||||
try {
|
|
||||||
const studioIds: string[] = [];
|
|
||||||
for (const studio of data.data.studios) {
|
|
||||||
const slug = (await generateSlug(studio.name)) as string;
|
|
||||||
const studioPayload = {
|
|
||||||
name: studio.name,
|
|
||||||
malId: studio.mal_id,
|
|
||||||
linkAbout: studio.url,
|
|
||||||
createdBy: SystemAccountId,
|
|
||||||
slug,
|
|
||||||
};
|
|
||||||
const insertedStudio = await prisma.studio.upsert({
|
|
||||||
where: { slug },
|
|
||||||
create: {
|
|
||||||
id: generateUUIDv7(),
|
|
||||||
...studioPayload,
|
|
||||||
},
|
|
||||||
update: studioPayload,
|
|
||||||
select: { id: true },
|
|
||||||
});
|
|
||||||
studioIds.push(insertedStudio.id);
|
|
||||||
}
|
|
||||||
for (const studio of data.data.producers) {
|
|
||||||
const slug = (await generateSlug(studio.name)) as string;
|
|
||||||
const studioPayload = {
|
|
||||||
name: studio.name,
|
|
||||||
malId: studio.mal_id,
|
|
||||||
linkAbout: studio.url,
|
|
||||||
createdBy: SystemAccountId,
|
|
||||||
slug,
|
|
||||||
};
|
|
||||||
const insertedStudio = await prisma.studio.upsert({
|
|
||||||
where: { slug },
|
|
||||||
create: {
|
|
||||||
id: generateUUIDv7(),
|
|
||||||
...studioPayload,
|
|
||||||
},
|
|
||||||
update: studioPayload,
|
|
||||||
select: { id: true },
|
|
||||||
});
|
|
||||||
studioIds.push(insertedStudio.id);
|
|
||||||
}
|
|
||||||
return studioIds;
|
|
||||||
} catch (error) {
|
|
||||||
throw new AppError(500, "Failed to insert studios", error);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
@ -1,7 +1,8 @@
|
|||||||
import { Prisma } from "@prisma/client";
|
import { Prisma } from "@prisma/client";
|
||||||
import { AppError } from "../../../helpers/error/instances/app";
|
import { AppError } from "../../../helpers/error/instances/app";
|
||||||
|
import { MediaFullInfoResponse } from "../types/mediaFullInfo.type";
|
||||||
import { prisma } from "../../../utils/databases/prisma/connection";
|
import { prisma } from "../../../utils/databases/prisma/connection";
|
||||||
import { generateUUIDv7 } from "../../../helpers/databases/uuidv7";
|
import { bulkInsertMediaProducerStudioLicensorRepository } from "./bulkInsertMediaProducerStudioLicensor.repository";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Media Payload Construction and Upsert
|
* Media Payload Construction and Upsert
|
||||||
@ -17,22 +18,138 @@ import { generateUUIDv7 } from "../../../helpers/databases/uuidv7";
|
|||||||
* @param data - The full media data for constructing the media payload.
|
* @param data - The full media data for constructing the media payload.
|
||||||
* @returns The inserted or updated media record.
|
* @returns The inserted or updated media record.
|
||||||
*/
|
*/
|
||||||
export const InsertMediaRepository = async ({
|
export const InsertMediaRepository = async ({ payload }: { payload: MediaFullInfoResponse["data"] }) => {
|
||||||
malId,
|
|
||||||
payload,
|
|
||||||
}: {
|
|
||||||
malId: number;
|
|
||||||
payload: Omit<Prisma.MediaUncheckedCreateInput, "id">;
|
|
||||||
}) => {
|
|
||||||
try {
|
try {
|
||||||
return await prisma.media.upsert({
|
const constructMediaPayload: Prisma.MediaUpsertArgs["create"] = {
|
||||||
where: { malId },
|
mal_id: payload.mal_id,
|
||||||
update: payload,
|
title: payload.title,
|
||||||
|
title_secondary: payload.title_english,
|
||||||
|
title_original: payload.title_japanese,
|
||||||
|
title_synonyms: payload.title_synonyms,
|
||||||
|
trailer: {
|
||||||
|
connectOrCreate: {
|
||||||
|
where: {
|
||||||
|
embed_url: payload.trailer.embed_url,
|
||||||
|
},
|
||||||
create: {
|
create: {
|
||||||
id: generateUUIDv7(),
|
embed_url: payload.trailer.embed_url,
|
||||||
...payload,
|
url: payload.trailer.url,
|
||||||
|
small_image_url: payload.trailer.images.small_image_url,
|
||||||
|
large_image_url: payload.trailer.images.large_image_url,
|
||||||
|
maximum_image_url: payload.trailer.images.maximum_image_url,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
synopsis: payload.synopsis,
|
||||||
|
small_image_url: payload.images.jpg.small_image_url,
|
||||||
|
medium_image_url: payload.images.jpg.image_url,
|
||||||
|
large_image_url: payload.images.jpg.large_image_url,
|
||||||
|
type: {
|
||||||
|
connectOrCreate: {
|
||||||
|
where: {
|
||||||
|
name: payload.type.toLowerCase(),
|
||||||
|
},
|
||||||
|
create: {
|
||||||
|
name: payload.type.toLowerCase(),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
source: {
|
||||||
|
connectOrCreate: {
|
||||||
|
where: {
|
||||||
|
name: payload.source.toLowerCase(),
|
||||||
|
},
|
||||||
|
create: {
|
||||||
|
name: payload.source.toLowerCase(),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
status: {
|
||||||
|
connectOrCreate: {
|
||||||
|
where: {
|
||||||
|
name: payload.status.toLowerCase(),
|
||||||
|
},
|
||||||
|
create: {
|
||||||
|
name: payload.status.toLowerCase(),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
airing: payload.airing,
|
||||||
|
start_airing: payload.aired.from,
|
||||||
|
end_airing: payload.aired.to,
|
||||||
|
age_rating: {
|
||||||
|
connectOrCreate: {
|
||||||
|
where: {
|
||||||
|
name: payload.rating.toLowerCase(),
|
||||||
|
},
|
||||||
|
create: {
|
||||||
|
name: payload.rating.toLowerCase(),
|
||||||
|
min_age: 0, // Placeholder, as the actual age rating details may require additional mapping
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
score_total: 0,
|
||||||
|
score_count: 0,
|
||||||
|
background: payload.background,
|
||||||
|
season: payload.season,
|
||||||
|
year: payload.year,
|
||||||
|
country: {
|
||||||
|
connectOrCreate: {
|
||||||
|
where: {
|
||||||
|
code: "jpn",
|
||||||
|
},
|
||||||
|
create: {
|
||||||
|
name: "japan",
|
||||||
|
slug: "japan",
|
||||||
|
code: "jpn",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
broadcast_day: payload.broadcast.day,
|
||||||
|
};
|
||||||
|
|
||||||
|
const producerPayload = [
|
||||||
|
...payload.producers.map((producer) => ({
|
||||||
|
mal_id: producer.mal_id,
|
||||||
|
type: producer.type,
|
||||||
|
name: producer.name,
|
||||||
|
url: producer.url,
|
||||||
|
status: "producer" as const,
|
||||||
|
})),
|
||||||
|
...payload.licensors.map((licensor) => ({
|
||||||
|
mal_id: licensor.mal_id,
|
||||||
|
type: licensor.type,
|
||||||
|
name: licensor.name,
|
||||||
|
url: licensor.url,
|
||||||
|
status: "licensor" as const,
|
||||||
|
})),
|
||||||
|
...payload.studios.map((studio) => ({
|
||||||
|
mal_id: studio.mal_id,
|
||||||
|
type: studio.type,
|
||||||
|
name: studio.name,
|
||||||
|
url: studio.url,
|
||||||
|
status: "studio" as const,
|
||||||
|
})),
|
||||||
|
];
|
||||||
|
|
||||||
|
return await prisma.$transaction(async (tx) => {
|
||||||
|
const media = await tx.media.upsert({
|
||||||
|
where: { mal_id: payload.mal_id },
|
||||||
|
create: constructMediaPayload,
|
||||||
|
update: constructMediaPayload,
|
||||||
|
select: {
|
||||||
|
id: true,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
await bulkInsertMediaProducerStudioLicensorRepository(tx, media.id, producerPayload);
|
||||||
|
return {
|
||||||
|
id: media.id,
|
||||||
|
mal_id: payload.mal_id,
|
||||||
|
name: payload.title,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
throw new AppError(500, "Failed to insert media", error);
|
throw new AppError(500, "Failed to insert media", error);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,28 +0,0 @@
|
|||||||
import { AppError } from "../../../helpers/error/instances/app";
|
|
||||||
import { prisma } from "../../../utils/databases/prisma/connection";
|
|
||||||
|
|
||||||
export const findEpisodeWithMediaIdRepository = async ({
|
|
||||||
media,
|
|
||||||
episode,
|
|
||||||
}: {
|
|
||||||
media: string;
|
|
||||||
episode: number;
|
|
||||||
}) => {
|
|
||||||
try {
|
|
||||||
const foundEpisode = await prisma.episode.findUnique({
|
|
||||||
where: {
|
|
||||||
mediaId_episode: {
|
|
||||||
mediaId: media,
|
|
||||||
episode: episode,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
select: {
|
|
||||||
id: true,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
if (!foundEpisode) throw new AppError(404, "Episode not found");
|
|
||||||
return foundEpisode;
|
|
||||||
} catch (error) {
|
|
||||||
throw new AppError(500, "Error finding episode with media id", error);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
@ -0,0 +1,14 @@
|
|||||||
|
import {AppError} from "../../../helpers/error/instances/app";
|
||||||
|
import {prisma} from "../../../utils/databases/prisma/connection";
|
||||||
|
|
||||||
|
export const findMediaWithMalIdRepository = async (malId: number) => {
|
||||||
|
try {
|
||||||
|
return await prisma.media.findUnique({
|
||||||
|
where: {
|
||||||
|
mal_id: malId
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
throw new AppError(500, "Failed to find media with malId", error)
|
||||||
|
}
|
||||||
|
};
|
||||||
@ -16,14 +16,27 @@ export const bulkInsertVideoSchema = {
|
|||||||
service_id: t.String({
|
service_id: t.String({
|
||||||
description: "The ID of the video service",
|
description: "The ID of the video service",
|
||||||
}),
|
}),
|
||||||
|
priority: t.Optional(t.Number({
|
||||||
|
description: "The priority of the video (can't be duplicate)",
|
||||||
|
})),
|
||||||
video_code: t.String({
|
video_code: t.String({
|
||||||
description: "The code of the video on the service",
|
description: "The code of the video on the service",
|
||||||
}),
|
}),
|
||||||
|
short_code: t.Optional(
|
||||||
|
t.String({
|
||||||
|
description: "The code of the preview video on the service",
|
||||||
|
}),
|
||||||
|
),
|
||||||
thumbnail_code: t.Optional(
|
thumbnail_code: t.Optional(
|
||||||
t.String({
|
t.String({
|
||||||
description: "The code of the thumbnail for the video on the service",
|
description: "The code of the thumbnail for the video on the service",
|
||||||
}),
|
}),
|
||||||
),
|
),
|
||||||
|
download_code: t.Optional(
|
||||||
|
t.String({
|
||||||
|
description: "The code of the download link for the video on the service",
|
||||||
|
})
|
||||||
|
)
|
||||||
}),
|
}),
|
||||||
),
|
),
|
||||||
}),
|
}),
|
||||||
|
|||||||
@ -1,35 +0,0 @@
|
|||||||
import { t } from "elysia";
|
|
||||||
import { AppRouteSchema } from "../../../helpers/types/AppRouteSchema";
|
|
||||||
|
|
||||||
export const updateAllEpisodeThumbnailSchema = {
|
|
||||||
body: t.Object({
|
|
||||||
service_reference_id: t.String({
|
|
||||||
description: "The ID of the service to which the target of episode thumbnails belong",
|
|
||||||
}),
|
|
||||||
}),
|
|
||||||
detail: {
|
|
||||||
summary: "Bulk update episode thumbnails",
|
|
||||||
description:
|
|
||||||
"Perform bulk update of episode thumbnails for all episodes associated with a specific service reference ID. This operation fetches the latest thumbnail data from external sources and updates the existing episode records in the database accordingly.",
|
|
||||||
responses: {
|
|
||||||
204: {
|
|
||||||
description: "Updating episode thumbnails operation completed successfully",
|
|
||||||
content: {
|
|
||||||
"application/json": {
|
|
||||||
schema: {
|
|
||||||
type: "object",
|
|
||||||
properties: {
|
|
||||||
success: { type: "boolean", default: true },
|
|
||||||
status: { type: "integer", default: 204 },
|
|
||||||
message: {
|
|
||||||
type: "string",
|
|
||||||
default: "Updating {newEpisodeThumbnailsCount} episode thumbnails operation completed successfully",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
} satisfies AppRouteSchema;
|
|
||||||
@ -1,64 +1,29 @@
|
|||||||
import { Prisma } from "@prisma/client";
|
|
||||||
import {ErrorForwarder} from "../../../../helpers/error/instances/forwarder";
|
import {ErrorForwarder} from "../../../../helpers/error/instances/forwarder";
|
||||||
import { bulkInsertGenresRepository } from "../../repositories/bulkInsertGenres.repository";
|
|
||||||
import {InsertMediaRepository} from "../../repositories/bulkinsertMedia.repository";
|
import {InsertMediaRepository} from "../../repositories/bulkinsertMedia.repository";
|
||||||
import { bulkInsertStudiosRepository } from "../../repositories/bulkInsertStudios.repository";
|
|
||||||
import { MediaFullInfoResponse } from "../../types/mediaFullInfo.type";
|
|
||||||
import { generateSlug } from "../../../../helpers/characters/generateSlug";
|
|
||||||
import { bulkInsertCharWithVAService } from "../internal/bulkInsertCharWithVA.service";
|
|
||||||
import { generateUUIDv7 } from "../../../../helpers/databases/uuidv7";
|
|
||||||
import { SystemAccountId } from "../../../../config/account/system";
|
|
||||||
import {getContentReferenceAPI} from "../../../../config/apis/jikan/media.reference";
|
import {getContentReferenceAPI} from "../../../../config/apis/jikan/media.reference";
|
||||||
|
import {bulkInsertMediaCharacterRepository} from "../../repositories/bulkInsertMediaCharacter.repository";
|
||||||
|
import {MediaFullInfoResponse} from "../../types/mediaFullInfo.type";
|
||||||
|
import {MediaCharacters} from "../../types/mediaCharacters";
|
||||||
|
import {bulkInsertMediaGenreRepository} from "../../repositories/bulkInsertMediaGenre.repository";
|
||||||
|
|
||||||
export const bulkInsertAnimeService = async (malId: number) => {
|
export const bulkInsertAnimeService = async (malId: number) => {
|
||||||
try {
|
try {
|
||||||
const { baseURL, getMediaFullInfo } = getContentReferenceAPI(malId);
|
const {baseURL, getMediaFullInfo, getMediaCharacters} = getContentReferenceAPI(malId);
|
||||||
const mediaFullInfo = (await fetch(baseURL + getMediaFullInfo).then((res) =>
|
const mediaFullInfo = (await fetch(baseURL + getMediaFullInfo).then((res) => res.json())) as MediaFullInfoResponse;
|
||||||
res.json(),
|
|
||||||
)) as MediaFullInfoResponse;
|
|
||||||
|
|
||||||
const insertedGenres = await bulkInsertGenresRepository(mediaFullInfo);
|
// Inserting Media and Producers (Producer, Studio, Licensor)
|
||||||
const insertedStudios = await bulkInsertStudiosRepository(mediaFullInfo);
|
|
||||||
const insertedCharacters = await bulkInsertCharWithVAService(malId);
|
|
||||||
|
|
||||||
const constructMediaPayload: Prisma.MediaUpsertArgs["create"] = {
|
|
||||||
id: generateUUIDv7(),
|
|
||||||
title: mediaFullInfo.data.title,
|
|
||||||
titleAlternative: mediaFullInfo.data
|
|
||||||
.titles as unknown as Prisma.InputJsonValue,
|
|
||||||
slug: await generateSlug(mediaFullInfo.data.title, {
|
|
||||||
model: "media",
|
|
||||||
target: "slug",
|
|
||||||
}),
|
|
||||||
malId: mediaFullInfo.data.mal_id,
|
|
||||||
genres: {
|
|
||||||
connect: insertedGenres.map((id) => ({ id })),
|
|
||||||
},
|
|
||||||
studios: {
|
|
||||||
connect: insertedStudios.map((id) => ({ id })),
|
|
||||||
},
|
|
||||||
characters: {
|
|
||||||
connect: insertedCharacters.map(({ id }) => ({ id })),
|
|
||||||
},
|
|
||||||
score: mediaFullInfo.data.score,
|
|
||||||
pictureMedium: mediaFullInfo.data.images.webp.image_url,
|
|
||||||
pictureLarge: mediaFullInfo.data.images.webp.large_image_url,
|
|
||||||
status: mediaFullInfo.data.status,
|
|
||||||
startAiring: mediaFullInfo.data.aired.from,
|
|
||||||
endAiring: mediaFullInfo.data.aired.to,
|
|
||||||
synopsis: mediaFullInfo.data.synopsis,
|
|
||||||
ageRating: mediaFullInfo.data.rating,
|
|
||||||
mediaType: mediaFullInfo.data.type,
|
|
||||||
source: mediaFullInfo.data.source,
|
|
||||||
onDraft: false,
|
|
||||||
uploadedBy: SystemAccountId,
|
|
||||||
};
|
|
||||||
const insertedMedia = await InsertMediaRepository({
|
const insertedMedia = await InsertMediaRepository({
|
||||||
malId: mediaFullInfo.data.mal_id,
|
payload: mediaFullInfo.data,
|
||||||
payload: constructMediaPayload,
|
|
||||||
});
|
});
|
||||||
|
|
||||||
return insertedMedia;
|
// Inserting Characters, Staff, and Voice Actors
|
||||||
|
const mediaChar = await fetch(baseURL + getMediaCharacters).then((res) => res.json()) as MediaCharacters;
|
||||||
|
await bulkInsertMediaCharacterRepository(insertedMedia.id, mediaChar.data);
|
||||||
|
|
||||||
|
// Inserting Genres and Demographics
|
||||||
|
await bulkInsertMediaGenreRepository(mediaFullInfo, insertedMedia.id)
|
||||||
|
|
||||||
|
return insertedMedia.id;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
ErrorForwarder(error);
|
ErrorForwarder(error);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,33 +1,35 @@
|
|||||||
import { ErrorForwarder } from "../../../../helpers/error/instances/forwarder";
|
|
||||||
import {MediaEpisodeInfoResponse} from "../../types/mediaEpisodeInfo.type";
|
import {MediaEpisodeInfoResponse} from "../../types/mediaEpisodeInfo.type";
|
||||||
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 {ErrorForwarder} from "../../../../helpers/error/instances/forwarder";
|
||||||
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";
|
import {findMediaWithMalIdRepository} from "../../repositories/findMediaWithMalId.repository";
|
||||||
|
|
||||||
export const bulkInsertEpisodeService = async (mal_id: number, page: number = 1) => {
|
export const bulkInsertEpisodeService = async (mal_id: number, page: number = 1) => {
|
||||||
try {
|
try {
|
||||||
const episodeAPI = getEpisodeReferenceAPI(mal_id);
|
const episodeAPI = getEpisodeReferenceAPI(mal_id);
|
||||||
const episodeData: MediaEpisodeInfoResponse = await fetch(
|
const episodeData: MediaEpisodeInfoResponse = await fetch(
|
||||||
`${episodeAPI.baseURL}${episodeAPI.getEpisodeList}?page=${page}`,
|
`${episodeAPI.baseURL}${episodeAPI.getEpisodeList}?page=${page}`,
|
||||||
).then((res) => res.json());
|
).then((res) => res.json()) as MediaEpisodeInfoResponse;
|
||||||
|
|
||||||
const mediaData = await selectMediaByMalIdRepository(mal_id);
|
const mediaData = await findMediaWithMalIdRepository(mal_id)
|
||||||
if (!mediaData) throw new AppError(404, `Media with Mal ID ${mal_id} not found in database`);
|
if (!mediaData) throw new AppError(404, "Media not found");
|
||||||
|
|
||||||
const insertedEpisodeData = [];
|
const constructedInput = episodeData.data.map(c => ({
|
||||||
episodeData.data.forEach(async (episode) => {
|
media_id: mediaData.id,
|
||||||
insertedEpisodeData.push(
|
episode_number: c.mal_id,
|
||||||
await bulkInsertEpisodesRepository({
|
title: c.title,
|
||||||
mediaId: mediaData.id!,
|
title_romanji: c.title_romanji,
|
||||||
episode: episode.mal_id,
|
title_origin: c.title_japanese,
|
||||||
name: episode.title,
|
aired_at: c.aired,
|
||||||
score: episode.score,
|
score: c.score,
|
||||||
uploadedBy: SystemAccountId,
|
filler: c.filler,
|
||||||
}),
|
recap: c.recap,
|
||||||
);
|
forum_url: c.forum_url,
|
||||||
});
|
created_by_id: SystemAccountId
|
||||||
|
}))
|
||||||
|
const insertedEpisodes = await bulkInsertEpisodesRepository(constructedInput)
|
||||||
return episodeData;
|
return episodeData;
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
ErrorForwarder(err);
|
ErrorForwarder(err);
|
||||||
|
|||||||
@ -0,0 +1,28 @@
|
|||||||
|
import { Prisma } from "@prisma/client";
|
||||||
|
import { MediaFullInfoResponse } from "../../types/mediaFullInfo.type";
|
||||||
|
import { prisma } from "../../../../utils/databases/prisma/connection";
|
||||||
|
|
||||||
|
interface InsertedProducer {
|
||||||
|
producer: string[];
|
||||||
|
licensor: string[];
|
||||||
|
studio: string[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export const bulkInsertProducerService = async (payload: MediaFullInfoResponse, systemAccountId: string) => {
|
||||||
|
const insertedPayload: InsertedProducer = {
|
||||||
|
producer: [],
|
||||||
|
licensor: [],
|
||||||
|
studio: [],
|
||||||
|
};
|
||||||
|
|
||||||
|
const insertingMainProducer = await prisma.producer.createMany({
|
||||||
|
data: payload.data.producers.map((producer) => ({
|
||||||
|
mal_id: producer.mal_id,
|
||||||
|
type: producer.type,
|
||||||
|
name: producer.name,
|
||||||
|
url: producer.url,
|
||||||
|
created_by_id: systemAccountId,
|
||||||
|
})),
|
||||||
|
skipDuplicates: true,
|
||||||
|
});
|
||||||
|
};
|
||||||
@ -1,34 +1,27 @@
|
|||||||
import {SystemAccountId} from "../../../../config/account/system";
|
import {SystemAccountId} from "../../../../config/account/system";
|
||||||
import {ErrorForwarder} from "../../../../helpers/error/instances/forwarder";
|
import {ErrorForwarder} from "../../../../helpers/error/instances/forwarder";
|
||||||
import { findEpisodeWithMediaIdRepository } from "../../repositories/findEpisodeWithMediaId.repository";
|
|
||||||
import {bulkInsertVideoRepository} from "../../repositories/bulkInsertVideo.repository";
|
import {bulkInsertVideoRepository} from "../../repositories/bulkInsertVideo.repository";
|
||||||
import {Static} from "elysia";
|
import {Static} from "elysia";
|
||||||
import {bulkInsertVideoSchema} from "../../schemas/bulkInsertVideo.schema";
|
import {bulkInsertVideoSchema} from "../../schemas/bulkInsertVideo.schema";
|
||||||
|
import {Prisma} from "@prisma/client";
|
||||||
|
|
||||||
export const bulkInsertVideoService = async (body: Static<typeof bulkInsertVideoSchema.body>) => {
|
export const bulkInsertVideoService = async (body: Static<typeof bulkInsertVideoSchema.body>) => {
|
||||||
try {
|
try {
|
||||||
const insertedVideos: string[] = [];
|
const constructedInput: Prisma.VideoCreateManyInput[] = body.data.flatMap((d) => (
|
||||||
for (const episodeData of body.data) {
|
d.videos.flatMap((v) => (
|
||||||
const episodeId = await findEpisodeWithMediaIdRepository({
|
{
|
||||||
media: body.media_id,
|
created_by_id: SystemAccountId,
|
||||||
episode: episodeData.episode,
|
media_id: body.media_id,
|
||||||
});
|
episode_number: d.episode,
|
||||||
|
video_service_id: v.service_id,
|
||||||
for (const videoData of episodeData.videos) {
|
video_code: v.video_code,
|
||||||
const insertedVideo = await bulkInsertVideoRepository({
|
short_code: v.short_code,
|
||||||
pendingUpload: false,
|
thumbnail_code: v.thumbnail_code,
|
||||||
episodeId: episodeId.id,
|
download_code: v.download_code
|
||||||
serviceId: videoData.service_id,
|
|
||||||
videoCode: videoData.video_code,
|
|
||||||
thumbnailCode: videoData.thumbnail_code,
|
|
||||||
uploadedBy: SystemAccountId,
|
|
||||||
});
|
|
||||||
|
|
||||||
insertedVideos.push(insertedVideo.id);
|
|
||||||
}
|
}
|
||||||
}
|
))
|
||||||
|
));
|
||||||
return insertedVideos;
|
return constructedInput
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
ErrorForwarder(error);
|
ErrorForwarder(error);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,40 +0,0 @@
|
|||||||
import { AppError } from "../../../../helpers/error/instances/app";
|
|
||||||
import { ErrorForwarder } from "../../../../helpers/error/instances/forwarder";
|
|
||||||
import { bulkUpdateThumbnailRepository } from "../../../episode/repositories/PUT/bulkUpdateThumbnail.repository";
|
|
||||||
import { getAllVideoServiceWithEpisodeRepository } from "../../../videoService/repositories/GET/getAllVideoServiceWithEpisode.repository";
|
|
||||||
|
|
||||||
export const updateAllEpisodeThumbnailService = async (
|
|
||||||
serviceReferenceId?: string,
|
|
||||||
) => {
|
|
||||||
try {
|
|
||||||
if (!serviceReferenceId)
|
|
||||||
throw new AppError(400, "Service Reference ID is required.");
|
|
||||||
|
|
||||||
const videosData = await getAllVideoServiceWithEpisodeRepository(
|
|
||||||
serviceReferenceId,
|
|
||||||
);
|
|
||||||
|
|
||||||
if (!videosData || videosData.length === 0)
|
|
||||||
throw new AppError(
|
|
||||||
404,
|
|
||||||
"No episode with no thumbnail found in the specified video service.",
|
|
||||||
);
|
|
||||||
|
|
||||||
const updatePayload = videosData.flatMap((videoService) => {
|
|
||||||
const { endpointThumbnail, videos } = videoService;
|
|
||||||
return videos.map((video) => ({
|
|
||||||
episodeId: video.episode.id,
|
|
||||||
thumbnailCode: endpointThumbnail!.replace(
|
|
||||||
":code:",
|
|
||||||
video.thumbnailCode || video.videoCode,
|
|
||||||
),
|
|
||||||
}));
|
|
||||||
});
|
|
||||||
|
|
||||||
await bulkUpdateThumbnailRepository(updatePayload);
|
|
||||||
|
|
||||||
return updatePayload.length;
|
|
||||||
} catch (error) {
|
|
||||||
ErrorForwarder(error);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
@ -3,7 +3,7 @@ import { getContentReferenceAPI } from "../../../../config/apis/jikan/media.refe
|
|||||||
import {ErrorForwarder} from "../../../../helpers/error/instances/forwarder";
|
import {ErrorForwarder} from "../../../../helpers/error/instances/forwarder";
|
||||||
import {bulkInsertCharactersRepository} from "../../repositories/bulkInsertCharacters.repository";
|
import {bulkInsertCharactersRepository} from "../../repositories/bulkInsertCharacters.repository";
|
||||||
import {bulkInsertLangVARepository} from "../../repositories/bulkInsertLangVA.repository";
|
import {bulkInsertLangVARepository} from "../../repositories/bulkInsertLangVA.repository";
|
||||||
import { MediaCharWithVAInfo } from "../../types/mediaCharWithVAInfo";
|
import {MediaCharWithVAInfo} from "../../types/mediaCharacters";
|
||||||
import {bulkInsertStaffOrPeopleService} from "./bulkInsertStaffOrPeople.service";
|
import {bulkInsertStaffOrPeopleService} from "./bulkInsertStaffOrPeople.service";
|
||||||
|
|
||||||
export const bulkInsertCharWithVAService = async (malId: number) => {
|
export const bulkInsertCharWithVAService = async (malId: number) => {
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
import {SystemAccountId} from "../../../../config/account/system";
|
import {SystemAccountId} from "../../../../config/account/system";
|
||||||
import {ErrorForwarder} from "../../../../helpers/error/instances/forwarder";
|
import {ErrorForwarder} from "../../../../helpers/error/instances/forwarder";
|
||||||
import {bulkInsertVoiceActorRepository} from "../../repositories/bulkInsertVoiceActor.repository";
|
import {bulkInsertVoiceActorRepository} from "../../repositories/bulkInsertVoiceActor.repository";
|
||||||
import { Person } from "../../types/mediaCharWithVAInfo";
|
import {Person} from "../../types/mediaCharacters";
|
||||||
|
|
||||||
export const bulkInsertStaffOrPeopleService = async (peopleData: Person) => {
|
export const bulkInsertStaffOrPeopleService = async (peopleData: Person) => {
|
||||||
try {
|
try {
|
||||||
|
|||||||
@ -1,59 +0,0 @@
|
|||||||
export interface MediaCharWithVAInfo {
|
|
||||||
data: Datum[];
|
|
||||||
}
|
|
||||||
|
|
||||||
interface Datum {
|
|
||||||
character: Character;
|
|
||||||
role: Role;
|
|
||||||
favorites: number;
|
|
||||||
voice_actors: VoiceActor[];
|
|
||||||
}
|
|
||||||
|
|
||||||
interface Character {
|
|
||||||
mal_id: number;
|
|
||||||
url: string;
|
|
||||||
images: CharacterImages;
|
|
||||||
name: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface CharacterImages {
|
|
||||||
jpg: Jpg;
|
|
||||||
webp: Webp;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface Jpg {
|
|
||||||
image_url: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface Webp {
|
|
||||||
image_url: string;
|
|
||||||
small_image_url: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
enum Role {
|
|
||||||
Main = "Main",
|
|
||||||
Supporting = "Supporting",
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface VoiceActor {
|
|
||||||
person: Person;
|
|
||||||
language: Language;
|
|
||||||
}
|
|
||||||
|
|
||||||
enum Language {
|
|
||||||
English = "English",
|
|
||||||
Japanese = "Japanese",
|
|
||||||
PortugueseBR = "Portuguese (BR)",
|
|
||||||
Spanish = "Spanish",
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface Person {
|
|
||||||
mal_id: number;
|
|
||||||
url: string;
|
|
||||||
images: PersonImages;
|
|
||||||
name: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface PersonImages {
|
|
||||||
jpg: Jpg;
|
|
||||||
}
|
|
||||||
43
src/modules/internal/types/mediaCharacters.ts
Normal file
43
src/modules/internal/types/mediaCharacters.ts
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
import {character_role} from "@prisma/client";
|
||||||
|
|
||||||
|
interface StaffVA {
|
||||||
|
mal_id: number;
|
||||||
|
url: string;
|
||||||
|
name: string;
|
||||||
|
images: {
|
||||||
|
jpg: {
|
||||||
|
image_url: string;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
interface voiceActor {
|
||||||
|
person: StaffVA;
|
||||||
|
language: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface Character {
|
||||||
|
mal_id: number;
|
||||||
|
name: string;
|
||||||
|
url: string;
|
||||||
|
images: {
|
||||||
|
jpg: {
|
||||||
|
image_url: string;
|
||||||
|
},
|
||||||
|
webp: {
|
||||||
|
image_url: string;
|
||||||
|
small_image_url: string;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface MediaChar {
|
||||||
|
character: Character;
|
||||||
|
role: character_role;
|
||||||
|
favorites: number;
|
||||||
|
voice_actors: voiceActor[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export type MediaCharacters = {
|
||||||
|
data: MediaChar[];
|
||||||
|
};
|
||||||
@ -1,4 +1,4 @@
|
|||||||
import { MediaType } from "@prisma/client";
|
import { media_season } from "@prisma/client";
|
||||||
export interface MediaFullInfoResponse {
|
export interface MediaFullInfoResponse {
|
||||||
data: Data;
|
data: Data;
|
||||||
}
|
}
|
||||||
@ -14,7 +14,7 @@ interface Data {
|
|||||||
title_english: string;
|
title_english: string;
|
||||||
title_japanese: string;
|
title_japanese: string;
|
||||||
title_synonyms: string[];
|
title_synonyms: string[];
|
||||||
type: MediaType;
|
type: string;
|
||||||
source: string;
|
source: string;
|
||||||
episodes: number;
|
episodes: number;
|
||||||
status: string;
|
status: string;
|
||||||
@ -30,16 +30,16 @@ interface Data {
|
|||||||
favorites: number;
|
favorites: number;
|
||||||
synopsis: string;
|
synopsis: string;
|
||||||
background: string;
|
background: string;
|
||||||
season: string;
|
season: media_season;
|
||||||
year: number;
|
year: number;
|
||||||
broadcast: Broadcast;
|
broadcast: Broadcast;
|
||||||
producers: Genre[];
|
producers: GenreOrProducer[];
|
||||||
licensors: unknown[];
|
licensors: GenreOrProducer[];
|
||||||
studios: Genre[];
|
studios: GenreOrProducer[];
|
||||||
genres: Genre[];
|
genres: GenreOrProducer[];
|
||||||
explicit_genres: unknown[];
|
explicit_genres: GenreOrProducer[];
|
||||||
themes: Genre[];
|
themes: GenreOrProducer[];
|
||||||
demographics: unknown[];
|
demographics: GenreOrProducer[];
|
||||||
relations: Relation[];
|
relations: Relation[];
|
||||||
theme: Theme;
|
theme: Theme;
|
||||||
external: External[];
|
external: External[];
|
||||||
@ -76,18 +76,13 @@ interface External {
|
|||||||
url: string;
|
url: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface Genre {
|
export interface GenreOrProducer {
|
||||||
mal_id: number;
|
mal_id: number;
|
||||||
type: Type;
|
type: string;
|
||||||
name: string;
|
name: string;
|
||||||
url: string;
|
url: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
enum Type {
|
|
||||||
Anime = "anime",
|
|
||||||
Manga = "manga",
|
|
||||||
}
|
|
||||||
|
|
||||||
interface Image {
|
interface Image {
|
||||||
image_url: string;
|
image_url: string;
|
||||||
small_image_url: string;
|
small_image_url: string;
|
||||||
@ -96,7 +91,7 @@ interface Image {
|
|||||||
|
|
||||||
interface Relation {
|
interface Relation {
|
||||||
relation: string;
|
relation: string;
|
||||||
entry: Genre[];
|
entry: GenreOrProducer[];
|
||||||
}
|
}
|
||||||
|
|
||||||
interface Theme {
|
interface Theme {
|
||||||
|
|||||||
@ -1,44 +0,0 @@
|
|||||||
import { AppError } from "../../../../helpers/error/instances/app";
|
|
||||||
import { videoServiceModel } from "../../model";
|
|
||||||
|
|
||||||
export const getAllVideoServiceWithEpisodeRepository = async (
|
|
||||||
videoServiceId: string,
|
|
||||||
) => {
|
|
||||||
try {
|
|
||||||
return await videoServiceModel.findMany({
|
|
||||||
where: {
|
|
||||||
id: videoServiceId,
|
|
||||||
endpointThumbnail: {
|
|
||||||
not: null,
|
|
||||||
},
|
|
||||||
videos: {
|
|
||||||
some: {
|
|
||||||
episode: {
|
|
||||||
pictureThumbnail: null,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
select: {
|
|
||||||
endpointThumbnail: true,
|
|
||||||
videos: {
|
|
||||||
select: {
|
|
||||||
thumbnailCode: true,
|
|
||||||
videoCode: true,
|
|
||||||
episode: {
|
|
||||||
select: {
|
|
||||||
id: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
} catch (error) {
|
|
||||||
throw new AppError(
|
|
||||||
500,
|
|
||||||
"An error occurred while fetching video services with episodes.",
|
|
||||||
error,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
Reference in New Issue
Block a user