const db = require('../database/database'); const { logger } = require('../middleware/logger'); class UnitOfWork { constructor() { this.repositories = {}; this.connection = null; this.inTransaction = false; } async start() { logger.info('UnitOfWork.start:start'); try { this.connection = await db.getConnection(); await this.connection.query('START TRANSACTION'); this.inTransaction = true; logger.info('UnitOfWork.start:success'); } catch (error) { logger.error('UnitOfWork.start:error', { error: error.message }); throw error; } } async commit() { logger.info('UnitOfWork.commit:start'); if (this.inTransaction && this.connection) { try { await this.connection.query('COMMIT'); this.inTransaction = false; await this.connection.release(); this.connection = null; logger.info('UnitOfWork.commit:success'); } catch (error) { logger.error('UnitOfWork.commit:error', { error: error.message }); throw error; } } } async rollback(error) { logger.warn('UnitOfWork.rollback:start'); if (this.inTransaction && this.connection) { try { await this.connection.query('ROLLBACK'); if (error) { logger.error('UnitOfWork.rollback:error', { error: error.message, stack: error.stack }); console.error('💥 Transaction rolled back due to error:', error); if (error.stack) { console.error('💥 Error stack:', error.stack); } } else { logger.error('UnitOfWork.rollback:unknown_error'); console.error('💥 Transaction rolled back due to unknown error'); } } catch (rollbackError) { logger.error('UnitOfWork.rollback:rollback_error', { error: rollbackError.message, stack: rollbackError.stack }); console.error('💥 Error during rollback:', rollbackError); if (rollbackError.stack) { console.error('💥 Rollback error stack:', rollbackError.stack); } } this.inTransaction = false; await this.connection.release(); this.connection = null; logger.info('UnitOfWork.rollback:complete'); } } registerRepository(name, repository) { this.repositories[name] = repository; } getRepository(name) { return this.repositories[name]; } getConnection() { if (!this.inTransaction || !this.connection) { throw new Error('UnitOfWork connection not available. Call start() before using getConnection().'); } return this.connection; } } module.exports = UnitOfWork;