{"version":3,"file":"index.mjs","sources":["../node_modules/@dqcai/logger/lib/index.mjs","../src/logger/index.ts","../src/core/universal-dao.ts","../src/core/database-factory.ts","../src/core/database-manager.ts","../src/core/base-service.ts","../src/core/service-manager.ts","../src/query/query-builder.ts","../src/adapters/base-adapter.ts","../src/types.ts"],"sourcesContent":["const f=(...l)=>l.map(t=>{if(typeof t==\"bigint\")return t.toString();if(typeof t==\"object\"&&t!==null)try{return JSON.stringify(t,(e,i)=>typeof i==\"bigint\"?i.toString():i instanceof Date?i.toISOString():typeof Buffer!=\"undefined\"&&Buffer.isBuffer(i)?`<Buffer ${i.length} bytes>`:typeof i==\"function\"?`<Function ${i.name||\"anonymous\"}>`:i,2)}catch(e){return`<Error stringifying: ${e.message}>`}return String(t)}).join(\" \");class E{constructor(t){this.transports=new Map,this.transportFactory=null,this.config=t,this.sessionId=t.sessionId||this.generateSessionId()}generateSessionId(){return`session_${Date.now()}_${Math.random().toString(36).substr(2,9)}`}getSessionId(){return this.sessionId}renewSession(){return this.sessionId=this.generateSessionId(),this.sessionId}setTransportFactory(t){this.transportFactory=t}addTransport(t){this.transports.set(t.name,t)}removeTransport(t){return this.transports.delete(t)}getTransport(t){return this.transports.get(t)}listTransports(){return Array.from(this.transports.keys())}setModuleConfig(t,e){this.config.modules[t]=e}getModuleConfig(t){return this.config.modules[t]}setGlobalEnabled(t){this.config.enabled=t}isGlobalEnabled(){return this.config.enabled}setDefaultLevel(t){this.config.defaultLevel=t}getConfig(){return JSON.parse(JSON.stringify(this.config))}setMetadata(t){this.config.metadata=Object.assign(Object.assign({},this.config.metadata),t)}shouldLog(t,e){if(!this.config.enabled)return!1;const i=this.config.modules[t];return i?i.enabled&&i.levels.includes(e):this.isLevelEnabled(e,this.config.defaultLevel)}isLevelEnabled(t,e){const i=[\"trace\",\"debug\",\"info\",\"warn\",\"error\"],s=i.indexOf(t),a=i.indexOf(e);return s===-1||a===-1?!1:s>=a}getTransportsForModule(t){const e=this.config.modules[t];return((e==null?void 0:e.transports)||[\"console\"]).map(i=>this.transports.get(i)).filter(i=>i!==void 0)}async sendToTransports(t,e){if(e.length===0)return;const i=e.map(async s=>{try{await s.log(t)}catch(a){console.error(`[UniversalLogger] Transport ${s.name} failed:`,a)}});await Promise.allSettled(i)}async log(t,e,i,s){if(!this.shouldLog(t,e))return;const a={timestamp:new Date().toISOString(),level:e,module:t,message:i,data:s,metadata:this.config.metadata,sessionId:this.sessionId},n=this.getTransportsForModule(t);await this.sendToTransports(a,n)}async trace(t,...e){const i=f(...e);await this.log(t,\"trace\",i)}async debug(t,...e){const i=f(...e);await this.log(t,\"debug\",i)}async info(t,...e){const i=f(...e);await this.log(t,\"info\",i)}async warn(t,...e){const i=f(...e);await this.log(t,\"warn\",i)}async error(t,...e){const i=f(...e);await this.log(t,\"error\",i)}async flush(){const t=Array.from(this.transports.values()).filter(e=>typeof e.flush==\"function\").map(e=>e.flush());await Promise.allSettled(t)}async cleanup(){const t=Array.from(this.transports.values()).filter(e=>typeof e.cleanup==\"function\").map(e=>e.cleanup());await Promise.allSettled(t)}createModuleLogger(t){return new F(t,this)}}class F{constructor(t,e){this.module=t,this.logger=e}async flush(){await this.logger.flush()}async trace(...t){const e=f(...t);await this.logger.trace(this.module,e)}async debug(...t){const e=f(...t);await this.logger.debug(this.module,e)}async info(...t){const e=f(...t);await this.logger.info(this.module,e)}async warn(...t){const e=f(...t);await this.logger.warn(this.module,e)}async error(...t){const e=f(...t);await this.logger.error(this.module,e)}getModuleName(){return this.module}}class b{constructor(t=!1){this.prefix=\"[InternalLogger]\",this.enabled=t}formatMessage(t,e,i){const s=new Date().toISOString(),a=i?` ${JSON.stringify(i)}`:\"\";return`${s} ${this.prefix} [${t}] ${e}${a}`}debug(t,e){this.enabled&&console.debug(this.formatMessage(\"DEBUG\",t,e))}info(t,e){this.enabled&&console.info(this.formatMessage(\"INFO\",t,e))}warn(t,e){this.enabled&&console.warn(this.formatMessage(\"WARN\",t,e))}error(t,e){if(this.enabled){const i=e instanceof Error?{message:e.message,stack:e.stack}:e;console.error(this.formatMessage(\"ERROR\",t,i))}}setEnabled(t){this.enabled=t}}class x{constructor(t){this.config=t,this.name=\"api\",this.buffer=[],this.timer=null,this.axios=null,this.endpoint=t.endpoint||\"/logs\",this.batchSize=t.batchSize||10,this.flushInterval=t.flushInterval||5e3,this.maxRetries=t.maxRetries||3,this.initAxios(),this.logger=new b(t.enableInternalLogging===!0)}cleanup(){throw new Error(\"Method not implemented.\")}async initAxios(){try{const t=await import(\"axios\");this.axios=t.default.create({baseURL:this.config.baseURL,timeout:1e4})}catch(t){this.logger.error(\"[ApiTransport] Kh\\xF4ng th\\u1EC3 load axios:\",t)}}async log(t){this.buffer.push(t),this.buffer.length>=this.batchSize?await this.flush():this.timer||(this.timer=setTimeout(()=>this.flush(),this.flushInterval))}async flush(){if(this.timer&&(clearTimeout(this.timer),this.timer=null),this.buffer.length===0||!this.axios)return;const t=[...this.buffer];this.buffer=[],await this.sendWithRetry(t)}async sendWithRetry(t,e=1){try{await this.axios.post(this.endpoint,{logs:t})}catch(i){e<this.maxRetries?(await new Promise(s=>setTimeout(s,1e3*e)),await this.sendWithRetry(t,e+1)):this.logger.error(\"[ApiTransport] G\\u1EEDi log th\\u1EA5t b\\u1EA1i sau\",{max_retries:this.maxRetries,err:i})}}async destroy(){await this.flush()}}var $=Object.freeze({__proto__:null,ApiTransport:x});class S{constructor(t={}){this.name=\"console\",this.config=Object.assign({colorize:!0,timestamp:!0,prefix:\"\"},t)}log(t){const e=[];this.config.timestamp&&e.push(`[${t.timestamp}]`),this.config.prefix&&e.push(`[${this.config.prefix}]`),e.push(`[${t.module}]`,`[${t.level.toUpperCase()}]`,t.message);const i=e.join(\" \"),s=t.data?[t.data]:[];this.config.colorize?this.logWithColor(t.level,i,s):this.logWithoutColor(t.level,i,s)}logWithColor(t,e,i){const s={trace:\"#999999\",debug:\"#0066cc\",info:\"#00cc66\",warn:\"#ff9900\",error:\"#cc0000\"}[t];console.log(`%c${e}`,`color: ${s}`,...i)}logWithoutColor(t,e,i){switch(t){case\"error\":console.error(e,...i);break;case\"warn\":console.warn(e,...i);break;case\"info\":console.info(e,...i);break;default:console.log(e,...i)}}}var I=Object.freeze({__proto__:null,ConsoleTransport:S});class z{constructor(t={}){this.name=\"db\",this.initialized=!1,this.initializing=!1,this.initPromise=null,this.DatabaseManager=null,this.BaseService=null,this.loggerSchema=null,this.logService=null,this.errorLogService=null,this.statisticsService=null,this.sessionService=null,this.buffer=[],this.timer=null,this.currentSessionId=null,this.flushInProgress=Promise.resolve(),this.config=Object.assign({databaseType:\"sqlite\",database:\"logger\",dbDirectory:\"./logs\",tableName:\"logs\",batchSize:100,flushInterval:5e3,enableStatistics:!0,enableErrorTable:!0,enableInternalLogging:!0},t),this.batchSize=this.config.batchSize,this.flushInterval=this.config.flushInterval,this.logger=new b(this.config.enableInternalLogging),this.initDatabase()}async initDatabase(){return this.initialized||this.initializing?this.initPromise||Promise.resolve():(this.initializing=!0,this.initPromise=(async()=>{try{this.logger.debug(\"Initializing database transport...\");const t=await import(\"@dqcai/orm\");this.DatabaseManager=t.DatabaseManager,this.BaseService=t.BaseService,this.logger.debug(\"ORM module loaded successfully\");const e=await Promise.resolve().then(function(){return V});this.loggerSchema=e.loggerSchema;const i=e.LOGGER_SCHEMA_NAME;this.logger.debug(\"Logger schema loaded successfully\"),this.DatabaseManager.registerSchemas({[i]:this.loggerSchema}),this.logger.debug(\"Schema registered\");const s=this.buildDbConfig();await this.DatabaseManager.initializeSchema(i,{dbConfig:s,validateVersion:!1}),this.logger.info(\"Database initialized successfully\",{type:this.config.databaseType,database:this.config.database}),await this.initializeServices(i),this.initialized=!0,this.logger.info(\"DBTransport initialized successfully\")}catch(t){throw this.logger.error(\"Failed to initialize DBTransport\",t),t}finally{this.initializing=!1}})(),this.initPromise)}buildDbConfig(){const t={databaseType:this.config.databaseType,database:this.config.database};switch(this.config.databaseType){case\"sqlite\":t.dbDirectory=this.config.dbDirectory,this.config.filename&&(t.filename=this.config.filename),t.pragma={journal_mode:\"WAL\",synchronous:\"NORMAL\",foreign_keys:!0};break;case\"postgresql\":case\"mysql\":case\"mariadb\":this.config.connectionString?t.connectionString=this.config.connectionString:(t.host=this.config.host||\"localhost\",t.port=this.config.port,t.user=this.config.user,t.password=this.config.password);break}return t}async initializeServices(t){this.logger.debug(\"Initializing services...\");class e extends this.BaseService{constructor(){super(t,\"logs\")}}class i extends this.BaseService{constructor(){super(t,\"error_logs\")}}class s extends this.BaseService{constructor(){super(t,\"log_statistics\")}}class a extends this.BaseService{constructor(){super(t,\"log_sessions\")}}this.logService=new e,await this.logService.initialize(),this.config.enableErrorTable&&(this.errorLogService=new i,await this.errorLogService.initialize()),this.config.enableStatistics&&(this.statisticsService=new s,await this.statisticsService.initialize(),this.sessionService=new a,await this.sessionService.initialize()),this.logger.info(\"Services initialized successfully\")}async log(t){if(!this.initialized&&(await this.initDatabase(),!this.initialized)){this.logger.error(\"Cannot log: Transport not initialized\");return}this.buffer.push(t),this.buffer.length>=this.batchSize?await this.flush():this.timer||(this.timer=setTimeout(()=>this.flush(),this.flushInterval))}async flush(){if(this.timer&&(clearTimeout(this.timer),this.timer=null),this.buffer.length===0)return;this.initialized||await this.initDatabase();const t=[...this.buffer];this.buffer=[];try{const e=t.map(i=>this.mapToLogRecord(i));if(await this.logService.bulkUpsert(e),this.config.enableErrorTable&&this.errorLogService){const i=t.filter(s=>s.level===\"error\").map(s=>this.mapToErrorRecord(s));i.length>0&&await this.errorLogService.bulkUpsert(i)}this.config.enableStatistics&&this.statisticsService&&await this.updateStatistics(t),this.logger.debug(`Successfully flushed ${t.length} logs to database`)}catch(e){this.buffer.unshift(...t),this.logger.error(\"Failed to flush logs to database\",{message:e.message,stack:e.stack,batchSize:t.length});const i=1e3+Math.random()*2e3;this.timer=setTimeout(()=>this.flush(),i)}}async updateStatistics(t){if(!this.statisticsService)return;const e=new Date().toISOString().split(\"T\")[0],i=new Map;for(const a of t){const n=`${a.module}:${a.level}`;i.set(n,(i.get(n)||0)+1)}const s=[];for(const[a,n]of i){const[o,h]=a.split(\":\"),c=await this.statisticsService.findOne({date:e,module:o,level:h});s.push({id:c==null?void 0:c.id,date:e,module:o,level:h,count:((c==null?void 0:c.count)||0)+n})}s.length>0&&await this.statisticsService.bulkUpsert(s,[\"date\",\"module\",\"level\"])}mapToLogRecord(t){const e=t.sessionId||this.currentSessionId||null;return e&&this.logger.debug(\"Mapping log with session_id\",{sessionId:e,message:t.message}),{timestamp:t.timestamp,level:t.level,module:t.module,message:t.message,data:t.data?JSON.stringify(t.data):null,metadata:t.metadata?JSON.stringify(t.metadata):null,session_id:e}}mapToErrorRecord(t){var e,i,s;return{timestamp:t.timestamp,module:t.module,message:t.message,stack_trace:((e=t.data)===null||e===void 0?void 0:e.stack)||((s=(i=t.data)===null||i===void 0?void 0:i.error)===null||s===void 0?void 0:s.stack)||String(t.data),data:t.data?JSON.stringify(t.data):null,metadata:t.metadata?JSON.stringify(t.metadata):null,session_id:t.sessionId||this.currentSessionId}}async startSession(t){if(this.initialized||await this.initDatabase(),this.currentSessionId=t||`session_${Date.now()}_${Math.random().toString(36).substr(2,9)}`,this.config.enableStatistics&&this.sessionService)try{await this.sessionService.findOne({session_id:this.currentSessionId})||await this.sessionService.create({session_id:this.currentSessionId,started_at:new Date().toISOString(),status:\"active\"}),this.logger.info(\"Session started\",{sessionId:this.currentSessionId})}catch(e){this.logger.error(\"Failed to start session\",e)}return this.currentSessionId}async endSession(){if(!(!this.currentSessionId||!this.sessionService))try{await this.sessionService.update({session_id:this.currentSessionId},{ended_at:new Date().toISOString(),status:\"ended\"}),this.logger.info(\"Session ended\",{sessionId:this.currentSessionId}),this.currentSessionId=null}catch(t){this.logger.error(\"Failed to end session\",t)}}async queryLogs(t={},e={}){this.initialized||await this.initDatabase();try{return(await this.logService.find(t,Object.assign(Object.assign({},e),{orderBy:{timestamp:\"DESC\"}}))).map(i=>Object.assign(Object.assign({},i),{data:i.data?JSON.parse(i.data):null,metadata:i.metadata?JSON.parse(i.metadata):null}))}catch(i){return this.logger.error(\"Failed to query logs\",i),[]}}async getLogsByLevel(t,e=100){return this.queryLogs({level:t},{limit:e})}async getLogsByModule(t,e=100){return this.queryLogs({module:t},{limit:e})}async getLogsBySession(t,e=100){return this.queryLogs({session_id:t},{limit:e})}async getStatistics(t={}){if(!this.initialized||!this.statisticsService)return[];try{return await this.statisticsService.find(t,{orderBy:{date:\"DESC\"}})}catch(e){return this.logger.error(\"Failed to get statistics\",e),[]}}async clearOldLogs(t=30){if(!this.initialized)return 0;try{const e=new Date;e.setDate(e.getDate()-t);const i=e.toISOString(),s=await this.logService.delete({timestamp:{$lt:i}});return this.logger.info(`Cleared ${s.deletedCount} old logs`),s.deletedCount||0}catch(e){return this.logger.error(\"Failed to clear old logs\",e),0}}async getTransportStats(){if(!this.initialized)return null;try{const t=await this.logService.count(),e=await this.logService.count({level:\"error\"}),i={};for(const s of[\"trace\",\"debug\",\"info\",\"warn\",\"error\"])i[s]=await this.logService.count({level:s});return{totalLogs:t,errorCount:e,levelCounts:i,bufferSize:this.buffer.length,initialized:this.initialized,currentSession:this.currentSessionId}}catch(t){return this.logger.error(\"Failed to get transport stats\",t),null}}async cleanup(){this.logger.info(\"Cleaning up DBTransport...\"),await this.flush(),this.currentSessionId&&await this.endSession(),this.DatabaseManager&&await this.DatabaseManager.closeAll(),this.logger.info(\"DBTransport cleanup completed\")}setInternalLogging(t){this.logger.setEnabled(t)}}class T{constructor(t={}){this.name=\"electron-file\",this.fs=null,this.path=null,this.app=null,this.logPath=\"\",this.initialized=!1,this.fileName=t.fileName||\"app.log\",this.maxFileSize=t.maxFileSize||10*1024*1024,this.maxFiles=t.maxFiles||5,this.initElectron(),this.logger=new b(t.enableInternalLogging===!0)}async initElectron(){try{this.fs=await import(\"fs\").then(i=>i.promises),this.path=await import(\"path\");const t=await import(\"electron\");this.app=t.app,this.logPath=this.path.join(this.app.getPath(\"userData\"),\"logs\",this.fileName);const e=this.path.dirname(this.logPath);await this.fs.mkdir(e,{recursive:!0}),this.initialized=!0}catch(t){this.logger.error(\"[ElectronFileTransport] Kh\\xF4ng th\\u1EC3 kh\\u1EDFi t\\u1EA1o:\",t)}}async log(t){if(!(!this.initialized&&(await this.initElectron(),!this.initialized)))try{const e=JSON.stringify(t)+`\n`;try{(await this.fs.stat(this.logPath)).size>=this.maxFileSize&&await this.rotateFiles()}catch(i){}await this.fs.appendFile(this.logPath,e,\"utf8\")}catch(e){this.logger.error(\"[ElectronFileTransport] Ghi file th\\u1EA5t b\\u1EA1i:\",e)}}async rotateFiles(){try{const t=this.path.dirname(this.logPath),e=this.path.basename(this.logPath,\".log\"),i=this.path.join(t,`${e}.${this.maxFiles}.log`);try{await this.fs.unlink(i)}catch(a){}for(let a=this.maxFiles-1;a>=1;a--){const n=this.path.join(t,`${e}.${a}.log`),o=this.path.join(t,`${e}.${a+1}.log`);try{await this.fs.rename(n,o)}catch(h){}}const s=this.path.join(t,`${e}.1.log`);await this.fs.rename(this.logPath,s)}catch(t){this.logger.error(\"[ElectronFileTransport] Rotate files th\\u1EA5t b\\u1EA1i:\",t)}}async getLogs(){if(!this.initialized)return[];try{const t=[],e=this.path.dirname(this.logPath),i=this.path.basename(this.logPath,\".log\");try{const s=await this.fs.readFile(this.logPath,\"utf8\");t.push(s)}catch(s){}for(let s=1;s<=this.maxFiles;s++){const a=this.path.join(e,`${i}.${s}.log`);try{const n=await this.fs.readFile(a,\"utf8\");t.push(n)}catch(n){}}return t}catch(t){return this.logger.error(\"[ElectronFileTransport] \\u0110\\u1ECDc logs th\\u1EA5t b\\u1EA1i:\",t),[]}}async clearLogs(){if(this.initialized)try{const t=this.path.dirname(this.logPath),e=this.path.basename(this.logPath,\".log\");try{await this.fs.unlink(this.logPath)}catch(i){}for(let i=1;i<=this.maxFiles;i++){const s=this.path.join(t,`${e}.${i}.log`);try{await this.fs.unlink(s)}catch(a){}}}catch(t){this.logger.error(\"[ElectronFileTransport] X\\xF3a logs th\\u1EA5t b\\u1EA1i:\",t)}}}var A=Object.freeze({__proto__:null,ElectronFileTransport:T});class D{constructor(t={}){this.name=\"node-file\",this.fs=null,this.path=null,this.initialized=!1,this.initializing=!1,this.initPromise=null,this.rotating=!1,this.filePath=t.filePath||\"./logs/app.log\",this.maxFileSize=t.maxFileSize||10*1024*1024,this.maxFiles=t.maxFiles||5,this.logger=new b(t.enableInternalLogging===!0),this.initNodeFS()}async initNodeFS(){return this.initialized||this.initializing?this.initPromise||Promise.resolve():(this.initializing=!0,this.initPromise=(async()=>{try{this.logger.debug(\"Initializing Node.js file system modules...\"),this.fs=await import(\"fs\").then(i=>i.promises);const t=await import(\"fs\");this.path=await import(\"path\"),this.logger.debug(\"File system modules loaded successfully\");const e=this.path.dirname(this.filePath);t.existsSync(e)?this.logger.debug(\"Log directory already exists\",{path:e}):(this.logger.info(\"Creating log directory\",{path:e}),await this.fs.mkdir(e,{recursive:!0}),this.logger.info(\"Log directory created successfully\")),this.initialized=!0,this.logger.info(\"NodeFileTransport initialized successfully\",{filePath:this.filePath,maxFileSize:this.maxFileSize,maxFiles:this.maxFiles})}catch(t){throw this.logger.error(\"Failed to initialize NodeFileTransport\",t),t}finally{this.initializing=!1}})(),this.initPromise)}async log(t){if(!this.initialized&&(await this.initNodeFS(),!this.initialized)){this.logger.error(\"Cannot log: Transport not initialized\");return}try{const e=JSON.stringify(t)+`\n`;try{const i=await this.fs.stat(this.filePath);i.size>=this.maxFileSize&&(this.logger.info(\"File size limit reached, rotating files\",{currentSize:i.size,maxSize:this.maxFileSize}),await this.rotateFiles())}catch(i){this.logger.debug(\"Log file does not exist yet, will be created\")}await this.fs.appendFile(this.filePath,e,\"utf8\")}catch(e){this.logger.error(\"Failed to write log to file\",{filePath:this.filePath,error:e})}}async rotateFiles(){if(this.rotating){this.logger.debug(\"Rotation already in progress, skipping...\");return}this.rotating=!0;try{this.logger.debug(\"Starting file rotation...\");const t=this.path.dirname(this.filePath),e=this.path.extname(this.filePath),i=this.path.basename(this.filePath,e),s=this.path.join(t,`${i}.${this.maxFiles}${e}`);try{await this.fs.unlink(s),this.logger.debug(\"Deleted oldest log file\",{file:s})}catch(n){}for(let n=this.maxFiles-1;n>=1;n--){const o=this.path.join(t,`${i}.${n}${e}`),h=this.path.join(t,`${i}.${n+1}${e}`);try{await this.fs.rename(o,h)}catch(c){}}const a=this.path.join(t,`${i}.1${e}`);try{await this.fs.rename(this.filePath,a),this.logger.info(\"File rotation completed\",{currentFile:this.filePath,backupFile:a})}catch(n){n.code===\"ENOENT\"?this.logger.warn(\"Current log file disappeared during rotation (race condition avoided)\"):this.logger.error(\"File rotation failed\",n)}}catch(t){this.logger.error(\"Unexpected error during rotation\",t)}finally{this.rotating=!1}}async getLogs(){if(!this.initialized)return this.logger.warn(\"Cannot get logs: Transport not initialized\"),[];try{this.logger.debug(\"Reading log files...\");const t=[],e=this.path.dirname(this.filePath),i=this.path.extname(this.filePath),s=this.path.basename(this.filePath,i);try{const a=await this.fs.readFile(this.filePath,\"utf8\");t.push(a),this.logger.debug(\"Read current log file\",{file:this.filePath,size:a.length})}catch(a){this.logger.debug(\"Current log file does not exist\")}for(let a=1;a<=this.maxFiles;a++){const n=this.path.join(e,`${s}.${a}${i}`);try{const o=await this.fs.readFile(n,\"utf8\");t.push(o),this.logger.debug(\"Read backup log file\",{file:n,size:o.length})}catch(o){break}}return this.logger.info(\"Successfully read log files\",{totalFiles:t.length}),t}catch(t){return this.logger.error(\"Failed to read log files\",t),[]}}enableInternalLogging(t){this.logger.setEnabled(t)}async clearLogs(){if(!this.initialized){this.logger.warn(\"Cannot clear logs: Transport not initialized\");return}try{this.logger.info(\"Clearing all log files...\");const t=this.path.dirname(this.filePath),e=this.path.extname(this.filePath),i=this.path.basename(this.filePath,e);let s=0;try{await this.fs.unlink(this.filePath),s++,this.logger.debug(\"Deleted current log file\",{file:this.filePath})}catch(a){this.logger.debug(\"Current log file does not exist\")}for(let a=1;a<=this.maxFiles;a++){const n=this.path.join(t,`${i}.${a}${e}`);try{await this.fs.unlink(n),s++,this.logger.debug(\"Deleted backup log file\",{file:n})}catch(o){break}}this.logger.info(\"Successfully cleared log files\",{deletedFiles:s})}catch(t){this.logger.error(\"Failed to clear log files\",t)}}async flush(){this.logger.debug(\"Flush called (no-op for file transport)\")}async cleanup(){this.logger.info(\"Cleaning up NodeFileTransport...\"),this.logger.info(\"NodeFileTransport cleanup completed\")}async getStats(){const t={filePath:this.filePath,maxFileSize:this.maxFileSize,maxFiles:this.maxFiles,initialized:this.initialized};if(this.initialized){try{const i=await this.fs.stat(this.filePath);t.currentFileSize=i.size}catch(i){t.currentFileSize=0}const e=await this.getLogs();t.totalFiles=e.length}return t}setInternalLogging(t){this.logger.setEnabled(t),this.logger.info(`Internal logging ${t?\"enabled\":\"disabled\"}`)}}var P=Object.freeze({__proto__:null,NodeFileTransport:D});class N{constructor(t={}){this.name=\"rn-file\",this.RNFS=null,this.initialized=!1,this.fileName=t.fileName||\"app.log\",this.maxFileSize=t.maxFileSize||5*1024*1024,this.maxFiles=t.maxFiles||3,this.initRNFS(),this.logger=new b(t.enableInternalLogging===!0)}async initRNFS(){try{this.RNFS=(await import(\"react-native-fs\")).default,this.initialized=!0}catch(t){this.logger.error(\"[RNFileTransport] Kh\\xF4ng th\\u1EC3 load react-native-fs:\",t)}}async log(t){if(!((!this.initialized||!this.RNFS)&&(await this.initRNFS(),!this.RNFS)))try{const e=`${this.RNFS.DocumentDirectoryPath}/${this.fileName}`,i=JSON.stringify(t)+`\n`;await this.RNFS.exists(e)&&(await this.RNFS.stat(e)).size>=this.maxFileSize&&await this.rotateFiles(e),await this.RNFS.appendFile(e,i,\"utf8\")}catch(e){this.logger.error(\"[RNFileTransport] Ghi file th\\u1EA5t b\\u1EA1i:\",e)}}async rotateFiles(t){try{const e=`${this.RNFS.DocumentDirectoryPath}/${this.fileName}.${this.maxFiles}`;await this.RNFS.exists(e)&&await this.RNFS.unlink(e);for(let i=this.maxFiles-1;i>=1;i--){const s=`${this.RNFS.DocumentDirectoryPath}/${this.fileName}.${i}`,a=`${this.RNFS.DocumentDirectoryPath}/${this.fileName}.${i+1}`;await this.RNFS.exists(s)&&await this.RNFS.moveFile(s,a)}await this.RNFS.moveFile(t,`${this.RNFS.DocumentDirectoryPath}/${this.fileName}.1`)}catch(e){this.logger.error(\"[RNFileTransport] Rotate files th\\u1EA5t b\\u1EA1i:\",e)}}async getLogs(){if(!this.RNFS)return[];try{const t=[];for(let e=0;e<=this.maxFiles;e++){const i=e===0?this.fileName:`${this.fileName}.${e}`,s=`${this.RNFS.DocumentDirectoryPath}/${i}`;if(await this.RNFS.exists(s)){const a=await this.RNFS.readFile(s,\"utf8\");t.push(a)}}return t}catch(t){return this.logger.error(\"[RNFileTransport] \\u0110\\u1ECDc logs th\\u1EA5t b\\u1EA1i:\",t),[]}}async clearLogs(){if(this.RNFS)try{for(let t=0;t<=this.maxFiles;t++){const e=t===0?this.fileName:`${this.fileName}.${t}`,i=`${this.RNFS.DocumentDirectoryPath}/${e}`;await this.RNFS.exists(i)&&await this.RNFS.unlink(i)}}catch(t){this.logger.error(\"[RNFileTransport] X\\xF3a logs th\\u1EA5t b\\u1EA1i:\",t)}}}var O=Object.freeze({__proto__:null,RNFileTransport:N});class R{static detectPlatform(){var t,e;return typeof navigator!=\"undefined\"&&navigator.product===\"ReactNative\"?\"react-native\":typeof process!=\"undefined\"&&!((t=process.versions)===null||t===void 0)&&t.electron?\"electron\":typeof process!=\"undefined\"&&!((e=process.versions)===null||e===void 0)&&e.node&&typeof window==\"undefined\"?\"node\":\"web\"}static async createConsoleTransport(t){const{ConsoleTransport:e}=await Promise.resolve().then(function(){return I});return new e(t||{})}static async createApiTransport(t){const{ApiTransport:e}=await Promise.resolve().then(function(){return $});return new e(t)}static async createFileTransport(t,e){const i=t||this.detectPlatform();try{switch(i){case\"react-native\":{const{RNFileTransport:s}=await Promise.resolve().then(function(){return O});return new s(e||{})}case\"electron\":{const{ElectronFileTransport:s}=await Promise.resolve().then(function(){return A});return new s(e||{})}case\"node\":{const{NodeFileTransport:s}=await Promise.resolve().then(function(){return P});return new s(e||{})}case\"web\":return console.warn(\"[TransportFactory] File transport kh\\xF4ng kh\\u1EA3 d\\u1EE5ng tr\\xEAn web browser\"),null;default:return console.warn(\"[TransportFactory] Platform kh\\xF4ng \\u0111\\u01B0\\u1EE3c h\\u1ED7 tr\\u1EE3:\",i),null}}catch(s){return console.error(\"[TransportFactory] Kh\\xF4ng th\\u1EC3 t\\u1EA1o file transport:\",s),null}}static async createDefaultTransports(t){const e=[],i=this.detectPlatform();if(e.push(await this.createConsoleTransport(t==null?void 0:t.console)),t!=null&&t.api&&e.push(await this.createApiTransport(t.api)),i!==\"web\"){const s=await this.createFileTransport(i,t==null?void 0:t.file);s&&e.push(s)}return e}}const p=(...l)=>l.map(t=>typeof t==\"object\"?JSON.stringify(t,null,2):String(t)).join(\" \");class M{constructor(t,e){this.moduleName=t,this.logger=e.createModuleLogger(t),this.logger.info(`${t} initialized`).catch(i=>{console.error(`Failed to log initialization for ${t}:`,i)})}logTrace(...t){const e=p(...t);this.logger.trace(e).catch(i=>{console.error(`Failed to log trace [${this.moduleName}]:`,i)})}logDebug(...t){const e=p(...t);this.logger.debug(e).catch(i=>{console.error(`Failed to log debug [${this.moduleName}]:`,i)})}logInfo(...t){const e=p(...t);this.logger.info(e).catch(i=>{console.error(`Failed to log info [${this.moduleName}]:`,i)})}logWarn(...t){const e=p(...t);this.logger.warn(e).catch(i=>{console.error(`Failed to log warn [${this.moduleName}]:`,i)})}logError(...t){const e=p(...t);this.logger.error(e).catch(i=>{console.error(`Failed to log error [${this.moduleName}]:`,i)})}async logTraceAsync(...t){const e=p(...t);await this.logger.trace(e)}async logDebugAsync(...t){const e=p(...t);await this.logger.debug(e)}async logInfoAsync(...t){const e=p(...t);await this.logger.info(e)}async logWarnAsync(...t){const e=p(...t);await this.logger.warn(e)}async logErrorAsync(...t){const e=p(...t);await this.logger.error(e)}async flushLogs(){typeof this.logger.flush==\"function\"&&await this.logger.flush()}getModuleName(){return this.moduleName}}class y{constructor(){this.config={enabled:!0,defaultLevel:\"info\",modules:{}}}setEnabled(t){return this.config.enabled=t,this}setDefaultLevel(t){return this.config.defaultLevel=t,this}setSessionId(t){return this.config.sessionId=t,this}setMetadata(t){return this.config.metadata=t,this}addModule(t,e=!0,i=[\"info\",\"warn\",\"error\"],s=[\"console\"]){return this.config.modules[t]={enabled:e,levels:i,transports:s},this}addModules(t){return t.forEach(e=>{var i,s,a;this.addModule(e.name,(i=e.enabled)!==null&&i!==void 0?i:!0,(s=e.levels)!==null&&s!==void 0?s:[\"info\",\"warn\",\"error\"],(a=e.transports)!==null&&a!==void 0?a:[\"console\"])}),this}setModuleTransports(t,e){return this.config.modules[t]?this.config.modules[t].transports=e:this.config.modules[t]={enabled:!0,levels:[\"info\",\"warn\",\"error\"],transports:e},this}enableAllLevelsForModule(t){return this.config.modules[t]?this.config.modules[t].levels=[\"trace\",\"debug\",\"info\",\"warn\",\"error\"]:this.config.modules[t]={enabled:!0,levels:[\"trace\",\"debug\",\"info\",\"warn\",\"error\"],transports:[\"console\"]},this}useDevelopmentPreset(){return this.config.enabled=!0,this.config.defaultLevel=\"debug\",this}useProductionPreset(){return this.config.enabled=!0,this.config.defaultLevel=\"warn\",this}useTestingPreset(){return this.config.enabled=!0,this.config.defaultLevel=\"trace\",this}build(){return JSON.parse(JSON.stringify(this.config))}}class w{static createDevelopmentConfig(){return new y().setEnabled(!0).setDefaultLevel(\"debug\").addModule(\"DatabaseManager\",!0,[\"debug\",\"info\",\"warn\",\"error\"],[\"console\"]).addModule(\"ApiClient\",!0,[\"info\",\"warn\",\"error\"],[\"console\"]).addModule(\"Cache\",!0,[\"debug\",\"info\",\"warn\",\"error\"],[\"console\"]).build()}static createProductionConfig(){return new y().setEnabled(!0).setDefaultLevel(\"warn\").addModule(\"DatabaseManager\",!0,[\"error\"],[\"console\"]).addModule(\"ApiClient\",!0,[\"warn\",\"error\"],[\"console\"]).addModule(\"Cache\",!1,[],[]).build()}static createCustomConfig(t=!1){return t?w.createDevelopmentConfig():w.createProductionConfig()}}function j(l,t,e){const i=e.value;e.value=async function(...s){this.moduleName||this.constructor.name;const a=this.logger;if(a)try{await a.debug(`Calling method: ${t}`,{args:s.length,argTypes:s.map(o=>typeof o)});const n=Date.now();try{const o=await i.apply(this,s),h=Date.now()-n;return await a.debug(`Method ${t} completed in ${h}ms`),o}catch(o){const h=Date.now()-n;throw await a.error(`Method ${t} failed after ${h}ms`,{error:o instanceof Error?o.message:String(o),stack:o instanceof Error?o.stack:void 0}),o}}catch(n){return console.warn(`[LogMethod] Logging failed for ${t}:`,n),await i.apply(this,s)}else return await i.apply(this,s)}}function _(l=1e3){return function(t,e,i){const s=i.value;i.value=async function(...a){const n=Date.now();try{const o=await s.apply(this,a),h=Date.now()-n,c=this.logger;if(c&&h>l)try{await c.warn(`Slow method detected: ${e} took ${h}ms`,{threshold:l,duration:h,methodName:e,className:this.constructor.name,args:a.length,timestamp:new Date().toISOString()})}catch(d){console.warn(`[LogPerformance] Logging failed for ${e}:`,d)}return o}catch(o){const h=Date.now()-n,c=this.logger;if(c)try{await c.error(`Method ${e} failed after ${h}ms`,{threshold:l,duration:h,methodName:e,className:this.constructor.name,error:o instanceof Error?o.message:String(o)})}catch(d){console.warn(`[LogPerformance] Logging failed for ${e}:`,d)}throw o}}}}function L(l=\"debug\"){return function(t,e,i){const s=i.value;i.value=async function(...a){const n=this.logger,o=`${this.constructor.name}.${e}`;if(n){const h=Date.now();try{await n[l](`\\u2192 Entering ${o}`,{args:a.map((g,m)=>({index:m,type:typeof g,value:typeof g==\"object\"?\"[Object]\":String(g).slice(0,100)}))});const c=await s.apply(this,a),d=Date.now()-h;return await n[l](`\\u2190 Exiting ${o} (${d}ms)`,{duration:d,resultType:typeof c,hasResult:c!==void 0}),c}catch(c){const d=Date.now()-h;throw await n.error(`\\u2717 ${o} threw error (${d}ms)`,{duration:d,error:c instanceof Error?c.message:String(c)}),c}}else return await s.apply(this,a)}}}function k(l=6e4){const t=new Map;return function(e,i,s){const a=s.value;s.value=async function(...n){const o=`${this.constructor.name}.${i}.${JSON.stringify(n)}`,h=Date.now(),c=t.get(o),d=this.logger;if(c&&c.expires>h){if(d)try{await d.debug(`Cache HIT for ${i}`,{cacheKey:o})}catch(m){console.warn(\"[LogCache] Logging failed:\",m)}return c.value}if(d)try{await d.debug(`Cache MISS for ${i}`,{cacheKey:o})}catch(m){console.warn(\"[LogCache] Logging failed:\",m)}const g=await a.apply(this,n);return t.set(o,{value:g,expires:h+l}),g}}}function B(l=3,t=1e3){return function(e,i,s){const a=s.value;s.value=async function(...n){const o=this.logger;let h;for(let c=1;c<=l;c++)try{return o&&c>1&&await o.info(`Retry attempt ${c}/${l} for ${i}`),await a.apply(this,n)}catch(d){if(h=d,o)try{await o.warn(`Attempt ${c}/${l} failed for ${i}`,{attempt:c,maxRetries:l,error:d instanceof Error?d.message:String(d),willRetry:c<l})}catch(g){console.warn(\"[LogRetry] Logging failed:\",g)}if(c<l){const g=t*Math.pow(2,c-1);await new Promise(m=>setTimeout(m,g))}}if(o)try{await o.error(`All ${l} attempts failed for ${i}`,{maxRetries:l,finalError:h instanceof Error?h.message:String(h)})}catch(c){console.warn(\"[LogRetry] Final logging failed:\",c)}throw h}}}function q(l,t=\"debug\"){return function(e){return class extends e{constructor(...i){super(...i);const s=i.find(a=>a&&typeof a==\"object\"&&typeof a.createModuleLogger==\"function\");if(s&&!this.logger){const a=l||e.name;this.logger=s.createModuleLogger(a),this.moduleName=a}}}}}const v=(l,t)=>{const e=l||w.createDevelopmentConfig(),i=new E(e);return i.addTransport(new S),t&&t.length>0&&t.forEach(s=>{i.addTransport(s)}),i},G={APP:\"App\",CONFIG:\"Config\",AUTH:\"Auth\",API:\"API\",DATABASE:\"Database\",MIDDLEWARE:\"Middleware\",UTILS:\"Utils\",SECURITY:\"Security\",VALIDATION:\"Validation\",CACHE:\"Cache\",FILE_SYSTEM:\"FileSystem\",NETWORK:\"Network\",SCHEDULER:\"Scheduler\",ERROR_HANDLER:\"ErrorHandler\"};class J{constructor(t){this.moduleName=t}trace(t,...e){r.getInstance().trace(this.moduleName,t,...e)}debug(t,...e){r.getInstance().debug(this.moduleName,t,...e)}info(t,...e){r.getInstance().info(this.moduleName,t,...e)}warn(t,...e){r.getInstance().warn(this.moduleName,t,...e)}error(t,...e){r.getInstance().error(this.moduleName,t,...e)}}class r{static createDefaultConfig(){return new y().setEnabled(!0).setDefaultLevel(\"warn\").build()}static setTransports(t){r.customTransports=t,r.instance&&t.forEach(e=>{r.instance.addTransport(e)})}static addTransport(t){r.customTransports.push(t),r.instance&&r.instance.addTransport(t)}static removeTransport(t){return r.customTransports=r.customTransports.filter(e=>e.name!==t),r.instance?r.instance.removeTransport(t):!1}static listTransports(){return r.instance?r.instance.listTransports():r.customTransports.map(t=>t.name)}static initialize(t,e){if(r.isInitializing){for(;r.isInitializing;);return r.instance}if(r.instance&&!t&&!e)return r.instance;r.isInitializing=!0;const i=t||r.createDefaultConfig(),s=[...r.customTransports,...e||[]];return r.currentConfig=i,r.instance=v(i,s),r.isInitializing=!1,r.instance}static getInstance(){return r.instance?r.instance:r.initialize()}static updateConfiguration(t){const e=r.currentConfig;e&&e.enabled===t.enabled&&e.defaultLevel===t.defaultLevel&&JSON.stringify(e.modules)===JSON.stringify(t.modules)||(r.currentConfig=t,r.instance=v(t,r.customTransports))}static async flush(){r.instance&&await r.instance.flush()}static async cleanup(){r.instance&&await r.instance.cleanup()}static setEnabled(t){r.currentConfig&&(r.currentConfig.enabled=t,r.updateConfiguration(r.currentConfig))}static enableModule(t,e,i){r.currentConfig&&r.currentConfig.modules&&(r.currentConfig.modules[t]={enabled:!0,levels:e||[\"debug\",\"info\",\"warn\",\"error\"],transports:i||[\"console\"]},r.updateConfiguration(r.currentConfig))}static disableModule(t){r.currentConfig&&r.currentConfig.modules&&(r.currentConfig.modules[t]={enabled:!1,levels:[],transports:[]},r.updateConfiguration(r.currentConfig))}static createDebugConfig(){return new y().setEnabled(!0).setDefaultLevel(\"trace\").build()}static createProductionConfig(){return new y().setEnabled(!0).setDefaultLevel(\"warn\").build()}static reset(){return r.customTransports=[],r.initialize()}static getActiveProxyModules(){return Array.from(r.proxyInstances.keys())}static getCurrentConfig(){return r.currentConfig?Object.assign({},r.currentConfig):null}}r.instance=null,r.currentConfig=null,r.customTransports=[],r.isInitializing=!1,r.proxyInstances=new Map;const U=l=>{if(r.proxyInstances.has(l))return r.proxyInstances.get(l);const t=new J(l);return r.proxyInstances.set(l,t),t},u={id:{name:\"id\",type:\"integer\",primaryKey:!0,autoIncrement:!0,required:!0,description:\"ID t\\u1EF1 \\u0111\\u1ED9ng t\\u0103ng\"},timestamp:{name:\"timestamp\",type:\"timestamp\",required:!0,index:!0,description:\"Th\\u1EDDi gian log\"},level:{name:\"level\",type:\"varchar\",length:20,required:!0,index:!0,enum:[\"trace\",\"debug\",\"info\",\"warn\",\"error\"],description:\"M\\u1EE9c \\u0111\\u1ED9 log\"},module:{name:\"module\",type:\"varchar\",length:100,required:!0,index:!0,description:\"T\\xEAn module\"},message:{name:\"message\",type:\"text\",required:!0,description:\"N\\u1ED9i dung log\"},data:{name:\"data\",type:\"text\",nullable:!0,description:\"D\\u1EEF li\\u1EC7u b\\u1ED5 sung (JSON string)\"},metadata:{name:\"metadata\",type:\"text\",nullable:!0,description:\"Metadata (JSON string)\"},session_id:{name:\"session_id\",type:\"varchar\",length:100,nullable:!0,index:!0,description:\"Session ID\"},created_at:{name:\"created_at\",type:\"timestamp\",default:\"CURRENT_TIMESTAMP\",description:\"Th\\u1EDDi gian t\\u1EA1o b\\u1EA3n ghi\"}},W={version:\"1.0\",database_name:\"logger\",description:\"Database l\\u01B0u tr\\u1EEF logs c\\u1EE7a h\\u1EC7 th\\u1ED1ng\",schemas:{logs:{description:\"B\\u1EA3ng l\\u01B0u tr\\u1EEF t\\u1EA5t c\\u1EA3 logs\",cols:[Object.assign({},u.id),Object.assign({},u.timestamp),Object.assign({},u.level),Object.assign({},u.module),Object.assign({},u.message),Object.assign({},u.data),Object.assign({},u.metadata),Object.assign({},u.session_id),Object.assign({},u.created_at)],indexes:[{name:\"idx_logs_timestamp\",fields:[\"timestamp\"],description:\"Index cho timestamp \\u0111\\u1EC3 query nhanh\"},{name:\"idx_logs_level\",fields:[\"level\"],description:\"Index cho level\"},{name:\"idx_logs_module\",fields:[\"module\"],description:\"Index cho module\"},{name:\"idx_logs_session_id\",fields:[\"session_id\"],description:\"Index cho session_id\"},{name:\"idx_logs_level_module\",fields:[\"level\",\"module\"],description:\"Index composite cho level v\\xE0 module\"},{name:\"idx_logs_timestamp_level\",fields:[\"timestamp\",\"level\"],description:\"Index composite cho timestamp v\\xE0 level\"}]},error_logs:{description:\"B\\u1EA3ng l\\u01B0u tr\\u1EEF ri\\xEAng error logs\",cols:[Object.assign({},u.id),Object.assign({},u.timestamp),Object.assign({},u.module),Object.assign({},u.message),{name:\"stack_trace\",type:\"text\",nullable:!0,description:\"Stack trace c\\u1EE7a error\"},Object.assign({},u.data),Object.assign({},u.metadata),Object.assign({},u.session_id),Object.assign({},u.created_at)],indexes:[{name:\"idx_error_logs_timestamp\",fields:[\"timestamp\"],description:\"Index cho timestamp\"},{name:\"idx_error_logs_module\",fields:[\"module\"],description:\"Index cho module\"}]},log_statistics:{description:\"B\\u1EA3ng th\\u1ED1ng k\\xEA logs theo ng\\xE0y/module\",cols:[{name:\"id\",type:\"integer\",primaryKey:!0,autoIncrement:!0,required:!0},{name:\"date\",type:\"date\",required:!0,index:!0,description:\"Ng\\xE0y th\\u1ED1ng k\\xEA\"},Object.assign({},u.module),Object.assign({},u.level),{name:\"count\",type:\"integer\",required:!0,default:0,description:\"S\\u1ED1 l\\u01B0\\u1EE3ng logs\"},Object.assign({},u.created_at),{name:\"updated_at\",type:\"timestamp\",default:\"CURRENT_TIMESTAMP\",description:\"Th\\u1EDDi gian c\\u1EADp nh\\u1EADt\"}],indexes:[{name:\"idx_stats_date_module_level\",fields:[\"date\",\"module\",\"level\"],unique:!0,description:\"Index unique composite\"}]},log_sessions:{description:\"B\\u1EA3ng qu\\u1EA3n l\\xFD sessions\",cols:[{name:\"id\",type:\"integer\",primaryKey:!0,autoIncrement:!0,required:!0},Object.assign({},u.session_id),{name:\"started_at\",type:\"timestamp\",required:!0,description:\"Th\\u1EDDi gian b\\u1EAFt \\u0111\\u1EA7u session\"},{name:\"ended_at\",type:\"timestamp\",nullable:!0,description:\"Th\\u1EDDi gian k\\u1EBFt th\\xFAc session\"},{name:\"total_logs\",type:\"integer\",default:0,description:\"T\\u1ED5ng s\\u1ED1 logs trong session\"},{name:\"error_count\",type:\"integer\",default:0,description:\"S\\u1ED1 l\\u01B0\\u1EE3ng errors\"},{name:\"status\",type:\"varchar\",length:20,default:\"active\",enum:[\"active\",\"ended\",\"expired\"],description:\"Tr\\u1EA1ng th\\xE1i session\"},Object.assign({},u.created_at)],indexes:[{name:\"idx_sessions_session_id\",fields:[\"session_id\"],unique:!0,description:\"Index unique cho session_id\"},{name:\"idx_sessions_status\",fields:[\"status\"],description:\"Index cho status\"}]}}},K=\"logger\",H={LOGS:\"logs\",ERROR_LOGS:\"error_logs\",LOG_STATISTICS:\"log_statistics\",LOG_SESSIONS:\"log_sessions\"};var V=Object.freeze({__proto__:null,LOGGER_SCHEMA_NAME:K,LOGGER_TABLES:H,loggerSchema:W});export{x as ApiTransport,M as BaseModule,r as CommonLoggerConfig,G as CommonModules,S as ConsoleTransport,z as DBTransport,T as ElectronFileTransport,q as EnableLogging,k as LogCache,j as LogMethod,L as LogMethodFlow,_ as LogPerformance,B as LogRetry,y as LoggerConfigBuilder,w as LoggerUtils,F as ModuleLogger,D as NodeFileTransport,N as RNFileTransport,R as TransportFactory,E as UniversalLogger,v as createLogger,U as createModuleLogger};\n//# sourceMappingURL=index.mjs.map\n","// in @dqcai/sqlite library\r\n// ./src/logger/index.ts\r\n\r\nimport {\r\n  BaseModule,\r\n  LoggerConfigBuilder,\r\n  CommonModules,\r\n  CommonLoggerConfig,\r\n  createModuleLogger,\r\n} from \"@dqcai/logger\";\r\n\r\nconst SQLiteModules = {\r\n  ...CommonModules,\r\n  DATABASE_MANAGER: \"DatabaseManager\",\r\n  DATABASE_FACTORY: \"DatabaseFactory\",\r\n  UNIVERSAL_DAO: \"UniversalDAO\",\r\n  BASE_SERVICE: \"BaseService\",\r\n  SERVICE_MANAGER: \"ServiceManager\",\r\n  QUERY_BUILDER: \"QueryBuilder\",\r\n  BASE_ADAPTER: \"BaseAdapter\",\r\n  NODEJS_ADAPTER: \"NodeJSAdapter\",\r\n  REACTNATIVE_ADAPTER: \"RN-Adapter\",\r\n  UNIVERSAL_SQLITE: \"UniversalSQLite\",\r\n  TRANSACTION: \"Transaction\",\r\n  CONNECTION: \"Connection\",\r\n};\r\n\r\n\r\n// ✅ Helper function để config logger\r\nexport function configureSQLiteLogger(\r\n  enabled: boolean = true,\r\n  defaultLevel: 'trace' | 'debug' | 'info' | 'warn' | 'error' = 'warn'\r\n) {\r\n  // console.log(`🔧 [SQLite] Configuring logger: enabled=${enabled}, level=${defaultLevel}`);\r\n  \r\n  const config = new LoggerConfigBuilder()\r\n    .setEnabled(enabled)\r\n    .setDefaultLevel(defaultLevel)\r\n    .build();\r\n    \r\n  CommonLoggerConfig.updateConfiguration(config);\r\n  \r\n  // console.log(\"✅ [SQLite] Logger configured:\", CommonLoggerConfig.getCurrentConfig());\r\n}\r\n\r\n// khởi tạo default config cho thư viện\r\nconfigureSQLiteLogger(true, 'warn');\r\n\r\n// ✅ Export utilities only\r\nexport { BaseModule, createModuleLogger, SQLiteModules, CommonLoggerConfig };","// src/core/universal-dao.ts\r\nimport {\r\n  ColumnDefinition,\r\n  DatabaseSchema,\r\n  ImportOptions,\r\n  ImportResult,\r\n  IndexDefinition,\r\n  QueryTable,\r\n  SQLiteAdapter,\r\n  SQLiteConnection,\r\n  SQLiteResult,\r\n  SQLiteRow,\r\n  TableDefinition,\r\n  TypeMappingConfig,\r\n  WhereClause,\r\n  ColumnMapping,\r\n} from \"@/types\";\r\n\r\n// Import logger configuration for internal use\r\nimport { SQLiteModules, createModuleLogger } from \"@/logger\";\r\nconst logger = createModuleLogger(SQLiteModules.UNIVERSAL_DAO);\r\n\r\nexport class UniversalDAO {\r\n  private connection: SQLiteConnection | null = null;\r\n  private isConnected: boolean = false;\r\n  private inTransaction: boolean = false;\r\n  private typeMappingConfig: TypeMappingConfig[\"type_mapping\"] | null = null;\r\n  private createIfNotExists: boolean = false;\r\n  private forceRecreate: boolean = false;\r\n\r\n  constructor(\r\n    private adapter: SQLiteAdapter,\r\n    private dbPath: string,\r\n    private options?: {\r\n      createIfNotExists?: boolean; // Mặc định false - không tạo mới nếu đã tồn tại\r\n      forceRecreate?: boolean; // Mặc định false - ép tạo lại = true\r\n    }\r\n  ) {\r\n    this.createIfNotExists = options?.createIfNotExists ?? false;\r\n    this.forceRecreate = options?.forceRecreate ?? false;\r\n\r\n    logger.trace(\"UniversalDAO constructor initialized\", {\r\n      dbPath: this.dbPath,\r\n      createIfNotExists: this.createIfNotExists,\r\n      forceRecreate: this.forceRecreate,\r\n    });\r\n  }\r\n\r\n  async connect(): Promise<void> {\r\n    logger.trace(\"Attempting to connect to database\", {\r\n      dbPath: this.dbPath,\r\n    });\r\n\r\n    if (this.isConnected) {\r\n      logger.debug(\"Already connected to database, skipping connection\");\r\n      return;\r\n    }\r\n\r\n    try {\r\n      this.connection = await this.adapter.connect(this.dbPath);\r\n      this.isConnected = true;\r\n      logger.info(\"Successfully connected to database\", {\r\n        dbPath: this.dbPath,\r\n      });\r\n    } catch (error) {\r\n      logger.error(\"Failed to connect to database\", {\r\n        dbPath: this.dbPath,\r\n        error: error instanceof Error ? error.message : error,\r\n      });\r\n      throw error;\r\n    }\r\n  }\r\n\r\n  async disconnect(): Promise<void> {\r\n    logger.trace(\"Attempting to disconnect from database\");\r\n\r\n    if (this.connection && this.isConnected) {\r\n      try {\r\n        await this.connection.close();\r\n        this.connection = null;\r\n        this.isConnected = false;\r\n        logger.info(\"Successfully disconnected from database\");\r\n      } catch (error) {\r\n        logger.error(\"Error during database disconnection\", {\r\n          error: error instanceof Error ? error.message : error,\r\n        });\r\n        throw error;\r\n      }\r\n    } else {\r\n      logger.debug(\"Database was not connected, nothing to disconnect\");\r\n    }\r\n  }\r\n\r\n  async close(): Promise<void> {\r\n    logger.trace(\"Closing database connection\");\r\n    await this.disconnect();\r\n  }\r\n\r\n  // Type mapping utilities\r\n  setTypeMappingConfig(config: TypeMappingConfig[\"type_mapping\"]): void {\r\n    logger.trace(\"Setting type mapping configuration\", { config });\r\n    this.typeMappingConfig = config;\r\n    logger.debug(\"Type mapping configuration updated\");\r\n  }\r\n\r\n  private convertToSQLiteType(genericType: string): string {\r\n    logger.trace(\"Converting generic type to SQLite type\", {\r\n      genericType,\r\n    });\r\n\r\n    if (!this.typeMappingConfig || !this.typeMappingConfig.sqlite) {\r\n      const defaultType = this.getDefaultSQLiteType(genericType);\r\n      logger.debug(\"Using default type mapping\", {\r\n        genericType,\r\n        sqliteType: defaultType,\r\n      });\r\n      return defaultType;\r\n    }\r\n\r\n    const sqliteMapping = this.typeMappingConfig.sqlite;\r\n    const mappedType = sqliteMapping[genericType.toLowerCase()] || \"TEXT\";\r\n    logger.debug(\"Using custom type mapping\", {\r\n      genericType,\r\n      sqliteType: mappedType,\r\n    });\r\n    return mappedType;\r\n  }\r\n\r\n  private getDefaultSQLiteType(genericType: string): string {\r\n    const defaultMapping: Record<string, string> = {\r\n      string: \"TEXT\",\r\n      varchar: \"TEXT\",\r\n      char: \"TEXT\",\r\n      email: \"TEXT\",\r\n      url: \"TEXT\",\r\n      uuid: \"TEXT\",\r\n      integer: \"INTEGER\",\r\n      bigint: \"INTEGER\",\r\n      smallint: \"INTEGER\",\r\n      tinyint: \"INTEGER\",\r\n      decimal: \"REAL\",\r\n      numeric: \"REAL\",\r\n      float: \"REAL\",\r\n      double: \"REAL\",\r\n      boolean: \"INTEGER\",\r\n      timestamp: \"TEXT\",\r\n      datetime: \"TEXT\",\r\n      date: \"TEXT\",\r\n      time: \"TEXT\",\r\n      json: \"TEXT\",\r\n      array: \"TEXT\",\r\n      blob: \"BLOB\",\r\n      binary: \"BLOB\",\r\n    };\r\n    return defaultMapping[genericType.toLowerCase()] || \"TEXT\";\r\n  }\r\n\r\n  private processColumnDefinition(col: ColumnDefinition): ColumnDefinition {\r\n    logger.trace(\"Processing column definition\", {\r\n      columnName: col.name,\r\n      originalType: col.type,\r\n    });\r\n\r\n    const processedCol: ColumnDefinition = { ...col };\r\n    processedCol.type = this.convertToSQLiteType(col.type);\r\n\r\n    const options: string[] = [];\r\n    if (col.constraints) {\r\n      logger.trace(\"Processing column constraints\", {\r\n        columnName: col.name,\r\n        constraints: col.constraints,\r\n      });\r\n\r\n      const constraints = col.constraints.toUpperCase().split(\" \");\r\n      if (constraints.includes(\"PRIMARY\")) {\r\n        options.push(\"PRIMARY KEY\");\r\n        processedCol.primary_key = true;\r\n      }\r\n      if (\r\n        constraints.includes(\"AUTO_INCREMENT\") ||\r\n        constraints.includes(\"AUTOINCREMENT\")\r\n      ) {\r\n        if (processedCol.primary_key) options.push(\"AUTOINCREMENT\");\r\n        processedCol.auto_increment = true;\r\n      }\r\n      if (constraints.includes(\"NOT\") && constraints.includes(\"NULL\")) {\r\n        options.push(\"NOT NULL\");\r\n        processedCol.nullable = false;\r\n      }\r\n      if (constraints.includes(\"UNIQUE\")) {\r\n        if (!processedCol.primary_key) options.push(\"UNIQUE\");\r\n        processedCol.unique = true;\r\n      }\r\n      // Handle DEFAULT values\r\n      const defaultIndex = constraints.indexOf(\"DEFAULT\");\r\n      if (defaultIndex !== -1 && constraints.length > defaultIndex + 1) {\r\n        const defaultValue = constraints[defaultIndex + 1];\r\n        options.push(`DEFAULT ${defaultValue}`);\r\n        processedCol.default = defaultValue;\r\n      }\r\n    }\r\n\r\n    processedCol.option_key = options.join(\" \").trim();\r\n    logger.debug(\"Column definition processed\", {\r\n      columnName: col.name,\r\n      finalType: processedCol.type,\r\n      options: processedCol.option_key,\r\n    });\r\n\r\n    return processedCol;\r\n  }\r\n\r\n  // Schema initialization with enhanced options\r\n  async initializeFromSchema(schema: DatabaseSchema): Promise<void> {\r\n    logger.info(\"Initializing database schema\", {\r\n      schemaVersion: schema.version,\r\n      tableCount: Object.keys(schema.schemas).length,\r\n    });\r\n\r\n    this.ensureConnected();\r\n\r\n    // Check if schema already exists\r\n    let hasExistingSchema = false;\r\n    try {\r\n      const result = await this.execute(\r\n        \"SELECT version FROM _schema_info ORDER BY applied_at DESC LIMIT 1\"\r\n      );\r\n      hasExistingSchema = result.rows.length > 0;\r\n      if (hasExistingSchema) {\r\n        logger.debug(\"Existing schema detected\", {\r\n          currentVersion: result.rows[0]?.version,\r\n        });\r\n      }\r\n    } catch (error) {\r\n      logger.debug(\r\n        \"The first time for init from Schema! No existing schema _schema_info detected\"\r\n      );\r\n      hasExistingSchema = false;\r\n    }\r\n\r\n    // Handle existing schema based on options\r\n    if (hasExistingSchema && !this.createIfNotExists && !this.forceRecreate) {\r\n      logger.info(\r\n        \"Schema exists and no recreation options set, using existing schema\"\r\n      );\r\n      if (schema.type_mapping) {\r\n        this.setTypeMappingConfig(schema.type_mapping);\r\n      }\r\n      return;\r\n    }\r\n\r\n    if (hasExistingSchema && this.forceRecreate) {\r\n      logger.warn(\r\n        \"Force recreate option enabled, dropping all existing tables\"\r\n      );\r\n      await this.dropAllTables();\r\n    }\r\n\r\n    if (schema.type_mapping) {\r\n      this.setTypeMappingConfig(schema.type_mapping);\r\n    }\r\n\r\n    try {\r\n      logger.debug(\"Enabling foreign key constraints\");\r\n      await this.execute(\"PRAGMA foreign_keys = ON\");\r\n    } catch (error) {\r\n      logger.warn(\"Failed to enable foreign key constraints\", {\r\n        error: error instanceof Error ? error.message : error,\r\n      });\r\n    }\r\n\r\n    await this.beginTransaction();\r\n\r\n    try {\r\n      logger.info(\"Creating tables from schema\");\r\n      for (const [tableName, tableConfig] of Object.entries(schema.schemas)) {\r\n        logger.debug(\"Creating table\", {\r\n          tableName,\r\n          columnCount: tableConfig.cols.length,\r\n        });\r\n\r\n        const tableDefinition: TableDefinition = {\r\n          name: tableName,\r\n          cols: tableConfig.cols.map((col) =>\r\n            this.processColumnDefinition(col)\r\n          ),\r\n          description: tableConfig.description,\r\n          indexes: tableConfig.indexes,\r\n          foreign_keys: tableConfig.foreign_keys,\r\n        };\r\n        await this.createTableWithForeignKeys(tableDefinition);\r\n      }\r\n\r\n      logger.info(\"Creating indexes for tables\");\r\n      for (const [tableName, tableConfig] of Object.entries(schema.schemas)) {\r\n        if (tableConfig.indexes?.length) {\r\n          logger.debug(\"Creating indexes for table\", {\r\n            tableName,\r\n            indexCount: tableConfig.indexes.length,\r\n          });\r\n          await this.createIndexesForTable(tableName, tableConfig.indexes);\r\n        }\r\n      }\r\n\r\n      await this.setSchemaVersion(schema.version);\r\n      await this.commitTransaction();\r\n      logger.info(\"Schema initialization completed successfully\", {\r\n        version: schema.version,\r\n      });\r\n    } catch (error) {\r\n      logger.error(\"Schema initialization failed, rolling back transaction\", {\r\n        error: error instanceof Error ? error.message : error,\r\n      });\r\n      await this.rollbackTransaction();\r\n      throw error;\r\n    }\r\n  }\r\n\r\n  private async dropAllTables(): Promise<void> {\r\n    logger.info(\"Dropping all existing tables\");\r\n\r\n    const tables = await this.execute(\r\n      \"SELECT name FROM sqlite_master WHERE type='table' AND name NOT LIKE 'sqlite_%'\"\r\n    );\r\n\r\n    logger.debug(\"Found tables to drop\", {\r\n      tableCount: tables.rows.length,\r\n    });\r\n\r\n    await this.beginTransaction();\r\n\r\n    try {\r\n      for (const table of tables.rows) {\r\n        logger.trace(\"Dropping table\", { tableName: table.name });\r\n        await this.execute(`DROP TABLE IF EXISTS ${table.name}`);\r\n      }\r\n      await this.commitTransaction();\r\n      logger.info(\"All tables dropped successfully\");\r\n    } catch (error) {\r\n      logger.error(\"Failed to drop tables, rolling back\", {\r\n        error: error instanceof Error ? error.message : error,\r\n      });\r\n      await this.rollbackTransaction();\r\n      throw error;\r\n    }\r\n  }\r\n\r\n  private async createTableWithForeignKeys(\r\n    table: TableDefinition\r\n  ): Promise<void> {\r\n    logger.trace(\"Creating table with foreign keys\", {\r\n      tableName: table.name,\r\n    });\r\n\r\n    const columnDefs = table.cols.map((col) =>\r\n      `${col.name} ${col.type} ${col.option_key || \"\"}`.trim()\r\n    );\r\n\r\n    const foreignKeyDefs: string[] = [];\r\n\r\n    // Hỗ trợ cả foreign_keys và foreignKeys\r\n    const foreignKeys = table.foreign_keys;\r\n\r\n    if (foreignKeys) {\r\n      logger.debug(\"Processing foreign keys\", {\r\n        tableName: table.name,\r\n        fkCount: foreignKeys.length,\r\n      });\r\n\r\n      for (const fk of foreignKeys) {\r\n        // Lấy column(s) - hỗ trợ cả snake_case và camelCase, số ít và số nhiều\r\n        const columns: string[] = fk.columns\r\n          ? Array.isArray(fk.columns)\r\n            ? (fk.columns as any)\r\n            : [fk.columns]\r\n          : [];\r\n\r\n        if (columns.length === 0) {\r\n          logger.warn(\"Foreign key without columns found\", {\r\n            tableName: table.name,\r\n            foreignKey: fk,\r\n          });\r\n          continue;\r\n        }\r\n\r\n        // Lấy reference table\r\n        const refTable = fk.references?.table;\r\n\r\n        // Lấy reference column(s) - hỗ trợ cả số ít và số nhiều\r\n        const refColumns: string[] = fk.references?.columns\r\n          ? Array.isArray(fk.references?.columns)\r\n            ? (fk.references?.columns as any)\r\n            : [fk.references?.columns]\r\n          : [];\r\n\r\n        if (!refTable || refColumns.length === 0) {\r\n          logger.warn(\"Invalid foreign key reference\", {\r\n            tableName: table.name,\r\n            foreignKey: fk,\r\n          });\r\n          continue;\r\n        }\r\n\r\n        // Tạo foreign key SQL\r\n        let fkSql = `FOREIGN KEY (${columns.join(\r\n          \", \"\r\n        )}) REFERENCES ${refTable}(${refColumns.join(\", \")})`;\r\n\r\n        // Hỗ trợ cả on_delete/onDelete và on_update/onUpdate\r\n        const onDelete = fk.on_delete;\r\n        const onUpdate = fk.on_update;\r\n\r\n        if (onDelete) fkSql += ` ON DELETE ${onDelete}`;\r\n        if (onUpdate) fkSql += ` ON UPDATE ${onUpdate}`;\r\n\r\n        foreignKeyDefs.push(fkSql);\r\n      }\r\n    }\r\n\r\n    const allDefs = [...columnDefs, ...foreignKeyDefs];\r\n    const sql = `CREATE TABLE IF NOT EXISTS ${table.name} (${allDefs.join(\r\n      \", \"\r\n    )})`;\r\n\r\n    try {\r\n      await this.execute(sql);\r\n      logger.debug(\"Table created successfully\", {\r\n        tableName: table.name,\r\n      });\r\n    } catch (error) {\r\n      logger.error(\"Failed to create table\", {\r\n        tableName: table.name,\r\n        sql,\r\n        error: error instanceof Error ? error.message : error,\r\n      });\r\n      throw error;\r\n    }\r\n  }\r\n\r\n  private async createIndexesForTable(\r\n    tableName: string,\r\n    indexes: IndexDefinition[]\r\n  ): Promise<void> {\r\n    logger.trace(\"Creating indexes for table\", {\r\n      tableName,\r\n      indexCount: indexes.length,\r\n    });\r\n\r\n    for (const index of indexes) {\r\n      const columns = index.columns.join(\", \");\r\n      const isUnique = index.unique || false;\r\n      const sql = `CREATE ${isUnique ? \"UNIQUE\" : \"\"} INDEX IF NOT EXISTS ${\r\n        index.name\r\n      } ON ${tableName} (${columns})`;\r\n\r\n      try {\r\n        await this.execute(sql);\r\n        logger.debug(\"Index created successfully\", {\r\n          indexName: index.name,\r\n          tableName,\r\n          columns: index.columns,\r\n          unique: isUnique,\r\n        });\r\n      } catch (error) {\r\n        logger.error(\"Failed to create index\", {\r\n          indexName: index.name,\r\n          tableName,\r\n          sql,\r\n          error: error instanceof Error ? error.message : error,\r\n        });\r\n        throw error;\r\n      }\r\n    }\r\n  }\r\n\r\n  // Transaction management\r\n  async beginTransaction(): Promise<void> {\r\n    logger.trace(\"Beginning transaction\");\r\n\r\n    if (this.inTransaction) {\r\n      const error = new Error(\"Transaction already in progress\");\r\n      logger.error(\"Cannot begin transaction\", { error: error.message });\r\n      throw error;\r\n    }\r\n\r\n    try {\r\n      await this.execute(\"BEGIN TRANSACTION\");\r\n      this.inTransaction = true;\r\n      logger.debug(\"Transaction started successfully\");\r\n    } catch (error) {\r\n      logger.error(\"Failed to begin transaction\", {\r\n        error: error instanceof Error ? error.message : error,\r\n      });\r\n      throw error;\r\n    }\r\n  }\r\n\r\n  async commitTransaction(): Promise<void> {\r\n    logger.trace(\"Committing transaction\");\r\n\r\n    if (!this.inTransaction) {\r\n      const error = new Error(\"No transaction in progress\");\r\n      logger.error(\"Cannot commit transaction\", { error: error.message });\r\n      throw error;\r\n    }\r\n\r\n    try {\r\n      await this.execute(\"COMMIT\");\r\n      this.inTransaction = false;\r\n      logger.debug(\"Transaction committed successfully\");\r\n    } catch (error) {\r\n      logger.error(\"Failed to commit transaction\", {\r\n        error: error instanceof Error ? error.message : error,\r\n      });\r\n      throw error;\r\n    }\r\n  }\r\n\r\n  async rollbackTransaction(): Promise<void> {\r\n    logger.trace(\"Rolling back transaction\");\r\n\r\n    if (!this.inTransaction) {\r\n      const error = new Error(\"No transaction in progress\");\r\n      logger.error(\"Cannot rollback transaction\", {\r\n        error: error.message,\r\n      });\r\n      throw error;\r\n    }\r\n\r\n    try {\r\n      await this.execute(\"ROLLBACK\");\r\n      this.inTransaction = false;\r\n      logger.debug(\"Transaction rolled back successfully\");\r\n    } catch (error) {\r\n      logger.error(\"Failed to rollback transaction\", {\r\n        error: error instanceof Error ? error.message : error,\r\n      });\r\n      throw error;\r\n    }\r\n  }\r\n\r\n  // Schema management\r\n  async getSchemaVersion(): Promise<string> {\r\n    logger.trace(\"Getting schema version\");\r\n\r\n    try {\r\n      const result = await this.getRst(\r\n        \"SELECT version FROM _schema_info ORDER BY applied_at DESC LIMIT 1\"\r\n      );\r\n      const version = result.version || \"0\";\r\n      logger.debug(\"Schema version retrieved\", { version });\r\n      return version;\r\n    } catch (error) {\r\n      logger.debug(\"No schema version found, returning default\", {\r\n        defaultVersion: \"0\",\r\n      });\r\n      return \"0\";\r\n    }\r\n  }\r\n\r\n  async setSchemaVersion(version: string): Promise<void> {\r\n    logger.trace(\"Setting schema version\", { version });\r\n\r\n    try {\r\n      await this.execute(`CREATE TABLE IF NOT EXISTS _schema_info (\r\n        version TEXT NOT NULL,\r\n        applied_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP\r\n      )`);\r\n      await this.execute(`INSERT INTO _schema_info (version) VALUES (?)`, [\r\n        version,\r\n      ]);\r\n      logger.info(\"Schema version set successfully\", { version });\r\n    } catch (error) {\r\n      logger.error(\"Failed to set schema version\", {\r\n        version,\r\n        error: error instanceof Error ? error.message : error,\r\n      });\r\n      throw error;\r\n    }\r\n  }\r\n\r\n  // CRUD Operations\r\n  async insert(insertTable: QueryTable): Promise<SQLiteResult> {\r\n    logger.trace(\"Performing insert operation\", {\r\n      tableName: insertTable.name,\r\n    });\r\n\r\n    const validCols = insertTable.cols.filter(\r\n      (col) => col.value !== undefined && col.value !== null\r\n    );\r\n\r\n    if (validCols.length === 0) {\r\n      const error = new Error(\"No valid columns to insert\");\r\n      logger.error(\"Insert operation failed\", {\r\n        tableName: insertTable.name,\r\n        error: error.message,\r\n      });\r\n      throw error;\r\n    }\r\n\r\n    const columnNames = validCols.map((col) => col.name).join(\", \");\r\n    const placeholders = validCols.map(() => \"?\").join(\", \");\r\n    const params = validCols.map((col) =>\r\n      typeof col.value === \"object\" ? JSON.stringify(col.value) : col.value\r\n    );\r\n\r\n    const sql = `INSERT INTO ${insertTable.name} (${columnNames}) VALUES (${placeholders})`;\r\n\r\n    logger.debug(\"Executing insert query\", {\r\n      tableName: insertTable.name,\r\n      columnCount: validCols.length,\r\n      sql,\r\n    });\r\n\r\n    try {\r\n      const result = await this.execute(sql, params);\r\n      logger.info(\"Insert operation completed successfully\", {\r\n        tableName: insertTable.name,\r\n        rowsAffected: result.rowsAffected,\r\n        lastInsertRowid: result.lastInsertRowId,\r\n      });\r\n      return result;\r\n    } catch (error) {\r\n      logger.error(\"Insert operation failed\", {\r\n        tableName: insertTable.name,\r\n        sql,\r\n        error: error instanceof Error ? error.message : error,\r\n      });\r\n      throw error;\r\n    }\r\n  }\r\n\r\n  async update(updateTable: QueryTable): Promise<SQLiteResult> {\r\n    logger.trace(\"Performing update operation\", {\r\n      tableName: updateTable.name,\r\n    });\r\n\r\n    const setCols = updateTable.cols.filter(\r\n      (col) =>\r\n        col.value !== undefined &&\r\n        !updateTable.wheres?.some((w) => w.name === col.name)\r\n    );\r\n\r\n    if (setCols.length === 0) {\r\n      const error = new Error(\"No columns to update\");\r\n      logger.error(\"Update operation failed\", {\r\n        tableName: updateTable.name,\r\n        error: error.message,\r\n      });\r\n      throw error;\r\n    }\r\n\r\n    const setClause = setCols.map((col) => `${col.name} = ?`).join(\", \");\r\n    const params = setCols.map((col) =>\r\n      typeof col.value === \"object\" ? JSON.stringify(col.value) : col.value\r\n    );\r\n\r\n    let sql = `UPDATE ${updateTable.name} SET ${setClause}`;\r\n    const whereClause = this.buildWhereClause(updateTable.wheres);\r\n\r\n    if (!whereClause.sql) {\r\n      const error = new Error(\"WHERE clause is required for UPDATE operation\");\r\n      logger.error(\"Update operation failed\", {\r\n        tableName: updateTable.name,\r\n        error: error.message,\r\n      });\r\n      throw error;\r\n    }\r\n\r\n    sql += whereClause.sql;\r\n    params.push(...whereClause.params);\r\n\r\n    logger.debug(\"Executing update query\", {\r\n      tableName: updateTable.name,\r\n      updateColumnCount: setCols.length,\r\n      whereConditions: updateTable.wheres?.length || 0,\r\n      sql,\r\n    });\r\n\r\n    try {\r\n      const result = await this.execute(sql, params);\r\n      logger.info(\"Update operation completed successfully\", {\r\n        tableName: updateTable.name,\r\n        rowsAffected: result.rowsAffected,\r\n      });\r\n      return result;\r\n    } catch (error) {\r\n      logger.error(\"Update operation failed\", {\r\n        tableName: updateTable.name,\r\n        sql,\r\n        error: error instanceof Error ? error.message : error,\r\n      });\r\n      throw error;\r\n    }\r\n  }\r\n\r\n  async delete(deleteTable: QueryTable): Promise<SQLiteResult> {\r\n    logger.trace(\"Performing delete operation\", {\r\n      tableName: deleteTable.name,\r\n    });\r\n\r\n    let sql = `DELETE FROM ${deleteTable.name}`;\r\n    const whereClause = this.buildWhereClause(deleteTable.wheres);\r\n\r\n    if (!whereClause.sql) {\r\n      const error = new Error(\"WHERE clause is required for DELETE operation\");\r\n      logger.error(\"Delete operation failed\", {\r\n        tableName: deleteTable.name,\r\n        error: error.message,\r\n      });\r\n      throw error;\r\n    }\r\n\r\n    sql += whereClause.sql;\r\n\r\n    logger.debug(\"Executing delete query\", {\r\n      tableName: deleteTable.name,\r\n      whereConditions: deleteTable.wheres?.length || 0,\r\n      sql,\r\n    });\r\n\r\n    try {\r\n      const result = await this.execute(sql, whereClause.params);\r\n      logger.info(\"Delete operation completed successfully\", {\r\n        tableName: deleteTable.name,\r\n        rowsAffected: result.rowsAffected,\r\n      });\r\n      return result;\r\n    } catch (error) {\r\n      logger.error(\"Delete operation failed\", {\r\n        tableName: deleteTable.name,\r\n        sql,\r\n        error: error instanceof Error ? error.message : error,\r\n      });\r\n      throw error;\r\n    }\r\n  }\r\n\r\n  async select(selectTable: QueryTable): Promise<SQLiteRow> {\r\n    logger.trace(\"Performing select single operation\", {\r\n      tableName: selectTable.name,\r\n    });\r\n\r\n    const { sql, params } = this.buildSelectQuery(selectTable, \" LIMIT 1\");\r\n\r\n    logger.debug(\"Executing select single query\", {\r\n      tableName: selectTable.name,\r\n      sql,\r\n    });\r\n\r\n    try {\r\n      const result = await this.execute(sql, params);\r\n      const row = result.rows[0] || {};\r\n      logger.debug(\"Select single operation completed\", {\r\n        tableName: selectTable.name,\r\n        hasResult: !!result.rows[0],\r\n      });\r\n      return row;\r\n    } catch (error) {\r\n      logger.error(\"Select single operation failed\", {\r\n        tableName: selectTable.name,\r\n        sql,\r\n        error: error instanceof Error ? error.message : error,\r\n      });\r\n      throw error;\r\n    }\r\n  }\r\n\r\n  async selectAll(selectTable: QueryTable): Promise<SQLiteRow[]> {\r\n    logger.trace(\"Performing select all operation\", {\r\n      tableName: selectTable.name,\r\n    });\r\n\r\n    const { sql, params } = this.buildSelectQuery(selectTable);\r\n\r\n    logger.debug(\"Executing select all query\", {\r\n      tableName: selectTable.name,\r\n      sql,\r\n    });\r\n\r\n    try {\r\n      const result = await this.execute(sql, params);\r\n      logger.debug(\"Select all operation completed\", {\r\n        tableName: selectTable.name,\r\n        rowCount: result.rows.length,\r\n      });\r\n      return result.rows;\r\n    } catch (error) {\r\n      logger.error(\"Select all operation failed\", {\r\n        tableName: selectTable.name,\r\n        sql,\r\n        error: error instanceof Error ? error.message : error,\r\n      });\r\n      throw error;\r\n    }\r\n  }\r\n\r\n  // Utility methods\r\n  private buildSelectQuery(\r\n    selectTable: QueryTable,\r\n    suffix: string = \"\"\r\n  ): { sql: string; params: any[] } {\r\n    const columns =\r\n      selectTable.cols.length > 0\r\n        ? selectTable.cols.map((col) => col.name).join(\", \")\r\n        : \"*\";\r\n\r\n    let sql = `SELECT ${columns} FROM ${selectTable.name}`;\r\n    const whereClause = this.buildWhereClause(selectTable.wheres);\r\n    sql += whereClause.sql;\r\n\r\n    if (selectTable.orderbys?.length) {\r\n      const orderBy = selectTable.orderbys\r\n        .map((o) => `${o.name} ${o.direction || \"ASC\"}`)\r\n        .join(\", \");\r\n      sql += ` ORDER BY ${orderBy}`;\r\n    }\r\n\r\n    if (selectTable.limitOffset) {\r\n      if (selectTable.limitOffset.limit)\r\n        sql += ` LIMIT ${selectTable.limitOffset.limit}`;\r\n      if (selectTable.limitOffset.offset)\r\n        sql += ` OFFSET ${selectTable.limitOffset.offset}`;\r\n    }\r\n\r\n    sql += suffix;\r\n    return { sql, params: whereClause.params };\r\n  }\r\n\r\n  private buildWhereClause(\r\n    wheres?: WhereClause[],\r\n    clause: string = \"WHERE\"\r\n  ): { sql: string; params: any[] } {\r\n    if (!wheres || wheres.length === 0) {\r\n      return { sql: \"\", params: [] };\r\n    }\r\n\r\n    const conditions: string[] = [];\r\n    const params: any[] = [];\r\n\r\n    for (const where of wheres) {\r\n      const operator = where.operator || \"=\";\r\n      conditions.push(`${where.name} ${operator} ?`);\r\n      params.push(where.value);\r\n    }\r\n\r\n    return { sql: ` ${clause} ${conditions.join(\" AND \")}`, params };\r\n  }\r\n\r\n  convertJsonToQueryTable(\r\n    tableName: string,\r\n    json: Record<string, any>,\r\n    idFields: string[] = [\"id\"]\r\n  ): QueryTable {\r\n    logger.trace(\"Converting JSON to QueryTable\", {\r\n      tableName,\r\n      fieldCount: Object.keys(json).length,\r\n      idFields,\r\n    });\r\n\r\n    const queryTable: QueryTable = { name: tableName, cols: [], wheres: [] };\r\n\r\n    for (const [key, value] of Object.entries(json)) {\r\n      queryTable.cols.push({ name: key, value });\r\n      if (idFields.includes(key) && value !== undefined) {\r\n        queryTable.wheres?.push({ name: key, value });\r\n      }\r\n    }\r\n\r\n    logger.debug(\"JSON converted to QueryTable\", {\r\n      tableName,\r\n      columnCount: queryTable.cols.length,\r\n      whereCount: queryTable.wheres?.length || 0,\r\n    });\r\n\r\n    return queryTable;\r\n  }\r\n\r\n  // Enhanced Data Import functionality\r\n  async importData(options: ImportOptions): Promise<ImportResult> {\r\n    logger.info(\"Starting data import operation\", {\r\n      tableName: options.tableName,\r\n      totalRows: options.data.length,\r\n      batchSize: options.batchSize || 1000,\r\n      validateData: options.validateData,\r\n      updateOnConflict: options.updateOnConflict,\r\n      skipErrors: options.skipErrors,\r\n    });\r\n\r\n    const startTime = Date.now();\r\n    const result: ImportResult = {\r\n      totalRows: options.data.length,\r\n      successRows: 0,\r\n      errorRows: 0,\r\n      errors: [],\r\n      executionTime: 0,\r\n    };\r\n\r\n    if (!this.isConnected) {\r\n      const error = new Error(\"Database is not connected\");\r\n      logger.error(\"Import failed - database not connected\");\r\n      throw error;\r\n    }\r\n\r\n    if (!options.data || options.data.length === 0) {\r\n      logger.warn(\"No data provided for import, returning empty result\");\r\n      result.executionTime = Date.now() - startTime;\r\n      return result;\r\n    }\r\n\r\n    const tableInfo = await this.getTableInfo(options.tableName);\r\n    if (tableInfo.length === 0) {\r\n      const error = new Error(`Table '${options.tableName}' does not exist`);\r\n      logger.error(\"Import failed - table does not exist\", {\r\n        tableName: options.tableName,\r\n      });\r\n      throw error;\r\n    }\r\n\r\n    logger.debug(\"Table info retrieved for import\", {\r\n      tableName: options.tableName,\r\n      columnCount: tableInfo.length,\r\n    });\r\n\r\n    const columnMap = new Map(\r\n      tableInfo.map((col) => [col.name.toLowerCase(), col])\r\n    );\r\n    const batchSize = options.batchSize || 1000;\r\n    let processedCount = 0;\r\n    const skipAutoIncrementPK = !options.includeAutoIncrementPK;\r\n\r\n    try {\r\n      await this.beginTransaction();\r\n\r\n      for (let i = 0; i < options.data.length; i += batchSize) {\r\n        const batch = options.data.slice(i, i + batchSize);\r\n        logger.debug(\"Processing import batch\", {\r\n          batchNumber: Math.floor(i / batchSize) + 1,\r\n          batchSize: batch.length,\r\n          totalBatches: Math.ceil(options.data.length / batchSize),\r\n        });\r\n\r\n        for (let j = 0; j < batch.length; j++) {\r\n          const rowIndex = i + j;\r\n          const rowData = batch[j];\r\n\r\n          try {\r\n            const processedData = options.validateData\r\n              ? this.validateAndTransformRow(\r\n                  rowData,\r\n                  columnMap,\r\n                  options.tableName,\r\n                  skipAutoIncrementPK\r\n                )\r\n              : this.transformRowData(rowData, columnMap, skipAutoIncrementPK);\r\n\r\n            if (options.updateOnConflict && options.conflictColumns) {\r\n              await this.insertOrUpdate(\r\n                options.tableName,\r\n                processedData,\r\n                options.conflictColumns\r\n              );\r\n            } else {\r\n              await this.insertRow(options.tableName, processedData);\r\n            }\r\n\r\n            result.successRows++;\r\n          } catch (error) {\r\n            result.errorRows++;\r\n            const errorInfo = {\r\n              rowIndex,\r\n              error: error instanceof Error ? error.message : String(error),\r\n              rowData,\r\n            };\r\n            result.errors.push(errorInfo);\r\n\r\n            logger.warn(\"Row import failed\", {\r\n              rowIndex,\r\n              tableName: options.tableName,\r\n              error: error instanceof Error ? error.message : error,\r\n            });\r\n\r\n            if (options.onError) {\r\n              options.onError(\r\n                error instanceof Error ? error : new Error(String(error)),\r\n                rowIndex,\r\n                rowData\r\n              );\r\n            }\r\n\r\n            if (!options.skipErrors) {\r\n              logger.error(\r\n                \"Import operation stopped due to error and skipErrors=false\"\r\n              );\r\n              throw error;\r\n            }\r\n          }\r\n\r\n          processedCount++;\r\n          if (options.onProgress && processedCount % 100 === 0) {\r\n            options.onProgress(processedCount, options.data.length);\r\n          }\r\n        }\r\n      }\r\n\r\n      await this.commitTransaction();\r\n      logger.info(\"Data import completed successfully\", {\r\n        tableName: options.tableName,\r\n        totalRows: result.totalRows,\r\n        successRows: result.successRows,\r\n        errorRows: result.errorRows,\r\n        executionTime: Date.now() - startTime,\r\n      });\r\n    } catch (error) {\r\n      logger.error(\"Import operation failed, rolling back transaction\", {\r\n        tableName: options.tableName,\r\n        processedCount,\r\n        error: error instanceof Error ? error.message : error,\r\n      });\r\n      await this.rollbackTransaction();\r\n      throw error;\r\n    }\r\n\r\n    if (options.onProgress) {\r\n      options.onProgress(processedCount, options.data.length);\r\n    }\r\n\r\n    result.executionTime = Date.now() - startTime;\r\n    return result;\r\n  }\r\n\r\n  // Import with column mapping\r\n  async importDataWithMapping(\r\n    tableName: string,\r\n    data: Record<string, any>[],\r\n    columnMappings: ColumnMapping[],\r\n    options: Partial<ImportOptions> = {}\r\n  ): Promise<ImportResult> {\r\n    logger.info(\"Starting data import with column mapping\", {\r\n      tableName,\r\n      dataRows: data.length,\r\n      mappingCount: columnMappings.length,\r\n    });\r\n\r\n    const transformedData = data.map((row, index) => {\r\n      logger.trace(\"Transforming row with column mappings\", {\r\n        rowIndex: index,\r\n      });\r\n      const newRow: Record<string, any> = {};\r\n\r\n      columnMappings.forEach((mapping) => {\r\n        if (row.hasOwnProperty(mapping.sourceColumn)) {\r\n          let value = row[mapping.sourceColumn];\r\n\r\n          if (mapping.transform) {\r\n            try {\r\n              value = mapping.transform(value);\r\n            } catch (error) {\r\n              logger.warn(\"Column transformation failed\", {\r\n                rowIndex: index,\r\n                sourceColumn: mapping.sourceColumn,\r\n                targetColumn: mapping.targetColumn,\r\n                error: error instanceof Error ? error.message : error,\r\n              });\r\n            }\r\n          }\r\n\r\n          newRow[mapping.targetColumn] = value;\r\n        }\r\n      });\r\n\r\n      return newRow;\r\n    });\r\n\r\n    logger.debug(\"Data transformation completed\", {\r\n      originalRowCount: data.length,\r\n      transformedRowCount: transformedData.length,\r\n    });\r\n\r\n    return await this.importData({\r\n      tableName,\r\n      data: transformedData,\r\n      ...options,\r\n    });\r\n  }\r\n\r\n  // Import from CSV\r\n  async importFromCSV(\r\n    tableName: string,\r\n    csvData: string,\r\n    options: {\r\n      delimiter?: string;\r\n      hasHeader?: boolean;\r\n      columnMappings?: ColumnMapping[];\r\n    } & Partial<ImportOptions> = {}\r\n  ): Promise<ImportResult> {\r\n    logger.info(\"Starting CSV import\", {\r\n      tableName,\r\n      csvLength: csvData.length,\r\n      delimiter: options.delimiter || \",\",\r\n      hasHeader: options.hasHeader !== false,\r\n    });\r\n\r\n    const delimiter = options.delimiter || \",\";\r\n    const hasHeader = options.hasHeader !== false;\r\n\r\n    const lines = csvData.split(\"\\n\").filter((line) => line.trim());\r\n    if (lines.length === 0) {\r\n      const error = new Error(\"CSV data is empty\");\r\n      logger.error(\"CSV import failed - empty data\");\r\n      throw error;\r\n    }\r\n\r\n    let headers: string[] = [];\r\n    let dataStartIndex = 0;\r\n\r\n    if (hasHeader) {\r\n      headers = lines[0]\r\n        .split(delimiter)\r\n        .map((h) => h.trim().replace(/^[\"']|[\"']$/g, \"\"));\r\n      dataStartIndex = 1;\r\n      logger.debug(\"CSV headers extracted\", {\r\n        headers,\r\n        headerCount: headers.length,\r\n      });\r\n    } else {\r\n      const firstRowCols = lines[0].split(delimiter).length;\r\n      headers = Array.from(\r\n        { length: firstRowCols },\r\n        (_, i) => `column_${i + 1}`\r\n      );\r\n      logger.debug(\"Generated column headers for headerless CSV\", {\r\n        columnCount: firstRowCols,\r\n        headers,\r\n      });\r\n    }\r\n\r\n    const data: Record<string, any>[] = [];\r\n    for (let i = dataStartIndex; i < lines.length; i++) {\r\n      const values = lines[i]\r\n        .split(delimiter)\r\n        .map((v) => v.trim().replace(/^[\"']|[\"']$/g, \"\"));\r\n      const row: Record<string, any> = {};\r\n\r\n      headers.forEach((header, index) => {\r\n        row[header] = values[index] || null;\r\n      });\r\n\r\n      data.push(row);\r\n    }\r\n\r\n    logger.debug(\"CSV data parsed\", {\r\n      totalLines: lines.length,\r\n      dataRows: data.length,\r\n      skipHeader: hasHeader,\r\n    });\r\n\r\n    if (options.columnMappings) {\r\n      logger.debug(\"Using column mappings for CSV import\");\r\n      return await this.importDataWithMapping(\r\n        tableName,\r\n        data,\r\n        options.columnMappings,\r\n        options\r\n      );\r\n    } else {\r\n      return await this.importData({\r\n        tableName,\r\n        data,\r\n        ...options,\r\n      });\r\n    }\r\n  }\r\n\r\n  private validateAndTransformRow(\r\n    rowData: Record<string, any>,\r\n    columnMap: Map<string, any>,\r\n    tableName: string,\r\n    skipAutoIncrementPK: boolean = true\r\n  ): Record<string, any> {\r\n    logger.trace(\"Validating and transforming row data\", { tableName });\r\n\r\n    const processedRow: Record<string, any> = {};\r\n\r\n    for (const [columnName, columnInfo] of columnMap.entries()) {\r\n      const isRequired = columnInfo.notnull === 1 && !columnInfo.dflt_value;\r\n      const isPrimaryKey = columnInfo.pk === 1;\r\n      const isAutoIncrementPK =\r\n        isPrimaryKey && columnInfo.type.toLowerCase().includes(\"integer\");\r\n\r\n      if (skipAutoIncrementPK && isAutoIncrementPK) {\r\n        continue;\r\n      }\r\n\r\n      const value = this.findValueForColumn(rowData, columnName);\r\n\r\n      if (isRequired && (value === null || value === undefined)) {\r\n        const error = new Error(\r\n          `Required column '${columnName}' is missing or null in table '${tableName}'`\r\n        );\r\n        logger.error(\"Row validation failed\", {\r\n          tableName,\r\n          columnName,\r\n          error: error.message,\r\n        });\r\n        throw error;\r\n      }\r\n\r\n      if (value !== null && value !== undefined) {\r\n        try {\r\n          processedRow[columnName] = this.convertValueToColumnType(\r\n            value,\r\n            columnInfo.type\r\n          );\r\n        } catch (error) {\r\n          logger.error(\"Value conversion failed during validation\", {\r\n            tableName,\r\n            columnName,\r\n            value,\r\n            columnType: columnInfo.type,\r\n            error: error instanceof Error ? error.message : error,\r\n          });\r\n          throw error;\r\n        }\r\n      }\r\n    }\r\n\r\n    return processedRow;\r\n  }\r\n\r\n  private transformRowData(\r\n    rowData: Record<string, any>,\r\n    columnMap: Map<string, any>,\r\n    skipAutoIncrementPK: boolean = true\r\n  ): Record<string, any> {\r\n    logger.trace(\"Transforming row data without validation\");\r\n\r\n    const processedRow: Record<string, any> = {};\r\n\r\n    for (const [key, value] of Object.entries(rowData)) {\r\n      const columnName = key.toLowerCase();\r\n      const columnInfo = columnMap.get(columnName);\r\n\r\n      if (!columnInfo) {\r\n        logger.trace(\"Column not found in table schema, skipping\", {\r\n          columnName: key,\r\n        });\r\n        continue;\r\n      }\r\n\r\n      const isPrimaryKey = columnInfo.pk === 1;\r\n      const isAutoIncrementPK =\r\n        isPrimaryKey && columnInfo.type.toLowerCase().includes(\"integer\");\r\n\r\n      if (skipAutoIncrementPK && isAutoIncrementPK) {\r\n        continue;\r\n      }\r\n\r\n      if (value !== null && value !== undefined) {\r\n        try {\r\n          processedRow[key] = this.convertValueToColumnType(\r\n            value,\r\n            columnInfo.type\r\n          );\r\n        } catch (error) {\r\n          logger.warn(\"Value conversion failed during transformation\", {\r\n            columnName: key,\r\n            value,\r\n            columnType: columnInfo.type,\r\n            error: error instanceof Error ? error.message : error,\r\n          });\r\n          // Continue processing other columns\r\n        }\r\n      }\r\n    }\r\n\r\n    return processedRow;\r\n  }\r\n\r\n  private findValueForColumn(\r\n    rowData: Record<string, any>,\r\n    columnName: string\r\n  ): any {\r\n    if (rowData.hasOwnProperty(columnName)) {\r\n      return rowData[columnName];\r\n    }\r\n\r\n    const lowerColumnName = columnName.toLowerCase();\r\n    for (const [key, value] of Object.entries(rowData)) {\r\n      if (key.toLowerCase() === lowerColumnName) {\r\n        return value;\r\n      }\r\n    }\r\n\r\n    return undefined;\r\n  }\r\n\r\n  private convertValueToColumnType(value: any, columnType: string): any {\r\n    if (value === null || value === undefined) {\r\n      return null;\r\n    }\r\n\r\n    const type = columnType.toLowerCase();\r\n\r\n    try {\r\n      if (type.includes(\"integer\") || type.includes(\"int\")) {\r\n        if (typeof value === \"boolean\") {\r\n          return value ? 1 : 0;\r\n        }\r\n        const num = parseInt(String(value));\r\n        return isNaN(num) ? null : num;\r\n      }\r\n\r\n      if (\r\n        type.includes(\"real\") ||\r\n        type.includes(\"float\") ||\r\n        type.includes(\"decimal\")\r\n      ) {\r\n        const num = parseFloat(String(value));\r\n        return isNaN(num) ? null : num;\r\n      }\r\n\r\n      if (type.includes(\"boolean\")) {\r\n        if (typeof value === \"boolean\") {\r\n          return value ? 1 : 0;\r\n        }\r\n        if (typeof value === \"string\") {\r\n          const lower = value.toLowerCase();\r\n          return lower === \"true\" || lower === \"1\" || lower === \"yes\" ? 1 : 0;\r\n        }\r\n        return value ? 1 : 0;\r\n      }\r\n\r\n      if (type.includes(\"json\")) {\r\n        if (typeof value === \"object\") {\r\n          return JSON.stringify(value);\r\n        }\r\n        if (typeof value === \"string\") {\r\n          try {\r\n            JSON.parse(value);\r\n            return value;\r\n          } catch {\r\n            throw new Error(\r\n              `Invalid JSON format for column type '${columnType}'`\r\n            );\r\n          }\r\n        }\r\n        return JSON.stringify(value);\r\n      }\r\n\r\n      if (type.includes(\"timestamp\") || type.includes(\"datetime\")) {\r\n        if (value instanceof Date) {\r\n          return value.toISOString();\r\n        }\r\n        if (typeof value === \"string\" || typeof value === \"number\") {\r\n          const date = new Date(value);\r\n          return isNaN(date.getTime()) ? value : date.toISOString();\r\n        }\r\n        return String(value);\r\n      }\r\n\r\n      return String(value);\r\n    } catch (error) {\r\n      throw new Error(\r\n        `Cannot convert value '${value}' to column type '${columnType}'`\r\n      );\r\n    }\r\n  }\r\n\r\n  private async insertRow(\r\n    tableName: string,\r\n    data: Record<string, any>\r\n  ): Promise<void> {\r\n    const columns = Object.keys(data);\r\n    const values = Object.values(data);\r\n    const placeholders = columns.map(() => \"?\").join(\", \");\r\n\r\n    const sql = `INSERT INTO ${tableName} (${columns.join(\r\n      \", \"\r\n    )}) VALUES (${placeholders})`;\r\n\r\n    try {\r\n      await this.execute(sql, values);\r\n    } catch (error) {\r\n      logger.trace(\"Insert row failed\", {\r\n        tableName,\r\n        columns,\r\n        error: error instanceof Error ? error.message : error,\r\n      });\r\n      throw error;\r\n    }\r\n  }\r\n\r\n  private async insertOrUpdate(\r\n    tableName: string,\r\n    data: Record<string, any>,\r\n    conflictColumns: string[]\r\n  ): Promise<void> {\r\n    logger.trace(\"Attempting insert or update\", {\r\n      tableName,\r\n      conflictColumns,\r\n    });\r\n\r\n    try {\r\n      await this.insertRow(tableName, data);\r\n    } catch (error) {\r\n      if (this.isConflictError(error)) {\r\n        logger.debug(\"Insert conflict detected, attempting update\", {\r\n          tableName,\r\n        });\r\n        await this.updateRowByColumns(tableName, data, conflictColumns);\r\n      } else {\r\n        throw error;\r\n      }\r\n    }\r\n  }\r\n\r\n  private async updateRowByColumns(\r\n    tableName: string,\r\n    data: Record<string, any>,\r\n    conflictColumns: string[]\r\n  ): Promise<void> {\r\n    const allColumns = Object.keys(data);\r\n    const updateColumns = allColumns.filter(\r\n      (col) => !conflictColumns.includes(col)\r\n    );\r\n    const whereColumns = conflictColumns;\r\n\r\n    if (updateColumns.length === 0) {\r\n      logger.debug(\"No columns to update, skipping update operation\", {\r\n        tableName,\r\n      });\r\n      return;\r\n    }\r\n\r\n    const setClause = updateColumns.map((col) => `${col} = ?`).join(\", \");\r\n    const whereClause = whereColumns.map((col) => `${col} = ?`).join(\" AND \");\r\n\r\n    const updateValues = updateColumns.map((col) => data[col]);\r\n    const whereValues = whereColumns.map((col) => data[col]);\r\n    const allValues = [...updateValues, ...whereValues];\r\n\r\n    const sql = `UPDATE ${tableName} SET ${setClause} WHERE ${whereClause}`;\r\n\r\n    try {\r\n      await this.execute(sql, allValues);\r\n      logger.trace(\"Update by columns completed\", {\r\n        tableName,\r\n        updateColumns,\r\n        whereColumns,\r\n      });\r\n    } catch (error) {\r\n      logger.error(\"Update by columns failed\", {\r\n        tableName,\r\n        sql,\r\n        error: error instanceof Error ? error.message : error,\r\n      });\r\n      throw error;\r\n    }\r\n  }\r\n\r\n  private isConflictError(error: any): boolean {\r\n    return (\r\n      error.code === \"SQLITE_CONSTRAINT_UNIQUE\" ||\r\n      error.code === \"SQLITE_CONSTRAINT_PRIMARYKEY\" ||\r\n      (error.message && error.message.includes(\"UNIQUE constraint failed\"))\r\n    );\r\n  }\r\n\r\n  // Database info methods\r\n  async getDatabaseInfo(): Promise<any> {\r\n    logger.trace(\"Getting database information\");\r\n\r\n    try {\r\n      const tables = await this.execute(\r\n        \"SELECT name FROM sqlite_master WHERE type='table'\"\r\n      );\r\n      const version = await this.getSchemaVersion();\r\n\r\n      const info = {\r\n        name: this.dbPath,\r\n        tables: tables.rows.map((t) => t.name),\r\n        isConnected: this.isConnected,\r\n        version,\r\n      };\r\n\r\n      logger.debug(\"Database information retrieved\", {\r\n        tableCount: info.tables.length,\r\n        isConnected: info.isConnected,\r\n        version: info.version,\r\n      });\r\n\r\n      return info;\r\n    } catch (error) {\r\n      logger.error(\"Failed to get database information\", {\r\n        error: error instanceof Error ? error.message : error,\r\n      });\r\n      throw error;\r\n    }\r\n  }\r\n\r\n  async getTableInfo(tableName: string): Promise<any[]> {\r\n    logger.trace(\"Getting table information\", { tableName });\r\n\r\n    try {\r\n      const result = await this.execute(`PRAGMA table_info(${tableName})`);\r\n      logger.debug(\"Table information retrieved\", {\r\n        tableName,\r\n        columnCount: result.rows.length,\r\n      });\r\n      return result.rows;\r\n    } catch (error) {\r\n      logger.error(\"Failed to get table information\", {\r\n        tableName,\r\n        error: error instanceof Error ? error.message : error,\r\n      });\r\n      throw error;\r\n    }\r\n  }\r\n\r\n  async dropTable(tableName: string): Promise<void> {\r\n    logger.info(\"Dropping table\", { tableName });\r\n\r\n    const sql = `DROP TABLE IF EXISTS ${tableName}`;\r\n\r\n    try {\r\n      await this.execute(sql);\r\n      logger.info(\"Table dropped successfully\", { tableName });\r\n    } catch (error) {\r\n      logger.error(\"Failed to drop table\", {\r\n        tableName,\r\n        error: error instanceof Error ? error.message : error,\r\n      });\r\n      throw error;\r\n    }\r\n  }\r\n\r\n  // Connection check method\r\n  isConnectionOpen(): boolean {\r\n    const isOpen = this.isConnected && !!this.connection;\r\n    logger.trace(\"Connection status checked\", { isOpen });\r\n    return isOpen;\r\n  }\r\n\r\n  async ensureConnected(): Promise<void> {\r\n    if (!this.isConnectionOpen()) {\r\n      logger.debug(\"Connection not open, attempting to connect\");\r\n      await this.connect();\r\n    }\r\n  }\r\n\r\n  async execute(sql: string, params: any[] = []): Promise<SQLiteResult> {\r\n    logger.trace(\"Executing SQL query\", {\r\n      sql: sql.substring(0, 100) + (sql.length > 100 ? \"...\" : \"\"),\r\n      paramCount: params.length,\r\n    });\r\n\r\n    this.ensureConnected();\r\n\r\n    try {\r\n      const result = await this.connection!.execute(sql, params);\r\n      logger.trace(\"SQL query executed successfully\", {\r\n        rowsAffected: result.rowsAffected,\r\n        rowsReturned: result.rows?.length || 0,\r\n      });\r\n      return result;\r\n    } catch (error) {\r\n      // ✅ CHỈ log khi KHÔNG phải lỗi _schema_info\r\n      if (sql.indexOf(\"_schema_info\") === -1) {\r\n        logger.error(\"SQL query execution failed\", {\r\n          sql: sql.substring(0, 200) + (sql.length > 200 ? \"...\" : \"\"),\r\n          paramCount: params.length,\r\n          error,\r\n        });\r\n      }\r\n      throw error;\r\n    }\r\n  }\r\n\r\n  async getRst(sql: string, params: any[] = []): Promise<SQLiteRow> {\r\n    const result = await this.execute(sql, params);\r\n    return result.rows[0] || {};\r\n  }\r\n\r\n  async getRsts(sql: string, params: any[] = []): Promise<SQLiteRow[]> {\r\n    const result = await this.execute(sql, params);\r\n    return result.rows;\r\n  }\r\n}\r\n","// src/core/database-factory.ts\r\nimport { SQLiteAdapter, DatabaseSchema, DbFactoryOptions } from \"@/types\";\r\nimport { UniversalDAO } from \"./universal-dao\";\r\n\r\nimport { createModuleLogger, SQLiteModules } from \"@/logger\";\r\nconst logger = createModuleLogger(SQLiteModules.DATABASE_FACTORY);\r\n\r\n/**\r\n * Universal DatabaseFactory - A powerful utility class designed to create and manage\r\n * UniversalDAO instances from JSON schema across all operating systems and frameworks\r\n * using TypeScript and JavaScript. It provides methods for creating new, opening existing\r\n * databases, checking integrity, and managing database lifecycle.\r\n */\r\nexport class DatabaseFactory {\r\n  private static adapters: SQLiteAdapter[] = [];\r\n\r\n  /**\r\n   * Register a SQLite adapter for use by the factory\r\n   * @param adapter The SQLite adapter to register\r\n   */\r\n  static registerAdapter(adapter: SQLiteAdapter): void {\r\n    logger.info(`Registering SQLite adapter: ${adapter.constructor.name}`, {\r\n      adapterName: adapter.constructor.name,\r\n      totalAdapters: this.adapters.length + 1,\r\n    });\r\n\r\n    this.adapters.push(adapter);\r\n\r\n    logger.debug(\r\n      `Successfully registered adapter. Total adapters: ${this.adapters.length}`\r\n    );\r\n  }\r\n\r\n  /**\r\n   * Get information about the current runtime environment\r\n   * @returns A string describing the current environment\r\n   */\r\n  static getEnvironmentInfo(): string {\r\n    logger.trace(\"Detecting runtime environment\");\r\n\r\n    let environment: string;\r\n\r\n    if (\r\n      typeof navigator !== \"undefined\" &&\r\n      navigator.product === \"ReactNative\"\r\n    ) {\r\n      environment = \"React Native\";\r\n    } else if (typeof globalThis.Bun !== \"undefined\") {\r\n      environment = \"Bun\";\r\n    } else if (typeof globalThis.Deno !== \"undefined\") {\r\n      environment = \"Deno\";\r\n    } else if (typeof window !== \"undefined\") {\r\n      environment = \"Browser\";\r\n    } else if (typeof process !== \"undefined\") {\r\n      environment = \"Node.js\";\r\n    } else {\r\n      environment = \"Unknown\";\r\n    }\r\n\r\n    logger.debug(`Detected runtime environment: ${environment}`);\r\n    return environment;\r\n  }\r\n\r\n  /**\r\n   * Detect the best available SQLite adapter for the current environment\r\n   * @returns The best available SQLite adapter\r\n   * @throws Error if no supported adapter is found\r\n   */\r\n  private static async detectBestAdapter(): Promise<SQLiteAdapter> {\r\n    logger.trace(\"Detecting best available SQLite adapter\", {\r\n      totalAdapters: this.adapters.length,\r\n      environment: this.getEnvironmentInfo(),\r\n    });\r\n\r\n    for (const adapter of this.adapters) {\r\n      logger.trace(`Testing adapter: ${adapter.constructor.name}`);\r\n\r\n      if (await adapter.isSupported()) {\r\n        logger.info(`Selected adapter: ${adapter.constructor.name}`, {\r\n          adapterName: adapter.constructor.name,\r\n          environment: this.getEnvironmentInfo(),\r\n        });\r\n        return adapter;\r\n      }\r\n\r\n      logger.debug(\r\n        `Adapter ${adapter.constructor.name} is not supported in current environment`\r\n      );\r\n    }\r\n\r\n    logger.error(\"No supported SQLite adapter found\", {\r\n      totalAdapters: this.adapters.length,\r\n      environment: this.getEnvironmentInfo(),\r\n    });\r\n\r\n    throw new Error(\"No supported SQLite adapter found\");\r\n  }\r\n\r\n  /**\r\n   * Validate schema version compatibility between database and config\r\n   * @param dao The UniversalDAO instance\r\n   * @param schema The database schema configuration\r\n   */\r\n  private static async validateSchemaVersion(\r\n    dao: UniversalDAO,\r\n    schema: DatabaseSchema\r\n  ): Promise<void> {\r\n    logger.trace(\"Validating schema version compatibility\", {\r\n      databaseName: schema.database_name,\r\n      configVersion: schema.version,\r\n    });\r\n\r\n    try {\r\n      const dbInfo = await dao.getDatabaseInfo();\r\n      logger.debug(\"Retrieved database info\", {\r\n        databaseVersion: dbInfo.version,\r\n        configVersion: schema.version,\r\n      });\r\n\r\n      if (dbInfo.version !== schema.version) {\r\n        const errorMsg = `Schema version mismatch: database (${dbInfo.version}) vs config (${schema.version})`;\r\n        logger.error(\"Schema version mismatch\", {\r\n          databaseName: schema.database_name,\r\n          databaseVersion: dbInfo.version,\r\n          configVersion: schema.version,\r\n        });\r\n        throw new Error(errorMsg);\r\n      }\r\n\r\n      logger.debug(\"Schema version validation successful\", {\r\n        databaseName: schema.database_name,\r\n        version: schema.version,\r\n      });\r\n    } catch (error) {\r\n      logger.error(\"Error during schema version validation\", {\r\n        databaseName: schema.database_name,\r\n        error: (error as Error).message,\r\n      });\r\n\r\n      throw new Error(\r\n        `Error validating schema version for ${schema.database_name}: ${\r\n          (error as Error).message\r\n        }`\r\n      );\r\n    }\r\n  }\r\n\r\n  /**\r\n   * Validate the provided schema object to ensure it has minimum required properties\r\n   * @param schema The schema object to validate\r\n   * @returns True if the schema is valid, otherwise throws an error\r\n   */\r\n  private static validateSchema(schema: any): schema is DatabaseSchema {\r\n    logger.trace(\"Validating database schema configuration\");\r\n\r\n    if (!schema) {\r\n      logger.error(\"Schema validation failed: null or undefined schema\");\r\n      throw new Error(\"Schema configuration is null or undefined.\");\r\n    }\r\n\r\n    if (\r\n      typeof schema.database_name !== \"string\" ||\r\n      schema.database_name.trim() === \"\"\r\n    ) {\r\n      logger.error(\"Schema validation failed: invalid database_name\", {\r\n        databaseName: schema.database_name,\r\n        type: typeof schema.database_name,\r\n      });\r\n      throw new Error(\r\n        \"Invalid or missing 'database_name' in schema. This is required to name the database file.\"\r\n      );\r\n    }\r\n\r\n    if (\r\n      typeof schema.schemas !== \"object\" ||\r\n      schema.schemas === null ||\r\n      Object.keys(schema.schemas).length === 0\r\n    ) {\r\n      logger.error(\"Schema validation failed: invalid schemas object\", {\r\n        databaseName: schema.database_name,\r\n        schemasType: typeof schema.schemas,\r\n        schemasCount: schema.schemas ? Object.keys(schema.schemas).length : 0,\r\n      });\r\n      throw new Error(\r\n        \"Invalid or missing 'schemas' object in schema. At least one table definition is required.\"\r\n      );\r\n    }\r\n\r\n    logger.debug(\"Schema validation successful\", {\r\n      databaseName: schema.database_name,\r\n      tablesCount: Object.keys(schema.schemas).length,\r\n      version: schema.version,\r\n    });\r\n\r\n    return true;\r\n  }\r\n\r\n  /**\r\n   * Create a new UniversalDAO instance (equivalent to SQLiteDAO)\r\n   * @param dbPath Path to the database file\r\n   * @param options Configuration options\r\n   * @returns A new UniversalDAO instance\r\n   */\r\n  static async createDAO(\r\n    dbPath: string,\r\n    options?: {\r\n      adapter?: SQLiteAdapter;\r\n      createIfNotExists?: boolean;\r\n      forceRecreate?: boolean;\r\n    }\r\n  ): Promise<UniversalDAO> {\r\n    logger.info(\"Creating new UniversalDAO instance\", {\r\n      dbPath,\r\n      hasCustomAdapter: !!options?.adapter,\r\n      createIfNotExists: options?.createIfNotExists ?? false,\r\n      forceRecreate: options?.forceRecreate ?? false,\r\n    });\r\n\r\n    let adapter: SQLiteAdapter;\r\n\r\n    if (options?.adapter) {\r\n      logger.debug(\"Using provided custom adapter\", {\r\n        adapterName: options.adapter.constructor.name,\r\n      });\r\n      adapter = options.adapter;\r\n    } else {\r\n      logger.debug(\"Detecting best adapter automatically\");\r\n      adapter = await this.detectBestAdapter();\r\n    }\r\n\r\n    const dao = new UniversalDAO(adapter, dbPath, {\r\n      createIfNotExists: options?.createIfNotExists ?? false,\r\n      forceRecreate: options?.forceRecreate ?? false,\r\n    });\r\n\r\n    logger.debug(\"UniversalDAO instance created successfully\", {\r\n      dbPath,\r\n      adapterName: adapter.constructor.name,\r\n    });\r\n\r\n    return dao;\r\n  }\r\n\r\n  /**\r\n   * Opens an existing database without initializing its schema.\r\n   * Includes integrity check to detect corrupted files.\r\n   * @param dbName The name of the database (e.g., 'core.db' or 'core').\r\n   * @param options Additional options for database connection.\r\n   * @returns A promise that resolves to a connected UniversalDAO instance.\r\n   */\r\n  public static async openExisting(\r\n    dbName: string,\r\n    options: Omit<\r\n      DbFactoryOptions,\r\n      \"config\" | \"configAsset\" | \"configPath\"\r\n    > = {}\r\n  ): Promise<UniversalDAO> {\r\n    logger.info(\"Opening existing database\", { dbName, options });\r\n\r\n    // Determine the database file path\r\n    const dbFileName = dbName.endsWith(\".db\") ? dbName : `${dbName}.db`;\r\n    logger.debug(\"Resolved database filename\", {\r\n      originalName: dbName,\r\n      resolvedName: dbFileName,\r\n    });\r\n\r\n    // Create and connect DAO instance\r\n    const dao = await this.createDAO(dbFileName, options);\r\n\r\n    try {\r\n      logger.debug(\"Connecting to database\", { dbFileName });\r\n      await dao.connect();\r\n\r\n      logger.debug(\"Running integrity check\", { dbFileName });\r\n      await dao.execute(\"PRAGMA integrity_check\");\r\n\r\n      logger.info(\"Database opened successfully\", { dbFileName });\r\n      return dao;\r\n    } catch (error) {\r\n      logger.error(\"Error opening database\", {\r\n        dbFileName,\r\n        error: (error as Error).message,\r\n      });\r\n\r\n      try {\r\n        await dao.close();\r\n      } catch (closeError) {\r\n        logger.warn(\"Error closing DAO after failed open\", {\r\n          dbFileName,\r\n          closeError: (closeError as Error).message,\r\n        });\r\n      }\r\n\r\n      throw new Error(\r\n        `Error opening database '${dbFileName}': ${(error as Error).message}`\r\n      );\r\n    }\r\n  }\r\n\r\n  /**\r\n   * Internal method to create or open database with various options\r\n   * @param options Configuration options\r\n   * @param isForceInit Allow re-initialization of existing database\r\n   * @param isForceDelete Force delete and recreate database\r\n   * @returns Promise that resolves to initialized UniversalDAO\r\n   */\r\n  private static async createOrOpenInternal(\r\n    options: DbFactoryOptions,\r\n    isForceInit: boolean = false,\r\n    isForceDelete: boolean = false\r\n  ): Promise<UniversalDAO> {\r\n    logger.info(\"Creating or opening database internally\", {\r\n      isForceInit,\r\n      isForceDelete,\r\n      hasConfig: !!options.config,\r\n      hasConfigAsset: !!options.configAsset,\r\n    });\r\n\r\n    let schema: DatabaseSchema;\r\n\r\n    // Step 1: Load schema\r\n    logger.trace(\"Loading database schema\");\r\n    if (options.config) {\r\n      logger.debug(\"Using provided config object\");\r\n      schema = options.config;\r\n    } else if (options.configAsset) {\r\n      logger.debug(\"Using provided config asset\");\r\n      schema = options.configAsset;\r\n    } else {\r\n      logger.error(\"No database schema configuration provided\");\r\n      throw new Error(\r\n        \"Either 'config', 'configAsset', or 'configPath' must be provided to the factory.\"\r\n      );\r\n    }\r\n\r\n    // Step 2: Validate schema\r\n    logger.trace(\"Validating schema configuration\");\r\n    this.validateSchema(schema);\r\n\r\n    // Step 3: Determine database path\r\n    const dbFileName = schema.database_name.endsWith(\".db\")\r\n      ? schema.database_name\r\n      : `${schema.database_name}.db`;\r\n\r\n    logger.debug(\"Database filename resolved\", {\r\n      originalName: schema.database_name,\r\n      resolvedName: dbFileName,\r\n    });\r\n\r\n    // Step 4: Create DAO instance\r\n    logger.debug(\"Creating DAO instance\", {\r\n      dbFileName,\r\n      hasCustomAdapter: !!options.adapter,\r\n      createIfNotExists: isForceInit,\r\n      forceRecreate: isForceDelete,\r\n    });\r\n\r\n    const dao = await this.createDAO(dbFileName, {\r\n      adapter: options.adapter,\r\n      createIfNotExists: isForceInit,\r\n      forceRecreate: isForceDelete,\r\n    });\r\n\r\n    try {\r\n      // Step 5: Connect to database\r\n      logger.debug(\"Connecting to database\", { dbFileName });\r\n      await dao.connect();\r\n\r\n      // Step 6: Initialize schema if needed\r\n      logger.debug(\"Initializing database schema\", { dbFileName });\r\n      await dao.initializeFromSchema(schema);\r\n\r\n      // Step 7: Validate schema version compatibility\r\n      logger.debug(\"Validating schema version compatibility\");\r\n      try {\r\n        await this.validateSchemaVersion(dao, schema);\r\n      } catch (schemaError: any) {\r\n        logger.error(\"Schema version validation failed\", {\r\n          dbFileName,\r\n          error: schemaError.message,\r\n        });\r\n\r\n        await dao.close();\r\n        throw new Error(\r\n          `Schema mismatch in existing database. Use forceRecreate=true to recreate with updated schema. Error: ${schemaError.message}`\r\n        );\r\n      }\r\n\r\n      logger.info(\"Database created/opened successfully\", {\r\n        dbFileName,\r\n        databaseName: schema.database_name,\r\n        version: schema.version,\r\n      });\r\n\r\n      return dao;\r\n    } catch (error) {\r\n      logger.error(\"Error during database creation/opening\", {\r\n        dbFileName,\r\n        error: (error as Error).message,\r\n      });\r\n\r\n      if (dao.isConnectionOpen()) {\r\n        try {\r\n          await dao.close();\r\n        } catch (closeError) {\r\n          logger.warn(\"Error closing DAO after failed operation\", {\r\n            dbFileName,\r\n            closeError: (closeError as Error).message,\r\n          });\r\n        }\r\n      }\r\n      throw error;\r\n    }\r\n  }\r\n\r\n  /**\r\n   * Create a new database (DANGEROUS - will delete existing database)\r\n   * Only use this for migrations or development, not in production\r\n   * @param options Configuration options\r\n   * @returns Promise that resolves to initialized UniversalDAO\r\n   */\r\n  public static async create(options: DbFactoryOptions): Promise<UniversalDAO> {\r\n    logger.warn(\r\n      \"Creating database with force recreate - this will delete existing database\",\r\n      {\r\n        databaseName:\r\n          options.config?.database_name || options.configAsset?.database_name,\r\n      }\r\n    );\r\n\r\n    return this.createOrOpenInternal(options, true, true);\r\n  }\r\n\r\n  /**\r\n   * Smart method to create or open database\r\n   * Only creates new tables if they don't exist and initializes file initially\r\n   * Will check if file exists and is valid before deciding to create new or open existing\r\n   * @param options Database configuration options\r\n   * @param isForceInit Force re-initialization of tables even if they exist (default: false)\r\n   * @returns Promise that resolves to initialized UniversalDAO\r\n   */\r\n  public static async createOrOpen(\r\n    options: DbFactoryOptions,\r\n    isForceInit: boolean = false\r\n  ): Promise<UniversalDAO> {\r\n    logger.info(\"Smart create or open database\", {\r\n      databaseName:\r\n        options.config?.database_name || options.configAsset?.database_name,\r\n      isForceInit,\r\n    });\r\n\r\n    return this.createOrOpenInternal(options, isForceInit);\r\n  }\r\n\r\n  /**\r\n   * Convenience method to create a database from a JSON asset\r\n   * @param configAsset The imported/required JSON configuration\r\n   * @param options Additional options for database creation\r\n   * @returns Promise that resolves to initialized UniversalDAO\r\n   */\r\n  public static async createFromAsset(\r\n    configAsset: DatabaseSchema,\r\n    options: Omit<\r\n      DbFactoryOptions,\r\n      \"config\" | \"configAsset\" | \"configPath\"\r\n    > = {}\r\n  ): Promise<UniversalDAO> {\r\n    logger.info(\"Creating database from asset\", {\r\n      databaseName: configAsset.database_name,\r\n      version: configAsset.version,\r\n    });\r\n\r\n    try {\r\n      return await this.create({\r\n        ...options,\r\n        configAsset,\r\n      });\r\n    } catch (error) {\r\n      logger.error(\"Error creating database from asset\", {\r\n        databaseName: configAsset.database_name,\r\n        error: (error as Error).message,\r\n      });\r\n\r\n      throw new Error(\r\n        `Error creating database from asset: ${(error as Error).message}`\r\n      );\r\n    }\r\n  }\r\n\r\n  /**\r\n   * Convenience method to create a database from a configuration object\r\n   * @param config The database schema configuration object\r\n   * @param options Additional options for database creation\r\n   * @returns Promise that resolves to initialized UniversalDAO\r\n   */\r\n  public static async createFromConfig(\r\n    config: DatabaseSchema,\r\n    options: Omit<\r\n      DbFactoryOptions,\r\n      \"config\" | \"configAsset\" | \"configPath\"\r\n    > = {}\r\n  ): Promise<UniversalDAO> {\r\n    logger.info(\"Creating database from config\", {\r\n      databaseName: config.database_name,\r\n      version: config.version,\r\n    });\r\n\r\n    try {\r\n      return await this.create({\r\n        ...options,\r\n        config,\r\n      });\r\n    } catch (error) {\r\n      logger.error(\"Error creating database from config\", {\r\n        databaseName: config.database_name,\r\n        error: (error as Error).message,\r\n      });\r\n\r\n      throw new Error(\r\n        `Error creating database from config: ${(error as Error).message}`\r\n      );\r\n    }\r\n  }\r\n}\r\n\r\nexport default DatabaseFactory;\r\n","// src/core/database-manager.ts\r\n\r\nimport {\r\n  DatabaseSchema,\r\n  ImportOptions,\r\n  ImportResult,\r\n  ColumnMapping,\r\n} from \"../types\";\r\nimport { DatabaseFactory } from \"./database-factory\";\r\nimport { UniversalDAO } from \"./universal-dao\";\r\n\r\nimport { createModuleLogger, SQLiteModules, CommonLoggerConfig } from \"@/logger\";\r\nconst logger = createModuleLogger(SQLiteModules.DATABASE_MANAGER);\r\n\r\n/* const initialConfig = CommonLoggerConfig.getCurrentConfig();\r\nconsole.log('📍 [database-manager.ts] Initial config:', initialConfig); */\r\n\r\nexport type DatabaseConnections = {\r\n  [key: string]: UniversalDAO;\r\n};\r\n\r\nexport interface RoleConfig {\r\n  roleName: string;\r\n  requiredDatabases: string[];\r\n  optionalDatabases?: string[];\r\n  priority?: number;\r\n}\r\n\r\nexport type RoleRegistry = {\r\n  [roleName: string]: RoleConfig;\r\n};\r\n\r\nexport interface DatabaseImportConfig {\r\n  databaseKey: string;\r\n  tableName: string;\r\n  data: Record<string, any>[];\r\n  options?: Partial<ImportOptions>;\r\n  columnMappings?: ColumnMapping[];\r\n}\r\n\r\nexport interface BulkImportResult {\r\n  totalDatabases: number;\r\n  successDatabases: number;\r\n  results: Record<string, ImportResult>;\r\n  errors: Record<string, Error>;\r\n  executionTime: number;\r\n}\r\n\r\nexport interface SchemaManager {\r\n  getSchema(key: string): DatabaseSchema | undefined;\r\n  registerSchema(key: string, schema: DatabaseSchema): void;\r\n  getAllSchemaKeys(): string[];\r\n  hasSchema(key: string): boolean;\r\n}\r\n\r\nexport class DatabaseManager {\r\n  private static maxConnections = 10;\r\n  private static connections: DatabaseConnections = {};\r\n  private static isInitialized = false;\r\n  private static roleRegistry: RoleRegistry = {};\r\n  private static currentRole: string | null = null;\r\n  private static currentUserRoles: string[] = [];\r\n  private static activeDatabases: Set<string> = new Set();\r\n  private static isClosingConnections = false;\r\n\r\n  // Schema management - support dynamic schemas\r\n  private static schemaConfigurations: Record<string, DatabaseSchema> = {};\r\n  private static schemaManager: SchemaManager | null = null;\r\n\r\n  // Event system for database reconnection\r\n  private static eventListeners: Map<\r\n    string,\r\n    Array<(dao: UniversalDAO) => void>\r\n  > = new Map();\r\n\r\n  /**\r\n   * Get the maximum number of allowed database connections\r\n   */\r\n  public static getMaxConnections(): number {\r\n    logger.trace(\"Getting max connections\", {\r\n      maxConnections: this.maxConnections,\r\n    });\r\n    return this.maxConnections;\r\n  }\r\n\r\n  /**\r\n   * Set the maximum number of allowed database connections\r\n   * @param maxConnections - The maximum number of connections (must be positive)\r\n   * @throws Error if maxConnections is not positive or if current connections exceed the new limit\r\n   */\r\n  public static setMaxConnections(maxConnections: number): void {\r\n    logger.debug(\"Setting max connections\", {\r\n      newMaxConnections: maxConnections,\r\n      currentMax: this.maxConnections,\r\n    });\r\n\r\n    if (maxConnections <= 0) {\r\n      logger.error(\"Invalid max connections value\", { maxConnections });\r\n      throw new Error(\"Maximum connections must be a positive number\");\r\n    }\r\n\r\n    const currentConnectionCount = Object.keys(this.connections).length;\r\n    if (currentConnectionCount > maxConnections) {\r\n      logger.error(\r\n        \"Cannot set max connections - would exceed current active connections\",\r\n        {\r\n          requestedMax: maxConnections,\r\n          currentActiveConnections: currentConnectionCount,\r\n          activeConnectionKeys: Object.keys(this.connections),\r\n        }\r\n      );\r\n      throw new Error(\r\n        `Cannot set maximum connections to ${maxConnections}. ` +\r\n          `Current active connections (${currentConnectionCount}) exceed the new limit. ` +\r\n          `Please close some connections first.`\r\n      );\r\n    }\r\n\r\n    this.maxConnections = maxConnections;\r\n    logger.info(\"Max connections updated successfully\", {\r\n      newMaxConnections: maxConnections,\r\n      currentActiveConnections: currentConnectionCount,\r\n    });\r\n  }\r\n\r\n  /**\r\n   * Set a schema manager for dynamic schema handling\r\n   */\r\n  public static setSchemaManager(manager: SchemaManager): void {\r\n    logger.debug(\"Setting schema manager\", {\r\n      hadPreviousManager: this.schemaManager !== null,\r\n    });\r\n    this.schemaManager = manager;\r\n    logger.info(\"Schema manager set successfully\");\r\n  }\r\n\r\n  /**\r\n   * Register a schema configuration dynamically\r\n   */\r\n  public static registerSchema(key: string, schema: DatabaseSchema): void {\r\n    logger.debug(\"Registering schema\", {\r\n      key,\r\n      schemaName: schema.database_name,\r\n    });\r\n    this.schemaConfigurations[key] = schema;\r\n    logger.info(\"Schema registered successfully\", {\r\n      key,\r\n      schemaName: schema.database_name,\r\n    });\r\n  }\r\n\r\n  /**\r\n   * Register multiple schemas at once\r\n   */\r\n  public static registerSchemas(schemas: Record<string, DatabaseSchema>): void {\r\n    const schemaKeys = Object.keys(schemas);\r\n    logger.debug(\"Registering multiple schemas\", {\r\n      count: schemaKeys.length,\r\n      keys: schemaKeys,\r\n    });\r\n\r\n    Object.entries(schemas).forEach(([key, schema]) => {\r\n      this.registerSchema(key, schema);\r\n    });\r\n\r\n    logger.info(\"Multiple schemas registered successfully\", {\r\n      count: schemaKeys.length,\r\n    });\r\n  }\r\n\r\n  /**\r\n   * Get schema from internal store or external manager\r\n   */\r\n  private static getSchema(key: string): DatabaseSchema | undefined {\r\n    logger.trace(\"Getting schema\", { key });\r\n\r\n    // Try internal schemas first\r\n    if (this.schemaConfigurations[key]) {\r\n      logger.trace(\"Schema found in internal configurations\", { key });\r\n      return this.schemaConfigurations[key];\r\n    }\r\n\r\n    // Try external schema manager\r\n    if (this.schemaManager) {\r\n      logger.trace(\"Checking external schema manager\", { key });\r\n      const schema = this.schemaManager.getSchema(key);\r\n      if (schema) {\r\n        logger.trace(\"Schema found in external manager\", { key });\r\n        return schema;\r\n      }\r\n    }\r\n\r\n    logger.warn(\"Schema not found\", { key });\r\n    return undefined;\r\n  }\r\n\r\n  /**\r\n   * Get all available schema keys\r\n   */\r\n  public static getAvailableSchemas(): string[] {\r\n    const internalKeys = Object.keys(this.schemaConfigurations);\r\n    const externalKeys = this.schemaManager?.getAllSchemaKeys() || [];\r\n    const allKeys = [...new Set([...internalKeys, ...externalKeys])];\r\n\r\n    logger.trace(\"Getting available schemas\", {\r\n      internalCount: internalKeys.length,\r\n      externalCount: externalKeys.length,\r\n      totalUnique: allKeys.length,\r\n    });\r\n\r\n    return allKeys;\r\n  }\r\n\r\n  /**\r\n   * Register a role configuration\r\n   */\r\n  public static registerRole(roleConfig: RoleConfig): void {\r\n    logger.debug(\"Registering role\", {\r\n      roleName: roleConfig.roleName,\r\n      requiredDatabases: roleConfig.requiredDatabases,\r\n      optionalDatabases: roleConfig.optionalDatabases,\r\n      priority: roleConfig.priority,\r\n    });\r\n\r\n    this.roleRegistry[roleConfig.roleName] = roleConfig;\r\n    logger.info(\"Role registered successfully\", {\r\n      roleName: roleConfig.roleName,\r\n    });\r\n  }\r\n\r\n  /**\r\n   * Register multiple roles\r\n   */\r\n  public static registerRoles(roleConfigs: RoleConfig[]): void {\r\n    logger.debug(\"Registering multiple roles\", { count: roleConfigs.length });\r\n    roleConfigs.forEach((config) => this.registerRole(config));\r\n    logger.info(\"Multiple roles registered successfully\", {\r\n      count: roleConfigs.length,\r\n    });\r\n  }\r\n\r\n  /**\r\n   * Get all registered roles\r\n   */\r\n  public static getRegisteredRoles(): RoleRegistry {\r\n    logger.trace(\"Getting registered roles\", {\r\n      count: Object.keys(this.roleRegistry).length,\r\n    });\r\n    return { ...this.roleRegistry };\r\n  }\r\n\r\n  /**\r\n   * Get databases for a specific role\r\n   */\r\n  public static getRoleDatabases(roleName: string): string[] {\r\n    logger.trace(\"Getting role databases\", { roleName });\r\n\r\n    const roleConfig = this.roleRegistry[roleName];\r\n    if (!roleConfig) {\r\n      logger.error(\"Role not found in registry\", {\r\n        roleName,\r\n        availableRoles: Object.keys(this.roleRegistry),\r\n      });\r\n      throw new Error(`Role '${roleName}' is not registered.`);\r\n    }\r\n\r\n    const databases = [\r\n      ...roleConfig.requiredDatabases,\r\n      ...(roleConfig.optionalDatabases || []),\r\n    ];\r\n\r\n    logger.trace(\"Role databases retrieved\", { roleName, databases });\r\n    return databases;\r\n  }\r\n\r\n  /**\r\n   * Get databases for current user roles\r\n   */\r\n  public static getCurrentUserDatabases(): string[] {\r\n    logger.trace(\"Getting current user databases\", {\r\n      currentUserRoles: this.currentUserRoles,\r\n    });\r\n\r\n    const allDatabases = new Set<string>();\r\n    allDatabases.add(\"core\"); // Core database is always included\r\n\r\n    for (const roleName of this.currentUserRoles) {\r\n      const roleConfig = this.roleRegistry[roleName];\r\n      if (roleConfig) {\r\n        roleConfig.requiredDatabases.forEach((db) => allDatabases.add(db));\r\n        if (roleConfig.optionalDatabases) {\r\n          roleConfig.optionalDatabases.forEach((db) => allDatabases.add(db));\r\n        }\r\n      } else {\r\n        logger.warn(\"Role config not found for current user role\", {\r\n          roleName,\r\n        });\r\n      }\r\n    }\r\n\r\n    const result = Array.from(allDatabases);\r\n    logger.debug(\"Current user databases calculated\", {\r\n      userRoles: this.currentUserRoles,\r\n      databases: result,\r\n    });\r\n    return result;\r\n  }\r\n\r\n  /**\r\n   * Initialize core database connection\r\n   */\r\n  public static async initializeCoreConnection(): Promise<void> {\r\n\r\n    console.log(\"initializeCoreConnection logger config:\", CommonLoggerConfig.getCurrentConfig());\r\n    logger.debug(\"Initializing core database connection\");\r\n\r\n    if (this.connections[\"core\"]) {\r\n      logger.debug(\"Core connection already exists\");\r\n      return;\r\n    }\r\n\r\n    try {\r\n      const coreSchema = this.getSchema(\"core\");\r\n      if (!coreSchema) {\r\n        logger.error(\"Core database schema not found\");\r\n        throw new Error(\"Core database schema not found.\");\r\n      }\r\n\r\n      logger.debug(\"Creating core database connection\", {\r\n        schemaName: coreSchema.database_name,\r\n      });\r\n      const dao = await DatabaseFactory.createOrOpen(\r\n        { config: coreSchema },\r\n        false\r\n      );\r\n\r\n      await dao.execute(\"PRAGMA integrity_check\");\r\n      this.connections[\"core\"] = dao;\r\n      logger.info(\"Core database connection initialized successfully\");\r\n    } catch (error) {\r\n      logger.error(\"Error initializing core database\", {\r\n        error: (error as Error).message,\r\n      });\r\n      throw new Error(\r\n        `Error initializing core database: ${(error as Error).message}`\r\n      );\r\n    }\r\n  }\r\n\r\n  /**\r\n   * Set current user roles and initialize connections\r\n   */\r\n  public static async setCurrentUserRoles(\r\n    userRoles: string[],\r\n    primaryRole?: string\r\n  ): Promise<void> {\r\n    logger.debug(\"Setting current user roles\", { userRoles, primaryRole });\r\n\r\n    // Validate roles exist\r\n    for (const roleName of userRoles) {\r\n      if (!this.roleRegistry[roleName]) {\r\n        logger.error(\"Role not registered\", {\r\n          roleName,\r\n          availableRoles: Object.keys(this.roleRegistry),\r\n        });\r\n        throw new Error(\r\n          `Role '${roleName}' is not registered. Please register it first.`\r\n        );\r\n      }\r\n    }\r\n\r\n    const previousRoles = [...this.currentUserRoles];\r\n    this.currentUserRoles = userRoles;\r\n    this.currentRole = primaryRole || userRoles[0] || null;\r\n\r\n    logger.info(\"User roles updated\", {\r\n      previousRoles,\r\n      newRoles: userRoles,\r\n      primaryRole: this.currentRole,\r\n    });\r\n\r\n    try {\r\n      await this.initializeUserRoleConnections();\r\n      await this.cleanupUnusedConnections(previousRoles);\r\n      logger.info(\"User role connections initialized successfully\");\r\n    } catch (error) {\r\n      logger.error(\"Failed to initialize user role connections\", {\r\n        error: (error as Error).message,\r\n      });\r\n      throw error;\r\n    }\r\n  }\r\n\r\n  /**\r\n   * Get current user roles\r\n   */\r\n  public static getCurrentUserRoles(): string[] {\r\n    logger.trace(\"Getting current user roles\", {\r\n      roles: this.currentUserRoles,\r\n    });\r\n    return [...this.currentUserRoles];\r\n  }\r\n\r\n  /**\r\n   * Get current primary role\r\n   */\r\n  public static getCurrentRole(): string | null {\r\n    logger.trace(\"Getting current primary role\", { role: this.currentRole });\r\n    return this.currentRole;\r\n  }\r\n\r\n  /**\r\n   * Initialize connections for current user roles\r\n   */\r\n  private static async initializeUserRoleConnections(): Promise<void> {\r\n    const requiredDatabases = this.getCurrentUserDatabases();\r\n    logger.debug(\"Initializing user role connections\", { requiredDatabases });\r\n\r\n    const failedInitializations: { key: string; error: Error }[] = [];\r\n\r\n    const initPromises = requiredDatabases.map(async (dbKey) => {\r\n      if (this.connections[dbKey]) {\r\n        logger.trace(\"Database already connected\", { dbKey });\r\n        return; // Already connected\r\n      }\r\n\r\n      try {\r\n        logger.debug(\"Initializing database connection\", { dbKey });\r\n        const schema = this.getSchema(dbKey);\r\n        if (!schema) {\r\n          throw new Error(\r\n            `Database key '${dbKey}' not found in schema configurations.`\r\n          );\r\n        }\r\n\r\n        const dao = await DatabaseFactory.createOrOpen(\r\n          { config: schema },\r\n          false\r\n        );\r\n        await dao.execute(\"PRAGMA integrity_check\");\r\n        this.connections[dbKey] = dao;\r\n        logger.info(\"Database connection initialized\", {\r\n          dbKey,\r\n          schemaName: schema.database_name,\r\n        });\r\n      } catch (error) {\r\n        const err = error instanceof Error ? error : new Error(String(error));\r\n        logger.error(\"Failed to initialize database connection\", {\r\n          dbKey,\r\n          error: err.message,\r\n        });\r\n\r\n        // Check if database is required for any role\r\n        const isRequired = this.currentUserRoles.some((roleName) => {\r\n          const roleConfig = this.roleRegistry[roleName];\r\n          return roleConfig && roleConfig.requiredDatabases.includes(dbKey);\r\n        });\r\n\r\n        if (isRequired) {\r\n          failedInitializations.push({ key: dbKey, error: err });\r\n        } else {\r\n          logger.warn(\"Optional database initialization failed\", {\r\n            dbKey,\r\n            error: err.message,\r\n          });\r\n        }\r\n        // Optional databases that fail are ignored\r\n      }\r\n    });\r\n\r\n    await Promise.all(initPromises);\r\n\r\n    if (failedInitializations.length > 0) {\r\n      const errorSummary = failedInitializations\r\n        .map((f) => `  - ${f.key}: ${f.error.message}`)\r\n        .join(\"\\n\");\r\n      logger.error(\"Failed to initialize required databases\", {\r\n        failedDatabases: failedInitializations.map((f) => f.key),\r\n        errorSummary,\r\n      });\r\n      throw new Error(\r\n        `Failed to initialize required databases for user roles:\\n${errorSummary}`\r\n      );\r\n    }\r\n  }\r\n\r\n  /**\r\n   * Cleanup unused connections\r\n   */\r\n  private static async cleanupUnusedConnections(\r\n    previousRoles: string[]\r\n  ): Promise<void> {\r\n    logger.debug(\"Cleaning up unused connections\", { previousRoles });\r\n\r\n    const previousDatabases = new Set<string>();\r\n    previousDatabases.add(\"core\");\r\n\r\n    for (const roleName of previousRoles) {\r\n      const roleConfig = this.roleRegistry[roleName];\r\n      if (roleConfig) {\r\n        roleConfig.requiredDatabases.forEach((db) => previousDatabases.add(db));\r\n        if (roleConfig.optionalDatabases) {\r\n          roleConfig.optionalDatabases.forEach((db) =>\r\n            previousDatabases.add(db)\r\n          );\r\n        }\r\n      }\r\n    }\r\n\r\n    const currentDatabases = new Set(this.getCurrentUserDatabases());\r\n    const databasesToClose = Array.from(previousDatabases).filter(\r\n      (db) => !currentDatabases.has(db)\r\n    );\r\n\r\n    logger.debug(\"Databases to cleanup\", {\r\n      databasesToClose,\r\n      previousDatabaseCount: previousDatabases.size,\r\n      currentDatabaseCount: currentDatabases.size,\r\n    });\r\n\r\n    if (databasesToClose.length > 0) {\r\n      for (const dbKey of databasesToClose) {\r\n        if (this.connections[dbKey]) {\r\n          try {\r\n            logger.debug(\"Closing unused database connection\", { dbKey });\r\n            await this.connections[dbKey].close();\r\n            delete this.connections[dbKey];\r\n            logger.info(\"Database connection closed\", { dbKey });\r\n          } catch (error) {\r\n            logger.error(\"Error closing database connection during cleanup\", {\r\n              dbKey,\r\n              error: (error as Error).message,\r\n            });\r\n            // Log error but continue cleanup\r\n          }\r\n        }\r\n      }\r\n      logger.info(\"Cleanup completed\", { closedConnections: databasesToClose });\r\n    } else {\r\n      logger.debug(\"No connections to cleanup\");\r\n    }\r\n  }\r\n\r\n  /**\r\n   * Check if current user has access to database\r\n   */\r\n  public static hasAccessToDatabase(dbKey: string): boolean {\r\n    const hasAccess = this.getSchema(dbKey) !== undefined;\r\n    logger.trace(\"Checking database access\", { dbKey, hasAccess });\r\n    return hasAccess;\r\n  }\r\n\r\n  /**\r\n   * Get database connection\r\n   */\r\n  public static get(key: string): UniversalDAO {\r\n    logger.trace(\"Getting database connection\", { key });\r\n\r\n    if (!this.hasAccessToDatabase(key)) {\r\n      logger.error(\"Access denied to database\", { key });\r\n      throw new Error(`Access denied: Database '${key}' is not accessible.`);\r\n    }\r\n\r\n    const dao = this.connections[key];\r\n    if (!dao) {\r\n      logger.error(\"Database not connected\", {\r\n        key,\r\n        availableConnections: Object.keys(this.connections),\r\n      });\r\n      throw new Error(\r\n        `Database '${key}' is not connected. Please ensure it's initialized.`\r\n      );\r\n    }\r\n\r\n    logger.trace(\"Database connection retrieved successfully\", { key });\r\n    return dao;\r\n  }\r\n\r\n  /**\r\n   * Register event listener for database reconnection\r\n   */\r\n  public static onDatabaseReconnect(\r\n    schemaName: string,\r\n    callback: (dao: UniversalDAO) => void\r\n  ): void {\r\n    logger.debug(\"Registering database reconnect listener\", { schemaName });\r\n\r\n    if (!this.eventListeners.has(schemaName)) {\r\n      this.eventListeners.set(schemaName, []);\r\n    }\r\n    this.eventListeners.get(schemaName)!.push(callback);\r\n\r\n    logger.trace(\"Database reconnect listener registered\", {\r\n      schemaName,\r\n      listenerCount: this.eventListeners.get(schemaName)!.length,\r\n    });\r\n  }\r\n\r\n  /**\r\n   * Remove event listener for database reconnection\r\n   */\r\n  public static offDatabaseReconnect(\r\n    schemaName: string,\r\n    callback: (dao: UniversalDAO) => void\r\n  ): void {\r\n    logger.debug(\"Removing database reconnect listener\", { schemaName });\r\n\r\n    const listeners = this.eventListeners.get(schemaName);\r\n    if (listeners) {\r\n      const index = listeners.indexOf(callback);\r\n      if (index > -1) {\r\n        listeners.splice(index, 1);\r\n        logger.trace(\"Database reconnect listener removed\", {\r\n          schemaName,\r\n          remainingListeners: listeners.length,\r\n        });\r\n      } else {\r\n        logger.warn(\"Database reconnect listener not found for removal\", {\r\n          schemaName,\r\n        });\r\n      }\r\n    } else {\r\n      logger.warn(\"No listeners found for schema\", { schemaName });\r\n    }\r\n  }\r\n\r\n  /**\r\n   * Notify listeners of database reconnection\r\n   */\r\n  private static notifyDatabaseReconnect(\r\n    schemaName: string,\r\n    dao: UniversalDAO\r\n  ): void {\r\n    const listeners = this.eventListeners.get(schemaName);\r\n    if (listeners) {\r\n      logger.debug(\"Notifying database reconnect listeners\", {\r\n        schemaName,\r\n        listenerCount: listeners.length,\r\n      });\r\n\r\n      listeners.forEach((callback, index) => {\r\n        try {\r\n          callback(dao);\r\n          logger.trace(\"Database reconnect listener notified\", {\r\n            schemaName,\r\n            listenerIndex: index,\r\n          });\r\n        } catch (error) {\r\n          logger.error(\"Error in database reconnect listener\", {\r\n            schemaName,\r\n            listenerIndex: index,\r\n            error: (error as Error).message,\r\n          });\r\n          // Handle callback errors gracefully\r\n        }\r\n      });\r\n    } else {\r\n      logger.trace(\"No listeners to notify for database reconnection\", {\r\n        schemaName,\r\n      });\r\n    }\r\n  }\r\n\r\n  /**\r\n   * Close all connections\r\n   */\r\n  private static async closeAllConnections(): Promise<void> {\r\n    if (this.isClosingConnections) {\r\n      logger.debug(\"Already closing connections, skipping\");\r\n      return;\r\n    }\r\n\r\n    logger.info(\"Closing all database connections\", {\r\n      connectionCount: Object.keys(this.connections).length,\r\n    });\r\n\r\n    this.isClosingConnections = true;\r\n    try {\r\n      // Save active databases\r\n      const currentActiveDb = Object.keys(this.connections);\r\n      currentActiveDb.forEach((dbKey) => this.activeDatabases.add(dbKey));\r\n\r\n      logger.debug(\"Saving active database list for potential reconnection\", {\r\n        activeDatabases: currentActiveDb,\r\n      });\r\n\r\n      const closePromises = Object.entries(this.connections).map(\r\n        async ([dbKey, dao]) => {\r\n          try {\r\n            logger.debug(\"Closing database connection\", { dbKey });\r\n            await dao.close();\r\n            logger.trace(\"Database connection closed\", { dbKey });\r\n          } catch (error) {\r\n            logger.error(\"Error closing database connection\", {\r\n              dbKey,\r\n              error: (error as Error).message,\r\n            });\r\n            // Log error but continue closing\r\n          }\r\n        }\r\n      );\r\n\r\n      await Promise.all(closePromises);\r\n      this.connections = {};\r\n      logger.info(\"All database connections closed successfully\");\r\n    } finally {\r\n      this.isClosingConnections = false;\r\n    }\r\n  }\r\n\r\n  /**\r\n   * Reopen connections\r\n   */\r\n  public static async reopenConnections(): Promise<void> {\r\n    logger.info(\"Reopening database connections\");\r\n\r\n    try {\r\n      await this.initializeCoreConnection();\r\n\r\n      if (this.currentUserRoles.length > 0) {\r\n        await this.initializeUserRoleConnections();\r\n      }\r\n\r\n      // Reinitialize previously active databases\r\n      const activeDbArray = Array.from(this.activeDatabases);\r\n      logger.debug(\"Reinitializing previously active databases\", {\r\n        activeDatabases: activeDbArray,\r\n      });\r\n\r\n      if (activeDbArray.length > 0) {\r\n        for (const dbKey of activeDbArray) {\r\n          if (!this.connections[dbKey]) {\r\n            const schema = this.getSchema(dbKey);\r\n            if (schema) {\r\n              try {\r\n                logger.debug(\"Reopening database connection\", { dbKey });\r\n                const dao = await DatabaseFactory.createOrOpen(\r\n                  { config: schema },\r\n                  false\r\n                );\r\n                await dao.connect();\r\n                this.connections[dbKey] = dao;\r\n                this.notifyDatabaseReconnect(dbKey, dao);\r\n                logger.info(\"Database connection reopened\", { dbKey });\r\n              } catch (error) {\r\n                logger.error(\"Failed to reopen database connection\", {\r\n                  dbKey,\r\n                  error: (error as Error).message,\r\n                });\r\n                // Log error but continue\r\n              }\r\n            } else {\r\n              logger.warn(\"Schema not found for previously active database\", {\r\n                dbKey,\r\n              });\r\n            }\r\n          } else if (this.connections[dbKey]) {\r\n            // Database exists, notify services\r\n            logger.trace(\"Database already connected, notifying listeners\", {\r\n              dbKey,\r\n            });\r\n            this.notifyDatabaseReconnect(dbKey, this.connections[dbKey]);\r\n          }\r\n        }\r\n      }\r\n\r\n      logger.info(\"Database connections reopened successfully\");\r\n    } catch (error) {\r\n      logger.error(\"Failed to reopen database connections\", {\r\n        error: (error as Error).message,\r\n      });\r\n      throw error;\r\n    }\r\n  }\r\n\r\n  /**\r\n   * Ensure database connection exists and is active\r\n   */\r\n  public static async ensureDatabaseConnection(\r\n    key: string\r\n  ): Promise<UniversalDAO> {\r\n    logger.debug(\"Ensuring database connection\", { key });\r\n    this.activeDatabases.add(key);\r\n\r\n    if (!this.hasAccessToDatabase(key)) {\r\n      logger.error(\"Access denied when ensuring database connection\", { key });\r\n      throw new Error(`Access denied: Database '${key}' is not accessible.`);\r\n    }\r\n\r\n    if (this.connections[key]) {\r\n      try {\r\n        const isConnected = this.connections[key].isConnectionOpen();\r\n        if (isConnected) {\r\n          logger.trace(\"Database connection already active\", { key });\r\n          return this.connections[key];\r\n        } else {\r\n          // Clean up inactive connection\r\n          logger.warn(\"Database connection inactive, cleaning up\", { key });\r\n          try {\r\n            await this.connections[key].close().catch(() => {});\r\n          } catch (error) {\r\n            logger.debug(\"Error during connection cleanup\", {\r\n              key,\r\n              error: (error as Error).message,\r\n            });\r\n            // Ignore cleanup errors\r\n          }\r\n          delete this.connections[key];\r\n        }\r\n      } catch (error) {\r\n        logger.error(\"Error checking connection status\", {\r\n          key,\r\n          error: (error as Error).message,\r\n        });\r\n        delete this.connections[key];\r\n      }\r\n    }\r\n\r\n    // Create new connection\r\n    logger.debug(\"Creating new database connection\", { key });\r\n    return await this.getLazyLoading(key);\r\n  }\r\n\r\n  /**\r\n   * Get all connections\r\n   */\r\n  public static getConnections(): DatabaseConnections {\r\n    logger.trace(\"Getting all connections\", {\r\n      count: Object.keys(this.connections).length,\r\n    });\r\n    return { ...this.connections };\r\n  }\r\n\r\n  /**\r\n   * Open all existing databases\r\n   */\r\n  public static async openAllExisting(\r\n    databaseKeys: string[]\r\n  ): Promise<boolean> {\r\n    logger.info(\"Opening all existing databases\", { databaseKeys });\r\n    const failedOpens: { key: string; error: Error }[] = [];\r\n\r\n    for (const key of databaseKeys) {\r\n      try {\r\n        logger.debug(\"Opening database\", { key });\r\n        const schema = this.getSchema(key);\r\n        if (!schema) {\r\n          throw new Error(`Invalid database key: ${key}. Schema not found.`);\r\n        }\r\n\r\n        const dao = await DatabaseFactory.createOrOpen(\r\n          { config: schema },\r\n          false\r\n        );\r\n        await dao.execute(\"PRAGMA integrity_check\");\r\n        this.connections[key] = dao;\r\n        logger.info(\"Database opened successfully\", {\r\n          key,\r\n          schemaName: schema.database_name,\r\n        });\r\n      } catch (error) {\r\n        const err = error instanceof Error ? error : new Error(String(error));\r\n        logger.error(\"Failed to open database\", { key, error: err.message });\r\n        failedOpens.push({ key, error: err });\r\n      }\r\n    }\r\n\r\n    if (failedOpens.length > 0) {\r\n      const errorSummary = failedOpens\r\n        .map((f) => `  - ${f.key}: ${f.error.message}`)\r\n        .join(\"\\n\");\r\n      logger.error(\"Failed to open one or more databases\", {\r\n        failedDatabases: failedOpens.map((f) => f.key),\r\n        errorSummary,\r\n      });\r\n      throw new Error(`Failed to open one or more databases:\\n${errorSummary}`);\r\n    }\r\n\r\n    this.isInitialized = true;\r\n    logger.info(\"All databases opened successfully\", {\r\n      count: databaseKeys.length,\r\n    });\r\n    return true;\r\n  }\r\n\r\n  /**\r\n   * Initialize databases lazily\r\n   */\r\n  public static async initLazySchema(databaseKeys: string[]): Promise<boolean> {\r\n    logger.debug(\"Initializing databases lazily\", { databaseKeys });\r\n\r\n    const invalidKeys = databaseKeys.filter((key) => !this.getSchema(key));\r\n    if (invalidKeys.length > 0) {\r\n      logger.error(\"Invalid database keys found\", { invalidKeys });\r\n      throw new Error(\r\n        `Invalid database keys: ${invalidKeys.join(\", \")}. Schemas not found.`\r\n      );\r\n    }\r\n\r\n    const newConnectionsCount = databaseKeys.filter(\r\n      (key) => !this.connections[key]\r\n    ).length;\r\n    const currentConnectionsCount = Object.keys(this.connections).length;\r\n\r\n    if (currentConnectionsCount + newConnectionsCount > this.maxConnections) {\r\n      logger.error(\"Would exceed maximum connections\", {\r\n        currentConnections: currentConnectionsCount,\r\n        newConnections: newConnectionsCount,\r\n        maxConnections: this.maxConnections,\r\n      });\r\n      throw new Error(\r\n        `Cannot initialize ${newConnectionsCount} new connections. Would exceed maximum of ${this.maxConnections} connections. Current: ${currentConnectionsCount}`\r\n      );\r\n    }\r\n\r\n    const failedInitializations: { key: string; error: Error }[] = [];\r\n    const initPromises = databaseKeys.map(async (key) => {\r\n      if (this.connections[key]) {\r\n        logger.trace(\"Database already initialized\", { key });\r\n        return; // Already initialized\r\n      }\r\n\r\n      try {\r\n        logger.debug(\"Initializing database\", { key });\r\n        const schema = this.getSchema(key)!;\r\n        const dao = await DatabaseFactory.createOrOpen(\r\n          { config: schema },\r\n          false\r\n        );\r\n        await dao.execute(\"PRAGMA integrity_check\");\r\n        this.connections[key] = dao;\r\n        logger.info(\"Database initialized successfully\", {\r\n          key,\r\n          schemaName: schema.database_name,\r\n        });\r\n      } catch (error) {\r\n        const err = error instanceof Error ? error : new Error(String(error));\r\n        logger.error(\"Failed to initialize database\", {\r\n          key,\r\n          error: err.message,\r\n        });\r\n        failedInitializations.push({ key, error: err });\r\n      }\r\n    });\r\n\r\n    await Promise.all(initPromises);\r\n\r\n    if (failedInitializations.length > 0) {\r\n      const errorSummary = failedInitializations\r\n        .map((f) => `  - ${f.key}: ${f.error.message}`)\r\n        .join(\"\\n\");\r\n      logger.error(\"Failed to initialize one or more databases\", {\r\n        failedDatabases: failedInitializations.map((f) => f.key),\r\n        errorSummary,\r\n      });\r\n      throw new Error(\r\n        `Failed to initialize one or more databases:\\n${errorSummary}`\r\n      );\r\n    }\r\n\r\n    if (Object.keys(this.connections).length > 0) {\r\n      this.isInitialized = true;\r\n      logger.info(\"Lazy schema initialization completed\", {\r\n        initializedCount: databaseKeys.length - failedInitializations.length,\r\n      });\r\n    }\r\n\r\n    return true;\r\n  }\r\n\r\n  /**\r\n   * Initialize all available databases\r\n   */\r\n  public static async initializeAll(): Promise<void> {\r\n    if (this.isInitialized) {\r\n      logger.debug(\"Database manager already initialized\");\r\n      return;\r\n    }\r\n\r\n    const availableSchemas = this.getAvailableSchemas();\r\n    logger.info(\"Initializing all available databases\", {\r\n      schemaCount: availableSchemas.length,\r\n      schemas: availableSchemas,\r\n    });\r\n\r\n    const failedInitializations: { key: string; error: Error }[] = [];\r\n\r\n    const initPromises = availableSchemas.map(async (key) => {\r\n      try {\r\n        logger.debug(\"Initializing schema\", { key });\r\n        const schema = this.getSchema(key)!;\r\n        const dao = await DatabaseFactory.createOrOpen(\r\n          { config: schema },\r\n          false\r\n        );\r\n        this.connections[key] = dao;\r\n        logger.info(\"Schema initialized successfully\", {\r\n          key,\r\n          schemaName: schema.database_name,\r\n        });\r\n      } catch (error) {\r\n        const err = error instanceof Error ? error : new Error(String(error));\r\n        logger.error(\"Failed to initialize schema\", {\r\n          key,\r\n          error: err.message,\r\n        });\r\n        failedInitializations.push({ key, error: err });\r\n      }\r\n    });\r\n\r\n    await Promise.all(initPromises);\r\n\r\n    if (failedInitializations.length > 0) {\r\n      this.isInitialized = false;\r\n      const errorSummary = failedInitializations\r\n        .map((f) => `  - ${f.key}: ${f.error.message}`)\r\n        .join(\"\\n\");\r\n      logger.error(\"Failed to initialize one or more databases\", {\r\n        failedDatabases: failedInitializations.map((f) => f.key),\r\n        errorSummary,\r\n      });\r\n      throw new Error(\r\n        `Failed to initialize one or more databases:\\n${errorSummary}`\r\n      );\r\n    }\r\n\r\n    this.isInitialized = true;\r\n    logger.info(\"All databases initialized successfully\", {\r\n      totalSchemas: availableSchemas.length,\r\n    });\r\n  }\r\n\r\n  /**\r\n   * Get database with lazy loading\r\n   */\r\n  public static async getLazyLoading(key: string): Promise<UniversalDAO> {\r\n    logger.debug(\"Getting database with lazy loading\", { key });\r\n    this.activeDatabases.add(key);\r\n\r\n    if (!this.hasAccessToDatabase(key)) {\r\n      logger.error(\"Access denied for lazy loading\", { key });\r\n      throw new Error(`Access denied: Database '${key}' is not accessible.`);\r\n    }\r\n\r\n    if (!this.connections[key]) {\r\n      const schema = this.getSchema(key);\r\n      if (!schema) {\r\n        logger.error(\"Schema not found for lazy loading\", { key });\r\n        throw new Error(`Invalid database key: ${key}. Schema not found.`);\r\n      }\r\n\r\n      if (Object.keys(this.connections).length >= this.maxConnections) {\r\n        logger.error(\"Maximum connections reached\", {\r\n          currentConnections: Object.keys(this.connections).length,\r\n          maxConnections: this.maxConnections,\r\n        });\r\n        throw new Error(\"Maximum number of database connections reached\");\r\n      }\r\n\r\n      logger.debug(\"Creating new connection for lazy loading\", {\r\n        key,\r\n        schemaName: schema.database_name,\r\n      });\r\n      const dao = await DatabaseFactory.createOrOpen({ config: schema }, false);\r\n      await dao.connect();\r\n      this.connections[key] = dao;\r\n      logger.info(\"Database connection created via lazy loading\", { key });\r\n    }\r\n\r\n    this.isInitialized = true;\r\n    return this.connections[key];\r\n  }\r\n\r\n  /**\r\n   * Execute cross-schema transaction\r\n   */\r\n  public static async executeCrossSchemaTransaction(\r\n    schemas: string[],\r\n    callback: (daos: Record<string, UniversalDAO>) => Promise<void>\r\n  ): Promise<void> {\r\n    logger.debug(\"Executing cross-schema transaction\", { schemas });\r\n\r\n    for (const key of schemas) {\r\n      if (!this.hasAccessToDatabase(key)) {\r\n        logger.error(\"Access denied for cross-schema transaction\", {\r\n          key,\r\n          schemas,\r\n        });\r\n        throw new Error(`Access denied: Database '${key}' is not accessible.`);\r\n      }\r\n    }\r\n\r\n    const daos = schemas.reduce((acc, key) => {\r\n      acc[key] = this.get(key);\r\n      return acc;\r\n    }, {} as Record<string, UniversalDAO>);\r\n\r\n    logger.debug(\"Starting cross-schema transaction\", { schemas });\r\n\r\n    try {\r\n      await Promise.all(\r\n        Object.values(daos).map((dao) => dao.beginTransaction())\r\n      );\r\n      logger.trace(\"All transactions started successfully\");\r\n\r\n      await callback(daos);\r\n      logger.trace(\"Transaction callback completed successfully\");\r\n\r\n      await Promise.all(\r\n        Object.values(daos).map((dao) => dao.commitTransaction())\r\n      );\r\n      logger.info(\"Cross-schema transaction completed successfully\", {\r\n        schemas,\r\n      });\r\n    } catch (error) {\r\n      logger.error(\"Cross-schema transaction failed, rolling back\", {\r\n        schemas,\r\n        error: (error as Error).message,\r\n      });\r\n\r\n      await Promise.all(\r\n        Object.values(daos).map((dao) => dao.rollbackTransaction())\r\n      );\r\n      logger.debug(\"Cross-schema transaction rolled back\");\r\n      throw error;\r\n    }\r\n  }\r\n\r\n  /**\r\n   * Import data to table\r\n   */\r\n  public static async importDataToTable(\r\n    databaseKey: string,\r\n    tableName: string,\r\n    data: Record<string, any>[],\r\n    options: Partial<ImportOptions> = {}\r\n  ): Promise<ImportResult> {\r\n    logger.debug(\"Importing data to table\", {\r\n      databaseKey,\r\n      tableName,\r\n      recordCount: data.length,\r\n      options,\r\n    });\r\n\r\n    if (!this.hasAccessToDatabase(databaseKey)) {\r\n      logger.error(\"Access denied for data import\", { databaseKey, tableName });\r\n      throw new Error(\r\n        `Access denied: Database '${databaseKey}' is not accessible.`\r\n      );\r\n    }\r\n\r\n    const dao = this.get(databaseKey);\r\n    try {\r\n      const result = await dao.importData({\r\n        tableName,\r\n        data,\r\n        ...options,\r\n      });\r\n      logger.info(\"Data import completed successfully\", {\r\n        databaseKey,\r\n        tableName,\r\n        importedRows: result.successRows,\r\n        skippedRows: result.errorRows,\r\n      });\r\n      return result;\r\n    } catch (error) {\r\n      logger.error(\"Data import failed\", {\r\n        databaseKey,\r\n        tableName,\r\n        error: (error as Error).message,\r\n      });\r\n      throw error;\r\n    }\r\n  }\r\n\r\n  /**\r\n   * Import data with column mapping\r\n   */\r\n  public static async importDataWithMapping(\r\n    databaseKey: string,\r\n    tableName: string,\r\n    data: Record<string, any>[],\r\n    columnMappings: ColumnMapping[],\r\n    options: Partial<ImportOptions> = {}\r\n  ): Promise<ImportResult> {\r\n    logger.debug(\"Importing data with column mapping\", {\r\n      databaseKey,\r\n      tableName,\r\n      recordCount: data.length,\r\n      mappingCount: columnMappings.length,\r\n      options,\r\n    });\r\n\r\n    if (!this.hasAccessToDatabase(databaseKey)) {\r\n      logger.error(\"Access denied for data import with mapping\", {\r\n        databaseKey,\r\n        tableName,\r\n      });\r\n      throw new Error(\r\n        `Access denied: Database '${databaseKey}' is not accessible.`\r\n      );\r\n    }\r\n\r\n    const dao = this.get(databaseKey);\r\n    try {\r\n      const result = await dao.importDataWithMapping(\r\n        tableName,\r\n        data,\r\n        columnMappings,\r\n        options\r\n      );\r\n      logger.info(\"Data import with mapping completed successfully\", {\r\n        databaseKey,\r\n        tableName,\r\n        importedRows: result.successRows,\r\n        skippedRows: result.errorRows,\r\n      });\r\n      return result;\r\n    } catch (error) {\r\n      logger.error(\"Data import with mapping failed\", {\r\n        databaseKey,\r\n        tableName,\r\n        error: (error as Error).message,\r\n      });\r\n      throw error;\r\n    }\r\n  }\r\n\r\n  /**\r\n   * Bulk import data\r\n   */\r\n  public static async bulkImport(\r\n    importConfigs: DatabaseImportConfig[]\r\n  ): Promise<BulkImportResult> {\r\n    const startTime = Date.now();\r\n    logger.info(\"Starting bulk import\", {\r\n      configCount: importConfigs.length,\r\n      configs: importConfigs.map((c) => ({\r\n        databaseKey: c.databaseKey,\r\n        tableName: c.tableName,\r\n        recordCount: c.data.length,\r\n      })),\r\n    });\r\n\r\n    const result: BulkImportResult = {\r\n      totalDatabases: importConfigs.length,\r\n      successDatabases: 0,\r\n      results: {},\r\n      errors: {},\r\n      executionTime: 0,\r\n    };\r\n\r\n    for (const config of importConfigs) {\r\n      const configKey = `${config.databaseKey}.${config.tableName}`;\r\n      logger.debug(\"Processing bulk import config\", { configKey });\r\n\r\n      try {\r\n        if (!this.hasAccessToDatabase(config.databaseKey)) {\r\n          throw new Error(\r\n            `Access denied: Database '${config.databaseKey}' is not accessible.`\r\n          );\r\n        }\r\n\r\n        const dao = this.get(config.databaseKey);\r\n        let importResult: ImportResult;\r\n\r\n        if (config.columnMappings) {\r\n          logger.trace(\"Using column mappings for import\", { configKey });\r\n          importResult = await dao.importDataWithMapping(\r\n            config.tableName,\r\n            config.data,\r\n            config.columnMappings,\r\n            config.options\r\n          );\r\n        } else {\r\n          logger.trace(\"Using direct import\", { configKey });\r\n          importResult = await dao.importData({\r\n            tableName: config.tableName,\r\n            data: config.data,\r\n            ...config.options,\r\n          });\r\n        }\r\n\r\n        result.results[configKey] = importResult;\r\n        result.successDatabases++;\r\n        logger.info(\"Bulk import config completed successfully\", {\r\n          configKey,\r\n          importedRows: importResult.successRows,\r\n          skippedRows: importResult.errorRows,\r\n        });\r\n      } catch (error) {\r\n        const err = error instanceof Error ? error : new Error(String(error));\r\n        logger.error(\"Bulk import config failed\", {\r\n          configKey,\r\n          error: err.message,\r\n        });\r\n        result.errors[configKey] = err;\r\n      }\r\n    }\r\n\r\n    result.executionTime = Date.now() - startTime;\r\n    logger.info(\"Bulk import completed\", {\r\n      totalConfigs: result.totalDatabases,\r\n      successfulConfigs: result.successDatabases,\r\n      failedConfigs: Object.keys(result.errors).length,\r\n      executionTimeMs: result.executionTime,\r\n    });\r\n\r\n    return result;\r\n  }\r\n\r\n  /**\r\n   * Import from CSV\r\n   */\r\n  public static async importFromCSV(\r\n    databaseKey: string,\r\n    tableName: string,\r\n    csvData: string,\r\n    options: {\r\n      delimiter?: string;\r\n      hasHeader?: boolean;\r\n      columnMappings?: ColumnMapping[];\r\n    } & Partial<ImportOptions> = {}\r\n  ): Promise<ImportResult> {\r\n    logger.debug(\"Importing from CSV\", {\r\n      databaseKey,\r\n      tableName,\r\n      csvSize: csvData.length,\r\n      options,\r\n    });\r\n\r\n    if (!this.hasAccessToDatabase(databaseKey)) {\r\n      logger.error(\"Access denied for CSV import\", { databaseKey, tableName });\r\n      throw new Error(\r\n        `Access denied: Database '${databaseKey}' is not accessible.`\r\n      );\r\n    }\r\n\r\n    const dao = this.get(databaseKey);\r\n    try {\r\n      const result = await dao.importFromCSV(tableName, csvData, options);\r\n      logger.info(\"CSV import completed successfully\", {\r\n        databaseKey,\r\n        tableName,\r\n        importedRows: result.successRows,\r\n        skippedRows: result.errorRows,\r\n      });\r\n      return result;\r\n    } catch (error) {\r\n      logger.error(\"CSV import failed\", {\r\n        databaseKey,\r\n        tableName,\r\n        error: (error as Error).message,\r\n      });\r\n      throw error;\r\n    }\r\n  }\r\n\r\n  /**\r\n   * Get connection count\r\n   */\r\n  public static getConnectionCount(): number {\r\n    const count = Object.keys(this.connections).length;\r\n    logger.trace(\"Getting connection count\", { count });\r\n    return count;\r\n  }\r\n\r\n  /**\r\n   * List all active connections\r\n   */\r\n  public static listConnections(): string[] {\r\n    const connections = Object.keys(this.connections);\r\n    logger.trace(\"Listing connections\", { connections });\r\n    return connections;\r\n  }\r\n\r\n  /**\r\n   * Close specific connection\r\n   */\r\n  public static async closeConnection(dbKey: string): Promise<void> {\r\n    logger.debug(\"Closing specific connection\", { dbKey });\r\n\r\n    const dao = this.connections[dbKey];\r\n    if (dao) {\r\n      try {\r\n        await dao.disconnect();\r\n        delete this.connections[dbKey];\r\n        logger.info(\"Database connection closed successfully\", { dbKey });\r\n      } catch (error) {\r\n        logger.error(\"Error closing database connection\", {\r\n          dbKey,\r\n          error: (error as Error).message,\r\n        });\r\n        throw error;\r\n      }\r\n    } else {\r\n      logger.warn(\"Attempted to close non-existent connection\", { dbKey });\r\n    }\r\n  }\r\n\r\n  /**\r\n   * Close all connections and reset state\r\n   */\r\n  public static async closeAll(): Promise<void> {\r\n    logger.info(\"Closing all connections and resetting state\");\r\n\r\n    await this.closeAllConnections();\r\n\r\n    this.currentUserRoles = [];\r\n    this.currentRole = null;\r\n    this.isInitialized = false;\r\n    this.activeDatabases.clear();\r\n    this.eventListeners.clear();\r\n    this.isClosingConnections = false;\r\n\r\n    logger.info(\"All connections closed and state reset successfully\");\r\n  }\r\n\r\n  /**\r\n   * Logout user - close role-specific connections\r\n   */\r\n  public static async logout(): Promise<void> {\r\n    logger.info(\"Logging out user\", {\r\n      currentUserRoles: this.currentUserRoles,\r\n    });\r\n\r\n    const connectionsToClose = Object.keys(this.connections).filter(\r\n      (key) => key !== \"core\"\r\n    );\r\n\r\n    logger.debug(\"Closing role-specific connections\", { connectionsToClose });\r\n\r\n    for (const dbKey of connectionsToClose) {\r\n      try {\r\n        await this.connections[dbKey].close();\r\n        delete this.connections[dbKey];\r\n        logger.debug(\"Role-specific connection closed\", { dbKey });\r\n      } catch (error) {\r\n        logger.error(\"Error closing connection during logout\", {\r\n          dbKey,\r\n          error: (error as Error).message,\r\n        });\r\n        // Log error but continue cleanup\r\n      }\r\n    }\r\n\r\n    this.currentUserRoles = [];\r\n    this.currentRole = null;\r\n\r\n    logger.info(\"User logout completed successfully\", {\r\n      closedConnections: connectionsToClose.length,\r\n    });\r\n  }\r\n}\r\n\r\n/* const finalConfig = CommonLoggerConfig.getCurrentConfig();\r\nif (finalConfig.defaultLevel !== initialConfig.defaultLevel) {\r\n  console.trace('⚠️ [database-manager.ts] Config changed!', {\r\n    from: initialConfig.defaultLevel,\r\n    to: finalConfig.defaultLevel\r\n  });\r\n} */","// src/core/base-service.ts\r\nimport {\r\n  QueryTable,\r\n  WhereClause,\r\n  OrderByClause,\r\n  ImportResult,\r\n  ColumnMapping,\r\n  ImportOptions,\r\n  ServiceStatus,\r\n  HealthCheckResult,\r\n} from \"@/types\";\r\nimport { UniversalDAO } from \"./universal-dao\";\r\nimport { DatabaseManager } from \"./database-manager\";\r\nimport { createModuleLogger, SQLiteModules } from \"@/logger\";\r\n\r\nconst logger = createModuleLogger(SQLiteModules.BASE_SERVICE);\r\n\r\nexport interface FindOptions {\r\n  where?: WhereClause[];\r\n  orderBy?: OrderByClause[];\r\n  limit?: number;\r\n  offset?: number;\r\n  columns?: string[];\r\n}\r\n\r\nexport type ErrorHandler = (error: Error) => void;\r\nexport type EventHandler = (data: any) => void;\r\n\r\n/**\r\n * Universal BaseService - An enhanced abstract base class designed to provide\r\n * comprehensive CRUD operations and database management features across all\r\n * operating systems and frameworks using TypeScript and JavaScript.\r\n */\r\nexport abstract class BaseService<T = any> {\r\n  protected dao: UniversalDAO | null = null;\r\n  protected schemaName: string;\r\n  protected tableName: string;\r\n  protected isOpened: boolean = false;\r\n  protected isInitialized: boolean = false;\r\n  protected errorHandlers: Map<string, ErrorHandler> = new Map();\r\n  protected eventListeners: Map<string, EventHandler[]> = new Map();\r\n  protected primaryKeyFields: string[] = [\"id\"];\r\n  private cache: Map<string, any> = new Map();\r\n  private reconnectHandler: (dao: UniversalDAO) => void;\r\n\r\n  constructor(schemaName: string, tableName?: string) {\r\n    this.schemaName = schemaName;\r\n    this.tableName = tableName || schemaName;\r\n\r\n    logger.debug(\"Creating BaseService instance\", {\r\n      schemaName: this.schemaName,\r\n      tableName: this.tableName,\r\n      primaryKeyFields: this.primaryKeyFields,\r\n    });\r\n\r\n    // Register reconnect listener for database reconnection\r\n    this.reconnectHandler = (newDao: UniversalDAO) => {\r\n      logger.info(\"Database reconnected for service\", {\r\n        schemaName: this.schemaName,\r\n        tableName: this.tableName,\r\n      });\r\n\r\n      this.dao = newDao;\r\n      this._emit(\"daoReconnected\", { schemaName: this.schemaName });\r\n    };\r\n\r\n    DatabaseManager.onDatabaseReconnect(schemaName, this.reconnectHandler);\r\n    this.bindMethods();\r\n\r\n    logger.trace(\"BaseService instance created successfully\", {\r\n      schemaName: this.schemaName,\r\n      tableName: this.tableName,\r\n    });\r\n  }\r\n\r\n  private bindMethods(): void {\r\n    logger.trace(\"Binding service methods\", {\r\n      schemaName: this.schemaName,\r\n      tableName: this.tableName,\r\n    });\r\n\r\n    const methods = Object.getOwnPropertyNames(Object.getPrototypeOf(this));\r\n    methods.forEach((method) => {\r\n      if (\r\n        typeof (this as any)[method] === \"function\" &&\r\n        method !== \"constructor\"\r\n      ) {\r\n        (this as any)[method] = (this as any)[method].bind(this);\r\n      }\r\n    });\r\n  }\r\n\r\n  /**\r\n   * Set primary key fields for the service\r\n   */\r\n  setPrimaryKeyFields(fields: string[]): this {\r\n    logger.debug(\"Setting primary key fields\", {\r\n      schemaName: this.schemaName,\r\n      tableName: this.tableName,\r\n      previousFields: this.primaryKeyFields,\r\n      newFields: fields,\r\n    });\r\n\r\n    this.primaryKeyFields = fields;\r\n    return this;\r\n  }\r\n\r\n  /**\r\n   * Initialize the service and establish database connection\r\n   */\r\n  async init(): Promise<this> {\r\n    logger.info(\"Initializing BaseService\", {\r\n      schemaName: this.schemaName,\r\n      tableName: this.tableName,\r\n      isInitialized: this.isInitialized,\r\n    });\r\n\r\n    try {\r\n      if (this.isInitialized) {\r\n        logger.debug(\"Service already initialized, skipping\", {\r\n          schemaName: this.schemaName,\r\n        });\r\n        return this;\r\n      }\r\n\r\n      logger.debug(\"Getting DAO from DatabaseManager\", {\r\n        schemaName: this.schemaName,\r\n      });\r\n\r\n      this.dao = await DatabaseManager.getLazyLoading(this.schemaName);\r\n\r\n      if (!this.dao) {\r\n        const errorMsg = `Failed to initialize DAO for schema: ${this.schemaName}`;\r\n        logger.error(errorMsg, {\r\n          schemaName: this.schemaName,\r\n        });\r\n        throw new Error(errorMsg);\r\n      }\r\n\r\n      if (!this.dao.isConnectionOpen()) {\r\n        logger.debug(\"DAO connection not open, connecting\", {\r\n          schemaName: this.schemaName,\r\n        });\r\n        await this.dao.connect();\r\n      }\r\n\r\n      this.isOpened = true;\r\n      this.isInitialized = true;\r\n\r\n      logger.info(\"BaseService initialized successfully\", {\r\n        schemaName: this.schemaName,\r\n        tableName: this.tableName,\r\n        isOpened: this.isOpened,\r\n        isInitialized: this.isInitialized,\r\n      });\r\n\r\n      this._emit(\"initialized\", { schemaName: this.schemaName });\r\n\r\n      return this;\r\n    } catch (error) {\r\n      logger.error(\"Error initializing BaseService\", {\r\n        schemaName: this.schemaName,\r\n        tableName: this.tableName,\r\n        error: (error as Error).message,\r\n      });\r\n\r\n      this._handleError(\"INIT_ERROR\", error as Error);\r\n      throw error;\r\n    }\r\n  }\r\n\r\n  /**\r\n   * Upsert a record - Insert if not exists, update if exists\r\n   * @param data - Data to insert or update\r\n   * @param searchFields - Fields to check for existence (defaults to primary key)\r\n   * @returns The created or updated record\r\n   */\r\n  async upsert(data: Partial<T>, searchFields?: string[]): Promise<T | null> {\r\n    logger.debug(\"Starting upsert operation\", {\r\n      schemaName: this.schemaName,\r\n      tableName: this.tableName,\r\n      hasData: !!data,\r\n      dataKeys: data ? Object.keys(data) : [],\r\n      searchFields: searchFields || this.primaryKeyFields,\r\n    });\r\n\r\n    await this._ensureInitialized();\r\n    await this.ensureValidConnection();\r\n\r\n    try {\r\n      this._validateData(data);\r\n\r\n      // Determine which fields to use for existence check\r\n      const fieldsToCheck = searchFields || this.primaryKeyFields;\r\n\r\n      logger.trace(\"Building conditions for existence check\", {\r\n        schemaName: this.schemaName,\r\n        tableName: this.tableName,\r\n        fieldsToCheck,\r\n      });\r\n\r\n      // Build conditions from specified fields\r\n      const conditions: Record<string, any> = {};\r\n      let hasAllRequiredFields = true;\r\n\r\n      for (const field of fieldsToCheck) {\r\n        const value = data[field as keyof T];\r\n        if (value !== undefined && value !== null) {\r\n          conditions[field] = value;\r\n        } else {\r\n          hasAllRequiredFields = false;\r\n          logger.trace(\"Missing required field for upsert check\", {\r\n            schemaName: this.schemaName,\r\n            tableName: this.tableName,\r\n            field,\r\n          });\r\n          break;\r\n        }\r\n      }\r\n\r\n      // If we don't have all required fields, treat as insert\r\n      if (!hasAllRequiredFields) {\r\n        logger.debug(\"Missing required fields, performing insert\", {\r\n          schemaName: this.schemaName,\r\n          tableName: this.tableName,\r\n          fieldsToCheck,\r\n        });\r\n        return await this.create(data);\r\n      }\r\n\r\n      // Check if record exists\r\n      logger.trace(\"Checking if record exists\", {\r\n        schemaName: this.schemaName,\r\n        tableName: this.tableName,\r\n        conditions,\r\n      });\r\n\r\n      const existingRecord = await this.findFirst(conditions);\r\n\r\n      if (existingRecord) {\r\n        // Record exists - perform update\r\n        const primaryKeyValue =\r\n          existingRecord[this.primaryKeyFields[0] as keyof T];\r\n\r\n        logger.debug(\"Record exists, performing update\", {\r\n          schemaName: this.schemaName,\r\n          tableName: this.tableName,\r\n          primaryKeyField: this.primaryKeyFields[0],\r\n          primaryKeyValue,\r\n        });\r\n\r\n        const result = await this.update(primaryKeyValue, data);\r\n\r\n        logger.info(\"Upsert completed (update)\", {\r\n          schemaName: this.schemaName,\r\n          tableName: this.tableName,\r\n          operation: \"update\",\r\n          primaryKeyValue,\r\n        });\r\n\r\n        this._emit(\"dataUpserted\", {\r\n          operation: \"upsert\",\r\n          action: \"update\",\r\n          data: result,\r\n        });\r\n\r\n        return result;\r\n      } else {\r\n        // Record doesn't exist - perform insert\r\n        logger.debug(\"Record does not exist, performing insert\", {\r\n          schemaName: this.schemaName,\r\n          tableName: this.tableName,\r\n        });\r\n\r\n        const result = await this.create(data);\r\n\r\n        logger.info(\"Upsert completed (insert)\", {\r\n          schemaName: this.schemaName,\r\n          tableName: this.tableName,\r\n          operation: \"insert\",\r\n        });\r\n\r\n        this._emit(\"dataUpserted\", {\r\n          operation: \"upsert\",\r\n          action: \"insert\",\r\n          data: result,\r\n        });\r\n\r\n        return result;\r\n      }\r\n    } catch (error) {\r\n      logger.error(\"Error during upsert operation\", {\r\n        schemaName: this.schemaName,\r\n        tableName: this.tableName,\r\n        error: (error as Error).message,\r\n      });\r\n\r\n      this._handleError(\"UPSERT_ERROR\", error as Error);\r\n      throw error;\r\n    }\r\n  }\r\n\r\n  /**\r\n   * Create a new record - Safe version với comprehensive error handling\r\n   */\r\n  async create(data: Partial<T>): Promise<T | null> {\r\n    logger.debug(\"Creating new record\", {\r\n      schemaName: this.schemaName,\r\n      tableName: this.tableName,\r\n      hasData: !!data,\r\n      dataKeys: data ? Object.keys(data) : [],\r\n    });\r\n\r\n    await this._ensureInitialized();\r\n    await this.ensureValidConnection();\r\n\r\n    try {\r\n      this._validateData(data);\r\n\r\n      logger.trace(\"Building data table for insert\", {\r\n        schemaName: this.schemaName,\r\n        tableName: this.tableName,\r\n      });\r\n\r\n      const queryTable = this.buildDataTable(data as Record<string, any>);\r\n      const result = await this.dao!.insert(queryTable);\r\n\r\n      if (result.rowsAffected === 0) {\r\n        const errorMsg = \"Insert operation failed - no rows affected\";\r\n        logger.error(errorMsg, {\r\n          schemaName: this.schemaName,\r\n          tableName: this.tableName,\r\n          result,\r\n        });\r\n        throw new Error(errorMsg);\r\n      }\r\n\r\n      logger.debug(\"Insert operation successful\", {\r\n        schemaName: this.schemaName,\r\n        tableName: this.tableName,\r\n        rowsAffected: result.rowsAffected,\r\n        lastInsertRowId: result.lastInsertRowId,\r\n      });\r\n\r\n      let createdRecord: T | null = null;\r\n      const primaryKeyValue = data[this.primaryKeyFields[0] as keyof T];\r\n\r\n      try {\r\n        if (primaryKeyValue !== undefined && primaryKeyValue !== null) {\r\n          logger.trace(\"Retrieving created record by primary key\", {\r\n            schemaName: this.schemaName,\r\n            tableName: this.tableName,\r\n            primaryKeyField: this.primaryKeyFields[0],\r\n            primaryKeyValue,\r\n          });\r\n          createdRecord = await this.findById(primaryKeyValue as any);\r\n        } else if (result.lastInsertRowId) {\r\n          logger.trace(\"Retrieving created record by last insert ID\", {\r\n            schemaName: this.schemaName,\r\n            tableName: this.tableName,\r\n            lastInsertRowId: result.lastInsertRowId,\r\n          });\r\n          createdRecord = await this.findById(result.lastInsertRowId);\r\n        }\r\n      } catch (findError) {\r\n        logger.warn(\"Could not retrieve created record\", {\r\n          schemaName: this.schemaName,\r\n          tableName: this.tableName,\r\n          findError: (findError as Error).message,\r\n        });\r\n      }\r\n\r\n      if (!createdRecord) {\r\n        logger.debug(\"Using original data as created record\", {\r\n          schemaName: this.schemaName,\r\n          tableName: this.tableName,\r\n        });\r\n        createdRecord = data as T;\r\n      }\r\n\r\n      logger.info(\"Record created successfully\", {\r\n        schemaName: this.schemaName,\r\n        tableName: this.tableName,\r\n        recordRetrieved: !!createdRecord,\r\n      });\r\n\r\n      this._emit(\"dataCreated\", { operation: \"create\", data: createdRecord });\r\n      return createdRecord;\r\n    } catch (error) {\r\n      logger.error(\"Error creating record\", {\r\n        schemaName: this.schemaName,\r\n        tableName: this.tableName,\r\n        error: (error as Error).message,\r\n      });\r\n\r\n      this._handleError(\"CREATE_ERROR\", error as Error);\r\n      throw error;\r\n    }\r\n  }\r\n\r\n  /**\r\n   * Update an existing record\r\n   */\r\n  async update(id: any, data: Partial<T>): Promise<T | null> {\r\n    logger.debug(\"Updating record\", {\r\n      schemaName: this.schemaName,\r\n      tableName: this.tableName,\r\n      id,\r\n      hasData: !!data,\r\n      dataKeys: data ? Object.keys(data) : [],\r\n    });\r\n\r\n    await this._ensureInitialized();\r\n\r\n    try {\r\n      if (!id) {\r\n        const errorMsg = \"ID is required for update\";\r\n        logger.error(errorMsg, {\r\n          schemaName: this.schemaName,\r\n          tableName: this.tableName,\r\n        });\r\n        throw new Error(errorMsg);\r\n      }\r\n\r\n      this._validateData(data);\r\n\r\n      const updateData = {\r\n        ...data,\r\n        [this.primaryKeyFields[0]]: id,\r\n      };\r\n\r\n      logger.trace(\"Building update query table\", {\r\n        schemaName: this.schemaName,\r\n        tableName: this.tableName,\r\n        id,\r\n      });\r\n\r\n      const queryTable = this.buildDataTable(updateData as Record<string, any>);\r\n      await this.dao!.update(queryTable);\r\n\r\n      logger.debug(\"Update operation completed\", {\r\n        schemaName: this.schemaName,\r\n        tableName: this.tableName,\r\n        id,\r\n      });\r\n\r\n      const result = await this.findById(id);\r\n\r\n      logger.info(\"Record updated successfully\", {\r\n        schemaName: this.schemaName,\r\n        tableName: this.tableName,\r\n        id,\r\n        recordFound: !!result,\r\n      });\r\n\r\n      this._emit(\"dataUpdated\", { operation: \"update\", id, data: result });\r\n      return result;\r\n    } catch (error) {\r\n      logger.error(\"Error updating record\", {\r\n        schemaName: this.schemaName,\r\n        tableName: this.tableName,\r\n        id,\r\n        error: (error as Error).message,\r\n      });\r\n\r\n      this._handleError(\"UPDATE_ERROR\", error as Error);\r\n      throw error;\r\n    }\r\n  }\r\n\r\n  /**\r\n   * Delete a record by ID\r\n   */\r\n  async delete(id: any): Promise<boolean> {\r\n    logger.debug(\"Deleting record\", {\r\n      schemaName: this.schemaName,\r\n      tableName: this.tableName,\r\n      id,\r\n    });\r\n\r\n    await this._ensureInitialized();\r\n\r\n    try {\r\n      if (!id) {\r\n        const errorMsg = \"ID is required for delete\";\r\n        logger.error(errorMsg, {\r\n          schemaName: this.schemaName,\r\n          tableName: this.tableName,\r\n        });\r\n        throw new Error(errorMsg);\r\n      }\r\n\r\n      const queryTable: QueryTable = {\r\n        name: this.tableName,\r\n        cols: [],\r\n        wheres: [{ name: this.primaryKeyFields[0], value: id }],\r\n      };\r\n\r\n      logger.trace(\"Executing delete operation\", {\r\n        schemaName: this.schemaName,\r\n        tableName: this.tableName,\r\n        id,\r\n        primaryKeyField: this.primaryKeyFields[0],\r\n      });\r\n\r\n      const result = await this.dao!.delete(queryTable);\r\n      const success = result.rowsAffected > 0;\r\n\r\n      if (success) {\r\n        logger.info(\"Record deleted successfully\", {\r\n          schemaName: this.schemaName,\r\n          tableName: this.tableName,\r\n          id,\r\n          rowsAffected: result.rowsAffected,\r\n        });\r\n        this._emit(\"dataDeleted\", { operation: \"delete\", id });\r\n      } else {\r\n        logger.warn(\"Delete operation completed but no rows affected\", {\r\n          schemaName: this.schemaName,\r\n          tableName: this.tableName,\r\n          id,\r\n        });\r\n      }\r\n\r\n      return success;\r\n    } catch (error) {\r\n      logger.error(\"Error deleting record\", {\r\n        schemaName: this.schemaName,\r\n        tableName: this.tableName,\r\n        id,\r\n        error: (error as Error).message,\r\n      });\r\n\r\n      this._handleError(\"DELETE_ERROR\", error as Error);\r\n      throw error;\r\n    }\r\n  }\r\n\r\n  /**\r\n   * Find a record by ID\r\n   */\r\n  async findById(id: any): Promise<T | null> {\r\n    logger.debug(\"Finding record by ID\", {\r\n      schemaName: this.schemaName,\r\n      tableName: this.tableName,\r\n      id,\r\n    });\r\n\r\n    await this._ensureInitialized();\r\n\r\n    try {\r\n      if (!id) {\r\n        const errorMsg = \"ID is required\";\r\n        logger.error(errorMsg, {\r\n          schemaName: this.schemaName,\r\n          tableName: this.tableName,\r\n        });\r\n        throw new Error(errorMsg);\r\n      }\r\n\r\n      const conditions = { [this.primaryKeyFields[0]]: id };\r\n\r\n      logger.trace(\"Building select query\", {\r\n        schemaName: this.schemaName,\r\n        tableName: this.tableName,\r\n        conditions,\r\n      });\r\n\r\n      const queryTable = this.buildSelectTable(conditions);\r\n      const result = await this.dao!.select(queryTable);\r\n\r\n      const record = Object.keys(result).length > 0 ? (result as T) : null;\r\n\r\n      logger.debug(\"Find by ID completed\", {\r\n        schemaName: this.schemaName,\r\n        tableName: this.tableName,\r\n        id,\r\n        recordFound: !!record,\r\n      });\r\n\r\n      this._emit(\"dataFetched\", { operation: \"findById\", id });\r\n      return record;\r\n    } catch (error) {\r\n      logger.error(\"Error finding record by ID\", {\r\n        schemaName: this.schemaName,\r\n        tableName: this.tableName,\r\n        id,\r\n        error: (error as Error).message,\r\n      });\r\n\r\n      this._handleError(\"FIND_BY_ID_ERROR\", error as Error);\r\n      throw error;\r\n    }\r\n  }\r\n\r\n  /**\r\n   * Find the first record matching conditions\r\n   */\r\n  async findFirst(conditions: Record<string, any> = {}): Promise<T | null> {\r\n    logger.debug(\"Finding first record\", {\r\n      schemaName: this.schemaName,\r\n      tableName: this.tableName,\r\n      conditionsCount: Object.keys(conditions).length,\r\n      conditions,\r\n    });\r\n\r\n    await this._ensureInitialized();\r\n\r\n    try {\r\n      logger.trace(\"Building select query for findFirst\", {\r\n        schemaName: this.schemaName,\r\n        tableName: this.tableName,\r\n      });\r\n\r\n      const queryTable = this.buildSelectTable(conditions);\r\n      const result = await this.dao!.select(queryTable);\r\n\r\n      const record = Object.keys(result).length > 0 ? (result as T) : null;\r\n\r\n      logger.debug(\"Find first completed\", {\r\n        schemaName: this.schemaName,\r\n        tableName: this.tableName,\r\n        recordFound: !!record,\r\n      });\r\n\r\n      this._emit(\"dataFetched\", { operation: \"findFirst\" });\r\n      return record;\r\n    } catch (error) {\r\n      logger.error(\"Error finding first record\", {\r\n        schemaName: this.schemaName,\r\n        tableName: this.tableName,\r\n        conditions,\r\n        error: (error as Error).message,\r\n      });\r\n\r\n      this._handleError(\"FIND_FIRST_ERROR\", error as Error);\r\n      throw error;\r\n    }\r\n  }\r\n\r\n  /**\r\n   * Find all records matching conditions\r\n   */\r\n  async findAll(\r\n    conditions: Record<string, any> = {},\r\n    options: FindOptions = {}\r\n  ): Promise<T[]> {\r\n    logger.debug(\"Finding all records\", {\r\n      schemaName: this.schemaName,\r\n      tableName: this.tableName,\r\n      conditionsCount: Object.keys(conditions).length,\r\n      hasLimit: !!options.limit,\r\n      hasOffset: !!options.offset,\r\n      hasOrderBy: !!(options.orderBy && options.orderBy.length > 0),\r\n      limit: options.limit,\r\n      offset: options.offset,\r\n    });\r\n\r\n    await this._ensureInitialized();\r\n\r\n    try {\r\n      // Build where clauses from conditions\r\n      const whereFromConditions = this.buildWhereFromObject(conditions);\r\n      const allWheres = [...whereFromConditions, ...(options.where || [])];\r\n\r\n      logger.trace(\"Building query for findAll\", {\r\n        schemaName: this.schemaName,\r\n        tableName: this.tableName,\r\n        totalWheres: allWheres.length,\r\n        hasColumns: !!(options.columns && options.columns.length > 0),\r\n      });\r\n\r\n      const queryTable: QueryTable = {\r\n        name: this.tableName,\r\n        cols: options.columns ? options.columns.map((name) => ({ name })) : [],\r\n        wheres: allWheres,\r\n        orderbys: options.orderBy,\r\n        limitOffset: {\r\n          limit: options.limit,\r\n          offset: options.offset,\r\n        },\r\n      };\r\n\r\n      const results = await this.dao!.selectAll(queryTable);\r\n\r\n      logger.info(\"Find all completed\", {\r\n        schemaName: this.schemaName,\r\n        tableName: this.tableName,\r\n        recordsFound: results.length,\r\n        conditionsCount: Object.keys(conditions).length,\r\n      });\r\n\r\n      this._emit(\"dataFetched\", {\r\n        operation: \"findAll\",\r\n        count: results.length,\r\n      });\r\n      return results as T[];\r\n    } catch (error) {\r\n      logger.error(\"Error finding all records\", {\r\n        schemaName: this.schemaName,\r\n        tableName: this.tableName,\r\n        conditions,\r\n        options,\r\n        error: (error as Error).message,\r\n      });\r\n\r\n      this._handleError(\"FIND_ALL_ERROR\", error as Error);\r\n      throw error;\r\n    }\r\n  }\r\n\r\n  /**\r\n   * Count records matching conditions\r\n   */\r\n  async count(where?: WhereClause[] | Record<string, any>): Promise<number> {\r\n    logger.debug(\"Counting records\", {\r\n      schemaName: this.schemaName,\r\n      tableName: this.tableName,\r\n      hasWhere: !!where,\r\n      whereType: where ? (Array.isArray(where) ? \"array\" : \"object\") : \"none\",\r\n    });\r\n\r\n    await this._ensureInitialized();\r\n\r\n    try {\r\n      let whereConditions: WhereClause[] = [];\r\n\r\n      if (Array.isArray(where)) {\r\n        whereConditions = where;\r\n        logger.trace(\"Using array where conditions\", {\r\n          schemaName: this.schemaName,\r\n          whereCount: whereConditions.length,\r\n        });\r\n      } else if (where && typeof where === \"object\") {\r\n        whereConditions = this.buildWhereFromObject(where);\r\n        logger.trace(\"Built where conditions from object\", {\r\n          schemaName: this.schemaName,\r\n          whereCount: whereConditions.length,\r\n        });\r\n      }\r\n\r\n      const queryTable: QueryTable = {\r\n        name: this.tableName,\r\n        cols: [{ name: \"COUNT(*) as count\" }],\r\n        wheres: whereConditions,\r\n      };\r\n\r\n      const result = await this.dao!.select(queryTable);\r\n      const count = result.count || 0;\r\n\r\n      logger.debug(\"Count completed\", {\r\n        schemaName: this.schemaName,\r\n        tableName: this.tableName,\r\n        count,\r\n      });\r\n\r\n      return count;\r\n    } catch (error) {\r\n      logger.error(\"Error counting records\", {\r\n        schemaName: this.schemaName,\r\n        tableName: this.tableName,\r\n        where,\r\n        error: (error as Error).message,\r\n      });\r\n\r\n      this._handleError(\"COUNT_ERROR\", error as Error);\r\n      throw error;\r\n    }\r\n  }\r\n\r\n  /**\r\n   * Check if a record exists by ID\r\n   */\r\n  async exists(id: any): Promise<boolean> {\r\n    logger.debug(\"Checking if record exists\", {\r\n      schemaName: this.schemaName,\r\n      tableName: this.tableName,\r\n      id,\r\n    });\r\n\r\n    const item = await this.findById(id);\r\n    const exists = item !== null;\r\n\r\n    logger.debug(\"Existence check completed\", {\r\n      schemaName: this.schemaName,\r\n      tableName: this.tableName,\r\n      id,\r\n      exists,\r\n    });\r\n\r\n    return exists;\r\n  }\r\n\r\n  /**\r\n   * Truncate table (delete all records and reset auto-increment)\r\n   */\r\n  async truncate(): Promise<void> {\r\n    logger.warn(\"Truncating table - this will delete all data\", {\r\n      schemaName: this.schemaName,\r\n      tableName: this.tableName,\r\n    });\r\n\r\n    await this._ensureInitialized();\r\n\r\n    try {\r\n      logger.debug(\"Executing truncate operations\", {\r\n        schemaName: this.schemaName,\r\n        tableName: this.tableName,\r\n      });\r\n\r\n      await this.dao!.execute(`DELETE FROM ${this.tableName}`);\r\n      await this.dao!.execute(\r\n        `DELETE FROM sqlite_sequence WHERE name='${this.tableName}'`\r\n      );\r\n\r\n      logger.info(\"Table truncated successfully\", {\r\n        schemaName: this.schemaName,\r\n        tableName: this.tableName,\r\n      });\r\n\r\n      this._emit(\"tableTruncated\", { tableName: this.tableName });\r\n    } catch (error) {\r\n      logger.error(\"Error truncating table\", {\r\n        schemaName: this.schemaName,\r\n        tableName: this.tableName,\r\n        error: (error as Error).message,\r\n      });\r\n\r\n      this._handleError(\"TRUNCATE_ERROR\", error as Error);\r\n      throw error;\r\n    }\r\n  }\r\n\r\n  /**\r\n   * Bulk upsert records - Insert if not exists, update if exists for multiple records\r\n   * @param dataArray - Array of data to insert or update\r\n   * @param searchFields - Fields to check for existence (defaults to primary key)\r\n   * @param useTransaction - Whether to wrap in transaction (default: true)\r\n   * @returns Result with created and updated records\r\n   */\r\n  async bulkUpsert(\r\n    dataArray: Partial<T>[],\r\n    searchFields?: string[],\r\n    useTransaction: boolean = true\r\n  ): Promise<{\r\n    created: T[];\r\n    updated: T[];\r\n    total: number;\r\n    errors: Array<{ index: number; data: Partial<T>; error: string }>;\r\n  }> {\r\n    logger.info(\"Starting bulk upsert operation\", {\r\n      schemaName: this.schemaName,\r\n      tableName: this.tableName,\r\n      itemsCount: dataArray.length,\r\n      searchFields: searchFields || this.primaryKeyFields,\r\n      useTransaction,\r\n    });\r\n\r\n    await this._ensureInitialized();\r\n    await this.ensureValidConnection();\r\n\r\n    try {\r\n      if (!Array.isArray(dataArray) || dataArray.length === 0) {\r\n        const errorMsg = \"Data must be a non-empty array\";\r\n        logger.error(errorMsg, {\r\n          schemaName: this.schemaName,\r\n          tableName: this.tableName,\r\n          dataType: typeof dataArray,\r\n          dataLength: Array.isArray(dataArray) ? dataArray.length : \"N/A\",\r\n        });\r\n        throw new Error(errorMsg);\r\n      }\r\n\r\n      const result = {\r\n        created: [] as T[],\r\n        updated: [] as T[],\r\n        total: dataArray.length,\r\n        errors: [] as Array<{ index: number; data: Partial<T>; error: string }>,\r\n      };\r\n\r\n      // Determine which fields to use for existence check\r\n      const fieldsToCheck = searchFields || this.primaryKeyFields;\r\n\r\n      logger.debug(\"Preparing bulk upsert\", {\r\n        schemaName: this.schemaName,\r\n        tableName: this.tableName,\r\n        fieldsToCheck,\r\n        itemsCount: dataArray.length,\r\n      });\r\n\r\n      // Process function\r\n      const processBulkUpsert = async () => {\r\n        for (let i = 0; i < dataArray.length; i++) {\r\n          const data = dataArray[i];\r\n\r\n          try {\r\n            if (i % 100 === 0) {\r\n              logger.trace(\"Bulk upsert progress\", {\r\n                schemaName: this.schemaName,\r\n                tableName: this.tableName,\r\n                processed: i,\r\n                total: dataArray.length,\r\n                created: result.created.length,\r\n                updated: result.updated.length,\r\n                errors: result.errors.length,\r\n              });\r\n            }\r\n\r\n            this._validateData(data);\r\n\r\n            // Build conditions from specified fields\r\n            const conditions: Record<string, any> = {};\r\n            let hasAllRequiredFields = true;\r\n\r\n            for (const field of fieldsToCheck) {\r\n              const value = data[field as keyof T];\r\n              if (value !== undefined && value !== null) {\r\n                conditions[field] = value;\r\n              } else {\r\n                hasAllRequiredFields = false;\r\n                break;\r\n              }\r\n            }\r\n\r\n            // If we don't have all required fields, treat as insert\r\n            if (!hasAllRequiredFields) {\r\n              logger.trace(\r\n                \"Missing required fields for item, performing insert\",\r\n                {\r\n                  schemaName: this.schemaName,\r\n                  tableName: this.tableName,\r\n                  index: i,\r\n                  fieldsToCheck,\r\n                }\r\n              );\r\n\r\n              const queryTable = this.buildDataTable(\r\n                data as Record<string, any>\r\n              );\r\n              await this.dao!.insert(queryTable);\r\n              result.created.push(data as T);\r\n              continue;\r\n            }\r\n\r\n            // Check if record exists\r\n            const existingRecord = await this.findFirst(conditions);\r\n\r\n            if (existingRecord) {\r\n              // Record exists - perform update\r\n              const primaryKeyValue =\r\n                existingRecord[this.primaryKeyFields[0] as keyof T];\r\n\r\n              logger.trace(\"Record exists, performing update\", {\r\n                schemaName: this.schemaName,\r\n                tableName: this.tableName,\r\n                index: i,\r\n                primaryKeyValue,\r\n              });\r\n\r\n              const updateData = {\r\n                ...data,\r\n                [this.primaryKeyFields[0]]: primaryKeyValue,\r\n              };\r\n\r\n              const queryTable = this.buildDataTable(\r\n                updateData as Record<string, any>\r\n              );\r\n              await this.dao!.update(queryTable);\r\n\r\n              const updatedRecord = await this.findById(primaryKeyValue);\r\n              if (updatedRecord) {\r\n                result.updated.push(updatedRecord);\r\n              }\r\n            } else {\r\n              // Record doesn't exist - perform insert\r\n              logger.trace(\"Record does not exist, performing insert\", {\r\n                schemaName: this.schemaName,\r\n                tableName: this.tableName,\r\n                index: i,\r\n              });\r\n\r\n              const queryTable = this.buildDataTable(\r\n                data as Record<string, any>\r\n              );\r\n              await this.dao!.insert(queryTable);\r\n              result.created.push(data as T);\r\n            }\r\n          } catch (error) {\r\n            logger.warn(\"Error processing item in bulk upsert\", {\r\n              schemaName: this.schemaName,\r\n              tableName: this.tableName,\r\n              index: i,\r\n              error: (error as Error).message,\r\n            });\r\n\r\n            result.errors.push({\r\n              index: i,\r\n              data,\r\n              error: (error as Error).message,\r\n            });\r\n          }\r\n        }\r\n      };\r\n\r\n      // Execute with or without transaction\r\n      if (useTransaction) {\r\n        logger.debug(\"Executing bulk upsert in transaction\", {\r\n          schemaName: this.schemaName,\r\n          tableName: this.tableName,\r\n          itemsCount: dataArray.length,\r\n        });\r\n\r\n        await this.executeTransaction(processBulkUpsert);\r\n      } else {\r\n        logger.debug(\"Executing bulk upsert without transaction\", {\r\n          schemaName: this.schemaName,\r\n          tableName: this.tableName,\r\n          itemsCount: dataArray.length,\r\n        });\r\n\r\n        await processBulkUpsert();\r\n      }\r\n\r\n      logger.info(\"Bulk upsert completed\", {\r\n        schemaName: this.schemaName,\r\n        tableName: this.tableName,\r\n        total: result.total,\r\n        created: result.created.length,\r\n        updated: result.updated.length,\r\n        errors: result.errors.length,\r\n        successRate: `${(\r\n          ((result.created.length + result.updated.length) / result.total) *\r\n          100\r\n        ).toFixed(2)}%`,\r\n      });\r\n\r\n      this._emit(\"dataBulkUpserted\", {\r\n        operation: \"bulkUpsert\",\r\n        created: result.created.length,\r\n        updated: result.updated.length,\r\n        errors: result.errors.length,\r\n        total: result.total,\r\n      });\r\n\r\n      return result;\r\n    } catch (error) {\r\n      logger.error(\"Error during bulk upsert operation\", {\r\n        schemaName: this.schemaName,\r\n        tableName: this.tableName,\r\n        itemsCount: dataArray.length,\r\n        error: (error as Error).message,\r\n      });\r\n\r\n      this._handleError(\"BULK_UPSERT_ERROR\", error as Error);\r\n      throw error;\r\n    }\r\n  }\r\n\r\n  /**\r\n   * Bulk insert records\r\n   */\r\n  async bulkInsert(items: Partial<T>[]): Promise<ImportResult> {\r\n    logger.info(\"Starting bulk insert\", {\r\n      schemaName: this.schemaName,\r\n      tableName: this.tableName,\r\n      itemsCount: items.length,\r\n    });\r\n\r\n    await this._ensureInitialized();\r\n\r\n    try {\r\n      if (!Array.isArray(items) || items.length === 0) {\r\n        const errorMsg = \"Items must be a non-empty array\";\r\n        logger.error(errorMsg, {\r\n          schemaName: this.schemaName,\r\n          tableName: this.tableName,\r\n          itemsType: typeof items,\r\n          itemsLength: Array.isArray(items) ? items.length : \"N/A\",\r\n        });\r\n        throw new Error(errorMsg);\r\n      }\r\n\r\n      logger.debug(\"Executing bulk insert operation\", {\r\n        schemaName: this.schemaName,\r\n        tableName: this.tableName,\r\n        itemsCount: items.length,\r\n      });\r\n\r\n      const result = await this.dao!.importData({\r\n        tableName: this.tableName,\r\n        data: items as Record<string, any>[],\r\n        batchSize: 1000,\r\n        skipErrors: false,\r\n        validateData: true,\r\n      });\r\n\r\n      logger.info(\"Bulk insert completed\", {\r\n        schemaName: this.schemaName,\r\n        tableName: this.tableName,\r\n        totalRows: result.totalRows,\r\n        successRows: result.successRows,\r\n        errorRows: result.errorRows,\r\n      });\r\n\r\n      this._emit(\"dataBulkCreated\", {\r\n        operation: \"bulkInsert\",\r\n        count: result.successRows,\r\n      });\r\n      return result;\r\n    } catch (error) {\r\n      logger.error(\"Error during bulk insert\", {\r\n        schemaName: this.schemaName,\r\n        tableName: this.tableName,\r\n        itemsCount: items.length,\r\n        error: (error as Error).message,\r\n      });\r\n\r\n      this._handleError(\"BULK_INSERT_ERROR\", error as Error);\r\n      throw error;\r\n    }\r\n  }\r\n\r\n  /**\r\n   * Bulk create records with transaction support\r\n   */\r\n  async bulkCreate(dataArray: Record<string, any>[]): Promise<T[]> {\r\n    logger.info(\"Starting bulk create with transaction\", {\r\n      schemaName: this.schemaName,\r\n      tableName: this.tableName,\r\n      itemsCount: dataArray.length,\r\n    });\r\n\r\n    await this._ensureInitialized();\r\n\r\n    try {\r\n      if (!Array.isArray(dataArray) || dataArray.length === 0) {\r\n        const errorMsg = \"Data must be a non-empty array\";\r\n        logger.error(errorMsg, {\r\n          schemaName: this.schemaName,\r\n          tableName: this.tableName,\r\n          dataType: typeof dataArray,\r\n          dataLength: Array.isArray(dataArray) ? dataArray.length : \"N/A\",\r\n        });\r\n        throw new Error(errorMsg);\r\n      }\r\n\r\n      const results: T[] = [];\r\n\r\n      logger.debug(\"Executing bulk create in transaction\", {\r\n        schemaName: this.schemaName,\r\n        tableName: this.tableName,\r\n        itemsCount: dataArray.length,\r\n      });\r\n\r\n      await this.executeTransaction(async () => {\r\n        for (let i = 0; i < dataArray.length; i++) {\r\n          const data = dataArray[i];\r\n\r\n          if (i % 100 === 0) {\r\n            logger.trace(\"Bulk create progress\", {\r\n              schemaName: this.schemaName,\r\n              tableName: this.tableName,\r\n              processed: i,\r\n              total: dataArray.length,\r\n            });\r\n          }\r\n\r\n          this._validateData(data);\r\n          const queryTable = this.buildDataTable(data);\r\n          await this.dao!.insert(queryTable);\r\n          results.push(data as T);\r\n        }\r\n      });\r\n\r\n      logger.info(\"Bulk create completed successfully\", {\r\n        schemaName: this.schemaName,\r\n        tableName: this.tableName,\r\n        recordsCreated: results.length,\r\n      });\r\n\r\n      this._emit(\"dataBulkCreated\", {\r\n        operation: \"bulkCreate\",\r\n        count: results.length,\r\n      });\r\n      return results;\r\n    } catch (error) {\r\n      logger.error(\"Error during bulk create\", {\r\n        schemaName: this.schemaName,\r\n        tableName: this.tableName,\r\n        itemsCount: dataArray.length,\r\n        error: (error as Error).message,\r\n      });\r\n\r\n      this._handleError(\"BULK_CREATE_ERROR\", error as Error);\r\n      throw error;\r\n    }\r\n  }\r\n\r\n  /**\r\n   * Execute operations within a transaction\r\n   */\r\n  async executeTransaction(callback: () => Promise<any>): Promise<any> {\r\n    logger.debug(\"Starting transaction\", {\r\n      schemaName: this.schemaName,\r\n      tableName: this.tableName,\r\n    });\r\n\r\n    await this._ensureInitialized();\r\n\r\n    try {\r\n      logger.trace(\"Beginning database transaction\", {\r\n        schemaName: this.schemaName,\r\n      });\r\n\r\n      await this.dao!.beginTransaction();\r\n      const result = await callback();\r\n\r\n      logger.trace(\"Committing transaction\", {\r\n        schemaName: this.schemaName,\r\n      });\r\n\r\n      await this.dao!.commitTransaction();\r\n\r\n      logger.info(\"Transaction completed successfully\", {\r\n        schemaName: this.schemaName,\r\n        tableName: this.tableName,\r\n      });\r\n\r\n      this._emit(\"transactionCompleted\", { operation: \"transaction\" });\r\n      return result;\r\n    } catch (error) {\r\n      logger.error(\"Transaction failed, rolling back\", {\r\n        schemaName: this.schemaName,\r\n        tableName: this.tableName,\r\n        error: (error as Error).message,\r\n      });\r\n\r\n      try {\r\n        await this.dao!.rollbackTransaction();\r\n        logger.debug(\"Transaction rollback successful\", {\r\n          schemaName: this.schemaName,\r\n        });\r\n      } catch (rollbackError) {\r\n        logger.error(\"Error during transaction rollback\", {\r\n          schemaName: this.schemaName,\r\n          rollbackError: (rollbackError as Error).message,\r\n        });\r\n        this._handleError(\"ROLLBACK_ERROR\", rollbackError as Error);\r\n      }\r\n\r\n      this._handleError(\"TRANSACTION_ERROR\", error as Error);\r\n      throw error;\r\n    }\r\n  }\r\n\r\n  /**\r\n   * Import data from CSV\r\n   */\r\n  async importFromCSV(\r\n    csvData: string,\r\n    options: {\r\n      delimiter?: string;\r\n      hasHeader?: boolean;\r\n      columnMappings?: ColumnMapping[];\r\n    } & Partial<ImportOptions> = {}\r\n  ): Promise<ImportResult> {\r\n    logger.info(\"Starting CSV import\", {\r\n      schemaName: this.schemaName,\r\n      tableName: this.tableName,\r\n      csvDataLength: csvData.length,\r\n      delimiter: options.delimiter,\r\n      hasHeader: options.hasHeader,\r\n      hasMappings: !!(\r\n        options.columnMappings && options.columnMappings.length > 0\r\n      ),\r\n    });\r\n\r\n    await this._ensureInitialized();\r\n\r\n    try {\r\n      const result = await this.dao!.importFromCSV(\r\n        this.tableName,\r\n        csvData,\r\n        options\r\n      );\r\n\r\n      logger.info(\"CSV import completed\", {\r\n        schemaName: this.schemaName,\r\n        tableName: this.tableName,\r\n        totalRows: result.totalRows,\r\n        successRows: result.successRows,\r\n        errorRows: result.errorRows,\r\n      });\r\n\r\n      this._emit(\"dataImported\", { operation: \"importFromCSV\", result });\r\n      return result;\r\n    } catch (error) {\r\n      logger.error(\"Error during CSV import\", {\r\n        schemaName: this.schemaName,\r\n        tableName: this.tableName,\r\n        csvDataLength: csvData.length,\r\n        error: (error as Error).message,\r\n      });\r\n\r\n      this._handleError(\"IMPORT_CSV_ERROR\", error as Error);\r\n      throw error;\r\n    }\r\n  }\r\n\r\n  /**\r\n   * Import data with column mapping\r\n   */\r\n  async importDataWithMapping(\r\n    data: Record<string, any>[],\r\n    columnMappings: ColumnMapping[],\r\n    options: Partial<ImportOptions> = {}\r\n  ): Promise<ImportResult> {\r\n    logger.info(\"Starting import with column mapping\", {\r\n      schemaName: this.schemaName,\r\n      tableName: this.tableName,\r\n      dataCount: data.length,\r\n      mappingsCount: columnMappings.length,\r\n    });\r\n\r\n    await this._ensureInitialized();\r\n\r\n    try {\r\n      const result = await this.dao!.importDataWithMapping(\r\n        this.tableName,\r\n        data,\r\n        columnMappings,\r\n        options\r\n      );\r\n\r\n      logger.info(\"Import with mapping completed\", {\r\n        schemaName: this.schemaName,\r\n        tableName: this.tableName,\r\n        totalRows: result.totalRows,\r\n        successRows: result.successRows,\r\n        errorRows: result.errorRows,\r\n      });\r\n\r\n      this._emit(\"dataImported\", { operation: \"importWithMapping\", result });\r\n      return result;\r\n    } catch (error) {\r\n      logger.error(\"Error during import with mapping\", {\r\n        schemaName: this.schemaName,\r\n        tableName: this.tableName,\r\n        dataCount: data.length,\r\n        mappingsCount: columnMappings.length,\r\n        error: (error as Error).message,\r\n      });\r\n\r\n      this._handleError(\"IMPORT_MAPPING_ERROR\", error as Error);\r\n      throw error;\r\n    }\r\n  }\r\n\r\n  // Utility methods\r\n  protected buildSelectTable(\r\n    conditions: Record<string, any> = {},\r\n    options: FindOptions = {}\r\n  ): QueryTable {\r\n    logger.trace(\"Building select table query\", {\r\n      schemaName: this.schemaName,\r\n      tableName: this.tableName,\r\n      conditionsCount: Object.keys(conditions).length,\r\n      hasOptions: Object.keys(options).length > 0,\r\n    });\r\n\r\n    const queryTable: QueryTable = {\r\n      name: this.tableName,\r\n      cols: [],\r\n      wheres: [],\r\n      orderbys: options.orderBy || [],\r\n      limitOffset: {},\r\n    };\r\n\r\n    if (options.columns && options.columns.length > 0) {\r\n      queryTable.cols = options.columns.map((name) => ({ name }));\r\n    }\r\n\r\n    if (conditions && Object.keys(conditions).length > 0) {\r\n      queryTable.wheres = Object.entries(conditions).map(([key, value]) => ({\r\n        name: key,\r\n        value,\r\n        operator: \"=\",\r\n      }));\r\n    }\r\n\r\n    if (options.limit !== undefined) {\r\n      queryTable.limitOffset!.limit = options.limit;\r\n    }\r\n    if (options.offset !== undefined) {\r\n      queryTable.limitOffset!.offset = options.offset;\r\n    }\r\n\r\n    return queryTable;\r\n  }\r\n\r\n  protected buildDataTable(data: Record<string, any>): QueryTable {\r\n    // ✅ Filter out undefined values trước khi build query\r\n    const cleanData = Object.entries(data).reduce((acc, [key, value]) => {\r\n      if (value !== undefined) {\r\n        acc[key] = value;\r\n      }\r\n      return acc;\r\n    }, {} as Record<string, any>);\r\n\r\n    logger.trace(\"Building data table for query\", {\r\n      schemaName: this.schemaName,\r\n      tableName: this.tableName,\r\n      dataKeys: Object.keys(cleanData),\r\n      removedKeys: Object.keys(data).filter((k) => data[k] === undefined),\r\n    });\r\n\r\n    return this.dao!.convertJsonToQueryTable(\r\n      this.tableName,\r\n      cleanData,\r\n      this.primaryKeyFields\r\n    );\r\n  }\r\n\r\n  protected buildWhereFromObject(obj: Record<string, any>): WhereClause[] {\r\n    const wheres = Object.entries(obj)\r\n      .filter(([_, value]) => value !== undefined)\r\n      .map(([key, value]) => ({ name: key, value }));\r\n\r\n    logger.trace(\"Built where clauses from object\", {\r\n      schemaName: this.schemaName,\r\n      originalKeys: Object.keys(obj).length,\r\n      filteredWheres: wheres.length,\r\n    });\r\n\r\n    return wheres;\r\n  }\r\n\r\n  // Event system\r\n  on(event: string, handler: EventHandler): this {\r\n    logger.trace(\"Adding event listener\", {\r\n      schemaName: this.schemaName,\r\n      tableName: this.tableName,\r\n      event,\r\n    });\r\n\r\n    if (!this.eventListeners.has(event)) {\r\n      this.eventListeners.set(event, []);\r\n    }\r\n    this.eventListeners.get(event)!.push(handler);\r\n    return this;\r\n  }\r\n\r\n  off(event: string, handler: EventHandler): this {\r\n    logger.trace(\"Removing event listener\", {\r\n      schemaName: this.schemaName,\r\n      tableName: this.tableName,\r\n      event,\r\n    });\r\n\r\n    const handlers = this.eventListeners.get(event);\r\n    if (handlers) {\r\n      const index = handlers.indexOf(handler);\r\n      if (index > -1) {\r\n        handlers.splice(index, 1);\r\n      }\r\n    }\r\n    return this;\r\n  }\r\n\r\n  protected _emit(event: string, data: any): void {\r\n    logger.trace(\"Emitting event\", {\r\n      schemaName: this.schemaName,\r\n      tableName: this.tableName,\r\n      event,\r\n      hasData: !!data,\r\n    });\r\n\r\n    const handlers = this.eventListeners.get(event);\r\n    if (handlers) {\r\n      handlers.forEach((handler) => {\r\n        try {\r\n          handler(data);\r\n        } catch (error) {\r\n          logger.error(\"Error in event handler\", {\r\n            schemaName: this.schemaName,\r\n            tableName: this.tableName,\r\n            event,\r\n            error: (error as Error).message,\r\n          });\r\n        }\r\n      });\r\n    }\r\n  }\r\n\r\n  // Error handling\r\n  setErrorHandler(errorType: string, handler: ErrorHandler): this {\r\n    logger.debug(\"Setting error handler\", {\r\n      schemaName: this.schemaName,\r\n      tableName: this.tableName,\r\n      errorType,\r\n    });\r\n\r\n    this.errorHandlers.set(errorType, handler);\r\n    return this;\r\n  }\r\n\r\n  protected _handleError(errorType: string, error: Error): void {\r\n    logger.error(\"Handling service error\", {\r\n      schemaName: this.schemaName,\r\n      tableName: this.tableName,\r\n      errorType,\r\n      error: error.message,\r\n    });\r\n\r\n    const handler = this.errorHandlers.get(errorType);\r\n    if (handler) {\r\n      try {\r\n        handler(error);\r\n      } catch (handlerError) {\r\n        logger.error(\"Error in error handler\", {\r\n          schemaName: this.schemaName,\r\n          tableName: this.tableName,\r\n          errorType,\r\n          handlerError: (handlerError as Error).message,\r\n        });\r\n      }\r\n    }\r\n    this._emit(\"error\", { errorType, error });\r\n  }\r\n\r\n  protected _validateData(data: any): void {\r\n    if (!data || typeof data !== \"object\") {\r\n      const errorMsg = \"Data must be a valid object\";\r\n      logger.error(\"Data validation failed\", {\r\n        schemaName: this.schemaName,\r\n        tableName: this.tableName,\r\n        dataType: typeof data,\r\n        isNull: data === null,\r\n      });\r\n      throw new Error(errorMsg);\r\n    }\r\n\r\n    // ✅ THÊM: Loại bỏ các field có giá trị undefined\r\n    Object.keys(data).forEach((key) => {\r\n      if (data[key] === undefined) {\r\n        delete data[key];\r\n        logger.trace(\"Removed undefined field\", {\r\n          schemaName: this.schemaName,\r\n          tableName: this.tableName,\r\n          field: key,\r\n        });\r\n      }\r\n    });\r\n  }\r\n\r\n  protected async _ensureInitialized(): Promise<void> {\r\n    if (!this.isInitialized) {\r\n      logger.debug(\"Service not initialized, initializing now\", {\r\n        schemaName: this.schemaName,\r\n        tableName: this.tableName,\r\n      });\r\n      await this.init();\r\n    }\r\n  }\r\n\r\n  private async ensureValidConnection(): Promise<void> {\r\n    logger.trace(\"Ensuring valid database connection\", {\r\n      schemaName: this.schemaName,\r\n      tableName: this.tableName,\r\n    });\r\n\r\n    try {\r\n      const isConnected = this.dao?.isConnectionOpen();\r\n      if (!isConnected) {\r\n        logger.debug(\"Connection not valid, getting new connection\", {\r\n          schemaName: this.schemaName,\r\n        });\r\n        this.dao = await DatabaseManager.ensureDatabaseConnection(\r\n          this.schemaName\r\n        );\r\n      }\r\n    } catch (error) {\r\n      logger.warn(\"Error checking connection, getting new connection\", {\r\n        schemaName: this.schemaName,\r\n        error: (error as Error).message,\r\n      });\r\n      this.dao = await DatabaseManager.ensureDatabaseConnection(\r\n        this.schemaName\r\n      );\r\n    }\r\n  }\r\n\r\n  // Information and status methods\r\n  async getDatabaseInfo(): Promise<any> {\r\n    logger.trace(\"Getting database info\", {\r\n      schemaName: this.schemaName,\r\n      tableName: this.tableName,\r\n    });\r\n\r\n    await this._ensureInitialized();\r\n    return await this.dao!.getDatabaseInfo();\r\n  }\r\n\r\n  async getTableInfo(): Promise<any[]> {\r\n    logger.trace(\"Getting table info\", {\r\n      schemaName: this.schemaName,\r\n      tableName: this.tableName,\r\n    });\r\n\r\n    await this._ensureInitialized();\r\n    return await this.dao!.getTableInfo(this.tableName);\r\n  }\r\n\r\n  getStatus(): ServiceStatus {\r\n    const status = {\r\n      schemaName: this.schemaName,\r\n      tableName: this.tableName,\r\n      isOpened: this.isOpened,\r\n      isInitialized: this.isInitialized,\r\n      hasDao: !!this.dao,\r\n    };\r\n\r\n    logger.trace(\"Getting service status\", status);\r\n    return status;\r\n  }\r\n\r\n  async healthCheck(): Promise<HealthCheckResult> {\r\n    logger.debug(\"Performing health check\", {\r\n      schemaName: this.schemaName,\r\n      tableName: this.tableName,\r\n    });\r\n\r\n    try {\r\n      await this._ensureInitialized();\r\n      const count = await this.count();\r\n\r\n      const result = {\r\n        healthy: true,\r\n        schemaName: this.schemaName,\r\n        recordCount: count,\r\n        timestamp: new Date().toISOString(),\r\n      };\r\n\r\n      logger.info(\"Health check passed\", {\r\n        schemaName: this.schemaName,\r\n        tableName: this.tableName,\r\n        recordCount: count,\r\n      });\r\n\r\n      return result;\r\n    } catch (error) {\r\n      const result = {\r\n        healthy: false,\r\n        schemaName: this.schemaName,\r\n        error: (error as Error).message,\r\n        timestamp: new Date().toISOString(),\r\n      };\r\n\r\n      logger.error(\"Health check failed\", {\r\n        schemaName: this.schemaName,\r\n        tableName: this.tableName,\r\n        error: (error as Error).message,\r\n      });\r\n\r\n      return result;\r\n    }\r\n  }\r\n\r\n  // Lifecycle management\r\n  async close(): Promise<boolean> {\r\n    logger.info(\"Closing BaseService\", {\r\n      schemaName: this.schemaName,\r\n      tableName: this.tableName,\r\n      isOpened: this.isOpened,\r\n      isInitialized: this.isInitialized,\r\n    });\r\n\r\n    try {\r\n      if (this.dao) {\r\n        await this.dao.close();\r\n        logger.debug(\"DAO closed successfully\", {\r\n          schemaName: this.schemaName,\r\n        });\r\n      }\r\n\r\n      this.isOpened = false;\r\n      this.isInitialized = false;\r\n      this.eventListeners.clear();\r\n      this.errorHandlers.clear();\r\n      this.cache.clear();\r\n\r\n      logger.info(\"BaseService closed successfully\", {\r\n        schemaName: this.schemaName,\r\n        tableName: this.tableName,\r\n      });\r\n\r\n      this._emit(\"closed\", { schemaName: this.schemaName });\r\n      return true;\r\n    } catch (error) {\r\n      logger.error(\"Error closing BaseService\", {\r\n        schemaName: this.schemaName,\r\n        tableName: this.tableName,\r\n        error: (error as Error).message,\r\n      });\r\n\r\n      this._handleError(\"CLOSE_ERROR\", error as Error);\r\n      throw error;\r\n    }\r\n  }\r\n\r\n  public destroy(): void {\r\n    logger.debug(\"Destroying BaseService\", {\r\n      schemaName: this.schemaName,\r\n      tableName: this.tableName,\r\n    });\r\n\r\n    // Remove reconnect listener\r\n    DatabaseManager.offDatabaseReconnect(\r\n      this.schemaName,\r\n      this.reconnectHandler\r\n    );\r\n\r\n    // Clear all resources\r\n    this.eventListeners.clear();\r\n    this.errorHandlers.clear();\r\n    this.cache.clear();\r\n\r\n    logger.trace(\"BaseService destroyed\", {\r\n      schemaName: this.schemaName,\r\n      tableName: this.tableName,\r\n    });\r\n  }\r\n\r\n  // Alias methods for backward compatibility\r\n  async getAll(\r\n    conditions: Record<string, any> = {},\r\n    options: FindOptions = {}\r\n  ): Promise<T[]> {\r\n    logger.trace(\"Using getAll alias\", {\r\n      schemaName: this.schemaName,\r\n      tableName: this.tableName,\r\n    });\r\n    return this.findAll(conditions, options);\r\n  }\r\n\r\n  async getById(id: string | number): Promise<T | null> {\r\n    logger.trace(\"Using getById alias\", {\r\n      schemaName: this.schemaName,\r\n      tableName: this.tableName,\r\n      id,\r\n    });\r\n    return this.findById(id);\r\n  }\r\n\r\n  async getFirst(conditions: Record<string, any> = {}): Promise<T | null> {\r\n    logger.trace(\"Using getFirst alias\", {\r\n      schemaName: this.schemaName,\r\n      tableName: this.tableName,\r\n    });\r\n    return this.findFirst(conditions);\r\n  }\r\n}\r\n","// src/core/service-manager.ts\r\nimport { BaseService } from \"./base-service\";\r\nimport { ServiceStatus, HealthCheckResult } from \"@/types\";\r\n\r\nimport { createModuleLogger, SQLiteModules } from \"@/logger\";\r\nconst logger = createModuleLogger(SQLiteModules.SERVICE_MANAGER);\r\n\r\n// Concrete service class mặc định\r\nexport class DefaultService extends BaseService {\r\n  // BaseService đã cung cấp đầy đủ functionality\r\n}\r\n\r\n// Interface cho cấu hình service\r\nexport interface ServiceConfig {\r\n  schemaName: string;\r\n  tableName: string;\r\n  primaryKeyFields?: string[];\r\n  serviceClass?: new (schemaName: string, tableName: string) => BaseService;\r\n}\r\n\r\n// Interface cho trạng thái service\r\nexport interface ServiceInfo {\r\n  key: string;\r\n  schemaName: string;\r\n  tableName: string;\r\n  status: ServiceStatus;\r\n  isRegistered: boolean;\r\n  createdAt: string;\r\n  lastAccessed?: string;\r\n}\r\n\r\n// Interface cho báo cáo sức khỏe\r\nexport interface HealthReport {\r\n  totalServices: number;\r\n  healthyServices: number;\r\n  unhealthyServices: number;\r\n  services: Array<HealthCheckResult & { serviceKey: string }>;\r\n  timestamp: string;\r\n  overallHealth: boolean;\r\n}\r\n\r\n// Event types cho ServiceManager\r\nexport interface ServiceManagerEvent {\r\n  type:\r\n    | \"SERVICE_CREATED\"\r\n    | \"SERVICE_DESTROYED\"\r\n    | \"SERVICE_ERROR\"\r\n    | \"HEALTH_CHECK_COMPLETED\";\r\n  serviceKey: string;\r\n  schemaName: string;\r\n  tableName: string;\r\n  timestamp: string;\r\n  data?: any;\r\n  error?: Error;\r\n}\r\n\r\nexport type ServiceManagerEventHandler = (event: ServiceManagerEvent) => void;\r\n\r\n/**\r\n * ServiceManager - Quản lý vòng đời các service con kế thừa từ BaseService\r\n * Không can thiệp vào DatabaseManager, chỉ tập trung quản lý service instances\r\n */\r\nexport class ServiceManager {\r\n  private static instance: ServiceManager | null = null;\r\n\r\n  // Service registry\r\n  private services: Map<string, BaseService> = new Map();\r\n  private serviceConfigs: Map<string, ServiceConfig> = new Map();\r\n  private serviceMetadata: Map<\r\n    string,\r\n    { createdAt: string; lastAccessed?: string }\r\n  > = new Map();\r\n\r\n  // Event system\r\n  private eventHandlers: Map<string, ServiceManagerEventHandler[]> = new Map();\r\n\r\n  // Lifecycle management\r\n  private isShuttingDown = false;\r\n  private cleanupInterval: any | null = null;\r\n\r\n  private constructor() {\r\n    logger.info(\"ServiceManager instance created\");\r\n    this.bindMethods();\r\n    this.startPeriodicCleanup();\r\n  }\r\n\r\n  /**\r\n   * Singleton instance\r\n   */\r\n  public static getInstance(): ServiceManager {\r\n    if (!ServiceManager.instance) {\r\n      logger.debug(\"Creating new ServiceManager singleton instance\");\r\n      ServiceManager.instance = new ServiceManager();\r\n    } else {\r\n      logger.trace(\"Returning existing ServiceManager singleton instance\");\r\n    }\r\n    return ServiceManager.instance;\r\n  }\r\n\r\n  /**\r\n   * Reset singleton (chủ yếu cho testing)\r\n   */\r\n  public static resetInstance(): void {\r\n    logger.warn(\"Resetting ServiceManager singleton instance\");\r\n    if (ServiceManager.instance) {\r\n      ServiceManager.instance.destroy();\r\n      ServiceManager.instance = null;\r\n      logger.info(\"ServiceManager singleton instance reset successfully\");\r\n    } else {\r\n      logger.debug(\"No ServiceManager instance to reset\");\r\n    }\r\n  }\r\n\r\n  private bindMethods(): void {\r\n    logger.trace(\"Binding ServiceManager methods\");\r\n    const methods = Object.getOwnPropertyNames(Object.getPrototypeOf(this));\r\n    methods.forEach((method) => {\r\n      if (\r\n        typeof (this as any)[method] === \"function\" &&\r\n        method !== \"constructor\"\r\n      ) {\r\n        (this as any)[method] = (this as any)[method].bind(this);\r\n      }\r\n    });\r\n    logger.trace(\"ServiceManager methods bound successfully\", {\r\n      methodCount: methods.length,\r\n    });\r\n  }\r\n\r\n  /**\r\n   * Tạo service key duy nhất\r\n   */\r\n  private createServiceKey(schemaName: string, tableName: string): string {\r\n    const key = `${schemaName}:${tableName}`;\r\n    logger.trace(\"Created service key\", { schemaName, tableName, key });\r\n    return key;\r\n  }\r\n\r\n  /**\r\n   * Validate service config\r\n   */\r\n  private validateServiceConfig(config: ServiceConfig): void {\r\n    logger.trace(\"Validating service config\", {\r\n      schemaName: config.schemaName,\r\n      tableName: config.tableName,\r\n    });\r\n\r\n    if (!config.schemaName?.trim()) {\r\n      logger.error(\"Invalid service config: schema name missing\", { config });\r\n      throw new Error(\"Schema name is required and cannot be empty\");\r\n    }\r\n    if (!config.tableName?.trim()) {\r\n      logger.error(\"Invalid service config: table name missing\", { config });\r\n      throw new Error(\"Table name is required and cannot be empty\");\r\n    }\r\n\r\n    logger.trace(\"Service config validation passed\", {\r\n      schemaName: config.schemaName,\r\n      tableName: config.tableName,\r\n    });\r\n  }\r\n\r\n  /**\r\n   * Đăng ký cấu hình service\r\n   */\r\n  public registerService(config: ServiceConfig): this {\r\n    logger.debug(\"Registering service\", {\r\n      schemaName: config.schemaName,\r\n      tableName: config.tableName,\r\n      primaryKeyFields: config.primaryKeyFields,\r\n      hasCustomServiceClass: !!config.serviceClass,\r\n    });\r\n\r\n    this.validateServiceConfig(config);\r\n\r\n    const serviceKey = this.createServiceKey(\r\n      config.schemaName,\r\n      config.tableName\r\n    );\r\n\r\n    // Normalize config\r\n    const normalizedConfig: ServiceConfig = {\r\n      schemaName: config.schemaName.trim(),\r\n      tableName: config.tableName.trim(),\r\n      primaryKeyFields: config.primaryKeyFields || [\"id\"],\r\n      serviceClass: config.serviceClass || DefaultService,\r\n    };\r\n\r\n    const wasAlreadyRegistered = this.serviceConfigs.has(serviceKey);\r\n    this.serviceConfigs.set(serviceKey, normalizedConfig);\r\n\r\n    if (wasAlreadyRegistered) {\r\n      logger.info(\"Service configuration updated\", { serviceKey });\r\n    } else {\r\n      logger.info(\"Service registered successfully\", { serviceKey });\r\n    }\r\n\r\n    return this;\r\n  }\r\n\r\n  /**\r\n   * Đăng ký nhiều services\r\n   */\r\n  public registerServices(configs: ServiceConfig[]): this {\r\n    logger.debug(\"Registering multiple services\", { count: configs.length });\r\n\r\n    configs.forEach((config, index) => {\r\n      try {\r\n        this.registerService(config);\r\n      } catch (error) {\r\n        logger.error(\"Failed to register service in batch\", {\r\n          index,\r\n          config,\r\n          error: (error as Error).message,\r\n        });\r\n        throw error;\r\n      }\r\n    });\r\n\r\n    logger.info(\"Multiple services registered successfully\", {\r\n      count: configs.length,\r\n    });\r\n    return this;\r\n  }\r\n\r\n  /**\r\n   * Tạo service instance từ config\r\n   */\r\n  private async createServiceInstance(\r\n    config: ServiceConfig\r\n  ): Promise<BaseService> {\r\n    logger.debug(\"Creating service instance\", {\r\n      schemaName: config.schemaName,\r\n      tableName: config.tableName,\r\n      serviceClassName: config.serviceClass?.name || \"DefaultService\",\r\n      serviceClass: config.serviceClass, // Thêm dòng này\r\n      isDefaultService: config.serviceClass === DefaultService,\r\n    });\r\n\r\n    const ServiceClass = config.serviceClass || DefaultService;\r\n\r\n    // Thêm validation\r\n    if (!ServiceClass) {\r\n      logger.error(\"ServiceClass is undefined\", { config });\r\n      throw new Error(\"ServiceClass is undefined\");\r\n    }\r\n\r\n    logger.debug(\"About to instantiate service\", {\r\n      ServiceClassConstructor: ServiceClass,\r\n      ServiceClassName: ServiceClass.name,\r\n    });\r\n\r\n    const service: any = new ServiceClass(config.schemaName, config.tableName);\r\n\r\n    // Verify instance type\r\n    logger.debug(\"Service instance created\", {\r\n      serviceConstructor: service.constructor.name,\r\n      servicePrototype: Object.getPrototypeOf(service).constructor.name,\r\n      hasFindByStoreId: typeof service.findByStoreId === \"function\",\r\n    });\r\n\r\n    if (config.primaryKeyFields) {\r\n      logger.trace(\"Setting primary key fields\", {\r\n        schemaName: config.schemaName,\r\n        tableName: config.tableName,\r\n        primaryKeyFields: config.primaryKeyFields,\r\n      });\r\n      service.setPrimaryKeyFields(config.primaryKeyFields);\r\n    }\r\n\r\n    logger.info(\"Service instance created successfully\", {\r\n      schemaName: config.schemaName,\r\n      tableName: config.tableName,\r\n    });\r\n\r\n    return service;\r\n  }\r\n\r\n  /**\r\n   * Lấy service (tự động tạo nếu chưa tồn tại)\r\n   */\r\n  public async getService(\r\n    schemaName: string,\r\n    tableName: string\r\n  ): Promise<BaseService> {\r\n    if (this.isShuttingDown) {\r\n      logger.error(\"ServiceManager is shutting down, cannot get service\", {\r\n        schemaName,\r\n        tableName,\r\n      });\r\n      throw new Error(\"ServiceManager is shutting down\");\r\n    }\r\n\r\n    const serviceKey = this.createServiceKey(schemaName, tableName);\r\n    logger.debug(\"Getting service\", { serviceKey });\r\n\r\n    // Update access time\r\n    const metadata = this.serviceMetadata.get(serviceKey);\r\n    if (metadata) {\r\n      metadata.lastAccessed = new Date().toISOString();\r\n      logger.trace(\"Updated service access time\", { serviceKey });\r\n    }\r\n\r\n    // Return existing service\r\n    if (this.services.has(serviceKey)) {\r\n      logger.trace(\"Returning existing service\", { serviceKey });\r\n      return this.services.get(serviceKey)!;\r\n    }\r\n\r\n    // Get or create default config\r\n    let config = this.serviceConfigs.get(serviceKey);\r\n    if (!config) {\r\n      logger.debug(\"Creating default config for unregistered service\", {\r\n        serviceKey,\r\n      });\r\n      config = {\r\n        schemaName,\r\n        tableName,\r\n        primaryKeyFields: [\"id\"],\r\n        serviceClass: DefaultService,\r\n      };\r\n      this.serviceConfigs.set(serviceKey, config);\r\n    }\r\n\r\n    try {\r\n      const service = await this.createServiceInstance(config);\r\n      this.services.set(serviceKey, service);\r\n\r\n      // Track metadata\r\n      this.serviceMetadata.set(serviceKey, {\r\n        createdAt: new Date().toISOString(),\r\n        lastAccessed: new Date().toISOString(),\r\n      });\r\n\r\n      this.emit(\"SERVICE_CREATED\", {\r\n        serviceKey,\r\n        schemaName,\r\n        tableName,\r\n      });\r\n\r\n      logger.info(\"Service created and cached successfully\", { serviceKey });\r\n      return service;\r\n    } catch (error) {\r\n      logger.error(\"Failed to create service\", {\r\n        serviceKey,\r\n        error: (error as Error).message,\r\n      });\r\n\r\n      this.emit(\"SERVICE_ERROR\", {\r\n        serviceKey,\r\n        schemaName,\r\n        tableName,\r\n        error: error as Error,\r\n      });\r\n      throw error;\r\n    }\r\n  }\r\n\r\n  /**\r\n   * Lấy service đã tồn tại (không tự động tạo)\r\n   */\r\n  public getExistingService(\r\n    schemaName: string,\r\n    tableName: string\r\n  ): BaseService | null {\r\n    const serviceKey = this.createServiceKey(schemaName, tableName);\r\n    logger.trace(\"Getting existing service\", { serviceKey });\r\n\r\n    const service = this.services.get(serviceKey) || null;\r\n    if (service) {\r\n      logger.trace(\"Existing service found\", { serviceKey });\r\n    } else {\r\n      logger.trace(\"Existing service not found\", { serviceKey });\r\n    }\r\n\r\n    return service;\r\n  }\r\n\r\n  /**\r\n   * Khởi tạo service\r\n   */\r\n  public async initializeService(\r\n    schemaName: string,\r\n    tableName: string\r\n  ): Promise<BaseService> {\r\n    const serviceKey = this.createServiceKey(schemaName, tableName);\r\n    logger.debug(\"Initializing service\", { serviceKey });\r\n\r\n    try {\r\n      const service = await this.getService(schemaName, tableName);\r\n      await service.init();\r\n      logger.info(\"Service initialized successfully\", { serviceKey });\r\n      return service;\r\n    } catch (error) {\r\n      logger.error(\"Failed to initialize service\", {\r\n        serviceKey,\r\n        error: (error as Error).message,\r\n      });\r\n      throw error;\r\n    }\r\n  }\r\n\r\n  /**\r\n   * Hủy service instance\r\n   */\r\n  public async destroyService(\r\n    schemaName: string,\r\n    tableName: string\r\n  ): Promise<boolean> {\r\n    const serviceKey = this.createServiceKey(schemaName, tableName);\r\n    logger.debug(\"Destroying service\", { serviceKey });\r\n\r\n    const service = this.services.get(serviceKey);\r\n\r\n    if (!service) {\r\n      logger.warn(\"Service not found for destruction\", { serviceKey });\r\n      return false;\r\n    }\r\n\r\n    try {\r\n      await service.close();\r\n      service.destroy();\r\n\r\n      this.services.delete(serviceKey);\r\n      this.serviceMetadata.delete(serviceKey);\r\n\r\n      this.emit(\"SERVICE_DESTROYED\", {\r\n        serviceKey,\r\n        schemaName,\r\n        tableName,\r\n      });\r\n\r\n      logger.info(\"Service destroyed successfully\", { serviceKey });\r\n      return true;\r\n    } catch (error) {\r\n      logger.error(\"Failed to destroy service\", {\r\n        serviceKey,\r\n        error: (error as Error).message,\r\n      });\r\n\r\n      this.emit(\"SERVICE_ERROR\", {\r\n        serviceKey,\r\n        schemaName,\r\n        tableName,\r\n        error: error as Error,\r\n      });\r\n      return false;\r\n    }\r\n  }\r\n\r\n  /**\r\n   * Lấy danh sách services theo schema\r\n   */\r\n  public getServicesBySchema(schemaName: string): BaseService[] {\r\n    logger.trace(\"Getting services by schema\", { schemaName });\r\n\r\n    const services: BaseService[] = [];\r\n\r\n    for (const [serviceKey, service] of this.services) {\r\n      const [keySchema] = serviceKey.split(\":\");\r\n      if (keySchema === schemaName) {\r\n        services.push(service);\r\n      }\r\n    }\r\n\r\n    logger.debug(\"Found services for schema\", {\r\n      schemaName,\r\n      count: services.length,\r\n    });\r\n    return services;\r\n  }\r\n\r\n  /**\r\n   * Lấy danh sách service keys theo schema\r\n   */\r\n  public getServiceKeysBySchema(schemaName: string): string[] {\r\n    logger.trace(\"Getting service keys by schema\", { schemaName });\r\n\r\n    const keys: string[] = [];\r\n\r\n    for (const serviceKey of this.services.keys()) {\r\n      const [keySchema] = serviceKey.split(\":\");\r\n      if (keySchema === schemaName) {\r\n        keys.push(serviceKey);\r\n      }\r\n    }\r\n\r\n    logger.debug(\"Found service keys for schema\", { schemaName, keys });\r\n    return keys;\r\n  }\r\n\r\n  /**\r\n   * Hủy tất cả services trong một schema\r\n   */\r\n  public async destroyServicesBySchema(schemaName: string): Promise<void> {\r\n    const serviceKeys = this.getServiceKeysBySchema(schemaName);\r\n    logger.debug(\"Destroying services by schema\", { schemaName, serviceKeys });\r\n\r\n    if (serviceKeys.length === 0) {\r\n      logger.debug(\"No services found to destroy for schema\", { schemaName });\r\n      return;\r\n    }\r\n\r\n    const destroyPromises = serviceKeys.map(async (serviceKey) => {\r\n      const [, tableName] = serviceKey.split(\":\");\r\n      try {\r\n        const result = await this.destroyService(schemaName, tableName);\r\n        logger.trace(\"Service destroy result\", { serviceKey, result });\r\n        return result;\r\n      } catch (error) {\r\n        logger.error(\"Error destroying service in schema cleanup\", {\r\n          serviceKey,\r\n          error: (error as Error).message,\r\n        });\r\n        return false;\r\n      }\r\n    });\r\n\r\n    const results = await Promise.all(destroyPromises);\r\n    const successCount = results.filter(Boolean).length;\r\n\r\n    logger.info(\"Schema services destruction completed\", {\r\n      schemaName,\r\n      totalServices: serviceKeys.length,\r\n      successfulDestroys: successCount,\r\n    });\r\n  }\r\n\r\n  /**\r\n   * Lấy thông tin tất cả services\r\n   */\r\n  public getAllServiceInfo(): ServiceInfo[] {\r\n    logger.trace(\"Getting all service info\");\r\n\r\n    const infos: ServiceInfo[] = [];\r\n\r\n    // Registered services\r\n    for (const [serviceKey, config] of this.serviceConfigs) {\r\n      const service = this.services.get(serviceKey);\r\n      const metadata = this.serviceMetadata.get(serviceKey);\r\n\r\n      infos.push({\r\n        key: serviceKey,\r\n        schemaName: config.schemaName,\r\n        tableName: config.tableName,\r\n        status: service\r\n          ? service.getStatus()\r\n          : {\r\n              schemaName: config.schemaName,\r\n              tableName: config.tableName,\r\n              isOpened: false,\r\n              isInitialized: false,\r\n              hasDao: false,\r\n            },\r\n        isRegistered: true,\r\n        createdAt: metadata?.createdAt || \"N/A\",\r\n        lastAccessed: metadata?.lastAccessed,\r\n      });\r\n    }\r\n\r\n    // Unregistered services (created on-the-fly)\r\n    for (const [serviceKey, service] of this.services) {\r\n      if (!this.serviceConfigs.has(serviceKey)) {\r\n        const [schemaName, tableName] = serviceKey.split(\":\");\r\n        const metadata = this.serviceMetadata.get(serviceKey);\r\n\r\n        infos.push({\r\n          key: serviceKey,\r\n          schemaName,\r\n          tableName,\r\n          status: service.getStatus(),\r\n          isRegistered: false,\r\n          createdAt: metadata?.createdAt || \"N/A\",\r\n          lastAccessed: metadata?.lastAccessed,\r\n        });\r\n      }\r\n    }\r\n\r\n    return infos;\r\n  }\r\n\r\n  /**\r\n   * Kiểm tra sức khỏe tất cả services\r\n   */\r\n  public async healthCheck(): Promise<HealthReport> {\r\n    const services = Array.from(this.services.entries());\r\n    const healthPromises = services.map(async ([serviceKey, service]) => {\r\n      try {\r\n        const health = await service.healthCheck();\r\n        return { ...health, serviceKey };\r\n      } catch (error) {\r\n        const [schemaName, tableName] = serviceKey.split(\":\");\r\n        return {\r\n          healthy: false,\r\n          schemaName,\r\n          error: (error as Error).message,\r\n          timestamp: new Date().toISOString(),\r\n          serviceKey,\r\n        };\r\n      }\r\n    });\r\n\r\n    const results = await Promise.all(healthPromises);\r\n    const healthyCount = results.filter((r) => r.healthy).length;\r\n\r\n    const report: HealthReport = {\r\n      totalServices: results.length,\r\n      healthyServices: healthyCount,\r\n      unhealthyServices: results.length - healthyCount,\r\n      services: results,\r\n      timestamp: new Date().toISOString(),\r\n      overallHealth: healthyCount === results.length,\r\n    };\r\n\r\n    this.emit(\"HEALTH_CHECK_COMPLETED\", {\r\n      serviceKey: \"*\",\r\n      schemaName: \"*\",\r\n      tableName: \"*\",\r\n      data: report,\r\n    });\r\n\r\n    return report;\r\n  }\r\n\r\n  /**\r\n   * Thực hiện transaction trên nhiều services trong cùng schema\r\n   * (Vì SQLite transaction chỉ hoạt động trong cùng database connection)\r\n   */\r\n  public async executeSchemaTransaction<T>(\r\n    schemaName: string,\r\n    callback: (services: BaseService[]) => Promise<T>\r\n  ): Promise<T> {\r\n    logger.trace(`Executing schema transaction for schema ${schemaName}`);\r\n    const services = this.getServicesBySchema(schemaName);\r\n\r\n    if (services.length === 0) {\r\n      logger.error(\"No services found for schema\", { schemaName });\r\n      throw new Error(`No services found for schema: ${schemaName}`);\r\n    }\r\n\r\n    // Ensure all services are initialized\r\n    for (const service of services) {\r\n      await service.init();\r\n    }\r\n\r\n    // Execute transaction on the first service (they share the same database)\r\n    const primaryService = services[0];\r\n\r\n    return await primaryService.executeTransaction(async () => {\r\n      return await callback(services);\r\n    });\r\n  }\r\n\r\n  /**\r\n   * Periodic cleanup for unused services\r\n   */\r\n  private startPeriodicCleanup(): void {\r\n    // Cleanup every 5 minutes\r\n    this.cleanupInterval = setInterval(() => {\r\n      this.cleanupUnusedServices();\r\n    }, 5 * 60 * 1000);\r\n  }\r\n\r\n  /**\r\n   * Cleanup services not accessed for a long time\r\n   */\r\n  private async cleanupUnusedServices(\r\n    maxIdleTime: number = 30 * 60 * 1000\r\n  ): Promise<void> {\r\n    if (this.isShuttingDown) {\r\n      return;\r\n    }\r\n\r\n    const now = Date.now();\r\n    const servicesToDestroy: string[] = [];\r\n\r\n    for (const [serviceKey, metadata] of this.serviceMetadata) {\r\n      if (!metadata.lastAccessed) {\r\n        continue;\r\n      }\r\n\r\n      const lastAccessTime = new Date(metadata.lastAccessed).getTime();\r\n      if (now - lastAccessTime > maxIdleTime) {\r\n        servicesToDestroy.push(serviceKey);\r\n      }\r\n    }\r\n\r\n    for (const serviceKey of servicesToDestroy) {\r\n      const [schemaName, tableName] = serviceKey.split(\":\");\r\n      await this.destroyService(schemaName, tableName);\r\n    }\r\n  }\r\n\r\n  /**\r\n   * Event system\r\n   */\r\n  public on(eventType: string, handler: ServiceManagerEventHandler): this {\r\n    if (!this.eventHandlers.has(eventType)) {\r\n      this.eventHandlers.set(eventType, []);\r\n    }\r\n    this.eventHandlers.get(eventType)!.push(handler);\r\n    return this;\r\n  }\r\n\r\n  public off(eventType: string, handler: ServiceManagerEventHandler): this {\r\n    const handlers = this.eventHandlers.get(eventType);\r\n    if (handlers) {\r\n      const index = handlers.indexOf(handler);\r\n      if (index > -1) {\r\n        handlers.splice(index, 1);\r\n      }\r\n    }\r\n    return this;\r\n  }\r\n\r\n  private emit(\r\n    type: ServiceManagerEvent[\"type\"],\r\n    data: Omit<ServiceManagerEvent, \"type\" | \"timestamp\">\r\n  ): void {\r\n    const event: ServiceManagerEvent = {\r\n      ...data,\r\n      type,\r\n      timestamp: new Date().toISOString(),\r\n    };\r\n\r\n    // Emit to specific event handlers\r\n    const handlers = this.eventHandlers.get(type);\r\n    if (handlers) {\r\n      handlers.forEach((handler) => {\r\n        try {\r\n          handler(event);\r\n        } catch (error) {\r\n          console.error(\r\n            `ServiceManager: Error in ${type} event handler:`,\r\n            error\r\n          );\r\n        }\r\n      });\r\n    }\r\n\r\n    // Emit to global event handlers\r\n    const globalHandlers = this.eventHandlers.get(\"*\");\r\n    if (globalHandlers) {\r\n      globalHandlers.forEach((handler) => {\r\n        try {\r\n          handler(event);\r\n        } catch (error) {\r\n          console.error(\r\n            \"ServiceManager: Error in global event handler:\",\r\n            error\r\n          );\r\n        }\r\n      });\r\n    }\r\n  }\r\n\r\n  /**\r\n   * Utility methods\r\n   */\r\n  public hasService(schemaName: string, tableName: string): boolean {\r\n    const serviceKey = this.createServiceKey(schemaName, tableName);\r\n    return this.services.has(serviceKey);\r\n  }\r\n\r\n  public isRegistered(schemaName: string, tableName: string): boolean {\r\n    const serviceKey = this.createServiceKey(schemaName, tableName);\r\n    return this.serviceConfigs.has(serviceKey);\r\n  }\r\n\r\n  public getServiceCount(): number {\r\n    return this.services.size;\r\n  }\r\n\r\n  public getRegisteredCount(): number {\r\n    return this.serviceConfigs.size;\r\n  }\r\n\r\n  public getSchemas(): string[] {\r\n    const schemas = new Set<string>();\r\n\r\n    for (const serviceKey of this.services.keys()) {\r\n      const [schemaName] = serviceKey.split(\":\");\r\n      schemas.add(schemaName);\r\n    }\r\n\r\n    return Array.from(schemas);\r\n  }\r\n\r\n  /**\r\n   * Destroy all services and cleanup resources\r\n   */\r\n  public async destroy(): Promise<void> {\r\n    this.isShuttingDown = true;\r\n\r\n    // Clear cleanup interval\r\n    if (this.cleanupInterval) {\r\n      clearInterval(this.cleanupInterval);\r\n      this.cleanupInterval = null;\r\n    }\r\n\r\n    // Destroy all services\r\n    const destroyPromises = Array.from(this.services.entries()).map(\r\n      async ([serviceKey, service]) => {\r\n        try {\r\n          await service.close();\r\n          service.destroy();\r\n        } catch (error) {\r\n          console.error(`Error destroying service ${serviceKey}:`, error);\r\n        }\r\n      }\r\n    );\r\n\r\n    await Promise.all(destroyPromises);\r\n\r\n    // Clear all data\r\n    this.services.clear();\r\n    this.serviceConfigs.clear();\r\n    this.serviceMetadata.clear();\r\n    this.eventHandlers.clear();\r\n\r\n    this.isShuttingDown = false;\r\n  }\r\n}\r\n\r\n// Export singleton instance\r\nexport const serviceManager = ServiceManager.getInstance();\r\n","// src/query/query-builder.ts\r\nimport { UniversalDAO } from '../core/universal-dao';\r\nimport { SQLiteResult, SQLiteRow } from '../types';\r\n\r\nexport interface QueryCondition {\r\n  field: string;\r\n  operator: string;\r\n  value: any;\r\n}\r\n\r\nexport interface JoinClause {\r\n  type: 'INNER' | 'LEFT' | 'RIGHT' | 'FULL OUTER';\r\n  table: string;\r\n  condition: string;\r\n}\r\n\r\nexport interface SubQuery {\r\n  query: QueryBuilder;\r\n  alias: string;\r\n}\r\n\r\n/**\r\n * Enhanced QueryBuilder with advanced SQL query construction capabilities\r\n */\r\nexport class QueryBuilder {\r\n  private tableName = '';\r\n  private selectFields: string[] = ['*'];\r\n  private joinClauses: JoinClause[] = [];\r\n  private whereConditions: QueryCondition[] = [];\r\n  private groupByFields: string[] = [];\r\n  private havingConditions: QueryCondition[] = [];\r\n  private orderByFields: string[] = [];\r\n  private limitValue: number | null = null;\r\n  private offsetValue: number | null = null;\r\n  private params: any[] = [];\r\n  private unionQueries: QueryBuilder[] = [];\r\n  private subQueries: SubQuery[] = [];\r\n  private cteQueries: Map<string, QueryBuilder> = new Map();\r\n  private dao: UniversalDAO | null = null;\r\n\r\n  constructor(dao?: UniversalDAO) {\r\n    this.dao = dao || null;\r\n  }\r\n\r\n  static table(name: string, dao?: UniversalDAO): QueryBuilder {\r\n    const builder = new QueryBuilder(dao);\r\n    builder.tableName = name;\r\n    return builder;\r\n  }\r\n\r\n  static from(name: string, dao?: UniversalDAO): QueryBuilder {\r\n    return QueryBuilder.table(name, dao);\r\n  }\r\n\r\n  // SELECT operations\r\n  select(fields: string | string[]): QueryBuilder {\r\n    this.selectFields = Array.isArray(fields) ? fields : [fields];\r\n    return this;\r\n  }\r\n\r\n  selectRaw(raw: string): QueryBuilder {\r\n    this.selectFields = [raw];\r\n    return this;\r\n  }\r\n\r\n  selectDistinct(fields: string | string[]): QueryBuilder {\r\n    const fieldList = Array.isArray(fields) ? fields.join(', ') : fields;\r\n    this.selectFields = [`DISTINCT ${fieldList}`];\r\n    return this;\r\n  }\r\n\r\n  // JOIN operations\r\n  join(table: string, condition: string, type: JoinClause['type'] = 'INNER'): QueryBuilder {\r\n    this.joinClauses.push({ type, table, condition });\r\n    return this;\r\n  }\r\n\r\n  innerJoin(table: string, condition: string): QueryBuilder {\r\n    return this.join(table, condition, 'INNER');\r\n  }\r\n\r\n  leftJoin(table: string, condition: string): QueryBuilder {\r\n    return this.join(table, condition, 'LEFT');\r\n  }\r\n\r\n  rightJoin(table: string, condition: string): QueryBuilder {\r\n    return this.join(table, condition, 'RIGHT');\r\n  }\r\n\r\n  fullOuterJoin(table: string, condition: string): QueryBuilder {\r\n    return this.join(table, condition, 'FULL OUTER');\r\n  }\r\n\r\n  // WHERE conditions\r\n  where(field: string, operator: string, value?: any): QueryBuilder;\r\n  where(field: string, value: any): QueryBuilder;\r\n  where(conditions: Record<string, any>): QueryBuilder;\r\n  where(fieldOrConditions: string | Record<string, any>, operatorOrValue?: string | any, value?: any): QueryBuilder {\r\n    if (typeof fieldOrConditions === 'object') {\r\n      // Handle object of conditions\r\n      Object.entries(fieldOrConditions).forEach(([field, val]) => {\r\n        this.whereConditions.push({ field, operator: '=', value: val });\r\n      });\r\n      return this;\r\n    }\r\n\r\n    let operator = '=';\r\n    let actualValue = operatorOrValue;\r\n\r\n    if (arguments.length === 3) {\r\n      operator = operatorOrValue;\r\n      actualValue = value;\r\n    }\r\n\r\n    this.whereConditions.push({ \r\n      field: fieldOrConditions, \r\n      operator, \r\n      value: actualValue \r\n    });\r\n    \r\n    return this;\r\n  }\r\n\r\n  whereEquals(field: string, value: any): QueryBuilder {\r\n    return this.where(field, '=', value);\r\n  }\r\n\r\n  whereNot(field: string, value: any): QueryBuilder {\r\n    return this.where(field, '!=', value);\r\n  }\r\n\r\n  whereLike(field: string, value: string): QueryBuilder {\r\n    return this.where(field, 'LIKE', value);\r\n  }\r\n\r\n  whereNotLike(field: string, value: string): QueryBuilder {\r\n    return this.where(field, 'NOT LIKE', value);\r\n  }\r\n\r\n  whereIn(field: string, values: any[]): QueryBuilder {\r\n    this.whereConditions.push({ field, operator: 'IN', value: values });\r\n    return this;\r\n  }\r\n\r\n  whereNotIn(field: string, values: any[]): QueryBuilder {\r\n    this.whereConditions.push({ field, operator: 'NOT IN', value: values });\r\n    return this;\r\n  }\r\n\r\n  whereBetween(field: string, min: any, max: any): QueryBuilder {\r\n    this.whereConditions.push({ field, operator: 'BETWEEN', value: [min, max] });\r\n    return this;\r\n  }\r\n\r\n  whereNotBetween(field: string, min: any, max: any): QueryBuilder {\r\n    this.whereConditions.push({ field, operator: 'NOT BETWEEN', value: [min, max] });\r\n    return this;\r\n  }\r\n\r\n  whereNull(field: string): QueryBuilder {\r\n    this.whereConditions.push({ field, operator: 'IS NULL', value: null });\r\n    return this;\r\n  }\r\n\r\n  whereNotNull(field: string): QueryBuilder {\r\n    this.whereConditions.push({ field, operator: 'IS NOT NULL', value: null });\r\n    return this;\r\n  }\r\n\r\n  whereExists(subquery: QueryBuilder): QueryBuilder {\r\n    this.whereConditions.push({ \r\n      field: '', \r\n      operator: 'EXISTS', \r\n      value: subquery \r\n    });\r\n    return this;\r\n  }\r\n\r\n  whereNotExists(subquery: QueryBuilder): QueryBuilder {\r\n    this.whereConditions.push({ \r\n      field: '', \r\n      operator: 'NOT EXISTS', \r\n      value: subquery \r\n    });\r\n    return this;\r\n  }\r\n\r\n  // OR WHERE conditions\r\n  orWhere(field: string, operator: string, value?: any): QueryBuilder;\r\n  orWhere(field: string, value: any): QueryBuilder;\r\n  orWhere(field: string, operatorOrValue?: string | any, value?: any): QueryBuilder {\r\n    // Implementation similar to where() but with OR logic\r\n    // This would require refactoring the condition structure to support AND/OR\r\n    return this.where(field, operatorOrValue as string, value);\r\n  }\r\n\r\n  // GROUP BY and HAVING\r\n  groupBy(fields: string | string[]): QueryBuilder {\r\n    this.groupByFields = Array.isArray(fields) ? fields : [fields];\r\n    return this;\r\n  }\r\n\r\n  having(field: string, operator: string, value?: any): QueryBuilder {\r\n    let actualOperator = '=';\r\n    let actualValue = operator;\r\n\r\n    if (arguments.length === 3) {\r\n      actualOperator = operator;\r\n      actualValue = value;\r\n    }\r\n\r\n    this.havingConditions.push({ \r\n      field, \r\n      operator: actualOperator, \r\n      value: actualValue \r\n    });\r\n    return this;\r\n  }\r\n\r\n  havingCount(field: string, operator: string, value: number): QueryBuilder {\r\n    return this.having(`COUNT(${field})`, operator, value);\r\n  }\r\n\r\n  // ORDER BY\r\n  orderBy(field: string, direction: 'ASC' | 'DESC' = 'ASC'): QueryBuilder {\r\n    this.orderByFields.push(`${field} ${direction}`);\r\n    return this;\r\n  }\r\n\r\n  orderByDesc(field: string): QueryBuilder {\r\n    return this.orderBy(field, 'DESC');\r\n  }\r\n\r\n  orderByRaw(raw: string): QueryBuilder {\r\n    this.orderByFields.push(raw);\r\n    return this;\r\n  }\r\n\r\n  latest(field: string = 'created_at'): QueryBuilder {\r\n    return this.orderByDesc(field);\r\n  }\r\n\r\n  oldest(field: string = 'created_at'): QueryBuilder {\r\n    return this.orderBy(field, 'ASC');\r\n  }\r\n\r\n  // LIMIT and OFFSET\r\n  limit(count: number): QueryBuilder {\r\n    this.limitValue = count;\r\n    return this;\r\n  }\r\n\r\n  offset(count: number): QueryBuilder {\r\n    this.offsetValue = count;\r\n    return this;\r\n  }\r\n\r\n  skip(count: number): QueryBuilder {\r\n    return this.offset(count);\r\n  }\r\n\r\n  take(count: number): QueryBuilder {\r\n    return this.limit(count);\r\n  }\r\n\r\n  firstRow(): QueryBuilder {\r\n    return this.limit(1);\r\n  }\r\n\r\n  paginate(page: number, perPage: number): QueryBuilder {\r\n    this.limitValue = perPage;\r\n    this.offsetValue = (page - 1) * perPage;\r\n    return this;\r\n  }\r\n\r\n  // UNION operations\r\n  union(query: QueryBuilder): QueryBuilder {\r\n    this.unionQueries.push(query);\r\n    return this;\r\n  }\r\n\r\n  unionAll(query: QueryBuilder): QueryBuilder {\r\n    // Note: SQLite doesn't differentiate UNION and UNION ALL like other databases\r\n    return this.union(query);\r\n  }\r\n\r\n  // CTE (Common Table Expressions)\r\n  with(alias: string, query: QueryBuilder): QueryBuilder {\r\n    this.cteQueries.set(alias, query);\r\n    return this;\r\n  }\r\n\r\n  // Subqueries\r\n  whereSubQuery(field: string, operator: string, subquery: QueryBuilder): QueryBuilder {\r\n    this.subQueries.push({ query: subquery, alias: '' });\r\n    this.whereConditions.push({ field, operator, value: subquery });\r\n    return this;\r\n  }\r\n\r\n  // Aggregation functions\r\n  count(field: string = '*'): QueryBuilder {\r\n    this.selectFields = [`COUNT(${field}) as count`];\r\n    return this;\r\n  }\r\n\r\n  sum(field: string): QueryBuilder {\r\n    this.selectFields = [`SUM(${field}) as sum`];\r\n    return this;\r\n  }\r\n\r\n  avg(field: string): QueryBuilder {\r\n    this.selectFields = [`AVG(${field}) as avg`];\r\n    return this;\r\n  }\r\n\r\n  max(field: string): QueryBuilder {\r\n    this.selectFields = [`MAX(${field}) as max`];\r\n    return this;\r\n  }\r\n\r\n  min(field: string): QueryBuilder {\r\n    this.selectFields = [`MIN(${field}) as min`];\r\n    return this;\r\n  }\r\n\r\n  // SQL Generation\r\n  toSQL(): { sql: string; params: any[] } {\r\n    let sql = '';\r\n    const params: any[] = [];\r\n\r\n    // CTE queries\r\n    if (this.cteQueries.size > 0) {\r\n      const cteList: string[] = [];\r\n      this.cteQueries.forEach((query, alias) => {\r\n        const { sql: cteSql, params: cteParams } = query.toSQL();\r\n        cteList.push(`${alias} AS (${cteSql})`);\r\n        params.push(...cteParams);\r\n      });\r\n      sql += `WITH ${cteList.join(', ')} `;\r\n    }\r\n\r\n    // Main SELECT\r\n    sql += `SELECT ${this.selectFields.join(', ')} FROM ${this.tableName}`;\r\n\r\n    // JOINs\r\n    if (this.joinClauses.length > 0) {\r\n      this.joinClauses.forEach(join => {\r\n        sql += ` ${join.type} JOIN ${join.table} ON ${join.condition}`;\r\n      });\r\n    }\r\n\r\n    // WHERE conditions\r\n    if (this.whereConditions.length > 0) {\r\n      const conditions: string[] = [];\r\n      this.whereConditions.forEach(condition => {\r\n        const { clause, conditionParams } = this.buildCondition(condition);\r\n        conditions.push(clause);\r\n        params.push(...conditionParams);\r\n      });\r\n      sql += ` WHERE ${conditions.join(' AND ')}`;\r\n    }\r\n\r\n    // GROUP BY\r\n    if (this.groupByFields.length > 0) {\r\n      sql += ` GROUP BY ${this.groupByFields.join(', ')}`;\r\n    }\r\n\r\n    // HAVING\r\n    if (this.havingConditions.length > 0) {\r\n      const conditions: string[] = [];\r\n      this.havingConditions.forEach(condition => {\r\n        const { clause, conditionParams } = this.buildCondition(condition);\r\n        conditions.push(clause);\r\n        params.push(...conditionParams);\r\n      });\r\n      sql += ` HAVING ${conditions.join(' AND ')}`;\r\n    }\r\n\r\n    // ORDER BY\r\n    if (this.orderByFields.length > 0) {\r\n      sql += ` ORDER BY ${this.orderByFields.join(', ')}`;\r\n    }\r\n\r\n    // LIMIT\r\n    if (this.limitValue !== null) {\r\n      sql += ` LIMIT ${this.limitValue}`;\r\n    }\r\n\r\n    // OFFSET\r\n    if (this.offsetValue !== null) {\r\n      sql += ` OFFSET ${this.offsetValue}`;\r\n    }\r\n\r\n    // UNION queries\r\n    if (this.unionQueries.length > 0) {\r\n      this.unionQueries.forEach(unionQuery => {\r\n        const { sql: unionSql, params: unionParams } = unionQuery.toSQL();\r\n        sql += ` UNION ${unionSql}`;\r\n        params.push(...unionParams);\r\n      });\r\n    }\r\n\r\n    return { sql, params };\r\n  }\r\n\r\n  private buildCondition(condition: QueryCondition): { clause: string; conditionParams: any[] } {\r\n    const { field, operator, value } = condition;\r\n    const params: any[] = [];\r\n\r\n    switch (operator.toUpperCase()) {\r\n      case 'IN':\r\n      case 'NOT IN':\r\n        const placeholders = (value as any[]).map(() => '?').join(', ');\r\n        params.push(...(value as any[]));\r\n        return { \r\n          clause: `${field} ${operator} (${placeholders})`, \r\n          conditionParams: params \r\n        };\r\n\r\n      case 'BETWEEN':\r\n      case 'NOT BETWEEN':\r\n        params.push(value[0], value[1]);\r\n        return { \r\n          clause: `${field} ${operator} ? AND ?`, \r\n          conditionParams: params \r\n        };\r\n\r\n      case 'IS NULL':\r\n      case 'IS NOT NULL':\r\n        return { \r\n          clause: `${field} ${operator}`, \r\n          conditionParams: [] \r\n        };\r\n\r\n      case 'EXISTS':\r\n      case 'NOT EXISTS':\r\n        const { sql: subSql, params: subParams } = (value as QueryBuilder).toSQL();\r\n        params.push(...subParams);\r\n        return { \r\n          clause: `${operator} (${subSql})`, \r\n          conditionParams: params \r\n        };\r\n\r\n      default:\r\n        if (value instanceof QueryBuilder) {\r\n          const { sql: subSql, params: subParams } = value.toSQL();\r\n          params.push(...subParams);\r\n          return { \r\n            clause: `${field} ${operator} (${subSql})`, \r\n            conditionParams: params \r\n          };\r\n        }\r\n        params.push(value);\r\n        return { \r\n          clause: `${field} ${operator} ?`, \r\n          conditionParams: params \r\n        };\r\n    }\r\n  }\r\n\r\n  // Execution methods (require DAO)\r\n  async get(): Promise<SQLiteRow[]> {\r\n    if (!this.dao) {\r\n      throw new Error('DAO instance required for query execution');\r\n    }\r\n    const { sql, params } = this.toSQL();\r\n    const result = await this.dao.execute(sql, params);\r\n    return result.rows;\r\n  }\r\n\r\n  async first(): Promise<SQLiteRow | null> {\r\n    this.limit(1);\r\n    const results = await this.get(); // This will apply the limit(1) set by firstRow()\r\n    return results.length > 0 ? results[0] : null;\r\n  }\r\n\r\n  async pluck(column: string): Promise<any[]> {\r\n    this.select(column);\r\n    const results = await this.get();\r\n    return results.map(row => row[column]);\r\n  }\r\n\r\n  async exists(): Promise<boolean> {\r\n    this.select('1').limit(1);\r\n    const results = await this.get();\r\n    return results.length > 0;\r\n  }\r\n\r\n  async countResult(): Promise<number> {\r\n    this.count();\r\n    const result = await this.first();\r\n    return result ? result.count : 0;\r\n  }\r\n\r\n  // Static helper methods for DML operations\r\n  static insert(tableName: string, data: Record<string, any>): { sql: string; params: any[] } {\r\n    const fields = Object.keys(data);\r\n    const values = Object.values(data);\r\n    const placeholders = values.map(() => '?').join(', ');\r\n\r\n    return {\r\n      sql: `INSERT INTO ${tableName} (${fields.join(', ')}) VALUES (${placeholders})`,\r\n      params: values\r\n    };\r\n  }\r\n\r\n  static insertMany(tableName: string, dataArray: Record<string, any>[]): { sql: string; params: any[] } {\r\n    if (dataArray.length === 0) {\r\n      throw new Error('Data array cannot be empty');\r\n    }\r\n\r\n    const fields = Object.keys(dataArray[0]);\r\n    const placeholders = fields.map(() => '?').join(', ');\r\n    const valueGroups = dataArray.map(() => `(${placeholders})`).join(', ');\r\n\r\n    const allValues = dataArray.flatMap(data => Object.values(data));\r\n\r\n    return {\r\n      sql: `INSERT INTO ${tableName} (${fields.join(', ')}) VALUES ${valueGroups}`,\r\n      params: allValues\r\n    };\r\n  }\r\n\r\n  static update(tableName: string, data: Record<string, any>, where: string, whereParams: any[] = []): { sql: string; params: any[] } {\r\n    const sets = Object.keys(data).map(key => `${key} = ?`).join(', ');\r\n    const params = [...Object.values(data), ...whereParams];\r\n\r\n    return {\r\n      sql: `UPDATE ${tableName} SET ${sets} WHERE ${where}`,\r\n      params\r\n    };\r\n  }\r\n\r\n  static delete(tableName: string, where: string, whereParams: any[] = []): { sql: string; params: any[] } {\r\n    return {\r\n      sql: `DELETE FROM ${tableName} WHERE ${where}`,\r\n      params: whereParams\r\n    };\r\n  }\r\n\r\n  static upsert(tableName: string, data: Record<string, any>, conflictColumns: string[]): { sql: string; params: any[] } {\r\n    const fields = Object.keys(data);\r\n    const values = Object.values(data);\r\n    const placeholders = values.map(() => '?').join(', ');\r\n\r\n    const updateColumns = fields.filter(field => !conflictColumns.includes(field));\r\n    const updateClause = updateColumns.length > 0\r\n      ? updateColumns.map(col => `${col} = excluded.${col}`).join(', ')\r\n      : '';\r\n\r\n    let sql = `INSERT INTO ${tableName} (${fields.join(', ')}) VALUES (${placeholders})`;\r\n\r\n    if (updateColumns.length > 0) {\r\n      sql += ` ON CONFLICT(${conflictColumns.join(', ')}) DO UPDATE SET ${updateClause}`;\r\n    } else {\r\n      sql += ` ON CONFLICT(${conflictColumns.join(', ')}) DO NOTHING`;\r\n    }\r\n\r\n    return { sql, params: values };\r\n  }\r\n\r\n  // Utility methods\r\n  clone(): QueryBuilder {\r\n    if (!this.dao) throw new Error('DAO instance required for cloning QueryBuilder');\r\n    const cloned = new QueryBuilder(this.dao);\r\n    cloned.tableName = this.tableName;\r\n    cloned.selectFields = [...this.selectFields];\r\n    cloned.joinClauses = [...this.joinClauses];\r\n    cloned.whereConditions = [...this.whereConditions];\r\n    cloned.groupByFields = [...this.groupByFields];\r\n    cloned.havingConditions = [...this.havingConditions];\r\n    cloned.orderByFields = [...this.orderByFields];\r\n    cloned.limitValue = this.limitValue;\r\n    cloned.offsetValue = this.offsetValue;\r\n    cloned.unionQueries = [...this.unionQueries];\r\n    cloned.subQueries = [...this.subQueries];\r\n    cloned.cteQueries = new Map(this.cteQueries);\r\n    return cloned;\r\n  }\r\n\r\n  toRawSQL(): string {\r\n    const { sql, params } = this.toSQL();\r\n    let rawSql = sql;\r\n    params.forEach(param => {\r\n      if (typeof param === 'string') {\r\n        rawSql = rawSql.replace('?', `'${param.replace(/'/g, \"''\")}'`);\r\n      } else if (param === null || param === undefined) {\r\n        rawSql = rawSql.replace('?', 'NULL');\r\n      } else {\r\n        rawSql = rawSql.replace('?', String(param));\r\n      }\r\n    });\r\n    return rawSql;\r\n  }\r\n\r\n  explain(): QueryBuilder {\r\n    this.selectFields = ['EXPLAIN QUERY PLAN ' + this.selectFields.join(', ')];\r\n    return this;\r\n  }\r\n}","// src/adapters/base-adapter.ts\r\nimport { SQLiteAdapter, SQLiteConnection } from '@/types';\r\n\r\n\r\nexport abstract class BaseAdapter implements SQLiteAdapter {\r\n  abstract connect(path: string): Promise<SQLiteConnection>;\r\n  abstract isSupported(): Promise<boolean>;\r\n\r\n  protected sanitizeSQL(sql: string): string {\r\n    return sql.trim();\r\n  }\r\n\r\n  protected bindParameters(sql: string, params?: any[]): string {\r\n    if (!params || params.length === 0) {\r\n      return sql;\r\n    }\r\n\r\n    let paramIndex = 0;\r\n    return sql.replace(/\\?/g, () => {\r\n      if (paramIndex < params.length) {\r\n        const param = params[paramIndex++];\r\n        if (typeof param === 'string') {\r\n          return `'${param.replace(/'/g, \"''\")}'`;\r\n        }\r\n        if (param === null || param === undefined) {\r\n          return 'NULL';\r\n        }\r\n        return String(param);\r\n      }\r\n      return '?';\r\n    });\r\n  }\r\n}","// src/types.ts\r\nexport interface SQLiteRow {\r\n  [key: string]: any;\r\n}\r\n\r\nexport interface SQLiteResult {\r\n  rows: SQLiteRow[];\r\n  rowsAffected: number;\r\n  lastInsertRowId?: number;\r\n}\r\n\r\nexport interface SQLiteConnection {\r\n  execute(sql: string, params?: any[]): Promise<SQLiteResult>;\r\n  close(): Promise<void>;\r\n}\r\n\r\nexport interface SQLiteAdapter {\r\n  connect(path: string): Promise<SQLiteConnection>;\r\n  isSupported(): Promise<boolean>;\r\n  name?: string;\r\n  version?: string;\r\n}\r\n\r\n// Enhanced schema types based on SQLiteDAO\r\nexport interface TypeMappingConfig {\r\n  type_mapping: {\r\n    [targetType: string]: {\r\n      [sourceType: string]: string;\r\n    };\r\n  };\r\n}\r\n\r\nexport interface ColumnDefinition {\r\n  name: string;\r\n  type: string;\r\n  precision?: number;\r\n  scale?: number;\r\n  option_key?: string;\r\n  description?: string;\r\n  nullable?: boolean;\r\n  default?: any;\r\n  primary_key?: boolean;\r\n  auto_increment?: boolean;\r\n  enum?: string[] | number[];\r\n  unique?: boolean;\r\n  constraints?: string;\r\n  length?: number;\r\n}\r\n\r\nexport interface Column {\r\n  name: string;\r\n  value?: any;\r\n}\r\n\r\nexport interface WhereClause {\r\n  name: string;\r\n  value: any;\r\n  operator?: string;\r\n}\r\n\r\nexport interface OrderByClause {\r\n  name: string;\r\n  direction?: \"ASC\" | \"DESC\";\r\n}\r\n\r\nexport interface LimitOffset {\r\n  limit?: number;\r\n  offset?: number;\r\n}\r\n\r\nexport interface QueryTable {\r\n  name: string;\r\n  cols: Column[];\r\n  wheres?: WhereClause[];\r\n  orderbys?: OrderByClause[];\r\n  limitOffset?: LimitOffset;\r\n}\r\n\r\nexport interface JoinClause {\r\n  type: \"INNER\" | \"LEFT\" | \"RIGHT\" | \"FULL\";\r\n  table: string;\r\n  on: string;\r\n}\r\n\r\nexport interface IndexDefinition {\r\n  name: string;\r\n  columns: string[];\r\n  unique?: boolean;\r\n  description?: string;\r\n}\r\n\r\nexport type ForeignKeyAction =\r\n  | \"CASCADE\"\r\n  | \"RESTRICT\"\r\n  | \"SET NULL\"\r\n  | \"NO ACTION\"\r\n  | undefined;\r\n\r\nexport interface ForeignKeyDefinition {\r\n  name: string;\r\n  columns: string[];\r\n  references: {\r\n    table: string;\r\n    columns: string[];\r\n  };\r\n  on_delete?: string | ForeignKeyAction;\r\n  on_update?: string | ForeignKeyAction;\r\n  description?: string;\r\n}\r\n\r\nexport interface TableDefinition {\r\n  name: string;\r\n  cols: ColumnDefinition[];\r\n  description?: string;\r\n  indexes?: IndexDefinition[];\r\n  foreign_keys?: ForeignKeyDefinition[];\r\n}\r\n\r\nexport interface DatabaseSchema {\r\n  version: string;\r\n  database_name: string;\r\n  description?: string;\r\n  type_mapping?: TypeMappingConfig[\"type_mapping\"];\r\n  schemas: Record<\r\n    string,\r\n    {\r\n      description?: string;\r\n      cols: ColumnDefinition[];\r\n      indexes?: IndexDefinition[];\r\n      foreign_keys?: ForeignKeyDefinition[];\r\n    }\r\n  >;\r\n}\r\n\r\n// Transaction types\r\nexport interface TransactionOperation {\r\n  type: \"insert\" | \"update\" | \"delete\" | \"select\";\r\n  table: QueryTable;\r\n}\r\n\r\nexport interface ImportOptions {\r\n  tableName: string;\r\n  data: Record<string, any>[];\r\n  batchSize?: number;\r\n  onProgress?: (processed: number, total: number) => void;\r\n  onError?: (\r\n    error: Error,\r\n    rowIndex: number,\r\n    rowData: Record<string, any>\r\n  ) => void;\r\n  skipErrors?: boolean;\r\n  validateData?: boolean;\r\n  updateOnConflict?: boolean;\r\n  conflictColumns?: string[];\r\n  includeAutoIncrementPK?: boolean;\r\n}\r\n\r\nexport interface ImportResult {\r\n  totalRows: number;\r\n  successRows: number;\r\n  errorRows: number;\r\n  errors: Array<{\r\n    rowIndex: number;\r\n    error: string;\r\n    rowData: Record<string, any>;\r\n  }>;\r\n  executionTime: number;\r\n}\r\n\r\n// Interface cho mapping column\r\nexport interface ColumnMapping {\r\n  sourceColumn: string;\r\n  targetColumn: string;\r\n  transform?: (value: any) => any;\r\n}\r\n\r\n// Interface for database factory options\r\nexport interface DbFactoryOptions {\r\n  config?: DatabaseSchema; // Option 1: Provide a config object directly\r\n  configAsset?: any; // Option 3: Provide a required JSON asset\r\n  dbDirectory?: string; // Optional: Directory to store the .db file\r\n  adapter?: SQLiteAdapter; // Optional: Specific adapter to use\r\n}\r\n\r\n// Thêm kiểu kiểm tra sức khỏe của Database\r\nexport interface ServiceStatus {\r\n  schemaName: string;\r\n  tableName: string;\r\n  isOpened: boolean;\r\n  isInitialized: boolean;\r\n  hasDao: boolean;\r\n}\r\n\r\nexport interface HealthCheckResult {\r\n  healthy: boolean;\r\n  schemaName: string;\r\n  recordCount?: number;\r\n  error?: string;\r\n  timestamp: string;\r\n}\r\n\r\n// Global type declarations for different environments\r\ndeclare global {\r\n  // Browser environment\r\n  interface Window {\r\n    SQL?: any;\r\n    initSqlJs?: (config?: any) => Promise<any>;\r\n    openDatabase?: (\r\n      name: string,\r\n      version: string,\r\n      displayName: string,\r\n      estimatedSize: number\r\n    ) => any;\r\n  }\r\n\r\n  // Deno environment\r\n  var Deno:\r\n    | {\r\n        env: any;\r\n        readTextFile?: (path: string) => Promise<string>;\r\n        writeTextFile?: (path: string, data: string) => Promise<void>;\r\n        version?: { deno: string };\r\n        [key: string]: any;\r\n      }\r\n    | undefined;\r\n\r\n  // Bun environment\r\n  var Bun:\r\n    | {\r\n        version: string;\r\n        [key: string]: any;\r\n      }\r\n    | undefined;\r\n\r\n  // React Native Windows\r\n  var Windows: any;\r\n\r\n  // Nodejs\r\n  var process: any;\r\n\r\n  // React Native Platform\r\n  var Platform:\r\n    | {\r\n        OS: string;\r\n        Version?: string;\r\n      }\r\n    | undefined;\r\n\r\n  // Navigator (React Native detection)\r\n  // var navigator: {\r\n  //   product?: string;\r\n  // } | undefined;\r\n}\r\n\r\nexport const SQLITE_TYPE_MAPPING = {\r\n  sqlite: {\r\n    // String types\r\n    string: \"TEXT\",\r\n    varchar: \"TEXT\",\r\n    char: \"TEXT\",\r\n    text: \"TEXT\",\r\n    email: \"TEXT\",\r\n    url: \"TEXT\",\r\n    uuid: \"TEXT\",\r\n\r\n    // Numeric types\r\n    integer: \"INTEGER\",\r\n    int: \"INTEGER\",\r\n    bigint: \"INTEGER\",\r\n    smallint: \"INTEGER\",\r\n    tinyint: \"INTEGER\",\r\n    number: \"REAL\",\r\n    decimal: \"REAL\",\r\n    numeric: \"REAL\",\r\n    float: \"REAL\",\r\n    double: \"REAL\",\r\n\r\n    // Boolean\r\n    boolean: \"INTEGER\",\r\n    bool: \"INTEGER\",\r\n\r\n    // Date/Time types\r\n    timestamp: \"TEXT\",\r\n    datetime: \"TEXT\",\r\n    date: \"TEXT\",\r\n    time: \"TEXT\",\r\n\r\n    // Complex types\r\n    json: \"TEXT\",\r\n    jsonb: \"TEXT\",\r\n    array: \"TEXT\",\r\n    object: \"TEXT\",\r\n\r\n    // Binary types\r\n    blob: \"BLOB\",\r\n    binary: \"BLOB\",\r\n\r\n    // MongoDB specific (fallback)\r\n    objectid: \"TEXT\",\r\n  },\r\n};\r\n"],"names":["f","l","t","e","i","E","a","n","F","S","y","w","v","G","J","r","r$1","U","u","SQLiteModules","CommonModules","configureSQLiteLogger","enabled","defaultLevel","config","LoggerConfigBuilder","CommonLoggerConfig","logger","createModuleLogger","UniversalDAO","adapter","dbPath","options","_a","_b","error","genericType","defaultType","mappedType","col","processedCol","constraints","defaultIndex","defaultValue","schema","hasExistingSchema","result","tableName","tableConfig","tableDefinition","tables","table","columnDefs","foreignKeyDefs","foreignKeys","fk","columns","refTable","refColumns","_c","_d","_e","fkSql","onDelete","onUpdate","allDefs","sql","indexes","index","isUnique","version","insertTable","validCols","columnNames","placeholders","params","updateTable","setCols","setClause","whereClause","deleteTable","selectTable","row","suffix","orderBy","o","wheres","clause","conditions","where","operator","json","idFields","queryTable","key","value","startTime","tableInfo","columnMap","batchSize","processedCount","skipAutoIncrementPK","batch","j","rowIndex","rowData","processedData","errorInfo","data","columnMappings","transformedData","newRow","mapping","csvData","delimiter","hasHeader","lines","line","headers","dataStartIndex","h","firstRowCols","_","values","header","processedRow","columnName","columnInfo","isRequired","isAutoIncrementPK","lowerColumnName","columnType","type","num","lower","date","conflictColumns","updateColumns","whereColumns","updateValues","whereValues","allValues","info","isOpen","DatabaseFactory","environment","dao","dbInfo","errorMsg","dbName","dbFileName","closeError","isForceInit","isForceDelete","schemaError","configAsset","DatabaseManager","maxConnections","currentConnectionCount","manager","schemas","schemaKeys","internalKeys","externalKeys","allKeys","roleConfig","roleConfigs","roleName","databases","allDatabases","db","coreSchema","userRoles","primaryRole","previousRoles","requiredDatabases","failedInitializations","initPromises","dbKey","err","errorSummary","previousDatabases","currentDatabases","databasesToClose","hasAccess","schemaName","callback","listeners","currentActiveDb","closePromises","activeDbArray","databaseKeys","failedOpens","invalidKeys","newConnectionsCount","currentConnectionsCount","availableSchemas","daos","acc","databaseKey","importConfigs","c","configKey","importResult","count","connections","connectionsToClose","BaseService","newDao","method","fields","searchFields","fieldsToCheck","hasAllRequiredFields","field","existingRecord","primaryKeyValue","createdRecord","findError","id","updateData","success","record","allWheres","name","results","whereConditions","exists","dataArray","useTransaction","processBulkUpsert","updatedRecord","items","rollbackError","cleanData","k","obj","event","handler","handlers","errorType","handlerError","status","DefaultService","ServiceManager","methods","serviceKey","normalizedConfig","wasAlreadyRegistered","configs","ServiceClass","service","metadata","services","keySchema","keys","serviceKeys","destroyPromises","successCount","infos","healthPromises","health","healthyCount","report","maxIdleTime","now","servicesToDestroy","lastAccessTime","eventType","globalHandlers","QueryBuilder","builder","raw","fieldList","condition","fieldOrConditions","operatorOrValue","val","actualValue","min","max","subquery","actualOperator","direction","page","perPage","query","alias","cteList","cteSql","cteParams","join","conditionParams","unionQuery","unionSql","unionParams","subSql","subParams","column","valueGroups","whereParams","sets","updateClause","cloned","rawSql","param","BaseAdapter","paramIndex","SQLITE_TYPE_MAPPING"],"mappings":"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","x_google_ignoreList":[0]}