Add Content, Model, and Story models with text processing and AI model configuration utilities
- Implement `Content` model for converting Tiptap raw data into HTML and plain text. - Add `Model` for storing and managing AI model configurations with pricing and metadata. - Introduce `Story` model to handle verbal styles and linguistic properties for diverse narrative structures. - Update `book.repository.ts` to refine `updateBookBasicInformation` and `insertNewPlotPoint` methods, removing unused parameters and optimizing queries.
This commit is contained in:
295
electron/database/models/Character.ts
Normal file
295
electron/database/models/Character.ts
Normal file
@@ -0,0 +1,295 @@
|
||||
import User from "./User";
|
||||
import System, {UserKey} from "./System";
|
||||
import CharacterRepo, {AttributeResult, CharacterResult, CompleteCharacterResult} from "../repositories/character.repo";
|
||||
|
||||
export type CharacterCategory = 'Main' | 'Secondary' | 'Recurring';
|
||||
|
||||
export interface CharacterPropsPost {
|
||||
id: number | null;
|
||||
name: string;
|
||||
lastName: 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 }[];
|
||||
role: string;
|
||||
biography?: string;
|
||||
history?: string;
|
||||
}
|
||||
|
||||
|
||||
export interface CharacterProps {
|
||||
id: string;
|
||||
name: string;
|
||||
lastName: string;
|
||||
title: string;
|
||||
category: string;
|
||||
image: string;
|
||||
role: string;
|
||||
biography: string;
|
||||
history: string;
|
||||
}
|
||||
|
||||
export interface CompleteCharacterProps {
|
||||
id?: string;
|
||||
name: string;
|
||||
lastName: string;
|
||||
title: string;
|
||||
category: string;
|
||||
image?: string;
|
||||
role: string;
|
||||
biography: string;
|
||||
history: string;
|
||||
[key: string]: Attribute[] | string | undefined;
|
||||
}
|
||||
|
||||
export interface Attribute {
|
||||
id: string;
|
||||
name: string;
|
||||
}
|
||||
|
||||
|
||||
export interface CharacterAttribute {
|
||||
type: string;
|
||||
values: Attribute[];
|
||||
}
|
||||
|
||||
export default class Character{
|
||||
public static async getCharacterList(userId: string, bookId: string): Promise<CharacterProps[]> {
|
||||
const user = new User(userId);
|
||||
const keys:UserKey[] = await System.getAllUserKeysAndVersions(userId);
|
||||
const characters: CharacterResult[] = await CharacterRepo.fetchCharacters(userId, bookId);
|
||||
if (!characters) return [];
|
||||
if (characters.length === 0) return [];
|
||||
const characterList:CharacterProps[] = [];
|
||||
for (const character of characters) {
|
||||
const userKey:string = await user.getUserKey(character.char_meta,true,keys);
|
||||
characterList.push({
|
||||
id:character.character_id,
|
||||
name:character.first_name ? System.decryptDataWithUserKey(character.first_name,userKey) : '',
|
||||
lastName: character.last_name ? System.decryptDataWithUserKey(character.last_name, userKey) : '',
|
||||
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) : '',
|
||||
})
|
||||
}
|
||||
return characterList;
|
||||
}
|
||||
|
||||
public static async addNewCharacter(userId: string, character: CharacterPropsPost, bookId: string): Promise<string> {
|
||||
const user = new User(userId);
|
||||
const meta:string = System.encryptDateKey(userId);
|
||||
const userKey:string = await user.getUserKey(meta,true);
|
||||
const characterId: string = System.createUniqueId();
|
||||
const encryptedName: string = System.encryptDataWithUserKey(character.name, userKey);
|
||||
const encryptedLastName: string = System.encryptDataWithUserKey(character.lastName, userKey);
|
||||
const encryptedTitle: string = System.encryptDataWithUserKey(character.title, userKey);
|
||||
const encryptedCategory: string = System.encryptDataWithUserKey(character.category, userKey);
|
||||
const encryptedImage: string = System.encryptDataWithUserKey(character.image, userKey);
|
||||
const encryptedRole: string = System.encryptDataWithUserKey(character.role, userKey);
|
||||
const encryptedBiography: string = System.encryptDataWithUserKey(character.biography ? character.biography : '', userKey);
|
||||
const encryptedHistory: string = System.encryptDataWithUserKey(character.history ? character.history : '', userKey);
|
||||
await CharacterRepo.addNewCharacter(userId, characterId, encryptedName, encryptedLastName, encryptedTitle, encryptedCategory, encryptedImage, encryptedRole, encryptedBiography, encryptedHistory, bookId, meta);
|
||||
const attributes: string[] = Object.keys(character);
|
||||
for (const key of attributes) {
|
||||
if (Array.isArray(character[key as keyof CharacterPropsPost])) {
|
||||
const array = character[key as keyof CharacterPropsPost] as { name: string }[];
|
||||
if (array.length > 0) {
|
||||
for (const item of array) {
|
||||
const type: string = key;
|
||||
const name: string = item.name;
|
||||
await this.addNewAttribute(characterId, userId, type, name);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return characterId;
|
||||
}
|
||||
|
||||
static async updateCharacter(userId: string, character: CharacterPropsPost): Promise<boolean> {
|
||||
const user = new User(userId);
|
||||
const meta: string = System.encryptDateKey(userId);
|
||||
const userKey: string = await user.getUserKey(meta, true);
|
||||
const encryptedName: string = System.encryptDataWithUserKey(character.name, userKey);
|
||||
const encryptedLastName: string = System.encryptDataWithUserKey(character.lastName, userKey);
|
||||
const encryptedTitle: string = System.encryptDataWithUserKey(character.title, userKey);
|
||||
const encryptedCategory: string = System.encryptDataWithUserKey(character.category, userKey);
|
||||
const encryptedImage: string = System.encryptDataWithUserKey(character.image, userKey);
|
||||
const encryptedRole: string = System.encryptDataWithUserKey(character.role, userKey);
|
||||
const encryptedBiography: string = System.encryptDataWithUserKey(character.biography ? character.biography : '', userKey);
|
||||
const encryptedHistory: string = System.encryptDataWithUserKey(character.history ? character.history : '', userKey);
|
||||
return await CharacterRepo.updateCharacter(userId, character.id, encryptedName, encryptedLastName, encryptedTitle, encryptedCategory, encryptedImage, encryptedRole, encryptedBiography, encryptedHistory, meta);
|
||||
}
|
||||
|
||||
static async addNewAttribute(characterId: string, userId: string, type: string, name: string): Promise<string> {
|
||||
const user = new User(userId);
|
||||
const meta: string = System.encryptDateKey(userId);
|
||||
const userKey: string = await user.getUserKey(meta, true);
|
||||
const attributeId: string = System.createUniqueId();
|
||||
const encryptedType: string = System.encryptDataWithUserKey(type, userKey);
|
||||
const encryptedName: string = System.encryptDataWithUserKey(name, userKey);
|
||||
return await CharacterRepo.insertAttribute(attributeId, characterId, userId, encryptedType, encryptedName, meta);
|
||||
}
|
||||
|
||||
static async deleteAttribute(userId: string, attributeId: string) {
|
||||
return await CharacterRepo.deleteAttribute(userId, attributeId);
|
||||
}
|
||||
|
||||
static async getAttributes(characterId: string, userId: string): Promise<CharacterAttribute[]> {
|
||||
const user: User = new User(userId);
|
||||
const keys: UserKey[] = await System.getAllUserKeysAndVersions(userId);
|
||||
const attributes: AttributeResult[] = await CharacterRepo.fetchAttributes(characterId, userId);
|
||||
if (!attributes?.length) return [];
|
||||
|
||||
const groupedMap: Map<string, Attribute[]> = new Map<string, Attribute[]>();
|
||||
|
||||
for (const attribute of attributes) {
|
||||
const userKey: string = await user.getUserKey(attribute.attr_meta, true, keys);
|
||||
const type: string = System.decryptDataWithUserKey(attribute.attribute_name, userKey);
|
||||
const value: string = attribute.attribute_value ? System.decryptDataWithUserKey(attribute.attribute_value, userKey) : '';
|
||||
|
||||
if (!groupedMap.has(type)) {
|
||||
groupedMap.set(type, []);
|
||||
}
|
||||
|
||||
groupedMap.get(type)!.push({
|
||||
id: attribute.attr_id,
|
||||
name: value
|
||||
});
|
||||
}
|
||||
|
||||
return Array.from<[string, Attribute[]], CharacterAttribute>(
|
||||
groupedMap,
|
||||
([type, values]: [string, Attribute[]]): CharacterAttribute => ({type, values})
|
||||
);
|
||||
}
|
||||
|
||||
static async getCompleteCharacterList(userId: string, bookId: string, characters: string[]): Promise<CompleteCharacterProps[]> {
|
||||
const characterList: CompleteCharacterResult[] = await CharacterRepo.fetchCompleteCharacters(userId, bookId, characters);
|
||||
|
||||
if (!characterList || characterList.length === 0) {
|
||||
return [];
|
||||
}
|
||||
|
||||
const user = new User(userId);
|
||||
const keys: UserKey[] = await System.getAllUserKeysAndVersions(userId);
|
||||
const completeCharactersMap = new Map<string, CompleteCharacterProps>();
|
||||
for (const character of characterList) {
|
||||
if (!character.character_id) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!completeCharactersMap.has(character.character_id)) {
|
||||
const userKey: string = await user.getUserKey(character.char_meta, true, keys);
|
||||
if (!userKey) {
|
||||
continue;
|
||||
}
|
||||
const personnageObj: CompleteCharacterProps = {
|
||||
id: '',
|
||||
name: character.first_name ? System.decryptDataWithUserKey(character.first_name, userKey) : '',
|
||||
lastName: character.last_name ? System.decryptDataWithUserKey(character.last_name, userKey) : '',
|
||||
title: character.title ? System.decryptDataWithUserKey(character.title, userKey) : '',
|
||||
category: character.category ? System.decryptDataWithUserKey(character.category, 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) : '',
|
||||
physical: [],
|
||||
psychological: [],
|
||||
relations: [],
|
||||
skills: [],
|
||||
weaknesses: [],
|
||||
strengths: [],
|
||||
goals: [],
|
||||
motivations: []
|
||||
};
|
||||
completeCharactersMap.set(character.character_id, personnageObj);
|
||||
}
|
||||
|
||||
const personnage: CompleteCharacterProps | undefined = completeCharactersMap.get(character.character_id);
|
||||
|
||||
if (!character.attr_meta) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const rowKey: string = await user.getUserKey(character.attr_meta, true, keys);
|
||||
|
||||
if (!personnage || !rowKey) {
|
||||
continue;
|
||||
}
|
||||
const decryptedName: string = System.decryptDataWithUserKey(character.attribute_name, rowKey);
|
||||
const decryptedValue: string = character.attribute_value ? System.decryptDataWithUserKey(character.attribute_value, rowKey) : '';
|
||||
|
||||
if (Array.isArray(personnage[decryptedName])) {
|
||||
personnage[decryptedName].push({
|
||||
id: '',
|
||||
name: decryptedValue
|
||||
});
|
||||
}
|
||||
}
|
||||
return Array.from(completeCharactersMap.values());
|
||||
}
|
||||
|
||||
static characterVCard(characters: CompleteCharacterProps[]): string {
|
||||
const charactersMap = new Map<string, CompleteCharacterProps>();
|
||||
let charactersDescription: string = '';
|
||||
|
||||
characters.forEach((character: CompleteCharacterProps): void => {
|
||||
const characterKey: string = character.name || character.id || 'unknown';
|
||||
|
||||
if (!charactersMap.has(characterKey)) {
|
||||
charactersMap.set(characterKey, {
|
||||
name: character.name,
|
||||
lastName: character.lastName,
|
||||
category: character.category,
|
||||
title: character.title,
|
||||
role: character.role,
|
||||
biography: character.biography,
|
||||
history: character.history
|
||||
});
|
||||
}
|
||||
|
||||
const characterData: CompleteCharacterProps = charactersMap.get(characterKey)!;
|
||||
|
||||
Object.keys(character).forEach((fieldName: string): void => {
|
||||
if (Array.isArray(character[fieldName])) {
|
||||
if (!characterData[fieldName]) characterData[fieldName] = [];
|
||||
(characterData[fieldName] as Attribute[]).push(...(character[fieldName] as Attribute[]));
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
charactersDescription = Array.from(charactersMap.values()).map((character: CompleteCharacterProps): string => {
|
||||
const descriptionFields: string[] = [];
|
||||
const fullName: string = [character.name, character.lastName].filter(Boolean).join(' ');
|
||||
if (fullName) descriptionFields.push(`Nom : ${fullName}`);
|
||||
|
||||
(['category', 'title', 'role', 'biography', 'history'] as const).forEach((propertyKey) => {
|
||||
if (character[propertyKey]) {
|
||||
descriptionFields.push(`${propertyKey.charAt(0).toUpperCase() + propertyKey.slice(1)} : ${character[propertyKey]}`);
|
||||
}
|
||||
});
|
||||
|
||||
Object.keys(character).forEach((propertyKey: string): void => {
|
||||
const propertyValue: string | Attribute[] | undefined = character[propertyKey];
|
||||
if (Array.isArray(propertyValue) && propertyValue.length > 0) {
|
||||
const capitalizedPropertyKey: string = propertyKey.charAt(0).toUpperCase() + propertyKey.slice(1);
|
||||
const formattedValues: string = propertyValue.map((item: Attribute) => item.name).join(', ');
|
||||
descriptionFields.push(`${capitalizedPropertyKey} : ${formattedValues}`);
|
||||
}
|
||||
});
|
||||
|
||||
return descriptionFields.join('\n');
|
||||
}).join('\n\n');
|
||||
return charactersDescription;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user