- 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.
217 lines
10 KiB
TypeScript
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
|
|
);
|
|
}
|
|
}
|