import { IDeckRepository } from '../../../Domain/IRepository/IDeckRepository'; import { UpdateDeckCommand } from './UpdateDeckCommand'; import { ShortDeckDto } from '../../DTOs/DeckDto'; import { DeckMapper } from '../../DTOs/Mappers/DeckMapper'; import { DeckAggregate } from '../../../Domain/Deck/DeckAggregate'; import { logAuth, logError } from '../../Services/Logger'; export class UpdateDeckCommandHandler { constructor(private readonly deckRepo: IDeckRepository) {} async execute(cmd: UpdateDeckCommand): Promise { if(cmd.state !== undefined && cmd.authLevel !== 1) { throw new Error('Only admin users can change deck state'); } try { let existingDeck: DeckAggregate | null = null; if (cmd.authLevel === 1) { existingDeck = await this.deckRepo.findByIdIncludingDeleted(cmd.id); } else { existingDeck = await this.deckRepo.findById(cmd.id); } if (!existingDeck) { logError(`Deck not found with ID: ${cmd.id}`); throw new Error('Deck not found'); } if(cmd.authLevel !== 1 && existingDeck.userid !== cmd.userid) { logAuth(`Unauthorized access attempt to deck with ID: ${cmd.id}, UserID: ${cmd.userid}`); throw new Error('Unauthorized'); } const for_update: Partial = {}; if(cmd.name !== undefined) for_update.name = cmd.name; if(cmd.type !== undefined) for_update.type = cmd.type; if(cmd.cards !== undefined) for_update.cards = cmd.cards; if(cmd.ctype !== undefined) for_update.ctype = cmd.ctype; if(cmd.state !== undefined) for_update.state = cmd.state; // Ensure we have something to update if (Object.keys(for_update).length === 0) { throw new Error('No fields provided for update'); } const deck = await this.deckRepo.update(cmd.id, { ...for_update }); if(!deck) { logError(`Deck update failed for ID: ${cmd.id}. Update returned null.`); throw new Error('Failed to update deck'); } return DeckMapper.toShortDto(deck); } catch (error: any) { logError(`Error updating deck: ${cmd.id}`, error); throw error; } } }