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 { 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 { 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, System.timeStampInSeconds(), 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, System.timeStampInSeconds(), lang ); } }