using System.Text.Json; using CMGMBLL.Interfaces; using CMGMDAL.DTOs; using CMGMDAL.Interfaces; using GB5Shared.DaprCache; using GB5Shared.DTO.Framework.Login; using GB5Shared.EventLogPublish; using GB5Shared.Resource.Response; using GB5Shared.Telemetry; using static GB5Shared.GB5Constant.Constant; using Microsoft.Extensions.Logging; namespace CMGMBLL.Implementations; public class CompetencyFrameworkBLL : ICompetencyFrameworkBLL { private readonly ICompetencyFrameworkDAL _dal; private readonly KeyInvalidate _keyInvalidate; private readonly EventLogPublish _eventLog; private readonly ILogger _logger; public CompetencyFrameworkBLL(ICompetencyFrameworkDAL dal, KeyInvalidate keyInvalidate, EventLogPublish eventLog, ILogger logger) { _dal = dal; _keyInvalidate = keyInvalidate; _eventLog = eventLog; _logger = logger; } public async Task GetByIdAsync(int frameworkId, LoginDTO login, CancellationToken ct) { try { var dto = await _dal.GetByIdAsync(frameworkId, login, ct).ConfigureAwait(false); return JsonSerializer.Serialize(dto); } catch (Exception ex) { GB5Trace.MarkFailed("get-framework-failed", ex); _logger.LogError(ex, "GetFramework failed for FrameworkId {FrameworkId}", frameworkId); throw; } } public async Task GetListAsync(short status, LoginDTO login, CancellationToken ct) { try { var list = await _dal.GetListAsync(status, login, ct).ConfigureAwait(false); return JsonSerializer.Serialize(list); } catch (Exception ex) { GB5Trace.MarkFailed("get-framework-list-failed", ex); _logger.LogError(ex, "GetFrameworkList failed"); throw; } } public async Task SaveAsync(CompetencyFrameworkDTO dto, LoginDTO login, CancellationToken ct) { try { GB5Trace.Step("validate-framework", new { dto.FrameworkId }); if (string.IsNullOrWhiteSpace(dto.Code)) return "Framework Code is required."; if (string.IsNullOrWhiteSpace(dto.Name)) return "Framework Name is required."; bool isNew = dto.FrameworkId == 0; GB5Trace.Step("save-framework", new { dto.FrameworkId, isNew }); int savedId = await _dal.SaveAsync(dto, isNew, login, ct).ConfigureAwait(false); GB5Trace.Step("event-publish", new { EventTypeId = EventTypeConstant.SAVECMGMFRAMEWORKEVENTTYPEID }); await _eventLog.PublishEventLogAsync("Competency Framework Saved", dto, EventTypeConstant.SAVECMGMFRAMEWORKEVENTTYPEID, savedId, login, ct: ct).ConfigureAwait(false); var cacheKey = new CacheKeyGeneration().KeyGeneration(savedId, EntityConstant.OBJECTCMGMFRAMEWORK, CacheKeyLevel.CLIENT_LEVEL, login); await _keyInvalidate.AllInvalidateCache(cacheKey).ConfigureAwait(false); return isNew ? $"{SuccessResponse.SaveSuccessMessage} {savedId}" : SuccessResponse.UpdateSuccess; } catch (Exception ex) { GB5Trace.MarkFailed("save-framework-failed", ex); _logger.LogError(ex, "SaveFramework failed for Code {Code}", dto.Code); throw; } } public async Task DeleteAsync(int frameworkId, LoginDTO login, CancellationToken ct) { try { GB5Trace.Step("validate-delete-framework", new { frameworkId }); int activeMaps = await _dal.HasActiveMapsAsync(frameworkId, login, ct).ConfigureAwait(false); if (activeMaps > 0) return "Cannot delete framework with active KRA mappings. Remove all KRA maps first."; GB5Trace.Step("delete-framework", new { frameworkId }); await _dal.DeleteAsync(frameworkId, login, ct).ConfigureAwait(false); GB5Trace.Step("event-publish", new { EventTypeId = EventTypeConstant.SAVECMGMFRAMEWORKEVENTTYPEID }); await _eventLog.PublishEventLogAsync("Competency Framework Deleted", new { FrameworkId = frameworkId }, EventTypeConstant.SAVECMGMFRAMEWORKEVENTTYPEID, frameworkId, login, ct: ct).ConfigureAwait(false); var cacheKey = new CacheKeyGeneration().KeyGeneration(frameworkId, EntityConstant.OBJECTCMGMFRAMEWORK, CacheKeyLevel.CLIENT_LEVEL, login); await _keyInvalidate.AllInvalidateCache(cacheKey).ConfigureAwait(false); return SuccessResponse.DeleteSuccessMessage; } catch (Exception ex) { GB5Trace.MarkFailed("delete-framework-failed", ex); _logger.LogError(ex, "DeleteFramework failed for FrameworkId {FrameworkId}", frameworkId); throw; } } }