Introduce series management functionality and repository updates
- Added `series-world.repo.ts` to handle database operations related to series worlds and their elements. - Implemented `series-sync.repo.ts` for managing synchronization between books and series. - Expanded `spell.ipc.ts` data models to include `seriesSpellId` for spell synchronization. - Refactored `insertSpellTag` method in `spelltag.repo.ts` for improved error handling and logic clarity.
This commit is contained in:
276
electron/database/models/SeriesCharacter.ts
Normal file
276
electron/database/models/SeriesCharacter.ts
Normal file
@@ -0,0 +1,276 @@
|
||||
import { getUserEncryptionKey } from "../keyManager.js";
|
||||
import System from "../System.js";
|
||||
import SeriesCharacterRepo, { SeriesCharacterAttributeResult, SeriesCharacterResult } from "../repositories/series-character.repo.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 lang - The language for error messages ('fr' or 'en')
|
||||
* @returns True if the deletion was successful
|
||||
*/
|
||||
public static deleteCharacter(userId: string, characterId: string, 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.');
|
||||
}
|
||||
return SeriesCharacterRepo.deleteCharacter(userId, characterId, lang);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 lang - The language for error messages ('fr' or 'en')
|
||||
* @returns True if the deletion was successful
|
||||
*/
|
||||
public static deleteAttribute(userId: string, attributeId: string, lang: 'fr' | 'en' = 'fr'): boolean {
|
||||
return SeriesCharacterRepo.deleteAttribute(userId, attributeId, lang);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 };
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user