Files
ERitors-Scribe-Desktop/electron/database/models/SeriesWorld.ts
natreex 209dc6f85a Remove CharacterComponent and CharacterDetail components
- Deleted `CharacterComponent` and `CharacterDetail` files from the project.
- Refactored related logic to improve code maintainability and reduce redundancy.
2026-02-05 14:12:08 -05:00

197 lines
8.7 KiB
TypeScript

import { getUserEncryptionKey } from "../keyManager.js";
import System from "../System.js";
import SeriesWorldRepo, { SeriesWorldResult } from "../repositories/series-world.repo.js";
import RemovedItem from "./RemovedItem.js";
export interface SeriesWorldElementProps {
id: string;
name: string;
description: string;
}
export interface SeriesWorldListProps {
id: string;
name: string;
history: string;
politics: string;
economy: string;
religion: string;
languages: string;
laws: SeriesWorldElementProps[];
biomes: SeriesWorldElementProps[];
issues: SeriesWorldElementProps[];
customs: SeriesWorldElementProps[];
kingdoms: SeriesWorldElementProps[];
climate: SeriesWorldElementProps[];
resources: SeriesWorldElementProps[];
wildlife: SeriesWorldElementProps[];
arts: SeriesWorldElementProps[];
ethnicGroups: SeriesWorldElementProps[];
socialClasses: SeriesWorldElementProps[];
importantCharacters: SeriesWorldElementProps[];
}
export interface SeriesWorldUpdateProps {
name: string;
history?: string;
politics?: string;
economy?: string;
religion?: string;
languages?: string;
}
const ELEMENT_TYPE_MAP: Record<number, keyof SeriesWorldListProps> = {
0: 'laws',
1: 'biomes',
2: 'issues',
3: 'customs',
4: 'kingdoms',
5: 'climate',
6: 'resources',
7: 'wildlife',
8: 'arts',
9: 'ethnicGroups',
10: 'socialClasses',
11: 'importantCharacters'
};
export default class SeriesWorld {
/**
* Retrieves all worlds and their elements for a series.
* @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 The list of worlds
*/
public static getWorldList(userId: string, seriesId: string, lang: 'fr' | 'en' = 'fr'): SeriesWorldListProps[] {
const userKey: string = getUserEncryptionKey(userId);
const worldsResult: SeriesWorldResult[] = SeriesWorldRepo.fetchWorlds(userId, seriesId, lang);
const worldsMap: Map<string, SeriesWorldListProps> = new Map();
for (const row of worldsResult) {
if (!worldsMap.has(row.world_id)) {
worldsMap.set(row.world_id, {
id: row.world_id,
name: row.world_name ? System.decryptDataWithUserKey(row.world_name, userKey) : '',
history: row.history ? System.decryptDataWithUserKey(row.history, userKey) : '',
politics: row.politics ? System.decryptDataWithUserKey(row.politics, userKey) : '',
economy: row.economy ? System.decryptDataWithUserKey(row.economy, userKey) : '',
religion: row.religion ? System.decryptDataWithUserKey(row.religion, userKey) : '',
languages: row.languages ? System.decryptDataWithUserKey(row.languages, userKey) : '',
laws: [],
biomes: [],
issues: [],
customs: [],
kingdoms: [],
climate: [],
resources: [],
wildlife: [],
arts: [],
ethnicGroups: [],
socialClasses: [],
importantCharacters: []
});
}
if (row.element_id) {
const world = worldsMap.get(row.world_id)!;
const element: SeriesWorldElementProps = {
id: row.element_id,
name: row.element_name ? System.decryptDataWithUserKey(row.element_name, userKey) : '',
description: row.element_description ? System.decryptDataWithUserKey(row.element_description, userKey) : ''
};
const key = ELEMENT_TYPE_MAP[row.element_type];
if (key && Array.isArray(world[key])) {
(world[key] as SeriesWorldElementProps[]).push(element);
}
}
}
return Array.from(worldsMap.values());
}
/**
* Adds a new world to a series.
* @param userId - The unique identifier of the user
* @param seriesId - The unique identifier of the series
* @param name - The name of the world
* @param lang - The language for error messages ('fr' or 'en')
* @returns The new world ID
*/
public static addWorld(userId: string, seriesId: string, name: string, lang: 'fr' | 'en' = 'fr'): string {
const hashedName: string = System.hashElement(name);
const exists: boolean = SeriesWorldRepo.checkWorldExist(userId, seriesId, hashedName, lang);
if (exists) {
throw new Error(lang === 'fr' ? 'Un monde avec ce nom existe déjà.' : 'A world with this name already exists.');
}
const userKey: string = getUserEncryptionKey(userId);
const worldId: string = System.createUniqueId();
const encryptedName: string = System.encryptDataWithUserKey(name, userKey);
SeriesWorldRepo.insertNewWorld(worldId, userId, seriesId, encryptedName, hashedName, lang);
return worldId;
}
/**
* Updates a world's information.
* @param userId - The unique identifier of the user
* @param worldId - The unique identifier of the world
* @param world - The updated world data
* @param lang - The language for error messages ('fr' or 'en')
* @returns True if successful
*/
public static updateWorld(userId: string, worldId: string, world: SeriesWorldUpdateProps, lang: 'fr' | 'en' = 'fr'): boolean {
const userKey: string = getUserEncryptionKey(userId);
const encryptedName: string = System.encryptDataWithUserKey(world.name, userKey);
const hashedName: string = System.hashElement(world.name);
const encryptedHistory: string | null = world.history ? System.encryptDataWithUserKey(world.history, userKey) : null;
const encryptedPolitics: string | null = world.politics ? System.encryptDataWithUserKey(world.politics, userKey) : null;
const encryptedEconomy: string | null = world.economy ? System.encryptDataWithUserKey(world.economy, userKey) : null;
const encryptedReligion: string | null = world.religion ? System.encryptDataWithUserKey(world.religion, userKey) : null;
const encryptedLanguages: string | null = world.languages ? System.encryptDataWithUserKey(world.languages, userKey) : null;
return SeriesWorldRepo.updateWorld(userId, worldId, encryptedName, hashedName, encryptedHistory, encryptedPolitics, encryptedEconomy, encryptedReligion, encryptedLanguages, lang);
}
/**
* Adds a new element to a world.
* @param userId - The unique identifier of the user
* @param worldId - The unique identifier of the world
* @param elementType - The type of element (0-11)
* @param name - The name of the element
* @param lang - The language for error messages ('fr' or 'en')
* @param description - The description of the element (optional)
* @returns The new element ID
*/
public static addElement(userId: string, worldId: string, elementType: number, name: string, lang: 'fr' | 'en' = 'fr', description?: string): string {
const userKey: string = getUserEncryptionKey(userId);
const elementId: string = System.createUniqueId();
const encryptedName: string = System.encryptDataWithUserKey(name, userKey);
const originalName: string = System.hashElement(name);
const encryptedDescription: string | null = description ? System.encryptDataWithUserKey(description, userKey) : null;
SeriesWorldRepo.insertElement(elementId, worldId, userId, elementType, encryptedName, originalName, encryptedDescription, lang);
return elementId;
}
/**
* Deletes an element from a world.
* @param userId - The unique identifier of the user
* @param elementId - The unique identifier of the element
* @param deletedAt - The timestamp of deletion
* @param lang - The language for error messages ('fr' or 'en')
* @returns True if successful
*/
public static deleteElement(userId: string, elementId: string, deletedAt: number = System.timeStampInSeconds(), lang: 'fr' | 'en' = 'fr'): boolean {
const deleted: boolean = SeriesWorldRepo.deleteElement(userId, elementId, lang);
if (deleted) {
RemovedItem.deleteTracker(userId, null, 'series_world_elements', elementId, deletedAt, lang);
}
return deleted;
}
}