/
VFlov
/
NotificationService_1
Обзор
Документация
Войти
/
VFlov
/
NotificationService_1
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
master
src/Gateway/NotificationService.Gateway/Controllers/NotificationsController.cs
196 строк
7 KB
VFlov
Update
25 дек 2025, 21:02
25 дек 2025, 21:02
cf3965d
Код
Авторство
О чём код?
using Microsoft.AspNetCore.Mvc; using NotificationService.Gateway.Services; using NotificationService.Shared.DTOs; using NotificationService.Shared.Models; using NotificationService.Shared.Validators; using System.Diagnostics; namespace NotificationService.Gateway.Controllers; [ApiController] [Route("api/[controller]")] public class NotificationsController : ControllerBase { private readonly INotificationService _notificationService; private readonly ILogger<NotificationsController> _logger; public NotificationsController( INotificationService notificationService, ILogger<NotificationsController> logger) { _notificationService = notificationService; _logger = logger; } /// <summary> /// Отправить уведомление /// </summary> [HttpPost] [ProducesResponseType(typeof(SendNotificationResponse), StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status400BadRequest)] public async Task<ActionResult<SendNotificationResponse>> SendNotification( [FromBody] SendNotificationRequest request, CancellationToken cancellationToken) { var stopwatch = Stopwatch.StartNew(); var requestId = Guid.NewGuid(); try { _logger.LogInformation( "[{RequestId}] Received notification request - Type: {Type}, Recipient: {Recipient}", requestId, request.Type, MaskSensitiveData(request.Recipient)); // Валидация запроса if (request == null) { _logger.LogWarning("[{RequestId}] Request body is null", requestId); return BadRequest(new SendNotificationResponse { Success = false, Message = "Request body is required" }); } var validationResult = NotificationValidator.ValidateRequest(request); if (!validationResult.IsValid) { _logger.LogWarning( "[{RequestId}] Validation failed: {Errors}", requestId, validationResult.GetErrorMessage()); return BadRequest(new SendNotificationResponse { Success = false, Message = validationResult.GetErrorMessage() }); } var response = await _notificationService.SendNotificationAsync(request, cancellationToken); stopwatch.Stop(); if (response.Success) { _logger.LogInformation( "[{RequestId}] Notification queued successfully - NotificationId: {NotificationId}, Duration: {Duration}ms", requestId, response.NotificationId, stopwatch.ElapsedMilliseconds); } else { _logger.LogWarning( "[{RequestId}] Failed to queue notification - Error: {Error}, Duration: {Duration}ms", requestId, response.Message, stopwatch.ElapsedMilliseconds); } return Ok(response); } catch (Exception ex) { stopwatch.Stop(); _logger.LogError(ex, "[{RequestId}] Error sending notification - Type: {Type}, Duration: {Duration}ms", requestId, request?.Type, stopwatch.ElapsedMilliseconds); return StatusCode(500, new SendNotificationResponse { Success = false, Message = "Internal server error. Please try again later." }); } } /// <summary> /// Получить статус уведомления /// </summary> [HttpGet("{id}")] [ProducesResponseType(typeof(NotificationStatusResponse), StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status404NotFound)] public async Task<ActionResult<NotificationStatusResponse>> GetNotificationStatus( Guid id, CancellationToken cancellationToken) { try { if (id == Guid.Empty) { _logger.LogWarning("Invalid notification ID: empty GUID"); return BadRequest(new { Message = "Invalid notification ID" }); } _logger.LogDebug("Getting status for notification {Id}", id); var status = await _notificationService.GetNotificationStatusAsync(id, cancellationToken); if (status == null) { _logger.LogWarning("Notification {Id} not found", id); return NotFound(new { Message = $"Notification {id} not found" }); } _logger.LogDebug("Retrieved status for notification {Id}: {Status}", id, status.Status); return Ok(status); } catch (Exception ex) { _logger.LogError(ex, "Error getting notification status for {Id}", id); return StatusCode(500, new { Message = "Internal server error" }); } } /// <summary> /// Получить список уведомлений по статусу /// </summary> [HttpGet("status/{status}")] [ProducesResponseType(typeof(IEnumerable<NotificationStatusResponse>), StatusCodes.Status200OK)] public async Task<ActionResult<IEnumerable<NotificationStatusResponse>>> GetNotificationsByStatus( NotificationStatus status, CancellationToken cancellationToken) { try { _logger.LogDebug("Getting notifications with status {Status}", status); var notifications = await _notificationService.GetNotificationsByStatusAsync(status, cancellationToken); var notificationList = notifications.ToList(); _logger.LogInformation( "Retrieved {Count} notifications with status {Status}", notificationList.Count, status); return Ok(notificationList); } catch (Exception ex) { _logger.LogError(ex, "Error getting notifications by status {Status}", status); return StatusCode(500, new { Message = "Internal server error" }); } } /// <summary> /// Маскирует чувствительные данные для логирования /// </summary> private static string MaskSensitiveData(string data) { if (string.IsNullOrEmpty(data) || data.Length <= 4) return "****"; if (data.Contains('@')) { // Email: show first 2 chars and domain var parts = data.Split('@'); if (parts.Length == 2 && parts[0].Length > 2) { return $"{parts[0][..2]}***@{parts[1]}"; } } // Phone or other: show first 3 and last 2 chars if (data.Length > 5) { return $"{data[..3]}***{data[^2..]}"; } return "****"; } }