Files
ERitors-Scribe-Desktop/electron/database/models/Issue.ts
natreex 209dc6f85a Remove CharacterComponent and CharacterDetail components
- Deleted `CharacterComponent` and `CharacterDetail` files from the project.
- Refactored related logic to improve code maintainability and reduce redundancy.
2026-02-05 14:12:08 -05:00

108 lines
3.9 KiB
TypeScript

import { getUserEncryptionKey } from "../keyManager.js";
import System from "../System.js";
import IssueRepository, { IssueQuery } from "../repositories/issue.repository.js";
import RemovedItem from "./RemovedItem.js";
/**
* Represents a synced issue with its metadata.
*/
export interface SyncedIssue {
id: string;
name: string;
lastUpdate: number;
}
/**
* Represents the basic properties of an issue.
*/
export interface IssueProps {
id: string;
name: string;
}
/**
* Model class for managing issues associated with books.
* Provides methods for CRUD operations on issues with encryption support.
*/
export default class Issue {
/**
* Retrieves all issues associated with a specific book.
* Decrypts issue names using the user's encryption key.
*
* @param userId - The unique identifier of the user.
* @param bookId - The unique identifier of the book.
* @param lang - The language for error messages ('fr' or 'en'). Defaults to 'fr'.
* @returns A promise resolving to an array of decrypted issues.
*/
public static async getIssuesFromBook(
userId: string,
bookId: string,
lang: 'fr' | 'en' = 'fr'
): Promise<IssueProps[]> {
const issueQueryResults: IssueQuery[] = IssueRepository.fetchIssuesFromBook(userId, bookId, lang);
const userEncryptionKey: string = getUserEncryptionKey(userId);
const decryptedIssues: IssueProps[] = [];
if (issueQueryResults.length > 0) {
for (const issueRecord of issueQueryResults) {
decryptedIssues.push({
id: issueRecord.issue_id,
name: System.decryptDataWithUserKey(issueRecord.name, userEncryptionKey)
});
}
}
return decryptedIssues;
}
/**
* Creates a new issue for a book.
* Encrypts and hashes the issue name before storage.
*
* @param userId - The unique identifier of the user.
* @param bookId - The unique identifier of the book.
* @param name - The plain text name of the issue.
* @param lang - The language for error messages ('fr' or 'en'). Defaults to 'fr'.
* @param existingIssueId - Optional existing issue ID for syncing purposes.
* @returns The unique identifier of the created issue.
*/
public static addNewIssue(
userId: string,
bookId: string,
name: string,
lang: 'fr' | 'en' = 'fr',
existingIssueId?: string
): string {
const userEncryptionKey: string = getUserEncryptionKey(userId);
const encryptedName: string = System.encryptDataWithUserKey(name, userEncryptionKey);
const hashedName: string = System.hashElement(name);
const issueId: string = existingIssueId || System.createUniqueId();
return IssueRepository.insertNewIssue(issueId, userId, bookId, encryptedName, hashedName, lang);
}
/**
* Removes an issue from the database.
*
* @param userId - The unique identifier of the user.
* @param bookId - The unique identifier of the book.
* @param issueId - The unique identifier of the issue to remove.
* @param deletedAt - The timestamp of deletion.
* @param lang - The language for error messages ('fr' or 'en'). Defaults to 'fr'.
* @returns True if the issue was successfully removed, false otherwise.
*/
public static removeIssue(
userId: string,
bookId: string,
issueId: string,
deletedAt: number = System.timeStampInSeconds(),
lang: 'fr' | 'en' = 'fr'
): boolean {
const deleted: boolean = IssueRepository.deleteIssue(userId, issueId, lang);
if (deleted) {
RemovedItem.deleteTracker(userId, bookId, 'book_issues', issueId, deletedAt, lang);
}
return deleted;
}
}