/** * TypeScript interfaces (copied from lib/models for type safety) */ export interface Subscription { subType: string; subTier: number; status: boolean; } export interface UserProps { id: string; name: string; lastName: string; username: string; authorName?: string; email?: string; accountVerified: boolean; termsAccepted: boolean; aiUsage: number; apiKeys: { gemini: boolean; openai: boolean; anthropic: boolean; }; books?: any[]; guideTour?: { [key: string]: boolean }[]; subscription?: Subscription[]; writingLang: number; writingLevel: number; ritePoints: number; creditsBalance: number; groupId: number; } /** * Database row types (snake_case from SQLite) */ export interface DBUser { user_id: string; first_name: string; last_name: string; username: string; email: string; origin_email: string; origin_username: string; author_name?: string; origin_author_name?: string; plateform: string; social_id?: string; user_group: number; password?: string; term_accepted: number; verify_code?: string; reg_date: number; account_verified: number; user_meta: string; // JSON containing apiKeys, guideTour, writingLang, writingLevel, aiUsage erite_points: number; stripe_customer_id?: string; credits_balance: number; synced?: number; } interface UserMeta { apiKeys?: { gemini: boolean; openai: boolean; anthropic: boolean; }; guideTour?: { [key: string]: boolean }[]; subscription?: Subscription[]; writingLang?: number; writingLevel?: number; aiUsage?: number; } /** * MAPPERS: DB → TypeScript Interfaces */ export function dbToUser(dbUser: DBUser): UserProps { let meta: UserMeta = {}; try { meta = JSON.parse(dbUser.user_meta || '{}'); } catch (error) { console.error('Failed to parse user_meta:', error); } return { id: dbUser.user_id, name: dbUser.first_name, lastName: dbUser.last_name, username: dbUser.username, authorName: dbUser.author_name, email: dbUser.email, accountVerified: dbUser.account_verified === 1, termsAccepted: dbUser.term_accepted === 1, aiUsage: meta.aiUsage || 0, apiKeys: meta.apiKeys || { gemini: false, openai: false, anthropic: false }, books: [], // Populated separately guideTour: meta.guideTour || [], subscription: meta.subscription || [], writingLang: meta.writingLang || 1, writingLevel: meta.writingLevel || 1, ritePoints: dbUser.erite_points, creditsBalance: dbUser.credits_balance, groupId: dbUser.user_group }; } /** * MAPPERS: TypeScript Interfaces → DB */ export function userToDb(user: UserProps, synced: number = 0): DBUser { const meta: UserMeta = { apiKeys: user.apiKeys, guideTour: user.guideTour, subscription: user.subscription, writingLang: user.writingLang, writingLevel: user.writingLevel, aiUsage: user.aiUsage }; return { user_id: user.id, first_name: user.name, last_name: user.lastName, username: user.username, email: user.email || '', origin_email: user.email || '', origin_username: user.username, author_name: user.authorName, origin_author_name: user.authorName, plateform: 'electron', social_id: undefined, user_group: user.groupId, password: undefined, term_accepted: user.termsAccepted ? 1 : 0, verify_code: undefined, reg_date: Date.now(), account_verified: user.accountVerified ? 1 : 0, user_meta: JSON.stringify(meta), erite_points: user.ritePoints, stripe_customer_id: undefined, credits_balance: user.creditsBalance, synced }; }