Remove CharacterComponent and CharacterDetail components

- Deleted `CharacterComponent` and `CharacterDetail` files from the project.
- Refactored related logic to improve code maintainability and reduce redundancy.
This commit is contained in:
natreex
2026-02-05 14:12:08 -05:00
parent cec5830360
commit 209dc6f85a
133 changed files with 17673 additions and 3110 deletions

View File

@@ -57,6 +57,40 @@ import { SyncedPlotPoint } from "./PlotPoint.js";
import { SyncedIssue } from "./Issue.js";
import { SyncedActSummary } from "./Act.js";
import { SyncedAIGuideLine, SyncedGuideLine } from "./GuideLine.js";
import {
SyncedSeries,
SyncedSeriesBook,
SyncedSeriesCharacter,
SyncedSeriesCharacterAttribute,
SyncedSeriesWorld,
SyncedSeriesWorldElement,
SyncedSeriesLocation,
SyncedSeriesLocationElement,
SyncedSeriesLocationSubElement,
SyncedSeriesSpell,
SyncedSeriesSpellTag
} from "./Book.js";
import SeriesRepo, {
SyncedSeriesResult,
SyncedSeriesBookResult
} from "../repositories/series.repo.js";
import SeriesCharacterRepo, {
SyncedSeriesCharacterResult,
SyncedSeriesCharacterAttributeResult
} from "../repositories/series-character.repo.js";
import SeriesWorldRepo, {
SyncedSeriesWorldResult,
SyncedSeriesWorldElementResult
} from "../repositories/series-world.repo.js";
import SeriesLocationRepo, {
SyncedSeriesLocationResult,
SyncedSeriesLocationElementResult,
SyncedSeriesLocationSubElementResult
} from "../repositories/series-location.repo.js";
import SeriesSpellRepo, {
SyncedSeriesSpellResult,
SyncedSeriesSpellTagResult
} from "../repositories/series-spell.repo.js";
/**
* Handles synchronization operations between local database and remote server.
@@ -375,9 +409,9 @@ export default class Sync {
decryptedSpells.push({
...spellRecord,
name: System.decryptDataWithUserKey(spellRecord.name, userEncryptionKey),
description: System.decryptDataWithUserKey(spellRecord.description, userEncryptionKey),
appearance: System.decryptDataWithUserKey(spellRecord.appearance, userEncryptionKey),
tags: System.decryptDataWithUserKey(spellRecord.tags, userEncryptionKey),
description: spellRecord.description ? System.decryptDataWithUserKey(spellRecord.description, userEncryptionKey) : null,
appearance: spellRecord.appearance ? System.decryptDataWithUserKey(spellRecord.appearance, userEncryptionKey) : null,
tags: spellRecord.tags ? System.decryptDataWithUserKey(spellRecord.tags, userEncryptionKey) : null,
power_level: spellRecord.power_level ? System.decryptDataWithUserKey(spellRecord.power_level, userEncryptionKey) : null,
components: spellRecord.components ? System.decryptDataWithUserKey(spellRecord.components, userEncryptionKey) : null,
limitations: spellRecord.limitations ? System.decryptDataWithUserKey(spellRecord.limitations, userEncryptionKey) : null,
@@ -823,9 +857,9 @@ export default class Sync {
for (const serverSpell of completeBook.spells) {
const spellExists: boolean = SpellRepo.isSpellExist(userId, serverSpell.spell_id, lang);
const encryptedName: string = System.encryptDataWithUserKey(serverSpell.name, userEncryptionKey);
const encryptedDescription: string = System.encryptDataWithUserKey(serverSpell.description, userEncryptionKey);
const encryptedAppearance: string = System.encryptDataWithUserKey(serverSpell.appearance, userEncryptionKey);
const encryptedTags: string = System.encryptDataWithUserKey(serverSpell.tags, userEncryptionKey);
const encryptedDescription: string | null = serverSpell.description ? System.encryptDataWithUserKey(serverSpell.description, userEncryptionKey) : null;
const encryptedAppearance: string | null = serverSpell.appearance ? System.encryptDataWithUserKey(serverSpell.appearance, userEncryptionKey) : null;
const encryptedTags: string | null = serverSpell.tags ? System.encryptDataWithUserKey(serverSpell.tags, userEncryptionKey) : null;
const encryptedPowerLevel: string | null = serverSpell.power_level ? System.encryptDataWithUserKey(serverSpell.power_level, userEncryptionKey) : null;
const encryptedComponents: string | null = serverSpell.components ? System.encryptDataWithUserKey(serverSpell.components, userEncryptionKey) : null;
const encryptedLimitations: string | null = serverSpell.limitations ? System.encryptDataWithUserKey(serverSpell.limitations, userEncryptionKey) : null;
@@ -1113,4 +1147,131 @@ export default class Sync {
};
});
}
// ===== SERIES SYNC METHODS =====
/**
* Retrieves all series for the current user with lightweight structure for sync comparison.
* Returns synced series with nested characters, worlds, locations, spells, and spell tags.
* All encrypted fields are decrypted before return.
* @param userId - The unique identifier of the user
* @param lang - The language for error messages ('fr' or 'en')
* @returns An array of synced series with all nested entities
*/
static getSyncedSeries(userId: string, lang: 'fr' | 'en'): SyncedSeries[] {
const userEncryptionKey: string = getUserEncryptionKey(userId);
const allSeries: SyncedSeriesResult[] = SeriesRepo.fetchSyncedSeries(userId, lang);
const allSeriesBooks: SyncedSeriesBookResult[] = SeriesRepo.fetchSyncedSeriesBooks(userId, lang);
const allCharacters: SyncedSeriesCharacterResult[] = SeriesCharacterRepo.fetchSyncedSeriesCharacters(userId, lang);
const allCharacterAttributes: SyncedSeriesCharacterAttributeResult[] = SeriesCharacterRepo.fetchSyncedSeriesCharacterAttributes(userId, lang);
const allWorlds: SyncedSeriesWorldResult[] = SeriesWorldRepo.fetchSyncedSeriesWorlds(userId, lang);
const allWorldElements: SyncedSeriesWorldElementResult[] = SeriesWorldRepo.fetchSyncedSeriesWorldElements(userId, lang);
const allLocations: SyncedSeriesLocationResult[] = SeriesLocationRepo.fetchSyncedSeriesLocations(userId, lang);
const allLocationElements: SyncedSeriesLocationElementResult[] = SeriesLocationRepo.fetchSyncedSeriesLocationElements(userId, lang);
const allLocationSubElements: SyncedSeriesLocationSubElementResult[] = SeriesLocationRepo.fetchSyncedSeriesLocationSubElements(userId, lang);
const allSpells: SyncedSeriesSpellResult[] = SeriesSpellRepo.fetchSyncedSeriesSpells(userId, lang);
const allSpellTags: SyncedSeriesSpellTagResult[] = SeriesSpellRepo.fetchSyncedSeriesSpellTags(userId, lang);
return allSeries.map((series: SyncedSeriesResult): SyncedSeries => {
const seriesId: string = series.series_id;
// Map series books
const books: SyncedSeriesBook[] = allSeriesBooks
.filter((sb: SyncedSeriesBookResult): boolean => sb.series_id === seriesId)
.map((sb: SyncedSeriesBookResult): SyncedSeriesBook => ({
bookId: sb.book_id,
order: sb.book_order,
lastUpdate: sb.last_update
}));
// Map characters with attributes
const characters: SyncedSeriesCharacter[] = allCharacters
.filter((c: SyncedSeriesCharacterResult): boolean => c.series_id === seriesId)
.map((c: SyncedSeriesCharacterResult): SyncedSeriesCharacter => ({
id: c.character_id,
name: System.decryptDataWithUserKey(c.first_name, userEncryptionKey),
lastUpdate: c.last_update,
attributes: allCharacterAttributes
.filter((a: SyncedSeriesCharacterAttributeResult): boolean => a.character_id === c.character_id)
.map((a: SyncedSeriesCharacterAttributeResult): SyncedSeriesCharacterAttribute => ({
id: a.attr_id,
name: System.decryptDataWithUserKey(a.attribute_name, userEncryptionKey),
lastUpdate: a.last_update
}))
}));
// Map worlds with elements
const worlds: SyncedSeriesWorld[] = allWorlds
.filter((w: SyncedSeriesWorldResult): boolean => w.series_id === seriesId)
.map((w: SyncedSeriesWorldResult): SyncedSeriesWorld => ({
id: w.world_id,
name: System.decryptDataWithUserKey(w.name, userEncryptionKey),
lastUpdate: w.last_update,
elements: allWorldElements
.filter((e: SyncedSeriesWorldElementResult): boolean => e.world_id === w.world_id)
.map((e: SyncedSeriesWorldElementResult): SyncedSeriesWorldElement => ({
id: e.element_id,
name: System.decryptDataWithUserKey(e.name, userEncryptionKey),
lastUpdate: e.last_update
}))
}));
// Map locations with elements and sub-elements
const locations: SyncedSeriesLocation[] = allLocations
.filter((l: SyncedSeriesLocationResult): boolean => l.series_id === seriesId)
.map((l: SyncedSeriesLocationResult): SyncedSeriesLocation => ({
id: l.loc_id,
name: System.decryptDataWithUserKey(l.loc_name, userEncryptionKey),
lastUpdate: l.last_update,
elements: allLocationElements
.filter((e: SyncedSeriesLocationElementResult): boolean => e.location_id === l.loc_id)
.map((e: SyncedSeriesLocationElementResult): SyncedSeriesLocationElement => ({
id: e.element_id,
name: System.decryptDataWithUserKey(e.element_name, userEncryptionKey),
lastUpdate: e.last_update,
subElements: allLocationSubElements
.filter((se: SyncedSeriesLocationSubElementResult): boolean => se.element_id === e.element_id)
.map((se: SyncedSeriesLocationSubElementResult): SyncedSeriesLocationSubElement => ({
id: se.sub_element_id,
name: System.decryptDataWithUserKey(se.sub_elem_name, userEncryptionKey),
lastUpdate: se.last_update
}))
}))
}));
// Map spells
const spells: SyncedSeriesSpell[] = allSpells
.filter((s: SyncedSeriesSpellResult): boolean => s.series_id === seriesId)
.map((s: SyncedSeriesSpellResult): SyncedSeriesSpell => ({
id: s.spell_id,
name: System.decryptDataWithUserKey(s.name, userEncryptionKey),
lastUpdate: s.last_update
}));
// Map spell tags
const spellTags: SyncedSeriesSpellTag[] = allSpellTags
.filter((t: SyncedSeriesSpellTagResult): boolean => t.series_id === seriesId)
.map((t: SyncedSeriesSpellTagResult): SyncedSeriesSpellTag => ({
id: t.tag_id,
name: System.decryptDataWithUserKey(t.name, userEncryptionKey),
lastUpdate: t.last_update
}));
return {
id: seriesId,
name: System.decryptDataWithUserKey(series.name, userEncryptionKey),
description: series.description
? System.decryptDataWithUserKey(series.description, userEncryptionKey)
: null,
lastUpdate: series.last_update,
books,
characters,
worlds,
locations,
spells,
spellTags
};
});
}
}