wip: create new req endpoint to get characters data

This commit is contained in:
2026-06-29 12:52:52 +07:00
parent a04d1ffdf1
commit 28b3de29d8
8 changed files with 148 additions and 139 deletions

View File

@ -1,9 +1,9 @@
import { baseURL } from "./baseUrl"; import {baseURL} from "./baseUrl";
export const getContentReferenceAPI = (malId: number) => { 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`,
}; };
}; };

View File

@ -0,0 +1,9 @@
import {AppError} from "../../../helpers/error/instances/app";
export const bulkInsertMediaCharacterRepository = async (animeMalId: number) => {
try {
return animeMalId
} catch (error) {
throw new AppError(500, "Failed to bulk insert media characters", error);
}
}

View File

@ -143,7 +143,11 @@ export const InsertMediaRepository = async ({ payload }: { payload: MediaFullInf
}); });
await bulkInsertMediaProducerStudioLicensorRepository(tx, media.id, producerPayload); await bulkInsertMediaProducerStudioLicensorRepository(tx, media.id, producerPayload);
return media.id; return {
id: media.id,
mal_id: payload.mal_id,
name: payload.title,
};
}); });
} catch (error) { } catch (error) {

View File

@ -1,17 +1,24 @@
import {ErrorForwarder} from "../../../../helpers/error/instances/forwarder"; import {ErrorForwarder} from "../../../../helpers/error/instances/forwarder";
import {InsertMediaRepository} from "../../repositories/bulkinsertMedia.repository"; import {InsertMediaRepository} from "../../repositories/bulkinsertMedia.repository";
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 {MediaFullInfoResponse} from "../../types/mediaFullInfo.type";
import {MediaCharacters} from "../../types/mediaCharacters";
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) => res.json())) as MediaFullInfoResponse; const mediaFullInfo = (await fetch(baseURL + getMediaFullInfo).then((res) => res.json())) as MediaFullInfoResponse;
return await InsertMediaRepository({ const insertedMedia = await InsertMediaRepository({
payload: mediaFullInfo.data, payload: mediaFullInfo.data,
}); });
} catch (error) {
ErrorForwarder(error);
} // await bulkInsertMediaCharacterRepository(insertedMedia.mal_id)
const mediaChar = await fetch(baseURL + getMediaCharacters).then((res) => res.json()) as MediaCharacters;
return mediaChar;
} catch (error) {
ErrorForwarder(error);
}
}; };

View File

@ -1,58 +1,58 @@
import { SystemAccountId } from "../../../../config/account/system"; import {SystemAccountId} from "../../../../config/account/system";
import { getContentReferenceAPI } from "../../../../config/apis/jikan/media.reference"; import {getContentReferenceAPI} from "../../../../config/apis/jikan/media.reference";
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) => {
try { try {
const { baseURL, getMediaCharactersWithVA } = getContentReferenceAPI(malId); const {baseURL, getMediaCharactersWithVA} = getContentReferenceAPI(malId);
const charactersWithVAData = (await fetch( const charactersWithVAData = (await fetch(
`${baseURL}${getMediaCharactersWithVA}`, `${baseURL}${getMediaCharactersWithVA}`,
).then((res) => res.json())) as MediaCharWithVAInfo; ).then((res) => res.json())) as MediaCharWithVAInfo;
const insertedCharacters = []; const insertedCharacters = [];
for (const charEntry of charactersWithVAData.data) { for (const charEntry of charactersWithVAData.data) {
// Insert character if not exists // Insert character if not exists
const characterInsertedId = await bulkInsertCharactersRepository({ const characterInsertedId = await bulkInsertCharactersRepository({
malId: charEntry.character.mal_id, malId: charEntry.character.mal_id,
name: charEntry.character.name, name: charEntry.character.name,
role: charEntry.role, role: charEntry.role,
favorites: charEntry.favorites, favorites: charEntry.favorites,
imageUrl: charEntry.character.images.webp.image_url, imageUrl: charEntry.character.images.webp.image_url,
smallImageUrl: charEntry.character.images.webp.small_image_url, smallImageUrl: charEntry.character.images.webp.small_image_url,
creatorId: SystemAccountId, creatorId: SystemAccountId,
}); });
// Insert character voice actors if not exists // Insert character voice actors if not exists
const insertedVAs: { staffId: string; lang: string }[] = []; const insertedVAs: { staffId: string; lang: string }[] = [];
for (const VAEntries of charEntry.voice_actors) { for (const VAEntries of charEntry.voice_actors) {
const insertedVAId = await bulkInsertStaffOrPeopleService( const insertedVAId = await bulkInsertStaffOrPeopleService(
VAEntries.person, VAEntries.person,
); );
insertedVAs.push({ insertedVAs.push({
staffId: insertedVAId.id, staffId: insertedVAId.id,
lang: VAEntries.language, lang: VAEntries.language,
}); });
} }
// Link character with inserted VAs // Link character with inserted VAs
for (const langVA of insertedVAs) { for (const langVA of insertedVAs) {
await bulkInsertLangVARepository({ await bulkInsertLangVARepository({
language: langVA.lang, language: langVA.lang,
vaId: langVA.staffId, vaId: langVA.staffId,
charId: characterInsertedId.id, charId: characterInsertedId.id,
creatorId: SystemAccountId, creatorId: SystemAccountId,
}); });
} }
insertedCharacters.push(characterInsertedId); insertedCharacters.push(characterInsertedId);
}
return insertedCharacters;
} catch (error) {
ErrorForwarder(error);
} }
return insertedCharacters;
} catch (error) {
ErrorForwarder(error);
}
}; };

View File

@ -1,17 +1,17 @@
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 {
return await bulkInsertVoiceActorRepository({ return await bulkInsertVoiceActorRepository({
malId: peopleData.mal_id, malId: peopleData.mal_id,
name: peopleData.name, name: peopleData.name,
imageUrl: peopleData.images.jpg.image_url, imageUrl: peopleData.images.jpg.image_url,
creatorId: SystemAccountId, creatorId: SystemAccountId,
}); });
} catch (error) { } catch (error) {
ErrorForwarder(error); ErrorForwarder(error);
} }
}; };

View File

@ -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;
}

View File

@ -0,0 +1,48 @@
interface StaffVA {
mal_id: number;
url: string;
images: {
jpg: {
image_url: string;
},
webp: {
image_url: string;
small_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;
}
}
}
enum Role {
Main = "Main",
Supporting = "Supporting",
Background = "Background",
}
interface MediaChar {
character: Character;
role: Role;
favorites: number;
voice_actors: voiceActor[];
}
export type MediaCharacters = Array<MediaChar>;