Add support for syncing tool settings with lastUpdate and improve consistency

- Introduced `lastUpdate` field in `book_tools` for tracking changes.
- Refactored tool enablement logic in `CharacterComponent`, `WorldSetting`, and `LocationComponent` for consistency.
- Updated database schema and migration scripts for `book_tools` table.
- Enhanced synchronization workflows to support new `lastUpdate` logic.
- Adjusted related models, repositories, and IPC handlers for streamlined management.
- Improved type safety and robustness in tool-related methods with additional checks.
This commit is contained in:
natreex
2026-01-15 18:35:48 -05:00
parent ac968b7764
commit 2e6b30c632
12 changed files with 252 additions and 226 deletions

View File

@@ -52,12 +52,11 @@ export interface BookToolsTable extends Record<string, SQLiteValue> {
characters_enabled: number;
worlds_enabled: number;
locations_enabled: number;
last_update: number;
}
export interface BookToolsSettings {
characters: boolean;
worlds: boolean;
locations: boolean;
export interface SyncedBookToolsResult extends Record<string, SQLiteValue> {
last_update: number;
}
export default class BookRepo {
@@ -380,7 +379,7 @@ export default class BookRepo {
static fetchBookTools(userId: string, bookId: string, lang: 'fr' | 'en'): BookToolsTable | null {
try {
const db: Database = System.getDb();
const query: string = 'SELECT book_id, user_id, characters_enabled, worlds_enabled, locations_enabled FROM book_tools WHERE user_id=? AND book_id=?';
const query: string = 'SELECT book_id, user_id, characters_enabled, worlds_enabled, locations_enabled, last_update FROM book_tools WHERE user_id=? AND book_id=?';
const params: SQLiteValue[] = [userId, bookId];
const result = db.get(query, params) as BookToolsTable | undefined;
return result ?? null;
@@ -393,20 +392,20 @@ export default class BookRepo {
}
}
static updateBookToolSetting(userId: string, bookId: string, toolName: 'characters_enabled' | 'worlds_enabled' | 'locations_enabled', enabled: boolean, lang: 'fr' | 'en'): boolean {
static updateBookToolSetting(userId: string, bookId: string, toolName: 'characters_enabled' | 'worlds_enabled' | 'locations_enabled', enabled: boolean, lastUpdate: number, lang: 'fr' | 'en'): boolean {
const enabledValue: number = enabled ? 1 : 0;
try {
const db: Database = System.getDb();
const updateQuery: string = `UPDATE book_tools SET ${toolName}=? WHERE user_id=? AND book_id=?`;
const updateResult: RunResult = db.run(updateQuery, [enabledValue, userId, bookId]);
const updateQuery: string = `UPDATE book_tools SET ${toolName}=?, last_update=? WHERE user_id=? AND book_id=?`;
const updateResult: RunResult = db.run(updateQuery, [enabledValue, lastUpdate, userId, bookId]);
if (updateResult.changes > 0) {
return true;
}
const charactersValue: number = toolName === 'characters_enabled' ? enabledValue : 0;
const worldsValue: number = toolName === 'worlds_enabled' ? enabledValue : 0;
const locationsValue: number = toolName === 'locations_enabled' ? enabledValue : 0;
const insertQuery: string = 'INSERT INTO book_tools (book_id, user_id, characters_enabled, worlds_enabled, locations_enabled) VALUES (?, ?, ?, ?, ?)';
const insertResult: RunResult = db.run(insertQuery, [bookId, userId, charactersValue, worldsValue, locationsValue]);
const insertQuery: string = 'INSERT INTO book_tools (book_id, user_id, characters_enabled, worlds_enabled, locations_enabled, last_update) VALUES (?, ?, ?, ?, ?, ?)';
const insertResult: RunResult = db.run(insertQuery, [bookId, userId, charactersValue, worldsValue, locationsValue, lastUpdate]);
return insertResult.changes > 0;
} catch (error: unknown) {
if (error instanceof Error) {
@@ -418,26 +417,35 @@ export default class BookRepo {
}
/**
* Inserts book tools settings during sync.
* @param bookId - The book identifier
* @param userId - The user identifier
* @param charactersEnabled - Whether characters tool is enabled
* @param worldsEnabled - Whether worlds tool is enabled
* @param locationsEnabled - Whether locations tool is enabled
* @param lang - The language for error messages
* @returns true if the insertion was successful
* Upserts book tools settings during sync.
* Inserts if not exists, updates if exists.
*/
static insertSyncBookTools(bookId: string, userId: string, charactersEnabled: number, worldsEnabled: number, locationsEnabled: number, lang: 'fr' | 'en'): boolean {
static insertSyncBookTools(bookId: string, userId: string, charactersEnabled: number, worldsEnabled: number, locationsEnabled: number, lastUpdate: number, lang: 'fr' | 'en'): boolean {
try {
const db: Database = System.getDb();
const query: string = 'INSERT INTO book_tools (book_id, user_id, characters_enabled, worlds_enabled, locations_enabled) VALUES (?, ?, ?, ?, ?)';
const params: SQLiteValue[] = [bookId, userId, charactersEnabled, worldsEnabled, locationsEnabled];
const insertResult: RunResult = db.run(query, params);
return insertResult.changes > 0;
const query: string = 'INSERT INTO book_tools (book_id, user_id, characters_enabled, worlds_enabled, locations_enabled, last_update) VALUES (?, ?, ?, ?, ?, ?) ON CONFLICT (book_id, user_id) DO UPDATE SET characters_enabled = excluded.characters_enabled, worlds_enabled = excluded.worlds_enabled, locations_enabled = excluded.locations_enabled, last_update = excluded.last_update';
const params: SQLiteValue[] = [bookId, userId, charactersEnabled, worldsEnabled, locationsEnabled, lastUpdate];
db.run(query, params);
return true;
} catch (error: unknown) {
if (error instanceof Error) {
console.error(`[BookRepository] DB Error: ${error.message}`);
}
return false;
}
}
static fetchSyncedBookTools(userId: string, bookId: string, lang: 'fr' | 'en'): SyncedBookToolsResult | null {
try {
const db: Database = System.getDb();
const query: string = 'SELECT last_update FROM book_tools WHERE user_id = ? AND book_id = ?';
const params: SQLiteValue[] = [userId, bookId];
const result = db.get(query, params) as SyncedBookToolsResult | undefined;
return result ?? null;
} catch (error: unknown) {
if (error instanceof Error) {
console.error(`DB Error: ${error.message}`);
throw new Error(lang === 'fr' ? "Impossible d'insérer les paramètres des outils." : 'Unable to insert tools settings.');
throw new Error(lang === 'fr' ? 'Impossible de récupérer les paramètres des outils.' : 'Unable to fetch tools settings.');
}
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
}