- 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.
223 lines
6.5 KiB
TypeScript
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;
|
|
}
|