Add BooksSyncContext, refine database schema, and enhance synchronization support

- Introduce `BooksSyncContext` for managing book synchronization states (server-only, local-only, to-sync, etc.).
- Remove `UserContext` and related dependencies.
- Refine localization strings (`en.json`) with sync-related updates (e.g., "toSyncFromServer", "toSyncToServer").
- Extend database schema with additional tables and fields for syncing books, chapters, and related entities.
- Add `last_update` fields and update corresponding repository methods to support synchronization logic.
- Enhance IPC handlers with stricter typing, data validation, and sync-aware operations.
This commit is contained in:
natreex
2025-12-07 14:36:03 -05:00
parent db2c88a42d
commit bb331b5c22
22 changed files with 2594 additions and 370 deletions

View File

@@ -115,7 +115,13 @@
"bookCard": {
"noCoverAlt": "No cover",
"initialsSeparator": ".",
"subtitlePlaceholder": "No subtitle"
"subtitlePlaceholder": "No subtitle",
"synced": "Synced",
"localOnly": "Local only",
"serverOnly": "Server only",
"toSyncFromServer": "Download from server",
"toSyncToServer": "Upload to server",
"sync": "Sync"
},
"scribeTopBar": {
"logoAlt": "Logo",

View File

@@ -115,7 +115,13 @@
"bookCard": {
"noCoverAlt": "Pas de couverture",
"initialsSeparator": ".",
"subtitlePlaceholder": "Aucun sous-titre"
"subtitlePlaceholder": "Aucun sous-titre",
"synced": "Synchronisé",
"localOnly": "Local uniquement",
"serverOnly": "Sur le serveur uniquement",
"toSyncFromServer": "Télécharger depuis le serveur",
"toSyncToServer": "Envoyer vers le serveur",
"sync": "Synchroniser"
},
"scribeTopBar": {
"logoAlt": "Logo",

View File

@@ -1,6 +1,61 @@
import {Author} from './User';
import {ActChapter, ChapterProps} from "@/lib/models/Chapter";
import {SelectBoxProps} from "@/shared/interface";
import {
BookActSummariesTable,
BookAIGuideLineTable,
BookChapterContentTable, BookChapterInfosTable,
BookChaptersTable, BookCharactersAttributesTable, BookCharactersTable, BookGuideLineTable, BookIncidentsTable,
BookIssuesTable, BookLocationTable, BookPlotPointsTable, BookWorldElementsTable, BookWorldTable,
EritBooksTable, LocationElementTable, LocationSubElementTable
} from "@/lib/models/BookTables";
import {
SyncedActSummary, SyncedAIGuideLine,
SyncedChapter,
SyncedCharacter, SyncedGuideLine,
SyncedIncident, SyncedIssue,
SyncedLocation,
SyncedPlotPoint,
SyncedWorld
} from "@/lib/models/SyncedBook";
export interface CompleteBook {
eritBooks: EritBooksTable[];
actSummaries: BookActSummariesTable[];
aiGuideLine: BookAIGuideLineTable[];
chapters: BookChaptersTable[];
chapterContents: BookChapterContentTable[];
chapterInfos: BookChapterInfosTable[];
characters: BookCharactersTable[];
characterAttributes: BookCharactersAttributesTable[];
guideLine: BookGuideLineTable[];
incidents: BookIncidentsTable[];
issues: BookIssuesTable[];
locations: BookLocationTable[];
plotPoints: BookPlotPointsTable[];
worlds: BookWorldTable[];
worldElements: BookWorldElementsTable[];
locationElements: LocationElementTable[];
locationSubElements: LocationSubElementTable[];
}
export interface SyncedBook {
id: string;
type: string;
title: string;
subTitle: string | null;
lastUpdate: number;
chapters: SyncedChapter[];
characters: SyncedCharacter[];
locations: SyncedLocation[];
worlds: SyncedWorld[];
incidents: SyncedIncident[];
plotPoints: SyncedPlotPoint[];
issues: SyncedIssue[];
actSummaries: SyncedActSummary[];
guideLine: SyncedGuideLine | null;
aiGuideLine: SyncedAIGuideLine | null;
}
export interface BookProps {
bookId: string;
@@ -30,6 +85,7 @@ export interface BookListProps {
wordCount?: number;
coverImage?: string;
bookMeta?: string;
itIsLocal?: boolean;
}
export interface GuideLine {

182
lib/models/BookTables.ts Normal file
View File

@@ -0,0 +1,182 @@
export interface EritBooksTable {
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 BookActSummariesTable {
act_sum_id: string;
book_id: string;
user_id: string;
act_index: number;
summary: string | null;
}
export interface BookAIGuideLineTable {
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;
}
export interface BookChaptersTable {
chapter_id: string;
book_id: string;
author_id: string;
title: string;
hashed_title: string | null;
words_count: number | null;
chapter_order: number | null;
}
export interface BookChapterContentTable {
content_id: string;
chapter_id: string;
author_id: string;
version: number;
content: string | null;
words_count: number;
time_on_it: number;
}
export interface BookChapterInfosTable {
chapter_info_id: string;
chapter_id: string;
act_id: number | null;
incident_id: string | null;
plot_point_id: string | null;
book_id: string;
author_id: string;
summary: string | null;
goal: string | null;
}
export interface BookCharactersTable {
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;
}
export interface BookCharactersAttributesTable {
attr_id: string;
character_id: string;
user_id: string;
attribute_name: string;
attribute_value: string;
}
export interface BookGuideLineTable {
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;
}
export interface BookIncidentsTable {
incident_id: string;
author_id: string;
book_id: string;
title: string;
hashed_title: string;
summary: string | null;
}
export interface BookIssuesTable {
issue_id: string;
author_id: string;
book_id: string;
name: string;
hashed_issue_name: string;
}
export interface BookLocationTable {
loc_id: string;
book_id: string;
user_id: string;
loc_name: string;
loc_original_name: string;
}
export interface BookPlotPointsTable {
plot_point_id: string;
title: string;
hashed_title: string;
summary: string | null;
linked_incident_id: string | null;
author_id: string;
book_id: string;
}
export interface BookWorldTable {
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;
}
export interface BookWorldElementsTable {
element_id: string;
world_id: string;
user_id: string;
element_type: number;
name: string;
original_name: string;
description: string | null;
}
export interface LocationElementTable {
element_id: string;
location: string;
user_id: string;
element_name: string;
original_name: string;
element_description: string | null;
}
export interface LocationSubElementTable {
sub_element_id: string;
element_id: string;
user_id: string;
sub_elem_name: string;
original_name: string;
sub_elem_description: string | null;
}

112
lib/models/SyncedBook.ts Normal file
View File

@@ -0,0 +1,112 @@
export interface SyncedBook {
id: string;
type: string;
title: string;
subTitle: string | null;
lastUpdate: number;
chapters: SyncedChapter[];
characters: SyncedCharacter[];
locations: SyncedLocation[];
worlds: SyncedWorld[];
incidents: SyncedIncident[];
plotPoints: SyncedPlotPoint[];
issues: SyncedIssue[];
actSummaries: SyncedActSummary[];
guideLine: SyncedGuideLine | null;
aiGuideLine: SyncedAIGuideLine | null;
}
export interface SyncedChapter {
id: string;
name: string;
lastUpdate: number;
contents: SyncedChapterContent[];
info: SyncedChapterInfo | null;
}
export interface SyncedChapterContent {
id: string;
lastUpdate: number;
}
export interface SyncedChapterInfo {
id: string;
lastUpdate: number;
}
export interface SyncedCharacter {
id: string;
name: string;
lastUpdate: number;
attributes: SyncedCharacterAttribute[];
}
export interface SyncedCharacterAttribute {
id: string;
name: string;
lastUpdate: number;
}
export interface SyncedLocation {
id: string;
name: string;
lastUpdate: number;
elements: SyncedLocationElement[];
}
export interface SyncedLocationElement {
id: string;
name: string;
lastUpdate: number;
subElements: SyncedLocationSubElement[];
}
export interface SyncedLocationSubElement {
id: string;
name: string;
lastUpdate: number;
}
export interface SyncedWorld {
id: string;
name: string;
lastUpdate: number;
elements: SyncedWorldElement[];
}
export interface SyncedWorldElement {
id: string;
name: string;
lastUpdate: number;
}
export interface SyncedIncident {
id: string;
name: string;
lastUpdate: number;
}
export interface SyncedPlotPoint {
id: string;
name: string;
lastUpdate: number;
}
export interface SyncedIssue {
id: string;
name: string;
lastUpdate: number;
}
export interface SyncedActSummary {
id: string;
lastUpdate: number;
}
export interface SyncedGuideLine {
lastUpdate: number;
}
export interface SyncedAIGuideLine {
lastUpdate: number;
}

View File

@@ -22,7 +22,6 @@ export interface UserProps {
openai: boolean,
anthropic: boolean,
},
books?: BookProps[];
guideTour?: GuideTour[];
subscription?: Subscription[];
writingLang: number;