Files
ERitors-Scribe-Desktop/electron/database/mappers/world.mapper.ts
natreex d5eb1691d9 Add database schema, encryption utilities, and local database service
- 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.
2025-11-17 09:34:54 -05:00

223 lines
6.5 KiB
TypeScript

/**
* TypeScript interfaces (copied from lib/models for type safety)
*/
export interface WorldElement {
id: string;
name: string;
description: string;
}
export interface WorldProps {
id: string;
name: string;
history: string;
politics: string;
economy: string;
religion: string;
languages: string;
laws?: WorldElement[];
biomes?: WorldElement[];
issues?: WorldElement[];
customs?: WorldElement[];
kingdoms?: WorldElement[];
climate?: WorldElement[];
resources?: WorldElement[];
wildlife?: WorldElement[];
arts?: WorldElement[];
ethnicGroups?: WorldElement[];
socialClasses?: WorldElement[];
importantCharacters?: WorldElement[];
}
/**
* Database row types (snake_case from SQLite)
*/
export interface DBWorld {
world_id: string;
name: string;
hashed_name: string;
author_id: string;
book_id: string;
history?: string;
politics?: string;
economy?: string;
religion?: string;
languages?: string;
meta_world: string;
synced?: number;
}
export interface DBWorldElement {
element_id: string;
world_id: string;
user_id: string;
element_type: number; // Type identifier for different element categories
name: string;
original_name: string;
description?: string;
meta_element: string;
synced?: number;
}
// Element type constants
export enum WorldElementType {
LAW = 1,
BIOME = 2,
ISSUE = 3,
CUSTOM = 4,
KINGDOM = 5,
CLIMATE = 6,
RESOURCE = 7,
WILDLIFE = 8,
ART = 9,
ETHNIC_GROUP = 10,
SOCIAL_CLASS = 11,
IMPORTANT_CHARACTER = 12
}
/**
* MAPPERS: DB → TypeScript Interfaces
*/
export function dbToWorld(dbWorld: DBWorld, elements: DBWorldElement[] = []): WorldProps {
// Group elements by type
const laws: WorldElement[] = [];
const biomes: WorldElement[] = [];
const issues: WorldElement[] = [];
const customs: WorldElement[] = [];
const kingdoms: WorldElement[] = [];
const climate: WorldElement[] = [];
const resources: WorldElement[] = [];
const wildlife: WorldElement[] = [];
const arts: WorldElement[] = [];
const ethnicGroups: WorldElement[] = [];
const socialClasses: WorldElement[] = [];
const importantCharacters: WorldElement[] = [];
for (const elem of elements) {
const worldElement: WorldElement = {
id: elem.element_id,
name: elem.name,
description: elem.description || ''
};
switch (elem.element_type) {
case WorldElementType.LAW:
laws.push(worldElement);
break;
case WorldElementType.BIOME:
biomes.push(worldElement);
break;
case WorldElementType.ISSUE:
issues.push(worldElement);
break;
case WorldElementType.CUSTOM:
customs.push(worldElement);
break;
case WorldElementType.KINGDOM:
kingdoms.push(worldElement);
break;
case WorldElementType.CLIMATE:
climate.push(worldElement);
break;
case WorldElementType.RESOURCE:
resources.push(worldElement);
break;
case WorldElementType.WILDLIFE:
wildlife.push(worldElement);
break;
case WorldElementType.ART:
arts.push(worldElement);
break;
case WorldElementType.ETHNIC_GROUP:
ethnicGroups.push(worldElement);
break;
case WorldElementType.SOCIAL_CLASS:
socialClasses.push(worldElement);
break;
case WorldElementType.IMPORTANT_CHARACTER:
importantCharacters.push(worldElement);
break;
}
}
return {
id: dbWorld.world_id,
name: dbWorld.name,
history: dbWorld.history || '',
politics: dbWorld.politics || '',
economy: dbWorld.economy || '',
religion: dbWorld.religion || '',
languages: dbWorld.languages || '',
laws,
biomes,
issues,
customs,
kingdoms,
climate,
resources,
wildlife,
arts,
ethnicGroups,
socialClasses,
importantCharacters
};
}
/**
* MAPPERS: TypeScript Interfaces → DB
*/
export function worldToDb(world: WorldProps, authorId: string, bookId: string, synced: number = 0): DBWorld {
return {
world_id: world.id,
name: world.name,
hashed_name: '',
author_id: authorId,
book_id: bookId,
history: world.history,
politics: world.politics,
economy: world.economy,
religion: world.religion,
languages: world.languages,
meta_world: '',
synced
};
}
export function worldElementsToDb(world: WorldProps, userId: string, synced: number = 0): DBWorldElement[] {
const elements: DBWorldElement[] = [];
const addElements = (type: WorldElementType, elems: WorldElement[]) => {
for (const elem of elems) {
elements.push({
element_id: elem.id,
world_id: world.id,
user_id: userId,
element_type: type,
name: elem.name,
original_name: elem.name,
description: elem.description,
meta_element: '',
synced
});
}
};
addElements(WorldElementType.LAW, world.laws || []);
addElements(WorldElementType.BIOME, world.biomes || []);
addElements(WorldElementType.ISSUE, world.issues || []);
addElements(WorldElementType.CUSTOM, world.customs || []);
addElements(WorldElementType.KINGDOM, world.kingdoms || []);
addElements(WorldElementType.CLIMATE, world.climate || []);
addElements(WorldElementType.RESOURCE, world.resources || []);
addElements(WorldElementType.WILDLIFE, world.wildlife || []);
addElements(WorldElementType.ART, world.arts || []);
addElements(WorldElementType.ETHNIC_GROUP, world.ethnicGroups || []);
addElements(WorldElementType.SOCIAL_CLASS, world.socialClasses || []);
addElements(WorldElementType.IMPORTANT_CHARACTER, world.importantCharacters || []);
return elements;
}