import {Database, QueryResult, RunResult, SQLiteValue} from 'node-sqlite3-wasm'; import System from "../System.js"; export interface BookQuery extends Record { book_id: string; type: string; author_id: string; title: string; hashed_title: string; sub_title: string | null; hashed_sub_title: string | null; summary: string | null; serie_id: number | null; desired_release_date: string | null; desired_word_count: number | null; words_count: number | null; cover_image: string | null; } export interface EritBooksTable extends Record { book_id: string; type: string; author_id: string; title: string; hashed_title: string; sub_title: string | null; hashed_sub_title: string | null; summary: string | null; serie_id: number | null; desired_release_date: string | null; desired_word_count: number | null; words_count: number | null; last_update: number; cover_image: string | null; } export interface BookActSummariesTable extends Record { act_sum_id: string; book_id: string; user_id: string; act_index: number; last_update: number; summary: string | null; } export interface BookAIGuideLineTable extends Record { user_id: string; book_id: string; global_resume: string | null; themes: string | null; verbe_tense: number | null; narrative_type: number | null; langue: number | null; dialogue_type: number | null; tone: string | null; atmosphere: string | null; current_resume: string | null; last_update: number; } export interface BookChaptersTable extends Record { chapter_id: string; book_id: string; author_id: string; title: string; hashed_title: string; words_count: number | null; chapter_order: number; last_update: number; } export interface BookChapterContentTable extends Record { content_id: string; chapter_id: string; author_id: string; version: number; content: string | null; words_count: number; time_on_it: number; last_update: number; } export interface BookChapterInfosTable extends Record { chapter_info_id: string; chapter_id: string; act_id: number; incident_id: string | null; plot_point_id: string | null; book_id: string; author_id: string; summary: string | null; goal: string | null; last_update: number; } export interface BookCharactersTable extends Record { character_id: string; book_id: string; user_id: string; first_name: string; last_name: string | null; category: string; title: string | null; image: string | null; role: string | null; biography: string | null; history: string | null; last_update: number; } export interface BookCharactersAttributesTable extends Record { attr_id: string; character_id: string; user_id: string; attribute_name: string; attribute_value: string; last_update: number; } export interface BookGuideLineTable extends Record { user_id: string; book_id: string; tone: string | null; atmosphere: string | null; writing_style: string | null; themes: string | null; symbolism: string | null; motifs: string | null; narrative_voice: string | null; pacing: string | null; intended_audience: string | null; key_messages: string | null; last_update: number; } export interface BookIncidentsTable extends Record { incident_id: string; author_id: string; book_id: string; title: string; hashed_title: string; summary: string | null; last_update: number; } export interface BookIssuesTable extends Record { issue_id: string; author_id: string; book_id: string; name: string; hashed_issue_name: string; last_update: number; } export interface BookLocationTable extends Record { loc_id: string; book_id: string; user_id: string; loc_name: string; loc_original_name: string; last_update: number; } export interface BookPlotPointsTable extends Record { plot_point_id: string; title: string; hashed_title: string; summary: string | null; linked_incident_id: string | null; author_id: string; book_id: string; last_update: number; } export interface BookWorldTable extends Record { world_id: string; name: string; hashed_name: string; author_id: string; book_id: string; history: string | null; politics: string | null; economy: string | null; religion: string | null; languages: string | null; last_update: number; } export interface BookWorldElementsTable extends Record { element_id: string; world_id: string; user_id: string; element_type: number; name: string; original_name: string; description: string | null; last_update: number; } export interface LocationElementTable extends Record { element_id: string; location: string; user_id: string; element_name: string; original_name: string; element_description: string | null; last_update: number; } export interface LocationSubElementTable extends Record { sub_element_id: string; element_id: string; user_id: string; sub_elem_name: string; original_name: string; sub_elem_description: string | null; last_update: number; } export interface SyncedBookResult extends Record { book_id: string; type: string; title: string; sub_title: string | null; last_update: number; } export interface SyncedChapterResult extends Record { chapter_id: string; book_id: string; title: string; last_update: number; } export interface SyncedChapterContentResult extends Record { content_id: string; chapter_id: string; last_update: number; } export interface SyncedChapterInfoResult extends Record { chapter_info_id: string; chapter_id: string | null; book_id: string; last_update: number; } export interface SyncedCharacterResult extends Record { character_id: string; book_id: string; first_name: string; last_update: number; } export interface SyncedCharacterAttributeResult extends Record { attr_id: string; character_id: string; attribute_name: string; last_update: number; } export interface SyncedLocationResult extends Record { loc_id: string; book_id: string; loc_name: string; last_update: number; } export interface SyncedLocationElementResult extends Record { element_id: string; location: string; element_name: string; last_update: number; } export interface SyncedLocationSubElementResult extends Record { sub_element_id: string; element_id: string; sub_elem_name: string; last_update: number; } export interface SyncedWorldResult extends Record { world_id: string; book_id: string; name: string; last_update: number; } export interface SyncedWorldElementResult extends Record { element_id: string; world_id: string; name: string; last_update: number; } export interface SyncedIncidentResult extends Record { incident_id: string; book_id: string; title: string; last_update: number; } export interface SyncedPlotPointResult extends Record { plot_point_id: string; book_id: string; title: string; last_update: number; } export interface SyncedIssueResult extends Record { issue_id: string; book_id: string; name: string; last_update: number; } export interface SyncedActSummaryResult extends Record { act_sum_id: string; book_id: string; last_update: number; } export interface SyncedGuideLineResult extends Record { book_id: string; last_update: number; } export interface SyncedAIGuideLineResult extends Record { book_id: string; last_update: number; } export interface GuideLineQuery extends Record { tone: string; atmosphere: string; writing_style: string; themes: string; symbolism: string; motifs: string; narrative_voice: string; pacing: string; intended_audience: string; key_messages: string; } export interface PlotPointQuery extends Record { plot_point_id: string; title: string; summary: string; linked_incident_id: string | null; } export interface IncidentQuery extends Record { incident_id: string; title: string; summary: string; } export interface IssueQuery extends Record { issue_id: string; name: string; } export interface ActQuery extends Record { act_index: number; summary: string; } export interface BookCoverQuery extends Record { cover_image: string; } export interface ChapterBookResult extends Record { title: string; chapter_order: number; content: string | null; } export interface WorldQuery extends Record { world_id: string; world_name: string; history: string | null; politics: string | null; economy: string | null; religion: string | null; languages: string | null; element_id: string | null; element_name: string | null; element_description: string | null; element_type: number | null; } export interface WorldElementValue { id: string; name: string; description: string; type: number; } export interface GuideLineAIQuery extends Record { user_id: string; book_id: string; global_resume: string | null; themes: string | null; verbe_tense: number | null; narrative_type: number | null; langue: number | null; dialogue_type: number | null; tone: string | null; atmosphere: string | null; current_resume: string | null; meta: string; } export default class BookRepo { public static fetchBooks(userId: string, lang: 'fr' | 'en'): BookQuery[] { try { const db: Database = System.getDb(); return db.all('SELECT book_id, type, author_id, title, sub_title, summary, serie_id, desired_release_date, desired_word_count, words_count, cover_image FROM erit_books WHERE author_id = ? ORDER BY book_id DESC', [userId]) as BookQuery[]; } catch (error: unknown) { if (error instanceof Error) { console.error(error.message); throw new Error(lang === 'fr' ? 'Impossible de récupérer la liste des livres.' : 'Unable to retrieve book list.'); } else { console.error(error); throw new Error(lang === 'fr' ? 'Une erreur inconnue est survenue.' : 'An unknown error occurred.'); } } } public static updateBookCover(bookId:string,coverImageName:string,userId:string, lang: 'fr' | 'en'):boolean{ try { const db: Database = System.getDb(); const result:RunResult = db.run('UPDATE `erit_books` SET cover_image=?, last_update=? WHERE `book_id`=? AND author_id=?', [coverImageName, System.timeStampInSeconds(), bookId, userId]); return result.changes>0; } catch (e: unknown) { if (e instanceof Error) { console.error(`DB Error: ${e.message}`); throw new Error(lang === 'fr' ? `Impossible de mettre à jour la couverture du livre.` : `Unable to update book cover.`); } else { console.error("An unknown error occurred."); throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred."); } } } public static fetchBook(bookId: string, userId: string, lang: 'fr' | 'en'): BookQuery { let result: BookQuery; try { const db: Database = System.getDb(); result = db.get('SELECT book_id, author_id, title, summary, sub_title, cover_image, desired_release_date, desired_word_count, words_count FROM erit_books WHERE book_id=? AND author_id=?', [bookId, userId]) as BookQuery; } catch (error: unknown) { if (error instanceof Error) { console.error(`DB Error: ${error.message}`); throw new Error(lang === 'fr' ? `Impossible de récupérer les informations du livre.` : `Unable to retrieve book information.`); } else { console.error("An unknown error occurred."); throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred."); } } if (!result) { throw new Error(lang === 'fr' ? `Livre non trouvé.` : `Book not found.`); } return result; } public static verifyBookExist(hashedTitle:string,hashedSubTitle:string,userId:string, lang: 'fr' | 'en'):boolean{ try { const db: Database = System.getDb(); const result:QueryResult|null = db.get('SELECT book_id FROM erit_books WHERE hashed_title=? AND author_id=? AND erit_books.hashed_sub_title=?', [hashedTitle,userId,hashedSubTitle]); return result!==null; } catch (err: unknown) { if (err instanceof Error) { console.error(`DB Error: ${err.message}`); throw new Error(lang === 'fr' ? `Impossible de vérifier l'existence du livre.` : `Unable to verify book existence.`); } else { console.error("An unknown error occurred."); throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred."); } } } public static fetchGuideLine(userId: string, bookId: string, lang: 'fr' | 'en'): GuideLineQuery[] { let result: GuideLineQuery[]; try { const db: Database = System.getDb(); result = db.all('SELECT * FROM book_guide_line WHERE book_id=? AND user_id=?', [bookId, userId]) as GuideLineQuery[]; } catch (e: unknown) { if (e instanceof Error) { console.error(`DB Error: ${e.message}`); throw new Error(lang === 'fr' ? `Impossible de récupérer la ligne directrice.` : `Unable to retrieve guideline.`); } else { console.error("An unknown error occurred."); throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred."); } } return result; } public static fetchAllActs(userId: string, bookId: string, lang: 'fr' | 'en'): ActQuery[] { try { const db: Database = System.getDb(); return db.all('SELECT act_index, summary FROM book_act_summaries WHERE book_id=? AND user_id=?', [bookId, userId]) as ActQuery[]; } catch (e: unknown) { if (e instanceof Error) { console.error(`DB Error: ${e.message}`); throw new Error(lang === 'fr' ? `Impossible de récupérer les actes.` : `Unable to retrieve acts.`); } else { console.error("An unknown error occurred."); throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred."); } } } public static fetchAllIncitentIncidents(userId:string,bookId:string, lang: 'fr' | 'en'):IncidentQuery[]{ try { const db: Database = System.getDb(); return db.all('SELECT incident_id, title, summary FROM book_incidents WHERE author_id=? AND book_id=?', [userId, bookId]) as IncidentQuery[]; } catch (e: unknown) { if (e instanceof Error) { console.error(`DB Error: ${e.message}`); throw new Error(lang === 'fr' ? `Impossible de récupérer les incidents.` : `Unable to retrieve incidents.`); } else { console.error("An unknown error occurred."); throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred."); } } } public static fetchAllPlotPoints(userId:string,bookId:string, lang: 'fr' | 'en'):PlotPointQuery[]{ try { const db: Database = System.getDb(); return db.all('SELECT plot_point_id, title, summary, linked_incident_id FROM book_plot_points WHERE author_id=? AND book_id=?', [userId, bookId]) as PlotPointQuery[]; } catch (e: unknown) { if (e instanceof Error) { console.error(`DB Error: ${e.message}`); throw new Error(lang === 'fr' ? `Impossible de récupérer les points d'intrigue.` : `Unable to retrieve plot points.`); } else { console.error("An unknown error occurred."); throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred."); } } } public static fetchIssuesFromBook(userId:string,bookId:string, lang: 'fr' | 'en'):IssueQuery[]{ try { const db: Database = System.getDb(); return db.all('SELECT issue_id, name FROM book_issues WHERE author_id=? AND book_id=?', [userId, bookId]) as IssueQuery[]; } catch (e: unknown) { if (e instanceof Error) { console.error(`DB Error: ${e.message}`); throw new Error(lang === 'fr' ? `Impossible de récupérer les problématiques.` : `Unable to retrieve issues.`); } else { console.error("An unknown error occurred."); throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred."); } } } public static insertBook(bookId: string, userId: string, encryptedTitle: string, hashedTitle: string, encryptedSubTitle: string, hashedSubTitle: string, encryptedSummary: string, type: string, serie: number, publicationDate: string, desiredWordCount: number, lang: 'fr' | 'en'): string { let result: RunResult; try { const db: Database = System.getDb(); result = db.run('INSERT INTO erit_books (book_id, type, author_id, title, hashed_title, sub_title, hashed_sub_title, summary, serie_id, desired_release_date, desired_word_count, last_update) VALUES (?,?,?,?,?,?,?,?,?,?,?,?)', [bookId, type, userId, encryptedTitle, hashedTitle, encryptedSubTitle, hashedSubTitle, encryptedSummary, serie, publicationDate ? publicationDate : null, desiredWordCount, System.timeStampInSeconds()]); } catch (err: unknown) { if (err instanceof Error) { console.error(`DB Error: ${err.message}`); throw new Error(lang === 'fr' ? `Impossible d'ajouter le livre.` : `Unable to add book.`); } else { console.error("An unknown error occurred."); throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred."); } } if (!result || result.changes === 0) { throw new Error(lang === 'fr' ? `Erreur lors de l'ajout du livre.` : `Error adding book.`); } return bookId; } public static fetchBookCover(userId:string,bookId:string, lang: 'fr' | 'en'):BookCoverQuery{ try { const db: Database = System.getDb(); return db.get('SELECT cover_image FROM erit_books WHERE author_id=? AND book_id=?', [userId, bookId]) as BookCoverQuery; } catch (e: unknown) { if (e instanceof Error) { console.error(`DB Error: ${e.message}`); throw new Error(lang === 'fr' ? `Impossible de récupérer la couverture du livre.` : `Unable to retrieve book cover.`); } else { console.error("An unknown error occurred."); throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred."); } } } static updateBookBasicInformation(userId: string, title: string, hashedTitle: string, subTitle: string, hashedSubTitle: string, summary: string, publicationDate: string, wordCount: number, bookId: string, lang: 'fr' | 'en'): boolean { try { const db: Database = System.getDb(); const result: RunResult = db.run('UPDATE erit_books SET title=?, hashed_title=?, sub_title=?, hashed_sub_title=?, summary=?, serie_id=?, desired_release_date=?, desired_word_count=?, last_update=? WHERE author_id=? AND book_id=?', [title, hashedTitle, subTitle, hashedSubTitle, summary, 0, publicationDate ? System.dateToMySqlDate(publicationDate) : null, wordCount, System.timeStampInSeconds(), userId, bookId]); return result.changes > 0; } catch (e: unknown) { if (e instanceof Error) { console.error(`DB Error: ${e.message}`); throw new Error(lang === 'fr' ? `Impossible de mettre à jour les informations du livre.` : `Unable to update book information.`); } else { console.error("An unknown error occurred."); throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred."); } } } static updateGuideLine(userId: string, bookId: string, encryptedTone: string, encryptedAtmosphere: string, encryptedWritingStyle: string, encryptedThemes: string, encryptedSymbolism: string, encryptedMotifs: string, encryptedNarrativeVoice: string, encryptedPacing: string, encryptedKeyMessages: string, encryptedIntendedAudience: string, lang: 'fr' | 'en'): boolean { try { const db: Database = System.getDb(); const result: RunResult = db.run('UPDATE book_guide_line SET tone=?, atmosphere=?, writing_style=?, themes=?, symbolism=?, motifs=?, narrative_voice=?, pacing=?, key_messages=?, last_update=? WHERE user_id=? AND book_id=?', [encryptedTone, encryptedAtmosphere, encryptedWritingStyle, encryptedThemes, encryptedSymbolism, encryptedMotifs, encryptedNarrativeVoice, encryptedPacing, encryptedKeyMessages, System.timeStampInSeconds(), userId, bookId]); if (result.changes > 0) { return true; } else { const insert:RunResult = db.run('INSERT INTO book_guide_line (user_id, book_id, tone, atmosphere, writing_style, themes, symbolism, motifs, narrative_voice, pacing, intended_audience, key_messages, last_update) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?)', [userId, bookId, encryptedTone, encryptedAtmosphere, encryptedWritingStyle, encryptedThemes, encryptedSymbolism, encryptedMotifs, encryptedNarrativeVoice, encryptedPacing, encryptedIntendedAudience, encryptedKeyMessages, System.timeStampInSeconds()]); return insert.changes > 0; } } catch (e: unknown) { if (e instanceof Error) { console.error(`DB Error: ${e.message}`); throw new Error(lang === 'fr' ? `Impossible de mettre à jour la ligne directrice.` : `Unable to update guideline.`); } else { console.error("An unknown error occurred."); throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred."); } } } public static updateActSummary(userId: string, bookId: string, actId: number, summary: string, lastUpdate: number, lang: 'fr' | 'en'): boolean { try { const db: Database = System.getDb(); const result: RunResult = db.run('UPDATE book_act_summaries SET summary=?, last_update=? WHERE user_id=? AND book_id=? AND act_sum_id=?', [summary, lastUpdate, userId, bookId, actId]); return result.changes > 0; } catch (e: unknown) { if (e instanceof Error) { console.error(`DB Error: ${e.message}`); throw new Error(lang === 'fr' ? `Impossible de mettre à jour le résumé de l'acte.` : `Unable to update act summary.`); } else { console.error("An unknown error occurred."); throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred."); } } } public static insertNewIncident(incidentId: string, userId: string, bookId: string, encryptedName: string, hashedName: string, lang: 'fr' | 'en'): string { let result: RunResult; try { const db: Database = System.getDb(); result = db.run('INSERT INTO book_incidents (incident_id,author_id, book_id, title, hashed_title, last_update) VALUES (?,?,?,?,?,?)', [incidentId, userId, bookId, encryptedName, hashedName, System.timeStampInSeconds()]); } catch (e: unknown) { if (e instanceof Error) { console.error(`DB Error: ${e.message}`); throw new Error(lang === 'fr' ? `Impossible d'ajouter l'élément déclencheur.` : `Unable to add incident.`); } else { console.error("An unknown error occurred."); throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred."); } } if (!result || result.changes === 0) { throw new Error(lang === 'fr' ? `Une erreur s'est produite lors de l'ajout de l'élément déclencheur.` : `Error adding incident.`); } return incidentId; } public static deleteIncident(userId: string, bookId: string, incidentId: string, lang: 'fr' | 'en'): boolean { try { const db: Database = System.getDb(); const result: RunResult = db.run('DELETE FROM book_incidents WHERE author_id=? AND book_id=? AND incident_id=?', [userId, bookId, incidentId]); return result.changes > 0; } catch (e: unknown) { if (e instanceof Error) { console.error(`DB Error: ${e.message}`); throw new Error(lang === 'fr' ? `Impossible de supprimer l'élément déclencheur.` : `Unable to delete incident.`); } else { console.error("An unknown error occurred."); throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred."); } } } static insertNewPlotPoint(plotPointId: string, userId: string, bookId: string, encryptedName: string, hashedName: string, incidentId: string, lang: 'fr' | 'en'): string { let existingResult: QueryResult | null; let insertResult: RunResult; try { const db: Database = System.getDb(); existingResult = db.get('SELECT plot_point_id FROM book_plot_points WHERE author_id=? AND book_id=? AND hashed_title=?', [userId, bookId, hashedName]); } catch (e: unknown) { if (e instanceof Error) { console.error(`DB Error: ${e.message}`); throw new Error(lang === 'fr' ? `Impossible de vérifier l'existence du point d'intrigue.` : `Unable to verify plot point existence.`); } else { console.error("An unknown error occurred."); throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred."); } } if (existingResult !== null) { throw new Error(lang === 'fr' ? `Ce point de l'intrigue existe déjà.` : `This plot point already exists.`); } try { const db: Database = System.getDb(); insertResult = db.run('INSERT INTO book_plot_points (plot_point_id,title,hashed_title,author_id,book_id,linked_incident_id,last_update) VALUES (?,?,?,?,?,?,?)', [plotPointId, encryptedName, hashedName, userId, bookId, incidentId, System.timeStampInSeconds()]); } catch (e: unknown) { if (e instanceof Error) { console.error(`DB Error: ${e.message}`); throw new Error(lang === 'fr' ? `Impossible d'ajouter le point d'intrigue.` : `Unable to add plot point.`); } else { console.error("An unknown error occurred."); throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred."); } } if (!insertResult || insertResult.changes === 0) { throw new Error(lang === 'fr' ? `Une erreur s'est produite lors de l'ajout du point d'intrigue.` : `Error adding plot point.`); } return plotPointId; } static deletePlotPoint(userId: string, plotNumId: string, lang: 'fr' | 'en'): boolean { try { const db: Database = System.getDb(); const result: RunResult = db.run('DELETE FROM book_plot_points WHERE author_id=? AND plot_point_id=?', [userId, plotNumId]); return result.changes > 0; } catch (e: unknown) { if (e instanceof Error) { console.error(`DB Error: ${e.message}`); throw new Error(lang === 'fr' ? `Impossible de supprimer le point d'intrigue.` : `Unable to delete plot point.`); } else { console.error("An unknown error occurred."); throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred."); } } } public static insertNewIssue(issueId: string, userId: string, bookId: string, encryptedName: string, hashedName: string, lang: 'fr' | 'en'): string { let existingResult: QueryResult | null; let insertResult: RunResult; try { const db: Database = System.getDb(); existingResult = db.get('SELECT issue_id FROM book_issues WHERE hashed_issue_name=? AND book_id=? AND author_id=?', [hashedName, bookId, userId]); } catch (e: unknown) { if (e instanceof Error) { console.error(`DB Error: ${e.message}`); throw new Error(lang === 'fr' ? `Impossible de vérifier l'existence de la problématique.` : `Unable to verify issue existence.`); } else { console.error("An unknown error occurred."); throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred."); } } if (existingResult !== null) { throw new Error(lang === 'fr' ? `La problématique existe déjà.` : `This issue already exists.`); } try { const db: Database = System.getDb(); insertResult = db.run('INSERT INTO book_issues (issue_id,author_id, book_id, name, hashed_issue_name, last_update) VALUES (?,?,?,?,?,?)', [issueId, userId, bookId, encryptedName, hashedName, System.timeStampInSeconds()]); } catch (e: unknown) { if (e instanceof Error) { console.error(`DB Error: ${e.message}`); throw new Error(lang === 'fr' ? `Impossible d'ajouter la problématique.` : `Unable to add issue.`); } else { console.error("An unknown error occurred."); throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred."); } } if (!insertResult || insertResult.changes === 0) { throw new Error(lang === 'fr' ? `Erreur pendant l'ajout de la problématique.` : `Error adding issue.`); } return issueId; } public static deleteIssue(userId: string, issueId: string, lang: 'fr' | 'en'): boolean { try { const db: Database = System.getDb(); const result: RunResult = db.run('DELETE FROM book_issues WHERE author_id=? AND issue_id=?', [userId, issueId]); return result.changes > 0; } catch (e: unknown) { if (e instanceof Error) { console.error(`DB Error: ${e.message}`); throw new Error(lang === 'fr' ? `Impossible de supprimer la problématique.` : `Unable to delete issue.`); } else { console.error("An unknown error occurred."); throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred."); } } } public static updateIncident(userId: string, bookId: string, incidentId: string, encryptedIncidentName: string, incidentHashedName: string, incidentSummary: string, lastUpdate: number, lang: 'fr' | 'en'): boolean { try { const db: Database = System.getDb(); const result: RunResult = db.run('UPDATE book_incidents SET title=?, hashed_title=?, summary=?, last_update=? WHERE author_id=? AND book_id=? AND incident_id=?', [encryptedIncidentName, incidentHashedName, incidentSummary, lastUpdate, userId, bookId, incidentId]); return result.changes > 0; } catch (e: unknown) { if (e instanceof Error) { console.error(`DB Error: ${e.message}`); throw new Error(lang === 'fr' ? `Impossible de mettre à jour l'incident.` : `Unable to update incident.`); } else { console.error("An unknown error occurred."); throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred."); } } } public static updatePlotPoint(userId: string, bookId: string, plotPointId: string, encryptedPlotPointName: string, plotPointHashedName: string, plotPointSummary: string, lastUpdate:number, lang: 'fr' | 'en'): boolean { try { const db: Database = System.getDb(); const result: RunResult = db.run('UPDATE book_plot_points SET title=?, hashed_title=?, summary=?, last_update=? WHERE author_id=? AND book_id=? AND plot_point_id=?', [encryptedPlotPointName, plotPointHashedName, plotPointSummary, lastUpdate, userId, bookId, plotPointId]); return result.changes > 0; } catch (e: unknown) { if (e instanceof Error) { console.error(`DB Error: ${e.message}`); throw new Error(lang === 'fr' ? `Impossible de mettre à jour le point d'intrigue.` : `Unable to update plot point.`); } else { console.error("An unknown error occurred."); throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred."); } } } public static checkWorldExist(userId:string,bookId:string,worldName:string, lang: 'fr' | 'en'):boolean{ try { const db: Database = System.getDb(); const result = db.get('SELECT world_id FROM book_world WHERE author_id=? AND book_id=? AND hashed_name=?', [userId,bookId,worldName]); return result !== null; } catch (e: unknown) { if (e instanceof Error) { console.error(`DB Error: ${e.message}`); throw new Error(lang === 'fr' ? `Impossible de vérifier l'existence du monde.` : `Unable to verify world existence.`); } else { console.error("An unknown error occurred."); throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred."); } } } public static insertNewWorld(worldId: string, userId: string, bookId: string, encryptedName: string, hashedName: string, lang: 'fr' | 'en'): string { let result: RunResult; try { const db: Database = System.getDb(); result = db.run('INSERT INTO book_world (world_id,author_id, book_id, name, hashed_name, last_update) VALUES (?,?,?,?,?,?)', [worldId, userId, bookId, encryptedName, hashedName, System.timeStampInSeconds()]); } catch (e: unknown) { if (e instanceof Error) { console.error(`DB Error: ${e.message}`); throw new Error(lang === 'fr' ? `Impossible d'ajouter le monde.` : `Unable to add world.`); } else { console.error("An unknown error occurred."); throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred."); } } if (!result || result.changes === 0) { throw new Error(lang === 'fr' ? `Erreur lors de l'ajout du monde.` : `Error adding world.`); } return worldId; } public static fetchWorlds(userId: string, bookId: string, lang: 'fr' | 'en'):WorldQuery[] { try { const db: Database = System.getDb(); return db.all('SELECT world.world_id AS world_id, world.name AS world_name, world.history, world.politics, world.economy, world.religion, world.languages, element.element_id AS element_id, element.name AS element_name, element.description AS element_description, element.element_type FROM book_world AS world LEFT JOIN book_world_elements AS element ON world.world_id=element.world_id WHERE world.author_id=? AND world.book_id=?', [userId, bookId]) as WorldQuery[]; } catch (e: unknown) { if (e instanceof Error) { console.error(`DB Error: ${e.message}`); throw new Error(lang === 'fr' ? `Impossible de récupérer les mondes.` : `Unable to retrieve worlds.`); } else { console.error("An unknown error occurred."); throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred."); } } } public static updateWorld(userId: string, worldId: string, encryptName: string, hashedName: string, encryptHistory: string, encryptPolitics: string, encryptEconomy: string, encryptReligion: string, encryptLanguages: string, lastUpdate: number, lang: 'fr' | 'en'): boolean { try { const db: Database = System.getDb(); const result: RunResult = db.run('UPDATE book_world SET name=?, hashed_name=?, history=?, politics=?, economy=?, religion=?, languages=?, last_update=? WHERE author_id=? AND world_id=?', [encryptName, hashedName, encryptHistory, encryptPolitics, encryptEconomy, encryptReligion, encryptLanguages, lastUpdate, userId, worldId]); return result.changes > 0; } catch (e: unknown) { if (e instanceof Error) { console.error(`DB Error: ${e.message}`); throw new Error(lang === 'fr' ? `Impossible de mettre à jour le monde.` : `Unable to update world.`); } else { console.error("An unknown error occurred."); throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred."); } } } public static updateWorldElements(userId: string, elements: WorldElementValue[], lang: 'fr' | 'en'): boolean { try { const db: Database = System.getDb(); for (const element of elements) { const result: RunResult = db.run('UPDATE book_world_elements SET name=?, description=?, element_type=?, last_update=? WHERE user_id=? AND element_id=?', [element.name, element.description, element.type, System.timeStampInSeconds(), userId, element.id]); if (result.changes <= 0) { return false; } } return true; } catch (e: unknown) { if (e instanceof Error) { console.error(`DB Error: ${e.message}`); throw new Error(lang === 'fr' ? `Impossible de mettre à jour les éléments du monde.` : `Unable to update world elements.`); } else { console.error("An unknown error occurred."); throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred."); } } } public static checkElementExist(worldNumId: string, hashedName: string, lang: 'fr' | 'en'): boolean { try { const db: Database = System.getDb(); const result = db.get('SELECT element_id FROM book_world_elements WHERE world_id=? AND original_name=?', [worldNumId, hashedName]); return result !== null; } catch (e: unknown) { if (e instanceof Error) { console.error(`DB Error: ${e.message}`); throw new Error(lang === 'fr' ? `Impossible de vérifier l'existence de l'élément.` : `Unable to verify element existence.`); } else { console.error("An unknown error occurred."); throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred."); } } } public static insertNewElement(userId: string, elementId: string, elementType: number, worldId: string, encryptedName: string, hashedName: string, lang: 'fr' | 'en'): string { let result: RunResult; try { const db: Database = System.getDb(); result = db.run('INSERT INTO book_world_elements (element_id,world_id,user_id, name, original_name, element_type, last_update) VALUES (?,?,?,?,?,?,?)', [elementId, worldId, userId, encryptedName, hashedName, elementType, System.timeStampInSeconds()]); } catch (e: unknown) { if (e instanceof Error) { console.error(`DB Error: ${e.message}`); throw new Error(lang === 'fr' ? `Impossible d'ajouter l'élément.` : `Unable to add element.`); } else { console.error("An unknown error occurred."); throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred."); } } if (!result || result.changes === 0) { throw new Error(lang === 'fr' ? `Erreur lors de l'ajout de l'élément.` : `Error adding element.`); } return elementId; } public static deleteElement(userId: string, elementId: string, lang: 'fr' | 'en'): boolean { try { const db: Database = System.getDb(); const result: RunResult = db.run('DELETE FROM book_world_elements WHERE user_id=? AND element_id=?', [userId, elementId]); return result.changes > 0; } catch (e: unknown) { if (e instanceof Error) { console.error(`DB Error: ${e.message}`); throw new Error(lang === 'fr' ? `Impossible de supprimer l'élément.` : `Unable to delete element.`); } else { console.error("An unknown error occurred."); throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred."); } } } public static deleteBook(userId: string, bookId: string, lang: 'fr' | 'en'): boolean { try { const db: Database = System.getDb(); const result: RunResult = db.run('DELETE FROM erit_books WHERE author_id=? AND book_id=?', [userId,bookId]); return result.changes > 0; } catch (e: unknown) { if (e instanceof Error) { console.error(`DB Error: ${e.message}`); throw new Error(lang === 'fr' ? `Impossible de supprimer le livre.` : `Unable to delete book.`); } else { console.error("An unknown error occurred."); throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred."); } } } static insertAIGuideLine(userId: string, bookId: string, narrativeType: number, dialogueType: number, encryptedPlotSummary: string, encryptedToneAtmosphere: string, verbTense: number, language: number, encryptedThemes: string, lang: 'fr' | 'en'): boolean { try { const db: Database = System.getDb(); let result: RunResult = db.run('UPDATE book_ai_guide_line SET narrative_type=?, dialogue_type=?, global_resume=?, atmosphere=?, verbe_tense=?, langue=?, themes=?, last_update=? WHERE user_id=? AND book_id=?', [narrativeType ? narrativeType : null, dialogueType ? dialogueType : null, encryptedPlotSummary, encryptedToneAtmosphere, verbTense ? verbTense : null, language ? language : null, encryptedThemes, System.timeStampInSeconds(), userId, bookId]); if (result.changes > 0) { return true; } else { result = db.run('INSERT INTO book_ai_guide_line (user_id, book_id, global_resume, themes, verbe_tense, narrative_type, langue, dialogue_type, tone, atmosphere, current_resume, last_update) VALUES (?,?,?,?,?,?,?,?,?,?,?,?)', [userId, bookId, encryptedPlotSummary, encryptedThemes, verbTense ? verbTense : null, narrativeType ? narrativeType : null, language ? language : null, dialogueType ? dialogueType : null, encryptedToneAtmosphere, encryptedToneAtmosphere, encryptedPlotSummary, System.timeStampInSeconds()]); return result.changes > 0; } } catch (e: unknown) { if (e instanceof Error) { console.error(`DB Error: ${e.message}`); throw new Error(lang === 'fr' ? `Impossible d'insérer la ligne directrice IA.` : `Unable to insert AI guideline.`); } else { console.error("An unknown error occurred."); throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred."); } } } static fetchGuideLineAI(userId: string, bookId: string, lang: 'fr' | 'en'): GuideLineAIQuery { let result: GuideLineAIQuery | null; try { const db: Database = System.getDb(); result = db.get('SELECT narrative_type, dialogue_type, global_resume, atmosphere, verbe_tense, langue, themes, current_resume FROM book_ai_guide_line WHERE user_id=? AND book_id=?', [userId, bookId]) as GuideLineAIQuery | null; } catch (e: unknown) { if (e instanceof Error) { console.error(`DB Error: ${e.message}`); throw new Error(lang === 'fr' ? `Impossible de récupérer la ligne directrice IA.` : `Unable to retrieve AI guideline.`); } else { console.error("An unknown error occurred."); throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred."); } } if (!result) { throw new Error(lang === 'fr' ? `Ligne directrice IA non trouvée.` : `AI guideline not found.`); } return result; } static insertActSummary(actSummaryId: string, userId: string, bookId: string, actId: number, actSummary: string, lang: 'fr' | 'en'): string { let result:RunResult try { const db: Database = System.getDb(); result = db.run('INSERT INTO book_act_summaries (act_sum_id, book_id, user_id, act_index, summary, last_update) VALUES (?,?,?,?,?,?)', [actSummaryId, bookId, userId, actId, actSummary, System.timeStampInSeconds()]); } catch (e: unknown) { if (e instanceof Error) { console.error(`DB Error: ${e.message}`); throw new Error(lang === 'fr' ? `Impossible d'ajouter le résumé de l'acte.` : `Unable to add act summary.`); } else { console.error("An unknown error occurred."); throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred."); } } if (!result) { throw new Error(lang === 'fr' ? `Erreur lors de l'ajout du résumé de l'acte.` : `Error adding act summary.`); } return actSummaryId; } static fetchCompleteBookChapters(id: string, lang: 'fr' | 'en'): ChapterBookResult[] { let result: ChapterBookResult[]; try { const db: Database = System.getDb(); result = db.all('SELECT title, chapter_order, content.content FROM book_chapters AS chapter LEFT JOIN book_chapter_content AS content ON chapter.chapter_id = content.chapter_id AND content.version = (SELECT MAX(version) FROM book_chapter_content WHERE chapter_id = chapter.chapter_id AND version > 1) WHERE chapter.book_id = ? ORDER BY chapter.chapter_order', [id]) as ChapterBookResult[]; } catch (e: unknown) { if (e instanceof Error) { console.error(`DB Error: ${e.message}`); throw new Error(lang === 'fr' ? `Impossible de récupérer les chapitres.` : `Unable to retrieve chapters.`); } else { console.error("An unknown error occurred."); throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred."); } } if (result.length === 0) { throw new Error(lang === 'fr' ? `Aucun chapitre trouvé.` : `No chapters found.`); } return result; } static fetchSyncedBooks(userId: string, lang: 'fr' | 'en'): SyncedBookResult[] { try { const db: Database = System.getDb(); return db.all('SELECT book_id, type, title, sub_title, last_update FROM erit_books WHERE author_id = ?', [userId]) as SyncedBookResult[]; } catch (e: unknown) { if (e instanceof Error) { console.error(`DB Error: ${e.message}`); throw new Error(lang === 'fr' ? `Impossible de récupérer les livres synchronisés.` : `Unable to retrieve synced books.`); } else { console.error("An unknown error occurred."); throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred."); } } } static fetchSyncedChapters(userId: string, lang: 'fr' | 'en'): SyncedChapterResult[] { try { const db: Database = System.getDb(); return db.all('SELECT chapter_id, book_id, title, last_update FROM book_chapters WHERE author_id = ?', [userId]) as SyncedChapterResult[]; } catch (e: unknown) { if (e instanceof Error) { console.error(`DB Error: ${e.message}`); throw new Error(lang === 'fr' ? `Impossible de récupérer les chapitres synchronisés.` : `Unable to retrieve synced chapters.`); } else { console.error("An unknown error occurred."); throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred."); } } } static fetchSyncedChapterContents(userId: string, lang: 'fr' | 'en'): SyncedChapterContentResult[] { try { const db: Database = System.getDb(); return db.all('SELECT content_id, chapter_id, last_update FROM book_chapter_content WHERE author_id = ?', [userId]) as SyncedChapterContentResult[]; } catch (e: unknown) { if (e instanceof Error) { console.error(`DB Error: ${e.message}`); throw new Error(lang === 'fr' ? `Impossible de récupérer le contenu des chapitres synchronisés.` : `Unable to retrieve synced chapter contents.`); } else { console.error("An unknown error occurred."); throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred."); } } } static fetchSyncedChapterInfos(userId: string, lang: 'fr' | 'en'): SyncedChapterInfoResult[] { try { const db: Database = System.getDb(); return db.all('SELECT chapter_info_id, chapter_id, book_id, last_update FROM book_chapter_infos WHERE author_id = ?', [userId]) as SyncedChapterInfoResult[]; } catch (e: unknown) { if (e instanceof Error) { console.error(`DB Error: ${e.message}`); throw new Error(lang === 'fr' ? `Impossible de récupérer les infos des chapitres synchronisés.` : `Unable to retrieve synced chapter infos.`); } else { console.error("An unknown error occurred."); throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred."); } } } static fetchSyncedCharacters(userId: string, lang: 'fr' | 'en'): SyncedCharacterResult[] { try { const db: Database = System.getDb(); return db.all('SELECT character_id, book_id, first_name, last_update FROM book_characters WHERE user_id = ?', [userId]) as SyncedCharacterResult[]; } catch (e: unknown) { if (e instanceof Error) { console.error(`DB Error: ${e.message}`); throw new Error(lang === 'fr' ? `Impossible de récupérer les personnages synchronisés.` : `Unable to retrieve synced characters.`); } else { console.error("An unknown error occurred."); throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred."); } } } static fetchSyncedCharacterAttributes(userId: string, lang: 'fr' | 'en'): SyncedCharacterAttributeResult[] { try { const db: Database = System.getDb(); return db.all('SELECT attr_id, character_id, attribute_name, last_update FROM book_characters_attributes WHERE user_id = ?', [userId]) as SyncedCharacterAttributeResult[]; } catch (e: unknown) { if (e instanceof Error) { console.error(`DB Error: ${e.message}`); throw new Error(lang === 'fr' ? `Impossible de récupérer les attributs des personnages synchronisés.` : `Unable to retrieve synced character attributes.`); } else { console.error("An unknown error occurred."); throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred."); } } } static fetchSyncedLocations(userId: string, lang: 'fr' | 'en'): SyncedLocationResult[] { try { const db: Database = System.getDb(); return db.all('SELECT loc_id, book_id, loc_name, last_update FROM book_location WHERE user_id = ?', [userId]) as SyncedLocationResult[]; } catch (e: unknown) { if (e instanceof Error) { console.error(`DB Error: ${e.message}`); throw new Error(lang === 'fr' ? `Impossible de récupérer les lieux synchronisés.` : `Unable to retrieve synced locations.`); } else { console.error("An unknown error occurred."); throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred."); } } } static fetchSyncedLocationElements(userId: string, lang: 'fr' | 'en'): SyncedLocationElementResult[] { try { const db: Database = System.getDb(); return db.all('SELECT element_id, location, element_name, last_update FROM location_element WHERE user_id = ?', [userId]) as SyncedLocationElementResult[]; } catch (e: unknown) { if (e instanceof Error) { console.error(`DB Error: ${e.message}`); throw new Error(lang === 'fr' ? `Impossible de récupérer les éléments de lieu synchronisés.` : `Unable to retrieve synced location elements.`); } else { console.error("An unknown error occurred."); throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred."); } } } static fetchSyncedLocationSubElements(userId: string, lang: 'fr' | 'en'): SyncedLocationSubElementResult[] { try { const db: Database = System.getDb(); return db.all('SELECT sub_element_id, element_id, sub_elem_name, last_update FROM location_sub_element WHERE user_id = ?', [userId]) as SyncedLocationSubElementResult[]; } catch (e: unknown) { if (e instanceof Error) { console.error(`DB Error: ${e.message}`); throw new Error(lang === 'fr' ? `Impossible de récupérer les sous-éléments de lieu synchronisés.` : `Unable to retrieve synced location sub-elements.`); } else { console.error("An unknown error occurred."); throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred."); } } } static fetchSyncedWorlds(userId: string, lang: 'fr' | 'en'): SyncedWorldResult[] { try { const db: Database = System.getDb(); return db.all('SELECT world_id, book_id, name, last_update FROM book_world WHERE author_id = ?', [userId]) as SyncedWorldResult[]; } catch (e: unknown) { if (e instanceof Error) { console.error(`DB Error: ${e.message}`); throw new Error(lang === 'fr' ? `Impossible de récupérer les mondes synchronisés.` : `Unable to retrieve synced worlds.`); } else { console.error("An unknown error occurred."); throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred."); } } } static fetchSyncedWorldElements(userId: string, lang: 'fr' | 'en'): SyncedWorldElementResult[] { try { const db: Database = System.getDb(); return db.all('SELECT element_id, world_id, name, last_update FROM book_world_elements WHERE user_id = ?', [userId]) as SyncedWorldElementResult[]; } catch (e: unknown) { if (e instanceof Error) { console.error(`DB Error: ${e.message}`); throw new Error(lang === 'fr' ? `Impossible de récupérer les éléments de monde synchronisés.` : `Unable to retrieve synced world elements.`); } else { console.error("An unknown error occurred."); throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred."); } } } static fetchSyncedIncidents(userId: string, lang: 'fr' | 'en'): SyncedIncidentResult[] { try { const db: Database = System.getDb(); return db.all('SELECT incident_id, book_id, title, last_update FROM book_incidents WHERE author_id = ?', [userId]) as SyncedIncidentResult[]; } catch (e: unknown) { if (e instanceof Error) { console.error(`DB Error: ${e.message}`); throw new Error(lang === 'fr' ? `Impossible de récupérer les incidents synchronisés.` : `Unable to retrieve synced incidents.`); } else { console.error("An unknown error occurred."); throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred."); } } } static fetchSyncedPlotPoints(userId: string, lang: 'fr' | 'en'): SyncedPlotPointResult[] { try { const db: Database = System.getDb(); return db.all('SELECT plot_point_id, book_id, title, last_update FROM book_plot_points WHERE author_id = ?', [userId]) as SyncedPlotPointResult[]; } catch (e: unknown) { if (e instanceof Error) { console.error(`DB Error: ${e.message}`); throw new Error(lang === 'fr' ? `Impossible de récupérer les points d'intrigue synchronisés.` : `Unable to retrieve synced plot points.`); } else { console.error("An unknown error occurred."); throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred."); } } } static fetchSyncedIssues(userId: string, lang: 'fr' | 'en'): SyncedIssueResult[] { try { const db: Database = System.getDb(); return db.all('SELECT issue_id, book_id, name, last_update FROM book_issues WHERE author_id = ?', [userId]) as SyncedIssueResult[]; } catch (e: unknown) { if (e instanceof Error) { console.error(`DB Error: ${e.message}`); throw new Error(lang === 'fr' ? `Impossible de récupérer les problématiques synchronisées.` : `Unable to retrieve synced issues.`); } else { console.error("An unknown error occurred."); throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred."); } } } static fetchSyncedActSummaries(userId: string, lang: 'fr' | 'en'): SyncedActSummaryResult[] { try { const db: Database = System.getDb(); return db.all('SELECT act_sum_id, book_id, last_update FROM book_act_summaries WHERE user_id = ?', [userId]) as SyncedActSummaryResult[]; } catch (e: unknown) { if (e instanceof Error) { console.error(`DB Error: ${e.message}`); throw new Error(lang === 'fr' ? `Impossible de récupérer les résumés d'actes synchronisés.` : `Unable to retrieve synced act summaries.`); } else { console.error("An unknown error occurred."); throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred."); } } } static fetchSyncedGuideLine(userId: string, lang: 'fr' | 'en'): SyncedGuideLineResult[] { try { const db: Database = System.getDb(); return db.all('SELECT book_id, last_update FROM book_guide_line WHERE user_id = ?', [userId]) as SyncedGuideLineResult[]; } catch (e: unknown) { if (e instanceof Error) { console.error(`DB Error: ${e.message}`); throw new Error(lang === 'fr' ? `Impossible de récupérer les lignes directrices synchronisées.` : `Unable to retrieve synced guidelines.`); } else { console.error("An unknown error occurred."); throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred."); } } } static fetchSyncedAIGuideLine(userId: string, lang: 'fr' | 'en'): SyncedAIGuideLineResult[] { try { const db: Database = System.getDb(); return db.all('SELECT book_id, last_update FROM book_ai_guide_line WHERE user_id = ?', [userId]) as SyncedAIGuideLineResult[]; } catch (e: unknown) { if (e instanceof Error) { console.error(`DB Error: ${e.message}`); throw new Error(lang === 'fr' ? `Impossible de récupérer les lignes directrices IA synchronisées.` : `Unable to retrieve synced AI guidelines.`); } else { console.error("An unknown error occurred."); throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred."); } } } // ===================== SYNC INSERT METHODS ===================== static insertSyncBook( bookId: string, userId: string, type: string, title: string, hashedTitle: string, subTitle: string | null, hashedSubTitle: string | null, summary: string | null, serieId: number | null, desiredReleaseDate: string | null, desiredWordCount: number | null, wordsCount: number | null, coverImage: string | null, lastUpdate: number, lang: 'fr' | 'en' ): boolean { try { const db: Database = System.getDb(); const result: RunResult = db.run( `INSERT INTO erit_books (book_id, author_id, type, title, hashed_title, sub_title, hashed_sub_title, summary, serie_id, desired_release_date, desired_word_count, words_count, cover_image, last_update) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`, [bookId, userId, type, title, hashedTitle, subTitle, hashedSubTitle, summary, serieId, desiredReleaseDate, desiredWordCount, wordsCount, coverImage, lastUpdate] ); return result.changes > 0; } catch (e: unknown) { if (e instanceof Error) { console.error(`DB Error: ${e.message}`); throw new Error(lang === 'fr' ? `Impossible d'insérer le livre synchronisé.` : `Unable to insert synced book.`); } else { throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred."); } } } static insertSyncActSummary( actSumId: string, bookId: string, userId: string, actIndex: number, summary: string | null, lastUpdate: number, lang: 'fr' | 'en' ): boolean { try { const db: Database = System.getDb(); const result: RunResult = db.run( `INSERT INTO book_act_summaries (act_sum_id, book_id, user_id, act_index, summary, last_update) VALUES (?, ?, ?, ?, ?, ?)`, [actSumId, bookId, userId, actIndex, summary, lastUpdate] ); return result.changes > 0; } catch (e: unknown) { if (e instanceof Error) { console.error(`DB Error: ${e.message}`); throw new Error(lang === 'fr' ? `Impossible d'insérer le résumé d'acte.` : `Unable to insert act summary.`); } else { throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred."); } } } static insertSyncAIGuideLine( userId: string, bookId: string, globalResume: string | null, themes: string | null, verbeTense: number | null, narrativeType: number | null, langue: number | null, dialogueType: number | null, tone: string | null, atmosphere: string | null, currentResume: string | null, lastUpdate: number, lang: 'fr' | 'en' ): boolean { try { const db: Database = System.getDb(); const result: RunResult = db.run( `INSERT INTO book_ai_guide_line (user_id, book_id, global_resume, themes, verbe_tense, narrative_type, langue, dialogue_type, tone, atmosphere, current_resume, last_update) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`, [userId, bookId, globalResume, themes, verbeTense, narrativeType, langue, dialogueType, tone, atmosphere, currentResume, lastUpdate] ); return result.changes > 0; } catch (e: unknown) { if (e instanceof Error) { console.error(`DB Error: ${e.message}`); throw new Error(lang === 'fr' ? `Impossible d'insérer la ligne directrice IA.` : `Unable to insert AI guideline.`); } else { throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred."); } } } static insertSyncChapter( chapterId: string, bookId: string, authorId: string, title: string, hashedTitle: string | null, wordsCount: number | null, chapterOrder: number | null, lastUpdate: number, lang: 'fr' | 'en' ): boolean { try { const db: Database = System.getDb(); const result: RunResult = db.run( `INSERT INTO book_chapters (chapter_id, book_id, author_id, title, hashed_title, words_count, chapter_order, last_update) VALUES (?, ?, ?, ?, ?, ?, ?, ?)`, [chapterId, bookId, authorId, title, hashedTitle, wordsCount, chapterOrder, lastUpdate] ); return result.changes > 0; } catch (e: unknown) { if (e instanceof Error) { console.error(`DB Error: ${e.message}`); throw new Error(lang === 'fr' ? `Impossible d'insérer le chapitre.` : `Unable to insert chapter.`); } else { throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred."); } } } static insertSyncChapterContent( contentId: string, chapterId: string, authorId: string, version: number, content: string | null, wordsCount: number, timeOnIt: number, lastUpdate: number, lang: 'fr' | 'en' ): boolean { try { const db: Database = System.getDb(); const result: RunResult = db.run( `INSERT INTO book_chapter_content (content_id, chapter_id, author_id, version, content, words_count, time_on_it, last_update) VALUES (?, ?, ?, ?, ?, ?, ?, ?)`, [contentId, chapterId, authorId, version, content, wordsCount, timeOnIt, lastUpdate] ); return result.changes > 0; } catch (e: unknown) { if (e instanceof Error) { console.error(`DB Error: ${e.message}`); throw new Error(lang === 'fr' ? `Impossible d'insérer le contenu du chapitre.` : `Unable to insert chapter content.`); } else { throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred."); } } } static insertSyncChapterInfo( chapterInfoId: string, chapterId: string, actId: number | null, incidentId: string | null, plotPointId: string | null, bookId: string, authorId: string, summary: string | null, goal: string | null, lastUpdate: number, lang: 'fr' | 'en' ): boolean { try { const db: Database = System.getDb(); const result: RunResult = db.run( `INSERT INTO book_chapter_infos (chapter_info_id, chapter_id, act_id, incident_id, plot_point_id, book_id, author_id, summary, goal, last_update) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`, [chapterInfoId, chapterId, actId, incidentId, plotPointId, bookId, authorId, summary, goal, lastUpdate] ); return result.changes > 0; } catch (e: unknown) { if (e instanceof Error) { console.error(`DB Error: ${e.message}`); throw new Error(lang === 'fr' ? `Impossible d'insérer les infos du chapitre.` : `Unable to insert chapter info.`); } else { throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred."); } } } static insertSyncCharacter( characterId: string, bookId: string, userId: string, firstName: string, lastName: string | null, category: string, title: string | null, image: string | null, role: string | null, biography: string | null, history: string | null, lastUpdate: number, lang: 'fr' | 'en' ): boolean { try { const db: Database = System.getDb(); const result: RunResult = db.run( `INSERT INTO book_characters (character_id, book_id, user_id, first_name, last_name, category, title, image, role, biography, history, last_update) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`, [characterId, bookId, userId, firstName, lastName, category, title, image, role, biography, history, lastUpdate] ); return result.changes > 0; } catch (e: unknown) { if (e instanceof Error) { console.error(`DB Error: ${e.message}`); throw new Error(lang === 'fr' ? `Impossible d'insérer le personnage.` : `Unable to insert character.`); } else { throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred."); } } } static insertSyncCharacterAttribute( attrId: string, characterId: string, userId: string, attributeName: string, attributeValue: string, lastUpdate: number, lang: 'fr' | 'en' ): boolean { try { const db: Database = System.getDb(); const result: RunResult = db.run( `INSERT INTO book_characters_attributes (attr_id, character_id, user_id, attribute_name, attribute_value, last_update) VALUES (?, ?, ?, ?, ?, ?)`, [attrId, characterId, userId, attributeName, attributeValue, lastUpdate] ); return result.changes > 0; } catch (e: unknown) { if (e instanceof Error) { console.error(`DB Error: ${e.message}`); throw new Error(lang === 'fr' ? `Impossible d'insérer l'attribut du personnage.` : `Unable to insert character attribute.`); } else { throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred."); } } } static insertSyncGuideLine( 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, intendedAudience: string | null, keyMessages: string | null, lastUpdate: number, lang: 'fr' | 'en' ): boolean { try { const db: Database = System.getDb(); const result: RunResult = db.run( `INSERT INTO book_guide_line (user_id, book_id, tone, atmosphere, writing_style, themes, symbolism, motifs, narrative_voice, pacing, intended_audience, key_messages, last_update) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`, [userId, bookId, tone, atmosphere, writingStyle, themes, symbolism, motifs, narrativeVoice, pacing, intendedAudience, keyMessages, lastUpdate] ); return result.changes > 0; } catch (e: unknown) { if (e instanceof Error) { console.error(`DB Error: ${e.message}`); throw new Error(lang === 'fr' ? `Impossible d'insérer la ligne directrice.` : `Unable to insert guideline.`); } else { throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred."); } } } static insertSyncIncident( incidentId: string, authorId: string, bookId: string, title: string, hashedTitle: string, summary: string | null, lastUpdate: number, lang: 'fr' | 'en' ): boolean { try { const db: Database = System.getDb(); const result: RunResult = db.run( `INSERT INTO book_incidents (incident_id, author_id, book_id, title, hashed_title, summary, last_update) VALUES (?, ?, ?, ?, ?, ?, ?)`, [incidentId, authorId, bookId, title, hashedTitle, summary, lastUpdate] ); return result.changes > 0; } catch (e: unknown) { if (e instanceof Error) { console.error(`DB Error: ${e.message}`); throw new Error(lang === 'fr' ? `Impossible d'insérer l'incident.` : `Unable to insert incident.`); } else { throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred."); } } } static insertSyncIssue( issueId: string, authorId: string, bookId: string, name: string, hashedIssueName: string, lastUpdate: number, lang: 'fr' | 'en' ): boolean { try { const db: Database = System.getDb(); const result: RunResult = db.run( `INSERT INTO book_issues (issue_id, author_id, book_id, name, hashed_issue_name, last_update) VALUES (?, ?, ?, ?, ?, ?)`, [issueId, authorId, bookId, name, hashedIssueName, lastUpdate] ); return result.changes > 0; } catch (e: unknown) { if (e instanceof Error) { console.error(`DB Error: ${e.message}`); throw new Error(lang === 'fr' ? `Impossible d'insérer la problématique.` : `Unable to insert issue.`); } else { throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred."); } } } static insertSyncLocation( locId: string, bookId: string, userId: string, locName: string, locOriginalName: string, lastUpdate: number, lang: 'fr' | 'en' ): boolean { try { const db: Database = System.getDb(); const result: RunResult = db.run( `INSERT INTO book_location (loc_id, book_id, user_id, loc_name, loc_original_name, last_update) VALUES (?, ?, ?, ?, ?, ?)`, [locId, bookId, userId, locName, locOriginalName, lastUpdate] ); return result.changes > 0; } catch (e: unknown) { if (e instanceof Error) { console.error(`DB Error: ${e.message}`); throw new Error(lang === 'fr' ? `Impossible d'insérer le lieu.` : `Unable to insert location.`); } else { throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred."); } } } static insertSyncPlotPoint( plotPointId: string, title: string, hashedTitle: string, summary: string | null, linkedIncidentId: string | null, authorId: string, bookId: string, lastUpdate: number, lang: 'fr' | 'en' ): boolean { try { const db: Database = System.getDb(); const result: RunResult = db.run( `INSERT INTO book_plot_points (plot_point_id, title, hashed_title, summary, linked_incident_id, author_id, book_id, last_update) VALUES (?, ?, ?, ?, ?, ?, ?, ?)`, [plotPointId, title, hashedTitle, summary, linkedIncidentId, authorId, bookId, lastUpdate] ); return result.changes > 0; } catch (e: unknown) { if (e instanceof Error) { console.error(`DB Error: ${e.message}`); throw new Error(lang === 'fr' ? `Impossible d'insérer le point d'intrigue.` : `Unable to insert plot point.`); } else { throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred."); } } } static insertSyncWorld( worldId: string, name: string, hashedName: string, authorId: string, bookId: string, history: string | null, politics: string | null, economy: string | null, religion: string | null, languages: string | null, lastUpdate: number, lang: 'fr' | 'en' ): boolean { try { const db: Database = System.getDb(); const result: RunResult = db.run( `INSERT INTO book_world (world_id, name, hashed_name, author_id, book_id, history, politics, economy, religion, languages, last_update) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`, [worldId, name, hashedName, authorId, bookId, history, politics, economy, religion, languages, lastUpdate] ); return result.changes > 0; } catch (e: unknown) { if (e instanceof Error) { console.error(`DB Error: ${e.message}`); throw new Error(lang === 'fr' ? `Impossible d'insérer le monde.` : `Unable to insert world.`); } else { throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred."); } } } static insertSyncWorldElement( elementId: string, worldId: string, userId: string, elementType: number, name: string, originalName: string, description: string | null, lastUpdate: number, lang: 'fr' | 'en' ): boolean { try { const db: Database = System.getDb(); const result: RunResult = db.run( `INSERT INTO book_world_elements (element_id, world_id, user_id, element_type, name, original_name, description, last_update) VALUES (?, ?, ?, ?, ?, ?, ?, ?)`, [elementId, worldId, userId, elementType, name, originalName, description, lastUpdate] ); return result.changes > 0; } catch (e: unknown) { if (e instanceof Error) { console.error(`DB Error: ${e.message}`); throw new Error(lang === 'fr' ? `Impossible d'insérer l'élément du monde.` : `Unable to insert world element.`); } else { throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred."); } } } static insertSyncLocationElement( elementId: string, location: string, userId: string, elementName: string, originalName: string, elementDescription: string | null, lastUpdate: number, lang: 'fr' | 'en' ): boolean { try { const db: Database = System.getDb(); const result: RunResult = db.run( `INSERT INTO location_element (element_id, location, user_id, element_name, original_name, element_description, last_update) VALUES (?, ?, ?, ?, ?, ?, ?)`, [elementId, location, userId, elementName, originalName, elementDescription, lastUpdate] ); return result.changes > 0; } catch (e: unknown) { if (e instanceof Error) { console.error(`DB Error: ${e.message}`); throw new Error(lang === 'fr' ? `Impossible d'insérer l'élément du lieu.` : `Unable to insert location element.`); } else { throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred."); } } } static insertSyncLocationSubElement( subElementId: string, elementId: string, userId: string, subElemName: string, originalName: string, subElemDescription: string | null, lastUpdate: number, lang: 'fr' | 'en' ): boolean { try { const db: Database = System.getDb(); const result: RunResult = db.run( `INSERT INTO location_sub_element (sub_element_id, element_id, user_id, sub_elem_name, original_name, sub_elem_description, last_update) VALUES (?, ?, ?, ?, ?, ?, ?)`, [subElementId, elementId, userId, subElemName, originalName, subElemDescription, lastUpdate] ); return result.changes > 0; } catch (e: unknown) { if (e instanceof Error) { console.error(`DB Error: ${e.message}`); throw new Error(lang === 'fr' ? `Impossible d'insérer le sous-élément du lieu.` : `Unable to insert location sub-element.`); } else { throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred."); } } } static async fetchCompleteActSummaryById(id: string, lang: "fr" | "en"):Promise { try { const db: Database = System.getDb(); return db.all( `SELECT act_sum_id, book_id, user_id, act_index, summary, last_update FROM book_act_summaries WHERE act_sum_id = ?`, [id] ) as BookActSummariesTable[]; } catch (e:unknown){ if (e instanceof Error) { throw new Error(lang === 'fr' ? `Impossible de récupérer le résumé d'acte complet.` : `Unable to retrieve complete act summary.`); } else { throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred."); } } } static async fetchCompleteChapterById(id: string, lang: "fr" | "en"):Promise { try { const db: Database = System.getDb(); return db.all( `SELECT chapter_id, book_id, author_id, title, hashed_title, words_count, chapter_order, last_update FROM book_chapters WHERE chapter_id = ?`, [id] ) as BookChaptersTable[]; } catch (e:unknown){ if (e instanceof Error) { throw new Error(lang === 'fr' ? `Impossible de récupérer le chapitre complet.` : `Unable to retrieve complete chapter.`); } else { throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred."); } } } static async fetchCompletePlotPointById(id: string, lang: "fr" | "en"):Promise { try { const db: Database = System.getDb(); return db.all( `SELECT plot_point_id, title, hashed_title, summary, linked_incident_id, author_id, book_id, last_update FROM book_plot_points WHERE plot_point_id = ?`, [id] ) as BookPlotPointsTable[]; } catch (e:unknown){ if (e instanceof Error) { throw new Error(lang === 'fr' ? `Impossible de récupérer le point d'intrigue complet.` : `Unable to retrieve complete plot point.`); } else { throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred."); } } } static async fetchCompleteIncidentById(id: string, lang: "fr" | "en"):Promise { try { const db: Database = System.getDb(); return db.all( `SELECT incident_id, author_id, book_id, title, hashed_title, summary, last_update FROM book_incidents WHERE incident_id = ?`, [id] ) as BookIncidentsTable[]; } catch (e:unknown){ if (e instanceof Error) { throw new Error(lang === 'fr' ? `Impossible de récupérer l'incident complet.` : `Unable to retrieve complete incident.`); } else { throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred."); } } } static async fetchCompleteChapterContentById(id: string, lang: "fr" | "en"):Promise { try { const db: Database = System.getDb(); return db.all( `SELECT content_id, chapter_id, author_id, version, content, words_count, time_on_it, last_update FROM book_chapter_content WHERE content_id = ?`, [id] ) as BookChapterContentTable[]; } catch (e:unknown){ if (e instanceof Error) { throw new Error(lang === 'fr' ? `Impossible de récupérer le contenu de chapitre complet.` : `Unable to retrieve complete chapter content.`); } else { throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred."); } } } static async fetchCompleteChapterInfoById(id: string, lang: "fr" | "en"):Promise { try { const db: Database = System.getDb(); return db.all( `SELECT chapter_info_id, chapter_id, act_id, incident_id, plot_point_id, book_id, author_id, summary, goal, last_update FROM book_chapter_infos WHERE chapter_info_id = ?`, [id] ) as BookChapterInfosTable[]; } catch (e:unknown){ if (e instanceof Error) { throw new Error(lang === 'fr' ? `Impossible de récupérer les informations de chapitre complètes.` : `Unable to retrieve complete chapter info.`); } else { throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred."); } } } static async fetchCompleteCharacterById(id: string, lang: "fr" | "en"):Promise { try { const db: Database = System.getDb(); return db.all( `SELECT character_id, book_id, user_id, first_name, last_name, category, title, image, role, biography, history, last_update FROM book_characters WHERE character_id = ?`, [id] ) as BookCharactersTable[]; } catch (e:unknown){ if (e instanceof Error) { throw new Error(lang === 'fr' ? `Impossible de récupérer le personnage complet.` : `Unable to retrieve complete character.`); } else { throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred."); } } } static async fetchCompleteCharacterAttributeById(id: string, lang: "fr" | "en"):Promise { try { const db: Database = System.getDb(); return db.all( `SELECT attr_id, character_id, user_id, attribute_name, attribute_value, last_update FROM book_characters_attributes WHERE attr_id = ?`, [id] ) as BookCharactersAttributesTable[]; } catch (e:unknown){ if (e instanceof Error) { throw new Error(lang === 'fr' ? `Impossible de récupérer l'attribut de personnage complet.` : `Unable to retrieve complete character attribute.`); } else { throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred."); } } } static async fetchCompleteLocationById(id: string, lang: "fr" | "en"):Promise { try { const db: Database = System.getDb(); return db.all( `SELECT loc_id, book_id, user_id, loc_name, loc_original_name, last_update FROM book_location WHERE loc_id = ?`, [id] ) as BookLocationTable[]; } catch (e:unknown){ if (e instanceof Error) { throw new Error(lang === 'fr' ? `Impossible de récupérer le lieu complet.` : `Unable to retrieve complete location.`); } else { throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred."); } } } static async fetchCompleteLocationElementById(id: string, lang: "fr" | "en"):Promise { try { const db: Database = System.getDb(); return db.all( `SELECT element_id, location, user_id, element_name, original_name, element_description, last_update FROM location_element WHERE element_id = ?`, [id] ) as LocationElementTable[]; } catch (e:unknown){ if (e instanceof Error) { throw new Error(lang === 'fr' ? `Impossible de récupérer l'élément de lieu complet.` : `Unable to retrieve complete location element.`); } else { throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred."); } } } static async fetchCompleteLocationSubElementById(id: string, lang: "fr" | "en"):Promise { try { const db: Database = System.getDb(); return db.all( `SELECT sub_element_id, element_id, user_id, sub_elem_name, original_name, sub_elem_description, last_update FROM location_sub_element WHERE sub_element_id = ?`, [id] ) as LocationSubElementTable[]; } catch (e:unknown){ if (e instanceof Error) { throw new Error(lang === 'fr' ? `Impossible de récupérer le sous-élément de lieu complet.` : `Unable to retrieve complete location sub-element.`); } else { throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred."); } } } static async fetchCompleteWorldById(id: string, lang: "fr" | "en"):Promise { try { const db: Database = System.getDb(); return db.all( `SELECT world_id, name, hashed_name, author_id, book_id, history, politics, economy, religion, languages, last_update FROM book_world WHERE world_id = ?`, [id] ) as BookWorldTable[]; } catch (e:unknown){ if (e instanceof Error) { throw new Error(lang === 'fr' ? `Impossible de récupérer le monde complet.` : `Unable to retrieve complete world.`); } else { throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred."); } } } static async fetchCompleteWorldElementById(id: string, lang: "fr" | "en"):Promise { try { const db: Database = System.getDb(); return db.all( `SELECT element_id, world_id, user_id, element_type, name, original_name, description, last_update FROM book_world_elements WHERE element_id = ?`, [id] ) as BookWorldElementsTable[]; } catch (e:unknown){ if (e instanceof Error) { throw new Error(lang === 'fr' ? `Impossible de récupérer l'élément de monde complet.` : `Unable to retrieve complete world element.`); } else { throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred."); } } } static async fetchCompleteIssueById(id: string, lang: "fr" | "en"):Promise { try { const db: Database = System.getDb(); return db.all( `SELECT issue_id, author_id, book_id, name, hashed_issue_name, last_update FROM book_issues WHERE issue_id = ?`, [id] ) as BookIssuesTable[]; } catch (e:unknown){ if (e instanceof Error) { throw new Error(lang === 'fr' ? `Impossible de récupérer le problème complet.` : `Unable to retrieve complete issue.`); } else { throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred."); } } } static async fetchCompleteBookById(bookId: string, lang: "fr" | "en") { try { const db: Database = System.getDb(); return db.all( `SELECT * FROM erit_books WHERE book_id = ?`, [bookId] ) as EritBooksTable[]; } catch (e: unknown) { if (e instanceof Error) { throw new Error(lang === 'fr' ? `Impossible de récupérer le livre complet.` : `Unable to retrieve complete book.`); } else { throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred."); } } } static updateWorldElement(userId: string, elementId: string, name: string, description: string, lastUpdate: number,lang: "fr" | "en"):boolean { try { const db: Database = System.getDb(); const query:string = `UPDATE book_world_elements SET name = ?, description = ?, last_update = FROM_UNIXTIME(?) WHERE element_id = UUID_TO_BIN(?) AND user_id = UUID_TO_BIN(?)`; const params:(string|number)[] = [name, description, lastUpdate, elementId, userId]; const result:RunResult = db.run(query, params); return result.changes > 0; } catch (e:unknown) { if (e instanceof Error) { console.error(`DB Error: ${e.message}`); throw new Error(lang === 'fr' ? `Impossible de mettre à jour l'élément du monde.` : `Unable to update world element.`); } else { console.error("An unknown error occurred."); throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred."); } } } static updateIssue(userId: string, bookId: string, issueId: string, name: string, hashedName: string, lastUpdate: number, lang: "fr" | "en"):boolean { try { const db: Database = System.getDb(); const query:string = `UPDATE book_issues SET name = ?, hashed_issue_name = ?, last_update = FROM_UNIXTIME(?) WHERE issue_id = UUID_TO_BIN(?) AND author_id = UUID_TO_BIN(?) AND book_id = UUID_TO_BIN(?)`; const params:(string|number)[] = [name, hashedName, lastUpdate, issueId, userId, bookId]; const result:RunResult = db.run(query, params); return result.changes > 0; } catch (e:unknown) { if (e instanceof Error) { console.error(`DB Error: ${e.message}`); throw new Error(lang === 'fr' ? `Impossible de mettre à jour la problématique.` : `Unable to update issue.`); } else { console.error("An unknown error occurred."); throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred."); } } } }