using AnalyticsDAL.CustomCode.Workspace; using AnalyticsDAL.DTO.Workspace; using GB5Shared.DaprCache; using GB5Shared.DTO.Framework.Login; using GB5Shared.Resource.Response; using GB5Shared.Telemetry; using Microsoft.Extensions.Logging; using static GB5Shared.GB5Constant.Constant; namespace AnalyticsBLL.Workspace { public class WorkspaceBLL : IWorkspaceBLL { private readonly IWorkspaceDAL _dal; private readonly KeyInvalidate _keyInvalidate; private readonly ILogger _logger; public WorkspaceBLL( IWorkspaceDAL dal, KeyInvalidate keyInvalidate, ILogger logger) { _dal = dal; _keyInvalidate = keyInvalidate; _logger = logger; } public async Task GetWorkspace(int workspaceId, LoginDTO login, CancellationToken ct) => await _dal.GetWorkspace(workspaceId, login, ct).ConfigureAwait(false); public async Task GetSelectListWorkspace(LoginDTO login, CancellationToken ct) => await _dal.GetSelectListWorkspace(login, ct).ConfigureAwait(false); public async Task SaveWorkspace(WorkspaceDTO dto, LoginDTO login, CancellationToken ct) { try { GB5Trace.Step("validate-workspace", new { dto.WorkspaceId }); if (string.IsNullOrWhiteSpace(dto.WorkspaceCode)) throw new ArgumentException("WorkspaceCode is required."); if (dto.WorkspaceCode.Length > 20) throw new ArgumentException("WorkspaceCode must not exceed 20 characters."); if (string.IsNullOrWhiteSpace(dto.WorkspaceName)) throw new ArgumentException("WorkspaceName is required."); if (dto.WorkspaceType > 2) throw new ArgumentException("WorkspaceType must be 0 (Standard), 1 (Consolidated), or 2 (Reporting)."); var isNew = dto.WorkspaceId == 0; if (await _dal.IsDuplicateCode(dto.WorkspaceCode, dto.WorkspaceId, login, ct).ConfigureAwait(false)) throw new InvalidOperationException($"WorkspaceCode '{dto.WorkspaceCode}' already exists."); if (await _dal.IsDuplicateName(dto.WorkspaceName, dto.WorkspaceId, login, ct).ConfigureAwait(false)) throw new InvalidOperationException($"WorkspaceName '{dto.WorkspaceName}' already exists."); dto.SourceType = isNew ? (byte)5 : dto.SourceType; GB5Trace.Step("save-workspace", new { dto.WorkspaceId, isNew }); int savedId; if (isNew) savedId = await _dal.SaveWorkspace(dto, login, ct).ConfigureAwait(false); else { savedId = dto.WorkspaceId; await _dal.UpdateWorkspace(dto, login, ct).ConfigureAwait(false); } var cacheKey = new CacheKeyGeneration().KeyGeneration( savedId, EntityConstant.OBJECTANALYSIS, CacheKeyLevel.CLIENT_LEVEL, login); await _keyInvalidate.AllInvalidateCache(cacheKey).ConfigureAwait(false); return isNew ? $"{SuccessResponse.SaveSuccessMessage} {savedId}" : SuccessResponse.UpdateSuccess; } catch (Exception ex) { GB5Trace.MarkFailed("save-workspace-failed", ex); _logger.LogError(ex, "SaveWorkspace failed for WorkspaceId {Id}", dto.WorkspaceId); throw; } } public async Task DeleteWorkspace(int workspaceId, LoginDTO login, CancellationToken ct) { try { GB5Trace.Step("delete-workspace", new { workspaceId }); await _dal.DeleteWorkspace(workspaceId, login, ct).ConfigureAwait(false); var cacheKey = new CacheKeyGeneration().KeyGeneration( workspaceId, EntityConstant.OBJECTANALYSIS, CacheKeyLevel.CLIENT_LEVEL, login); await _keyInvalidate.AllInvalidateCache(cacheKey).ConfigureAwait(false); return SuccessResponse.DeleteSuccessMessage; } catch (Exception ex) { GB5Trace.MarkFailed("delete-workspace-failed", ex); _logger.LogError(ex, "DeleteWorkspace failed for WorkspaceId {Id}", workspaceId); throw; } } public async Task ValidateWorkspaceVisibility(int workspaceId, LoginDTO login, CancellationToken ct) { var tenantId = await _dal.GetWorkspaceTenantId(workspaceId, login, ct).ConfigureAwait(false); if (tenantId is null) throw new ArgumentException($"Workspace {workspaceId} does not exist.", nameof(workspaceId)); if (tenantId != -1 && tenantId != login.ClientId) throw new ArgumentException( $"Workspace {workspaceId} is private to another tenant and is not assignable here.", nameof(workspaceId)); } } }