- Deleted `CharacterComponent` and `CharacterDetail` files from the project. - Refactored related logic to improve code maintainability and reduce redundancy.
288 lines
17 KiB
TypeScript
288 lines
17 KiB
TypeScript
import { getUserEncryptionKey } from "../keyManager.js";
|
|
import System from "../System.js";
|
|
import SeriesCharacterRepo, { SeriesCharacterAttributeResult, SeriesCharacterResult } from "../repositories/series-character.repo.js";
|
|
import RemovedItem from "./RemovedItem.js";
|
|
|
|
export type CharacterCategory = 'Main' | 'Secondary' | 'Recurring';
|
|
|
|
export interface SeriesCharacterPropsPost {
|
|
id: string | null;
|
|
name: string;
|
|
lastName: string;
|
|
nickname: string;
|
|
age: number | null;
|
|
gender: string;
|
|
species: string;
|
|
nationality: string;
|
|
status: string;
|
|
category: CharacterCategory;
|
|
title: string;
|
|
image: string;
|
|
physical: { name: string }[];
|
|
psychological: { name: string }[];
|
|
relations: { name: string }[];
|
|
skills: { name: string }[];
|
|
weaknesses: { name: string }[];
|
|
strengths: { name: string }[];
|
|
goals: { name: string }[];
|
|
motivations: { name: string }[];
|
|
arc: { name: string }[];
|
|
secrets: { name: string }[];
|
|
fears: { name: string }[];
|
|
flaws: { name: string }[];
|
|
beliefs: { name: string }[];
|
|
conflicts: { name: string }[];
|
|
quotes: { name: string }[];
|
|
distinguishingMarks: { name: string }[];
|
|
items: { name: string }[];
|
|
affiliations: { name: string }[];
|
|
role: string;
|
|
biography?: string;
|
|
history?: string;
|
|
speechPattern?: string;
|
|
catchphrase?: string;
|
|
residence?: string;
|
|
notes?: string;
|
|
color?: string;
|
|
}
|
|
|
|
export interface SeriesCharacterListProps {
|
|
id: string;
|
|
name: string;
|
|
lastName: string;
|
|
nickname: string;
|
|
age: number | null;
|
|
gender: string;
|
|
species: string;
|
|
nationality: string;
|
|
status: string;
|
|
title: string;
|
|
category: string;
|
|
image: string;
|
|
role: string;
|
|
biography: string;
|
|
history: string;
|
|
speechPattern: string;
|
|
catchphrase: string;
|
|
residence: string;
|
|
notes: string;
|
|
color: string;
|
|
}
|
|
|
|
export interface SeriesAttribute {
|
|
id: string;
|
|
name: string;
|
|
}
|
|
|
|
export interface CharacterAttributesResponse {
|
|
attributes: SeriesAttribute[];
|
|
}
|
|
|
|
export default class SeriesCharacter {
|
|
/**
|
|
* Retrieves a list of characters for a specific series owned by a user.
|
|
* @param userId - The unique identifier of the user
|
|
* @param seriesId - The unique identifier of the series
|
|
* @param lang - The language for error messages ('fr' or 'en')
|
|
* @returns Characters list
|
|
*/
|
|
public static getCharacterList(userId: string, seriesId: string, lang: 'fr' | 'en' = 'fr'): SeriesCharacterListProps[] {
|
|
const characters: SeriesCharacterResult[] = SeriesCharacterRepo.fetchCharacters(userId, seriesId, lang);
|
|
if (!characters || characters.length === 0) {
|
|
return [];
|
|
}
|
|
|
|
const userKey: string = getUserEncryptionKey(userId);
|
|
|
|
return characters.map((character: SeriesCharacterResult): SeriesCharacterListProps => ({
|
|
id: character.character_id,
|
|
name: character.first_name ? System.decryptDataWithUserKey(character.first_name, userKey) : '',
|
|
lastName: character.last_name ? System.decryptDataWithUserKey(character.last_name, userKey) : '',
|
|
nickname: character.nickname ? System.decryptDataWithUserKey(character.nickname, userKey) : '',
|
|
age: character.age ? parseInt(System.decryptDataWithUserKey(character.age, userKey), 10) : null,
|
|
gender: character.gender ? System.decryptDataWithUserKey(character.gender, userKey) : '',
|
|
species: character.species ? System.decryptDataWithUserKey(character.species, userKey) : '',
|
|
nationality: character.nationality ? System.decryptDataWithUserKey(character.nationality, userKey) : '',
|
|
status: character.status ? System.decryptDataWithUserKey(character.status, userKey) : 'alive',
|
|
title: character.title ? System.decryptDataWithUserKey(character.title, userKey) : '',
|
|
category: character.category ? System.decryptDataWithUserKey(character.category, userKey) : '',
|
|
image: character.image ? System.decryptDataWithUserKey(character.image, userKey) : '',
|
|
role: character.role ? System.decryptDataWithUserKey(character.role, userKey) : '',
|
|
biography: character.biography ? System.decryptDataWithUserKey(character.biography, userKey) : '',
|
|
history: character.history ? System.decryptDataWithUserKey(character.history, userKey) : '',
|
|
speechPattern: character.speech_pattern ? System.decryptDataWithUserKey(character.speech_pattern, userKey) : '',
|
|
catchphrase: character.catchphrase ? System.decryptDataWithUserKey(character.catchphrase, userKey) : '',
|
|
residence: character.residence ? System.decryptDataWithUserKey(character.residence, userKey) : '',
|
|
notes: character.notes ? System.decryptDataWithUserKey(character.notes, userKey) : '',
|
|
color: character.color ? System.decryptDataWithUserKey(character.color, userKey) : '',
|
|
}));
|
|
}
|
|
|
|
/**
|
|
* Adds a new character to a series with all its attributes.
|
|
* @param userId - The unique identifier of the user
|
|
* @param character - The character data to create
|
|
* @param seriesId - The unique identifier of the series
|
|
* @param lang - The language for error messages ('fr' or 'en')
|
|
* @returns The newly created character's ID
|
|
*/
|
|
public static addNewCharacter(userId: string, character: SeriesCharacterPropsPost, seriesId: string, lang: 'fr' | 'en' = 'fr'): string {
|
|
const userKey: string = getUserEncryptionKey(userId);
|
|
const characterId: string = System.createUniqueId();
|
|
const encryptedName: string = System.encryptDataWithUserKey(character.name, userKey);
|
|
const encryptedLastName: string | null = character.lastName ? System.encryptDataWithUserKey(character.lastName, userKey) : null;
|
|
const encryptedNickname: string | null = character.nickname ? System.encryptDataWithUserKey(character.nickname, userKey) : null;
|
|
const encryptedAge: string | null = character.age !== null ? System.encryptDataWithUserKey(String(character.age), userKey) : null;
|
|
const encryptedGender: string | null = character.gender ? System.encryptDataWithUserKey(character.gender, userKey) : null;
|
|
const encryptedSpecies: string | null = character.species ? System.encryptDataWithUserKey(character.species, userKey) : null;
|
|
const encryptedNationality: string | null = character.nationality ? System.encryptDataWithUserKey(character.nationality, userKey) : null;
|
|
const encryptedStatus: string | null = character.status ? System.encryptDataWithUserKey(character.status, userKey) : null;
|
|
const encryptedTitle: string | null = character.title ? System.encryptDataWithUserKey(character.title, userKey) : null;
|
|
const encryptedCategory: string | null = character.category ? System.encryptDataWithUserKey(character.category, userKey) : null;
|
|
const encryptedImage: string | null = character.image ? System.encryptDataWithUserKey(character.image, userKey) : null;
|
|
const encryptedRole: string | null = character.role ? System.encryptDataWithUserKey(character.role, userKey) : null;
|
|
const encryptedBiography: string | null = character.biography ? System.encryptDataWithUserKey(character.biography, userKey) : null;
|
|
const encryptedHistory: string | null = character.history ? System.encryptDataWithUserKey(character.history, userKey) : null;
|
|
const encryptedSpeechPattern: string | null = character.speechPattern ? System.encryptDataWithUserKey(character.speechPattern, userKey) : null;
|
|
const encryptedCatchphrase: string | null = character.catchphrase ? System.encryptDataWithUserKey(character.catchphrase, userKey) : null;
|
|
const encryptedResidence: string | null = character.residence ? System.encryptDataWithUserKey(character.residence, userKey) : null;
|
|
const encryptedNotes: string | null = character.notes ? System.encryptDataWithUserKey(character.notes, userKey) : null;
|
|
const encryptedColor: string | null = character.color ? System.encryptDataWithUserKey(character.color, userKey) : null;
|
|
|
|
SeriesCharacterRepo.addNewCharacter(userId, characterId, encryptedName, encryptedLastName, encryptedNickname, encryptedAge, encryptedGender, encryptedSpecies, encryptedNationality, encryptedStatus, encryptedTitle, encryptedCategory, encryptedImage, encryptedRole, encryptedBiography, encryptedHistory, encryptedSpeechPattern, encryptedCatchphrase, encryptedResidence, encryptedNotes, encryptedColor, seriesId, lang);
|
|
|
|
const attributeKeys: string[] = Object.keys(character);
|
|
for (const attributeKey of attributeKeys) {
|
|
const attributeValue = character[attributeKey as keyof SeriesCharacterPropsPost];
|
|
if (Array.isArray(attributeValue)) {
|
|
const attributeArray: { name: string }[] = attributeValue;
|
|
if (attributeArray.length > 0) {
|
|
for (const attributeItem of attributeArray) {
|
|
const attributeType: string = attributeKey;
|
|
const attributeName: string = attributeItem.name;
|
|
this.addNewAttribute(characterId, userId, attributeType, attributeName, lang);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return characterId;
|
|
}
|
|
|
|
/**
|
|
* Updates an existing character's information and attributes.
|
|
* @param userId - The unique identifier of the user
|
|
* @param character - The updated character data
|
|
* @param lang - The language for error messages ('fr' or 'en')
|
|
* @returns True if the update was successful
|
|
*/
|
|
public static updateCharacter(userId: string, character: SeriesCharacterPropsPost, lang: 'fr' | 'en' = 'fr'): boolean {
|
|
if (!character.id) {
|
|
throw new Error(lang === 'fr' ? 'ID du personnage requis.' : 'Character ID required.');
|
|
}
|
|
|
|
const exists: boolean = SeriesCharacterRepo.isCharacterExist(userId, character.id, lang);
|
|
if (!exists) {
|
|
throw new Error(lang === 'fr' ? 'Personnage non trouvé.' : 'Character not found.');
|
|
}
|
|
|
|
const userKey: string = getUserEncryptionKey(userId);
|
|
const encryptedName: string = System.encryptDataWithUserKey(character.name, userKey);
|
|
const encryptedLastName: string | null = character.lastName ? System.encryptDataWithUserKey(character.lastName, userKey) : null;
|
|
const encryptedNickname: string | null = character.nickname ? System.encryptDataWithUserKey(character.nickname, userKey) : null;
|
|
const encryptedAge: string | null = character.age !== null ? System.encryptDataWithUserKey(String(character.age), userKey) : null;
|
|
const encryptedGender: string | null = character.gender ? System.encryptDataWithUserKey(character.gender, userKey) : null;
|
|
const encryptedSpecies: string | null = character.species ? System.encryptDataWithUserKey(character.species, userKey) : null;
|
|
const encryptedNationality: string | null = character.nationality ? System.encryptDataWithUserKey(character.nationality, userKey) : null;
|
|
const encryptedStatus: string | null = character.status ? System.encryptDataWithUserKey(character.status, userKey) : null;
|
|
const encryptedTitle: string | null = character.title ? System.encryptDataWithUserKey(character.title, userKey) : null;
|
|
const encryptedCategory: string | null = character.category ? System.encryptDataWithUserKey(character.category, userKey) : null;
|
|
const encryptedImage: string | null = character.image ? System.encryptDataWithUserKey(character.image, userKey) : null;
|
|
const encryptedRole: string | null = character.role ? System.encryptDataWithUserKey(character.role, userKey) : null;
|
|
const encryptedBiography: string | null = character.biography ? System.encryptDataWithUserKey(character.biography, userKey) : null;
|
|
const encryptedHistory: string | null = character.history ? System.encryptDataWithUserKey(character.history, userKey) : null;
|
|
const encryptedSpeechPattern: string | null = character.speechPattern ? System.encryptDataWithUserKey(character.speechPattern, userKey) : null;
|
|
const encryptedCatchphrase: string | null = character.catchphrase ? System.encryptDataWithUserKey(character.catchphrase, userKey) : null;
|
|
const encryptedResidence: string | null = character.residence ? System.encryptDataWithUserKey(character.residence, userKey) : null;
|
|
const encryptedNotes: string | null = character.notes ? System.encryptDataWithUserKey(character.notes, userKey) : null;
|
|
const encryptedColor: string | null = character.color ? System.encryptDataWithUserKey(character.color, userKey) : null;
|
|
|
|
return SeriesCharacterRepo.updateCharacter(userId, character.id, encryptedName, encryptedLastName, encryptedNickname, encryptedAge, encryptedGender, encryptedSpecies, encryptedNationality, encryptedStatus, encryptedTitle, encryptedCategory, encryptedImage, encryptedRole, encryptedBiography, encryptedHistory, encryptedSpeechPattern, encryptedCatchphrase, encryptedResidence, encryptedNotes, encryptedColor, lang);
|
|
}
|
|
|
|
/**
|
|
* Deletes a character from a series.
|
|
* @param userId - The unique identifier of the user
|
|
* @param characterId - The unique identifier of the character
|
|
* @param deletedAt - The timestamp of deletion
|
|
* @param lang - The language for error messages ('fr' or 'en')
|
|
* @returns True if the deletion was successful
|
|
*/
|
|
public static deleteCharacter(userId: string, characterId: string, deletedAt: number = System.timeStampInSeconds(), lang: 'fr' | 'en' = 'fr'): boolean {
|
|
const exists: boolean = SeriesCharacterRepo.isCharacterExist(userId, characterId, lang);
|
|
if (!exists) {
|
|
throw new Error(lang === 'fr' ? 'Personnage non trouvé.' : 'Character not found.');
|
|
}
|
|
const deleted: boolean = SeriesCharacterRepo.deleteCharacter(userId, characterId, lang);
|
|
if (deleted) {
|
|
RemovedItem.deleteTracker(userId, null, 'series_characters', characterId, deletedAt, lang);
|
|
}
|
|
return deleted;
|
|
}
|
|
|
|
/**
|
|
* Adds a new attribute to a character.
|
|
* @param characterId - The unique identifier of the character
|
|
* @param userId - The unique identifier of the user
|
|
* @param type - The attribute type
|
|
* @param name - The attribute value
|
|
* @param lang - The language for error messages ('fr' or 'en')
|
|
* @returns The attribute ID
|
|
*/
|
|
public static addNewAttribute(characterId: string, userId: string, type: string, name: string, lang: 'fr' | 'en' = 'fr'): string {
|
|
const userKey: string = getUserEncryptionKey(userId);
|
|
const attributeId: string = System.createUniqueId();
|
|
const encryptedType: string = System.encryptDataWithUserKey(type, userKey);
|
|
const encryptedName: string = System.encryptDataWithUserKey(name, userKey);
|
|
|
|
SeriesCharacterRepo.insertAttribute(attributeId, characterId, userId, encryptedType, encryptedName, lang);
|
|
|
|
return attributeId;
|
|
}
|
|
|
|
/**
|
|
* Deletes an attribute from a character.
|
|
* @param userId - The unique identifier of the user
|
|
* @param attributeId - The unique identifier of the attribute
|
|
* @param deletedAt - The timestamp of deletion
|
|
* @param lang - The language for error messages ('fr' or 'en')
|
|
* @returns True if the deletion was successful
|
|
*/
|
|
public static deleteAttribute(userId: string, attributeId: string, deletedAt: number = System.timeStampInSeconds(), lang: 'fr' | 'en' = 'fr'): boolean {
|
|
const deleted: boolean = SeriesCharacterRepo.deleteAttribute(userId, attributeId, lang);
|
|
if (deleted) {
|
|
RemovedItem.deleteTracker(userId, null, 'series_characters_attributes', attributeId, deletedAt, lang);
|
|
}
|
|
return deleted;
|
|
}
|
|
|
|
/**
|
|
* Gets all attributes for a character.
|
|
* @param userId - The unique identifier of the user
|
|
* @param characterId - The unique identifier of the character
|
|
* @param lang - The language for error messages ('fr' or 'en')
|
|
* @returns The character's attributes
|
|
*/
|
|
public static getCharacterAttributes(userId: string, characterId: string, lang: 'fr' | 'en' = 'fr'): CharacterAttributesResponse {
|
|
const userKey: string = getUserEncryptionKey(userId);
|
|
const attributesResult: SeriesCharacterAttributeResult[] = SeriesCharacterRepo.fetchAttributes(characterId, userId, lang);
|
|
|
|
const attributes: SeriesAttribute[] = attributesResult.map((attr) => ({
|
|
id: attr.attr_id,
|
|
name: System.decryptDataWithUserKey(attr.attribute_value, userKey)
|
|
}));
|
|
|
|
return { attributes };
|
|
}
|
|
}
|