Integrate session management, multilingual IPC handlers, and Book database operations
- Add `LocalSystem` with handlers for session retrieval (`userId`, `lang`) and error handling. - Extend IPC handlers to support multilingual operations (`fr`, `en`) and session data injection
This commit is contained in:
507
electron/ipc/book.ipc.ts
Normal file
507
electron/ipc/book.ipc.ts
Normal file
@@ -0,0 +1,507 @@
|
||||
import { ipcMain } from 'electron';
|
||||
import {
|
||||
createDbHandler2,
|
||||
// Auto-handlers: automatically inject userId AND lang
|
||||
createAutoHandler,
|
||||
createAutoHandler1
|
||||
} from '../database/LocalSystem.js';
|
||||
import Book from '../database/models/Book.js';
|
||||
import type { BookProps, GuideLine, GuideLineAI, Act, Issue, WorldProps } from '../database/models/Book.js';
|
||||
|
||||
ipcMain.handle(
|
||||
'db:book:getAll',
|
||||
createAutoHandler<BookProps[]>(
|
||||
async function(userId: string, lang: 'fr' | 'en') {
|
||||
return await Book.getBooks(userId, lang);
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
ipcMain.handle(
|
||||
'db:book:get',
|
||||
createAutoHandler1<string, BookProps>(
|
||||
async function(userId: string, bookId: string, lang: 'fr' | 'en') {
|
||||
return await Book.getBook(bookId, userId, lang);
|
||||
}
|
||||
)
|
||||
);
|
||||
// Frontend call: await window.electron.invoke('db:book:get', bookId);
|
||||
|
||||
// ============================================================
|
||||
// 3. POST /book/basic-information
|
||||
// ============================================================
|
||||
interface UpdateBookBasicData {
|
||||
title: string;
|
||||
subTitle: string;
|
||||
summary: string;
|
||||
publicationDate: string;
|
||||
wordCount: number;
|
||||
bookId: string;
|
||||
}
|
||||
|
||||
ipcMain.handle(
|
||||
'db:book:updateBasicInformation',
|
||||
createAutoHandler1<UpdateBookBasicData, boolean>(
|
||||
function(userId: string, data: UpdateBookBasicData, lang: 'fr' | 'en') {
|
||||
return Book.updateBookBasicInformation(
|
||||
userId,
|
||||
data.title,
|
||||
data.subTitle,
|
||||
data.summary,
|
||||
data.publicationDate,
|
||||
data.wordCount,
|
||||
data.bookId,
|
||||
lang
|
||||
);
|
||||
}
|
||||
)
|
||||
);
|
||||
// Frontend call: await window.electron.invoke('db:book:updateBasicInformation', data);
|
||||
|
||||
// ============================================================
|
||||
// 4. GET /book/guide-line
|
||||
// ============================================================
|
||||
ipcMain.handle(
|
||||
'db:book:guideline:get',
|
||||
createAutoHandler1<string, GuideLine | null>(
|
||||
async function(userId: string, bookId: string, lang: 'fr' | 'en') {
|
||||
return await Book.getGuideLine(userId, bookId, lang);
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
// ============================================================
|
||||
// 5. POST /book/guide-line
|
||||
// ============================================================
|
||||
interface UpdateGuideLineData {
|
||||
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;
|
||||
}
|
||||
|
||||
ipcMain.handle(
|
||||
'db:book:guideline:update',
|
||||
createAutoHandler1<UpdateGuideLineData, boolean>(
|
||||
async function(userId: string, data: UpdateGuideLineData, lang: 'fr' | 'en') {
|
||||
return await Book.updateGuideLine(
|
||||
userId,
|
||||
data.bookId,
|
||||
data.tone,
|
||||
data.atmosphere,
|
||||
data.writingStyle,
|
||||
data.themes,
|
||||
data.symbolism,
|
||||
data.motifs,
|
||||
data.narrativeVoice,
|
||||
data.pacing,
|
||||
data.keyMessages,
|
||||
data.intendedAudience,
|
||||
lang
|
||||
);
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
// ============================================================
|
||||
// 6. GET /book/story
|
||||
// ============================================================
|
||||
interface StoryData {
|
||||
acts: Act[];
|
||||
issues: Issue[];
|
||||
}
|
||||
|
||||
ipcMain.handle(
|
||||
'db:book:story:get',
|
||||
createDbHandler2<string, 'fr' | 'en', StoryData>(
|
||||
async function(userId: string, bookId: string, lang: 'fr' | 'en') {
|
||||
const acts = await Book.getActsData(userId, bookId, lang);
|
||||
const issues = await Book.getIssuesFromBook(userId, bookId, lang);
|
||||
return {
|
||||
acts,
|
||||
issues
|
||||
};
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
// ============================================================
|
||||
// 7. POST /book/story
|
||||
// TODO: Implement updateStory in Book.ts
|
||||
// ============================================================
|
||||
// interface StoryUpdateData {
|
||||
// bookId: string;
|
||||
// acts: Act[];
|
||||
// mainChapters: ChapterProps[];
|
||||
// }
|
||||
//
|
||||
// ipcMain.handle(
|
||||
// 'db:book:story:update',
|
||||
// createDbHandler2<StoryUpdateData, 'fr' | 'en', boolean>(
|
||||
// function(userId: string, data: StoryUpdateData, lang: 'fr' | 'en') {
|
||||
// return Book.updateStory(userId, data.bookId, data.acts, data.mainChapters, lang);
|
||||
// }
|
||||
// )
|
||||
// );
|
||||
|
||||
// ============================================================
|
||||
// 8. POST /book/add
|
||||
// ============================================================
|
||||
interface CreateBookData {
|
||||
title: string;
|
||||
subTitle: string | null;
|
||||
summary: string | null;
|
||||
type: string;
|
||||
serieId: number | null;
|
||||
desiredReleaseDate: string | null;
|
||||
desiredWordCount: number | null;
|
||||
}
|
||||
|
||||
ipcMain.handle(
|
||||
'db:book:create',
|
||||
createDbHandler2<CreateBookData, 'fr' | 'en', string>(
|
||||
function(userId: string, data: CreateBookData, lang: 'fr' | 'en') {
|
||||
return Book.addBook(
|
||||
null,
|
||||
userId,
|
||||
data.title,
|
||||
data.subTitle || '',
|
||||
data.summary || '',
|
||||
data.type,
|
||||
data.serieId || 0,
|
||||
data.desiredReleaseDate || '',
|
||||
data.desiredWordCount || 0,
|
||||
lang
|
||||
);
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
// ============================================================
|
||||
// 9. POST /book/cover
|
||||
// ============================================================
|
||||
// TODO: Implement updateBookCover in Book.ts
|
||||
// ipcMain.handle(
|
||||
// 'db:book:cover:update',
|
||||
// createDbHandler3<string, string, 'fr' | 'en', boolean>(
|
||||
// function(userId: string, bookId: string, coverImageName: string, lang: 'fr' | 'en') {
|
||||
// return Book.updateBookCover(userId, bookId, coverImageName, lang);
|
||||
// }
|
||||
// )
|
||||
// );
|
||||
|
||||
// ============================================================
|
||||
// 10. POST /book/incident/new
|
||||
// ============================================================
|
||||
interface AddIncidentData {
|
||||
bookId: string;
|
||||
name: string;
|
||||
}
|
||||
|
||||
ipcMain.handle(
|
||||
'db:book:incident:add',
|
||||
createDbHandler2<AddIncidentData, 'fr' | 'en', string>(
|
||||
function(userId: string, data: AddIncidentData, lang: 'fr' | 'en') {
|
||||
return Book.addNewIncident(userId, data.bookId, data.name, lang);
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
// ============================================================
|
||||
// 11. DELETE /book/incident/remove
|
||||
// ============================================================
|
||||
interface RemoveIncidentData {
|
||||
bookId: string;
|
||||
incidentId: string;
|
||||
}
|
||||
|
||||
ipcMain.handle(
|
||||
'db:book:incident:remove',
|
||||
createDbHandler2<RemoveIncidentData, 'fr' | 'en', boolean>(
|
||||
function(userId: string, data: RemoveIncidentData, lang: 'fr' | 'en') {
|
||||
return Book.removeIncident(userId, data.bookId, data.incidentId, lang);
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
// ============================================================
|
||||
// 12. POST /book/plot/new
|
||||
// ============================================================
|
||||
interface AddPlotPointData {
|
||||
bookId: string;
|
||||
name: string;
|
||||
incidentId: string;
|
||||
}
|
||||
|
||||
ipcMain.handle(
|
||||
'db:book:plot:add',
|
||||
createDbHandler2<AddPlotPointData, 'fr' | 'en', string>(
|
||||
function(userId: string, data: AddPlotPointData, lang: 'fr' | 'en') {
|
||||
return Book.addNewPlotPoint(
|
||||
userId,
|
||||
data.bookId,
|
||||
data.incidentId,
|
||||
data.name,
|
||||
lang
|
||||
);
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
// ============================================================
|
||||
// 13. DELETE /book/plot/remove
|
||||
// ============================================================
|
||||
ipcMain.handle(
|
||||
'db:book:plot:remove',
|
||||
createDbHandler2<string, 'fr' | 'en', boolean>(
|
||||
function(userId: string, plotPointId: string, lang: 'fr' | 'en') {
|
||||
return Book.removePlotPoint(userId, plotPointId, lang);
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
// ============================================================
|
||||
// 14. POST /book/issue/add
|
||||
// ============================================================
|
||||
interface AddIssueData {
|
||||
bookId: string;
|
||||
name: string;
|
||||
}
|
||||
|
||||
ipcMain.handle(
|
||||
'db:book:issue:add',
|
||||
createDbHandler2<AddIssueData, 'fr' | 'en', string>(
|
||||
function(userId: string, data: AddIssueData, lang: 'fr' | 'en') {
|
||||
return Book.addNewIssue(userId, data.bookId, data.name, lang);
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
// ============================================================
|
||||
// 15. DELETE /book/issue/remove
|
||||
// ============================================================
|
||||
ipcMain.handle(
|
||||
'db:book:issue:remove',
|
||||
createDbHandler2<string, 'fr' | 'en', boolean>(
|
||||
function(userId: string, issueId: string, lang: 'fr' | 'en') {
|
||||
return Book.removeIssue(userId, issueId, lang);
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
// ============================================================
|
||||
// 16. GET /book/worlds
|
||||
// ============================================================
|
||||
ipcMain.handle(
|
||||
'db:book:worlds:get',
|
||||
createDbHandler2<string, 'fr' | 'en', WorldProps[]>(
|
||||
function(userId: string, bookId: string, lang: 'fr' | 'en') {
|
||||
return Book.getWorlds(userId, bookId, lang);
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
// ============================================================
|
||||
// 17. POST /book/world/add
|
||||
// ============================================================
|
||||
interface AddWorldData {
|
||||
bookId: string;
|
||||
worldName: string;
|
||||
}
|
||||
|
||||
ipcMain.handle(
|
||||
'db:book:world:add',
|
||||
createDbHandler2<AddWorldData, 'fr' | 'en', string>(
|
||||
function(userId: string, data: AddWorldData, lang: 'fr' | 'en') {
|
||||
return Book.addNewWorld(userId, data.bookId, data.worldName, lang);
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
// ============================================================
|
||||
// 18. POST /book/world/element/add
|
||||
// ============================================================
|
||||
interface AddWorldElementData {
|
||||
worldId: string;
|
||||
elementName: string;
|
||||
elementType: number;
|
||||
}
|
||||
|
||||
ipcMain.handle(
|
||||
'db:book:world:element:add',
|
||||
createDbHandler2<AddWorldElementData, 'fr' | 'en', string>(
|
||||
function(userId: string, data: AddWorldElementData, lang: 'fr' | 'en') {
|
||||
return Book.addNewElementToWorld(
|
||||
userId,
|
||||
data.worldId,
|
||||
data.elementName,
|
||||
data.elementType.toString(),
|
||||
lang
|
||||
);
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
// ============================================================
|
||||
// 19. DELETE /book/world/element/delete
|
||||
// ============================================================
|
||||
ipcMain.handle(
|
||||
'db:book:world:element:remove',
|
||||
createDbHandler2<string, 'fr' | 'en', boolean>(
|
||||
function(userId: string, elementId: string, lang: 'fr' | 'en') {
|
||||
return Book.removeElementFromWorld(userId, elementId, lang);
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
// ============================================================
|
||||
// 20. PUT /book/world/update
|
||||
// TODO: Implement updateWorld in Book.ts
|
||||
// ============================================================
|
||||
// ipcMain.handle(
|
||||
// 'db:book:world:update',
|
||||
// createDbHandler2<WorldProps, 'fr' | 'en', boolean>(
|
||||
// function(userId: string, world: WorldProps, lang: 'fr' | 'en') {
|
||||
// return Book.updateWorld(userId, world, lang);
|
||||
// }
|
||||
// )
|
||||
// );
|
||||
|
||||
// ============================================================
|
||||
// 21. DELETE /book/cover/delete
|
||||
// TODO: Implement deleteCoverPicture in Book.ts
|
||||
// ============================================================
|
||||
// ipcMain.handle(
|
||||
// 'db:book:cover:delete',
|
||||
// createDbHandler2<string, 'fr' | 'en', boolean>(
|
||||
// function(userId: string, bookId: string, lang: 'fr' | 'en') {
|
||||
// return Book.deleteCoverPicture(userId, bookId, lang);
|
||||
// }
|
||||
// )
|
||||
// );
|
||||
|
||||
// ============================================================
|
||||
// 22. DELETE /book/delete
|
||||
// ============================================================
|
||||
ipcMain.handle(
|
||||
'db:book:delete',
|
||||
createDbHandler2<string, 'fr' | 'en', boolean>(
|
||||
function(userId: string, bookId: string, lang: 'fr' | 'en') {
|
||||
return Book.removeBook(userId, bookId, lang);
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
// ============================================================
|
||||
// 23. GET /book/ai/guideline
|
||||
// ============================================================
|
||||
ipcMain.handle(
|
||||
'db:book:guideline:ai:get',
|
||||
createDbHandler2<string, 'fr' | 'en', GuideLineAI>(
|
||||
function(userId: string, bookId: string, lang: 'fr' | 'en') {
|
||||
return Book.getGuideLineAI(bookId, userId, lang);
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
// ============================================================
|
||||
// 24. POST /book/ai/guideline (set)
|
||||
// ============================================================
|
||||
interface SetAIGuideLineData {
|
||||
bookId: string;
|
||||
narrativeType: number;
|
||||
dialogueType: number;
|
||||
globalResume: string;
|
||||
atmosphere: string;
|
||||
verbeTense: number;
|
||||
langue: number;
|
||||
themes: string;
|
||||
}
|
||||
|
||||
ipcMain.handle(
|
||||
'db:book:guideline:ai:set',
|
||||
createDbHandler2<SetAIGuideLineData, 'fr' | 'en', boolean>(
|
||||
function(userId: string, data: SetAIGuideLineData, lang: 'fr' | 'en') {
|
||||
return Book.setAIGuideLine(
|
||||
data.bookId,
|
||||
userId,
|
||||
data.narrativeType,
|
||||
data.dialogueType,
|
||||
data.globalResume,
|
||||
data.atmosphere,
|
||||
data.verbeTense,
|
||||
data.langue,
|
||||
data.themes,
|
||||
lang
|
||||
);
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
// ============================================================
|
||||
// 25. GET /book/transform/epub
|
||||
// ============================================================
|
||||
// TODO: Implement transformToEpub in Book.ts
|
||||
// ipcMain.handle(
|
||||
// 'db:book:export:epub',
|
||||
// createDbHandler2<string, 'fr' | 'en', ExportData>(
|
||||
// function(userId: string, bookId: string, lang: 'fr' | 'en') {
|
||||
// return Book.transformToEpub(userId, bookId, lang);
|
||||
// }
|
||||
// )
|
||||
// );
|
||||
|
||||
// ============================================================
|
||||
// 26. GET /book/transform/pdf
|
||||
// ============================================================
|
||||
// TODO: Implement transformToPDF in Book.ts
|
||||
// ipcMain.handle(
|
||||
// 'db:book:export:pdf',
|
||||
// createDbHandler2<string, 'fr' | 'en', ExportData>(
|
||||
// function(userId: string, bookId: string, lang: 'fr' | 'en') {
|
||||
// return Book.transformToPDF(userId, bookId, lang);
|
||||
// }
|
||||
// )
|
||||
// );
|
||||
|
||||
// ============================================================
|
||||
// 27. GET /book/transform/docx
|
||||
// ============================================================
|
||||
// TODO: Implement transformToDOCX in Book.ts
|
||||
// ipcMain.handle(
|
||||
// 'db:book:export:docx',
|
||||
// createDbHandler2<string, 'fr' | 'en', ExportData>(
|
||||
// function(userId: string, bookId: string, lang: 'fr' | 'en') {
|
||||
// return Book.transformToDOCX(userId, bookId, lang);
|
||||
// }
|
||||
// )
|
||||
// );
|
||||
|
||||
// ============================================================
|
||||
// 28. GET /book/tags
|
||||
// TODO: Implement getTagsFromBook in Book.ts
|
||||
// ============================================================
|
||||
// interface BookTags {
|
||||
// characters: Tag[];
|
||||
// locations: Tag[];
|
||||
// objects: Tag[];
|
||||
// worldElements: Tag[];
|
||||
// }
|
||||
//
|
||||
// ipcMain.handle(
|
||||
// 'db:book:tags:get',
|
||||
// createDbHandler2<string, 'fr' | 'en', BookTags>(
|
||||
// function(userId: string, bookId: string, lang: 'fr' | 'en') {
|
||||
// return Book.getTagsFromBook(userId, bookId, lang);
|
||||
// }
|
||||
// )
|
||||
// );
|
||||
|
||||
console.log('[IPC] Book handlers registered');
|
||||
Reference in New Issue
Block a user