Files
tnsu-approval-route/backend/Tnsu.ApprovalRoute.Infrastructure/TnsuPortal/HttpTnsuPortalClient.cs
T
2026-08-12 12:19:04 +05:00

120 lines
5.4 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using System.Net;
using System.Net.Http.Headers;
using System.Net.Http.Json;
using System.Text.Json;
using System.Text.Json.Serialization;
using Microsoft.AspNetCore.Http;
using Tnsu.ApprovalRoute.Domain.Enums;
namespace Tnsu.ApprovalRoute.Infrastructure.TnsuPortal;
public sealed class HttpTnsuPortalClient(
HttpClient httpClient,
TnsuPortalTokenProvider tokenProvider,
IHttpContextAccessor httpContextAccessor) : ITnsuPortalClient
{
private static readonly JsonSerializerOptions JsonOptions = new() { PropertyNameCaseInsensitive = true };
public async Task<EmployeeDirectoryInfo?> GetEmployeeByEmailAsync(string email, CancellationToken cancellationToken)
{
var employee = await GetAsync<EmployeeResponse>(
$"/Employee/ByEmail?email={Uri.EscapeDataString(email)}", cancellationToken);
if (employee is null)
return null;
return new EmployeeDirectoryInfo(employee.CompanyId ?? Guid.Empty, employee.DepartmentId, employee.Company ?? string.Empty, employee.Position);
}
public async Task<string?> GetEmployeeByPositionAsync(string position, string company, CancellationToken cancellationToken)
{
var employee = await GetAsync<EmployeeResponse>(
$"/Employee/ByPosition?position={Uri.EscapeDataString(position)}&company={Uri.EscapeDataString(company)}", cancellationToken);
return employee?.Email;
}
public async Task<string?> GetManagerAsync(string email, string managerType, CancellationToken cancellationToken)
{
var manager = await GetAsync<ManagerResponse>(
$"/Employee/Manager?email={Uri.EscapeDataString(email)}&managerType={Uri.EscapeDataString(managerType)}", cancellationToken);
return manager?.ManagerEmail;
}
public async Task<IReadOnlyList<ProjectExecutorInfo>> GetProjectExecutorsAsync(Guid projectId, CancellationToken cancellationToken)
{
var project = await GetAsync<ProjectResponse>($"/Project/{projectId}", cancellationToken);
if (project is null)
return [];
var executors = new List<ProjectExecutorInfo>();
AddIfPresent(executors, ProjectRole.ProjectManager, project.ProjectManager);
AddIfPresent(executors, ProjectRole.Planner, project.Planner);
AddIfPresent(executors, ProjectRole.ManagerHSE, project.ManagerHSE);
AddIfPresent(executors, ProjectRole.Security, project.Security);
return executors;
}
// Ответ — {"managerEmail": "..."} (та же форма, что у /Employee/Manager),
// а НЕ форма сотрудника (EmployeeResponse) — проверено живым вызовом
// (GET /Employee/DepartmentHead?departmentId=... на отделе "АУП"/"ТОО
// Монтажник-Т" вернул именно managerEmail). 404 с телом {"error": "..."}
// на отделах без руководителя уже отфильтровывается общим GetAsync<T>.
public async Task<string?> GetDepartmentHeadEmailAsync(Guid departmentId, CancellationToken cancellationToken)
{
var manager = await GetAsync<ManagerResponse>(
$"/Employee/DepartmentHead?departmentId={Uri.EscapeDataString(departmentId.ToString())}", cancellationToken);
return manager?.ManagerEmail;
}
private async Task<T?> GetAsync<T>(string requestUri, CancellationToken cancellationToken) where T : class
{
using var request = new HttpRequestMessage(HttpMethod.Get, requestUri);
await AuthorizeAsync(request, cancellationToken);
using var response = await httpClient.SendAsync(request, cancellationToken);
if (response.StatusCode == HttpStatusCode.NotFound)
return null;
response.EnsureSuccessStatusCode();
return await response.Content.ReadFromJsonAsync<T>(JsonOptions, cancellationToken);
}
private static void AddIfPresent(List<ProjectExecutorInfo> executors, ProjectRole role, string? email)
{
if (!string.IsNullOrWhiteSpace(email))
executors.Add(new ProjectExecutorInfo(role, email));
}
private async Task AuthorizeAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
var incoming = httpContextAccessor.HttpContext?.Request.Headers.Authorization.ToString();
if (!string.IsNullOrWhiteSpace(incoming))
{
request.Headers.TryAddWithoutValidation("Authorization", incoming);
return;
}
var token = await tokenProvider.GetAccessTokenAsync(cancellationToken);
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", token);
}
private sealed record EmployeeResponse(
[property: JsonPropertyName("email")] string? Email,
[property: JsonPropertyName("company")] string? Company,
[property: JsonPropertyName("companyId")] Guid? CompanyId,
[property: JsonPropertyName("departmentId")] Guid? DepartmentId,
[property: JsonPropertyName("position")] string? Position);
private sealed record ManagerResponse(
[property: JsonPropertyName("managerEmail")] string? ManagerEmail);
private sealed record ProjectResponse(
[property: JsonPropertyName("projectManager")] string? ProjectManager,
[property: JsonPropertyName("planner")] string? Planner,
[property: JsonPropertyName("managerHSE")] string? ManagerHSE,
[property: JsonPropertyName("security")] string? Security);
}