Files
ERitors-Scribe-Desktop/electron/database/models/GuideLine.ts
natreex cf6fb97bf0 Add models for guidelines, incidents, plot points, issues, acts, and world data
- Introduced new models: `GuideLine`, `Incident`, `PlotPoint`, `Issue`, `Act`, and `World` for managing book-related entities.
- Integrated encryption/decryption for sensitive properties in all models using user-specific keys.
- Added methods for CRUD operations and synchronization workflows with error handling and multilingual support.
- Improved maintainability with JSDoc comments and streamlined queries.
2026-01-12 13:38:10 -05:00

217 lines
10 KiB
TypeScript

import { getUserEncryptionKey } from "../keyManager.js";
import System from "../System.js";
import GuidelineRepo, { GuideLineAIQuery, GuideLineQuery } from "../repositories/guideline.repository.js";
export interface SyncedGuideLine {
lastUpdate: number;
}
export interface SyncedAIGuideLine {
lastUpdate: number;
}
export interface GuideLineProps {
tone: string;
atmosphere: string;
writingStyle: string;
themes: string;
symbolism: string;
motifs: string;
narrativeVoice: string;
pacing: string;
intendedAudience: string;
keyMessages: string;
}
export interface GuideLineAI {
narrativeType: number | null;
dialogueType: number | null;
globalResume: string | null;
atmosphere: string | null;
verbeTense: number | null;
langue: number | null;
currentResume: string | null;
themes: string | null;
}
export default class GuideLine {
/**
* Retrieves and decrypts the guideline for a specific book.
* @param userId - The unique identifier of the user
* @param bookId - The unique identifier of the book
* @param lang - The language for error messages ('fr' or 'en'), defaults to 'fr'
* @returns The decrypted guideline properties or null if not found
*/
public static async getGuideLine(userId: string, bookId: string, lang: 'fr' | 'en' = 'fr'): Promise<GuideLineProps | null> {
const guideLineResults: GuideLineQuery[] = GuidelineRepo.fetchGuideLine(userId, bookId, lang);
if (guideLineResults.length === 0) {
return null;
}
const guideLineData: GuideLineQuery = guideLineResults[0];
const encryptionKey: string = getUserEncryptionKey(userId);
return {
tone: guideLineData.tone ? System.decryptDataWithUserKey(guideLineData.tone, encryptionKey) : '',
atmosphere: guideLineData.atmosphere ? System.decryptDataWithUserKey(guideLineData.atmosphere, encryptionKey) : '',
writingStyle: guideLineData.writing_style ? System.decryptDataWithUserKey(guideLineData.writing_style, encryptionKey) : '',
themes: guideLineData.themes ? System.decryptDataWithUserKey(guideLineData.themes, encryptionKey) : '',
symbolism: guideLineData.symbolism ? System.decryptDataWithUserKey(guideLineData.symbolism, encryptionKey) : '',
motifs: guideLineData.motifs ? System.decryptDataWithUserKey(guideLineData.motifs, encryptionKey) : '',
narrativeVoice: guideLineData.narrative_voice ? System.decryptDataWithUserKey(guideLineData.narrative_voice, encryptionKey) : '',
pacing: guideLineData.pacing ? System.decryptDataWithUserKey(guideLineData.pacing, encryptionKey) : '',
intendedAudience: guideLineData.intended_audience ? System.decryptDataWithUserKey(guideLineData.intended_audience, encryptionKey) : '',
keyMessages: guideLineData.key_messages ? System.decryptDataWithUserKey(guideLineData.key_messages, encryptionKey) : '',
};
}
/**
* Updates or creates a guideline for a specific book with encrypted data.
* @param userId - The unique identifier of the user
* @param bookId - The unique identifier of the book
* @param tone - The tone setting for the book (nullable)
* @param atmosphere - The atmosphere setting for the book (nullable)
* @param writingStyle - The writing style for the book (nullable)
* @param themes - The themes for the book (nullable)
* @param symbolism - The symbolism elements for the book (nullable)
* @param motifs - The motifs for the book (nullable)
* @param narrativeVoice - The narrative voice for the book (nullable)
* @param pacing - The pacing setting for the book (nullable)
* @param keyMessages - The key messages for the book (nullable)
* @param intendedAudience - The intended audience for the book (nullable)
* @param lang - The language for error messages ('fr' or 'en'), defaults to 'fr'
* @returns True if the update was successful, false otherwise
*/
public static async updateGuideLine(
userId: string,
bookId: string,
tone: string | null,
atmosphere: string | null,
writingStyle: string | null,
themes: string | null,
symbolism: string | null,
motifs: string | null,
narrativeVoice: string | null,
pacing: string | null,
keyMessages: string | null,
intendedAudience: string | null,
lang: 'fr' | 'en' = 'fr'
): Promise<boolean> {
const encryptionKey: string = getUserEncryptionKey(userId);
const encryptedTone: string = tone ? System.encryptDataWithUserKey(tone, encryptionKey) : '';
const encryptedAtmosphere: string = atmosphere ? System.encryptDataWithUserKey(atmosphere, encryptionKey) : '';
const encryptedWritingStyle: string = writingStyle ? System.encryptDataWithUserKey(writingStyle, encryptionKey) : '';
const encryptedThemes: string = themes ? System.encryptDataWithUserKey(themes, encryptionKey) : '';
const encryptedSymbolism: string = symbolism ? System.encryptDataWithUserKey(symbolism, encryptionKey) : '';
const encryptedMotifs: string = motifs ? System.encryptDataWithUserKey(motifs, encryptionKey) : '';
const encryptedNarrativeVoice: string = narrativeVoice ? System.encryptDataWithUserKey(narrativeVoice, encryptionKey) : '';
const encryptedPacing: string = pacing ? System.encryptDataWithUserKey(pacing, encryptionKey) : '';
const encryptedKeyMessages: string = keyMessages ? System.encryptDataWithUserKey(keyMessages, encryptionKey) : '';
const encryptedIntendedAudience: string = intendedAudience ? System.encryptDataWithUserKey(intendedAudience, encryptionKey) : '';
return GuidelineRepo.updateGuideLine(
userId,
bookId,
encryptedTone,
encryptedAtmosphere,
encryptedWritingStyle,
encryptedThemes,
encryptedSymbolism,
encryptedMotifs,
encryptedNarrativeVoice,
encryptedPacing,
encryptedKeyMessages,
encryptedIntendedAudience,
lang
);
}
/**
* Retrieves and decrypts the AI guideline for a specific book.
* @param userId - The unique identifier of the user
* @param bookId - The unique identifier of the book
* @param lang - The language for error messages ('fr' or 'en'), defaults to 'fr'
* @returns The decrypted AI guideline data with default values if not found
* @throws Error if an unexpected error occurs during retrieval
*/
static getGuideLineAI(userId: string, bookId: string, lang: 'fr' | 'en' = 'fr'): GuideLineAI {
const encryptionKey: string = getUserEncryptionKey(userId);
try {
const aiGuideLineData: GuideLineAIQuery = GuidelineRepo.fetchGuideLineAI(userId, bookId, lang);
return {
narrativeType: aiGuideLineData.narrative_type,
dialogueType: aiGuideLineData.dialogue_type,
globalResume: aiGuideLineData.global_resume ? System.decryptDataWithUserKey(aiGuideLineData.global_resume, encryptionKey) : '',
atmosphere: aiGuideLineData.atmosphere ? System.decryptDataWithUserKey(aiGuideLineData.atmosphere, encryptionKey) : '',
verbeTense: aiGuideLineData.verbe_tense,
themes: aiGuideLineData.themes ? System.decryptDataWithUserKey(aiGuideLineData.themes, encryptionKey) : '',
currentResume: aiGuideLineData.current_resume ? System.decryptDataWithUserKey(aiGuideLineData.current_resume, encryptionKey) : '',
langue: aiGuideLineData.langue
};
} catch (error: unknown) {
if (error instanceof Error && error.message.includes('not found')) {
return {
narrativeType: 0,
dialogueType: 0,
globalResume: '',
atmosphere: '',
verbeTense: 0,
themes: '',
currentResume: '',
langue: 0
};
}
if (error instanceof Error) {
throw new Error(error.message);
} else {
const errorMessage: string = lang === 'fr'
? "Erreur inconnue lors de la recuperation de la ligne directrice de l'IA."
: "Unknown error while fetching AI guideline.";
throw new Error(errorMessage);
}
}
}
/**
* Creates or updates an AI guideline for a specific book with encrypted data.
* @param userId - The unique identifier of the user
* @param bookId - The unique identifier of the book
* @param narrativeType - The narrative type identifier
* @param dialogueType - The dialogue type identifier
* @param plotSummary - The plot summary text to be encrypted
* @param toneAtmosphere - The tone and atmosphere description to be encrypted
* @param verbTense - The verb tense identifier
* @param language - The language identifier
* @param themes - The themes description to be encrypted
* @param lang - The language for error messages ('fr' or 'en'), defaults to 'fr'
* @returns True if the operation was successful, false otherwise
*/
public static setAIGuideLine(
userId: string,
bookId: string,
narrativeType: number,
dialogueType: number,
plotSummary: string,
toneAtmosphere: string,
verbTense: number,
language: number,
themes: string,
lang: 'fr' | 'en' = 'fr'
): boolean {
const encryptionKey: string = getUserEncryptionKey(userId);
const encryptedPlotSummary: string = plotSummary ? System.encryptDataWithUserKey(plotSummary, encryptionKey) : '';
const encryptedToneAtmosphere: string = toneAtmosphere ? System.encryptDataWithUserKey(toneAtmosphere, encryptionKey) : '';
const encryptedThemes: string = themes ? System.encryptDataWithUserKey(themes, encryptionKey) : '';
return GuidelineRepo.insertAIGuideLine(
userId,
bookId,
narrativeType,
dialogueType,
encryptedPlotSummary,
encryptedToneAtmosphere,
verbTense,
language,
encryptedThemes,
lang
);
}
}