- Implement `schema.ts` for SQLite schema creation, indexing, and sync metadata initialization. - Develop `encryption.ts` with AES-256-GCM encryption utilities for securing database data. - Add `database.service.ts` to manage CRUD operations with encryption support, user-specific databases, and schema initialization. - Integrate book, chapter, and character operations with encrypted content handling and sync preparation.
175 lines
4.3 KiB
TypeScript
175 lines
4.3 KiB
TypeScript
/**
|
|
* TypeScript interfaces (copied from lib/models for type safety)
|
|
*/
|
|
|
|
export interface ChapterContent {
|
|
version: number;
|
|
content: string;
|
|
wordsCount: number;
|
|
}
|
|
|
|
export interface ChapterProps {
|
|
chapterId: string;
|
|
chapterOrder: number;
|
|
title: string;
|
|
chapterContent: ChapterContent;
|
|
}
|
|
|
|
export interface ActChapter {
|
|
chapterInfoId: string;
|
|
chapterId: string;
|
|
title: string;
|
|
chapterOrder: number;
|
|
actId: number;
|
|
incidentId?: string;
|
|
plotPointId?: string;
|
|
summary: string;
|
|
goal: string;
|
|
}
|
|
|
|
/**
|
|
* Database row types (snake_case from SQLite)
|
|
*/
|
|
export interface DBChapter {
|
|
chapter_id: string;
|
|
book_id: string;
|
|
author_id: string;
|
|
title: string;
|
|
hashed_title?: string;
|
|
words_count?: number;
|
|
chapter_order?: number;
|
|
meta_chapter: string;
|
|
synced?: number;
|
|
}
|
|
|
|
export interface DBChapterContent {
|
|
content_id: string;
|
|
chapter_id: string;
|
|
author_id: string;
|
|
version: number;
|
|
content: string;
|
|
words_count: number;
|
|
meta_chapter_content: string;
|
|
time_on_it: number;
|
|
synced?: number;
|
|
}
|
|
|
|
export interface DBChapterInfo {
|
|
chapter_info_id: string;
|
|
chapter_id?: string;
|
|
act_id?: number;
|
|
incident_id?: string;
|
|
plot_point_id?: string;
|
|
book_id?: string;
|
|
author_id?: string;
|
|
summary: string;
|
|
goal: string;
|
|
meta_chapter_info: string;
|
|
synced?: number;
|
|
}
|
|
|
|
/**
|
|
* MAPPERS: DB → TypeScript Interfaces
|
|
*/
|
|
|
|
export function dbToChapter(dbChapter: DBChapter, dbContent?: DBChapterContent): ChapterProps {
|
|
const chapterContent: ChapterContent = dbContent ? {
|
|
version: dbContent.version,
|
|
content: dbContent.content,
|
|
wordsCount: dbContent.words_count
|
|
} : {
|
|
version: 2,
|
|
content: '',
|
|
wordsCount: 0
|
|
};
|
|
|
|
return {
|
|
chapterId: dbChapter.chapter_id,
|
|
chapterOrder: dbChapter.chapter_order || 0,
|
|
title: dbChapter.title,
|
|
chapterContent
|
|
};
|
|
}
|
|
|
|
export function dbToChapterContent(dbContent: DBChapterContent): ChapterContent {
|
|
return {
|
|
version: dbContent.version,
|
|
content: dbContent.content,
|
|
wordsCount: dbContent.words_count
|
|
};
|
|
}
|
|
|
|
export function dbToActChapter(dbChapter: DBChapter, dbInfo: DBChapterInfo): ActChapter {
|
|
return {
|
|
chapterInfoId: dbInfo.chapter_info_id,
|
|
chapterId: dbChapter.chapter_id,
|
|
title: dbChapter.title,
|
|
chapterOrder: dbChapter.chapter_order || 0,
|
|
actId: dbInfo.act_id || 0,
|
|
incidentId: dbInfo.incident_id,
|
|
plotPointId: dbInfo.plot_point_id,
|
|
summary: dbInfo.summary,
|
|
goal: dbInfo.goal
|
|
};
|
|
}
|
|
|
|
/**
|
|
* MAPPERS: TypeScript Interfaces → DB
|
|
*/
|
|
|
|
export function chapterToDb(chapter: ChapterProps, bookId: string, authorId: string, synced: number = 0): DBChapter {
|
|
return {
|
|
chapter_id: chapter.chapterId,
|
|
book_id: bookId,
|
|
author_id: authorId,
|
|
title: chapter.title,
|
|
hashed_title: '',
|
|
words_count: chapter.chapterContent.wordsCount,
|
|
chapter_order: chapter.chapterOrder,
|
|
meta_chapter: '',
|
|
synced
|
|
};
|
|
}
|
|
|
|
export function chapterContentToDb(
|
|
content: ChapterContent,
|
|
contentId: string,
|
|
chapterId: string,
|
|
authorId: string,
|
|
timeOnIt: number = 0,
|
|
synced: number = 0
|
|
): DBChapterContent {
|
|
return {
|
|
content_id: contentId,
|
|
chapter_id: chapterId,
|
|
author_id: authorId,
|
|
version: content.version,
|
|
content: content.content,
|
|
words_count: content.wordsCount,
|
|
meta_chapter_content: '',
|
|
time_on_it: timeOnIt,
|
|
synced
|
|
};
|
|
}
|
|
|
|
export function actChapterToDbInfo(
|
|
actChapter: ActChapter,
|
|
bookId: string,
|
|
authorId: string,
|
|
synced: number = 0
|
|
): DBChapterInfo {
|
|
return {
|
|
chapter_info_id: actChapter.chapterInfoId,
|
|
chapter_id: actChapter.chapterId,
|
|
act_id: actChapter.actId,
|
|
incident_id: actChapter.incidentId,
|
|
plot_point_id: actChapter.plotPointId,
|
|
book_id: bookId,
|
|
author_id: authorId,
|
|
summary: actChapter.summary,
|
|
goal: actChapter.goal,
|
|
meta_chapter_info: '',
|
|
synced
|
|
};
|
|
}
|