157 lines
4.7 KiB
TypeScript
157 lines
4.7 KiB
TypeScript
import { Prisma } from "@prisma/client";
|
|
import { AppError } from "../../../helpers/error/instances/app";
|
|
import { MediaFullInfoResponse } from "../types/mediaFullInfo.type";
|
|
import { prisma } from "../../../utils/databases/prisma/connection";
|
|
import { bulkInsertMediaProducerStudioLicensorRepository } from "./bulkInsertMediaProducerStudioLicensor.repository";
|
|
|
|
/**
|
|
* Media Payload Construction and Upsert
|
|
*
|
|
* This section constructs the payload for the media insertion or update.
|
|
* It gathers all necessary information from the media data, including
|
|
* title, alternative titles, slug, associated genres and studios, score,
|
|
* images, status, airing dates, synopsis, age rating, media type, source,
|
|
* and other relevant details. This payload is then used in an upsert
|
|
* operation to ensure that the media record is either created or updated
|
|
* in the database.
|
|
*
|
|
* @param data - The full media data for constructing the media payload.
|
|
* @returns The inserted or updated media record.
|
|
*/
|
|
export const InsertMediaRepository = async ({ payload }: { payload: MediaFullInfoResponse["data"] }) => {
|
|
try {
|
|
const constructMediaPayload: Prisma.MediaUpsertArgs["create"] = {
|
|
mal_id: payload.mal_id,
|
|
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: {
|
|
embed_url: payload.trailer.embed_url,
|
|
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) {
|
|
throw new AppError(500, "Failed to insert media", error);
|
|
}
|
|
};
|