using AutomationDAL.CustomCode.Script; using AutomationDAL.DTO.Script; using GB5Shared.DTO.Framework.Login; using GB5Shared.Resource.Response; using GB5Shared.Telemetry; using Microsoft.Extensions.Logging; namespace AutomationBLL.Script; public class ScriptBLL : IScriptBLL { private static readonly string[] ValidCategories = { "PortalDownload", "PortalUpload", "Test", "DataSync", "Reporting" }; private static readonly string[] ValidRuntimeTypes = { "PlaywrightNode", "PlaywrightDotNet", "Cypress", "Other" }; private static readonly string[] ValidCriticalities = { "BusinessCritical", "BestEffort" }; private readonly IScriptDAL _dal; private readonly ILogger _logger; public ScriptBLL(IScriptDAL dal, ILogger logger) { _dal = dal; _logger = logger; } public async Task GetById(int scriptId, LoginDTO login, CancellationToken ct) => await _dal.GetById(scriptId, login, ct).ConfigureAwait(false); public async Task> GetCatalog(string? category, string? searchText, LoginDTO login, CancellationToken ct) => await _dal.GetCatalog(category, searchText, login, ct).ConfigureAwait(false); public async Task Save(ScriptDTO dto, LoginDTO login, CancellationToken ct) { try { GB5Trace.Step("validate-script", new { dto.ScriptId, dto.ScriptName }); if (string.IsNullOrWhiteSpace(dto.ScriptName)) throw new InvalidOperationException("Script Name is required."); if (!ValidCategories.Contains(dto.Category)) throw new InvalidOperationException($"Category must be one of: {string.Join(", ", ValidCategories)}"); if (!ValidRuntimeTypes.Contains(dto.RuntimeType)) throw new InvalidOperationException($"RuntimeType must be one of: {string.Join(", ", ValidRuntimeTypes)}"); if (!ValidCriticalities.Contains(dto.Criticality)) throw new InvalidOperationException($"Criticality must be one of: {string.Join(", ", ValidCriticalities)}"); if (dto.OwnerUserId <= 0) throw new InvalidOperationException("OwnerUserId is required."); var isNew = dto.ScriptId == 0; GB5Trace.Step("save-script", new { dto.ScriptId, isNew }); if (isNew) { int newId = await _dal.Insert(dto, login, ct).ConfigureAwait(false); return $"{SuccessResponse.SaveSuccessMessage} {newId}"; } await _dal.Update(dto, login, ct).ConfigureAwait(false); return SuccessResponse.UpdateSuccess; } catch (Exception ex) { GB5Trace.MarkFailed("save-script-failed", ex); _logger.LogError(ex, "Save failed for ScriptName {ScriptName}", dto.ScriptName); throw; } } }