✨ feat: create bulk insertion for characters
This commit is contained in:
1
src/config/account/system.ts
Normal file
1
src/config/account/system.ts
Normal file
@ -0,0 +1 @@
|
||||
export const SystemAccountId = "b734b9bc-b4ea-408f-a80e-0a837ce884da";
|
||||
1
src/config/apis/baseUrl.ts
Normal file
1
src/config/apis/baseUrl.ts
Normal file
@ -0,0 +1 @@
|
||||
export const baseURL = "https://api.jikan.moe/v4";
|
||||
@ -1,6 +1,8 @@
|
||||
import { baseURL } from "./baseUrl";
|
||||
|
||||
export const getContentReferenceAPI = (malId: number) => {
|
||||
return {
|
||||
baseURL: "https://api.jikan.moe/v4",
|
||||
baseURL,
|
||||
getMediaFullInfo: `/anime/${malId}/full`,
|
||||
getMediaCharactersWithVA: `/anime/${malId}/characters`,
|
||||
};
|
||||
|
||||
8
src/config/apis/people.reference.ts
Normal file
8
src/config/apis/people.reference.ts
Normal file
@ -0,0 +1,8 @@
|
||||
import { baseURL } from "./baseUrl";
|
||||
|
||||
export const getPeopleAPI = (malId: number) => {
|
||||
return {
|
||||
baseURL,
|
||||
getPeopleInfo: `/people/${malId}`,
|
||||
};
|
||||
};
|
||||
@ -0,0 +1,18 @@
|
||||
import { Prisma } from "@prisma/client";
|
||||
import { AppError } from "../../../helpers/error/instances/app";
|
||||
import { prisma } from "../../../utils/databases/prisma/connection";
|
||||
|
||||
export const bulkInsertCharactersRepository = async (
|
||||
payload: Prisma.CharacterUpsertArgs["create"],
|
||||
) => {
|
||||
try {
|
||||
return await prisma.character.upsert({
|
||||
where: { malId: payload.malId },
|
||||
create: payload,
|
||||
update: payload,
|
||||
select: { id: true },
|
||||
});
|
||||
} catch (error) {
|
||||
throw new AppError(500, "Failed to bulk insert characters", error);
|
||||
}
|
||||
};
|
||||
@ -0,0 +1,24 @@
|
||||
import { Prisma } from "@prisma/client";
|
||||
import { AppError } from "../../../helpers/error/instances/app";
|
||||
import { prisma } from "../../../utils/databases/prisma/connection";
|
||||
|
||||
export const bulkInsertLangVARepository = async (
|
||||
payload: Prisma.LangVACharUpsertArgs["create"],
|
||||
) => {
|
||||
try {
|
||||
const insertedVA = await prisma.langVAChar.upsert({
|
||||
where: {
|
||||
language_vaId_charId: {
|
||||
language: payload.language,
|
||||
vaId: payload.vaId!,
|
||||
charId: payload.charId!,
|
||||
},
|
||||
},
|
||||
create: payload,
|
||||
update: {},
|
||||
});
|
||||
return insertedVA.id;
|
||||
} catch (error) {
|
||||
throw new AppError(500, "Failed to bulk insert VAs", error);
|
||||
}
|
||||
};
|
||||
@ -2,18 +2,17 @@ import { Prisma } from "@prisma/client";
|
||||
import { AppError } from "../../../helpers/error/instances/app";
|
||||
import { prisma } from "../../../utils/databases/prisma/connection";
|
||||
|
||||
export const bulkInsertVARepository = async (
|
||||
export const bulkInsertVoiceActorRepository = async (
|
||||
payload: Prisma.VoiceActorUpsertArgs["create"],
|
||||
) => {
|
||||
try {
|
||||
const insertedVA = await prisma.voiceActor.upsert({
|
||||
return await prisma.voiceActor.upsert({
|
||||
where: { malId: payload.malId },
|
||||
create: payload,
|
||||
update: payload,
|
||||
select: { id: true },
|
||||
});
|
||||
return insertedVA.id;
|
||||
} catch (error) {
|
||||
throw new AppError(500, "Failed to bulk insert VAs", error);
|
||||
throw new AppError(500, "Failed to bulk insert voice actor", error);
|
||||
}
|
||||
};
|
||||
@ -1,6 +1,10 @@
|
||||
import { SystemAccountId } from "../../../../config/account/system";
|
||||
import { getContentReferenceAPI } from "../../../../config/apis/media.reference";
|
||||
import { ErrorForwarder } from "../../../../helpers/error/instances/forwarder";
|
||||
import { bulkInsertCharactersRepository } from "../../repositories/bulkInsertCharacters.repository";
|
||||
import { bulkInsertLangVARepository } from "../../repositories/bulkInsertLangVA.repository";
|
||||
import { MediaCharWithVAInfo } from "../../types/mediaCharWithVAInfo";
|
||||
import { bulkInsertStaffOrPeopleService } from "./bulkInsertStaffOrPeople.service";
|
||||
|
||||
export const bulkInsertCharWithVAService = async (malId: number) => {
|
||||
try {
|
||||
@ -9,7 +13,45 @@ export const bulkInsertCharWithVAService = async (malId: number) => {
|
||||
`${baseURL}${getMediaCharactersWithVA}`,
|
||||
).then((res) => res.json())) as MediaCharWithVAInfo;
|
||||
|
||||
return;
|
||||
const insertedCharacters = [];
|
||||
for (const charEntry of charactersWithVAData.data) {
|
||||
// Insert character if not exists
|
||||
const characterInsertedId = await bulkInsertCharactersRepository({
|
||||
malId: charEntry.character.mal_id,
|
||||
name: charEntry.character.name,
|
||||
role: charEntry.role,
|
||||
favorites: charEntry.favorites,
|
||||
imageUrl: charEntry.character.images.webp.image_url,
|
||||
smallImageUrl: charEntry.character.images.webp.small_image_url,
|
||||
creatorId: SystemAccountId,
|
||||
});
|
||||
|
||||
// Insert character voice actors if not exists
|
||||
const insertedVAs: { staffId: string; lang: string }[] = [];
|
||||
for (const VAEntries of charEntry.voice_actors) {
|
||||
const insertedVAId = await bulkInsertStaffOrPeopleService(
|
||||
VAEntries.person.mal_id,
|
||||
);
|
||||
insertedVAs.push({
|
||||
staffId: insertedVAId.id,
|
||||
lang: VAEntries.language,
|
||||
});
|
||||
}
|
||||
|
||||
// Link character with inserted VAs
|
||||
for (const langVA of insertedVAs) {
|
||||
await bulkInsertLangVARepository({
|
||||
language: langVA.lang,
|
||||
vaId: langVA.staffId,
|
||||
charId: characterInsertedId.id,
|
||||
creatorId: SystemAccountId,
|
||||
});
|
||||
}
|
||||
|
||||
insertedCharacters.push(characterInsertedId);
|
||||
}
|
||||
|
||||
return insertedCharacters;
|
||||
} catch (error) {
|
||||
ErrorForwarder(error);
|
||||
}
|
||||
|
||||
@ -0,0 +1,27 @@
|
||||
import { SystemAccountId } from "../../../../config/account/system";
|
||||
import { getPeopleAPI } from "../../../../config/apis/people.reference";
|
||||
import { ErrorForwarder } from "../../../../helpers/error/instances/forwarder";
|
||||
import { bulkInsertVoiceActorRepository } from "../../repositories/bulkInsertVoiceActor.repository";
|
||||
import { PeopleInfoResponse } from "../../types/peopleInfo";
|
||||
|
||||
export const bulkInsertStaffOrPeopleService = async (malId: number) => {
|
||||
try {
|
||||
const { baseURL, getPeopleInfo } = getPeopleAPI(malId);
|
||||
const peopleData = (await fetch(baseURL + getPeopleInfo).then((res) =>
|
||||
res.json(),
|
||||
)) as PeopleInfoResponse;
|
||||
|
||||
return await bulkInsertVoiceActorRepository({
|
||||
malId: peopleData.data.mal_id,
|
||||
name: peopleData.data.name,
|
||||
birthday: peopleData.data.birthday,
|
||||
description: peopleData.data.about,
|
||||
aboutUrl: peopleData.data.url,
|
||||
imageUrl: peopleData.data.images.jpg.image_url,
|
||||
websiteUrl: peopleData.data.website_url,
|
||||
creatorId: SystemAccountId,
|
||||
});
|
||||
} catch (error) {
|
||||
ErrorForwarder(error);
|
||||
}
|
||||
};
|
||||
25
src/modules/internal/types/peopleInfo.ts
Normal file
25
src/modules/internal/types/peopleInfo.ts
Normal file
@ -0,0 +1,25 @@
|
||||
export interface PeopleInfoResponse {
|
||||
data: Data;
|
||||
}
|
||||
|
||||
interface Data {
|
||||
mal_id: number;
|
||||
url: string;
|
||||
website_url: null;
|
||||
images: Images;
|
||||
name: string;
|
||||
given_name: null;
|
||||
family_name: null;
|
||||
alternate_names: any[];
|
||||
birthday: Date;
|
||||
favorites: number;
|
||||
about: string;
|
||||
}
|
||||
|
||||
interface Images {
|
||||
jpg: Jpg;
|
||||
}
|
||||
|
||||
interface Jpg {
|
||||
image_url: string;
|
||||
}
|
||||
Reference in New Issue
Block a user