121 lines
4.6 KiB
C#
121 lines
4.6 KiB
C#
using Microsoft.AspNetCore.Mvc;
|
|
using QRRapidoApp.Data;
|
|
using QRRapidoApp.Models;
|
|
using System.Diagnostics;
|
|
using System.Security.Claims;
|
|
|
|
namespace QRRapidoApp.Controllers
|
|
{
|
|
/// <summary>
|
|
/// Controller for handling user ratings
|
|
/// </summary>
|
|
[Route("api/ratings")]
|
|
[ApiController]
|
|
public class RatingsController : ControllerBase
|
|
{
|
|
private readonly MongoDbContext _dbContext;
|
|
private readonly ILogger<RatingsController> _logger;
|
|
|
|
public RatingsController(MongoDbContext dbContext, ILogger<RatingsController> logger)
|
|
{
|
|
_dbContext = dbContext;
|
|
_logger = logger;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Submit a new rating
|
|
/// </summary>
|
|
[HttpPost]
|
|
public async Task<IActionResult> SubmitRating([FromBody] RatingSubmissionDto submission)
|
|
{
|
|
var stopwatch = Stopwatch.StartNew();
|
|
|
|
using (_logger.BeginScope(new Dictionary<string, object>
|
|
{
|
|
["Rating"] = submission.Rating,
|
|
["HasComment"] = !string.IsNullOrWhiteSpace(submission.Comment)
|
|
}))
|
|
{
|
|
_logger.LogInformation("Rating submission - Rating: {Rating}, HasName: {HasName}, HasEmail: {HasEmail}, HasComment: {HasComment}",
|
|
submission.Rating, !string.IsNullOrWhiteSpace(submission.Name), !string.IsNullOrWhiteSpace(submission.Email), !string.IsNullOrWhiteSpace(submission.Comment));
|
|
|
|
try
|
|
{
|
|
// Validate rating value
|
|
if (submission.Rating < 1 || submission.Rating > 5)
|
|
{
|
|
_logger.LogWarning("Invalid rating value - Rating: {Rating}", submission.Rating);
|
|
return BadRequest(new { error = "Rating must be between 1 and 5" });
|
|
}
|
|
|
|
// Check MongoDB connection
|
|
if (!_dbContext.IsConnected || _dbContext.Ratings == null)
|
|
{
|
|
_logger.LogError("MongoDB not connected or Ratings collection unavailable");
|
|
return StatusCode(503, new { error = "Database unavailable" });
|
|
}
|
|
|
|
// Get user ID if authenticated
|
|
var userId = User?.FindFirst(ClaimTypes.NameIdentifier)?.Value;
|
|
|
|
// Get culture from request
|
|
var culture = System.Globalization.CultureInfo.CurrentUICulture.Name;
|
|
|
|
// Get IP address
|
|
var ipAddress = HttpContext.Connection.RemoteIpAddress?.ToString();
|
|
|
|
// Create rating object
|
|
var rating = new Rating
|
|
{
|
|
RatingValue = submission.Rating,
|
|
Name = submission.Name,
|
|
Email = submission.Email,
|
|
Comment = submission.Comment,
|
|
Url = submission.Url ?? string.Empty,
|
|
UserAgent = submission.UserAgent ?? string.Empty,
|
|
UserId = userId,
|
|
CreatedAt = DateTime.UtcNow,
|
|
IpAddress = ipAddress,
|
|
Culture = culture
|
|
};
|
|
|
|
// Save to MongoDB
|
|
await _dbContext.Ratings.InsertOneAsync(rating);
|
|
|
|
stopwatch.Stop();
|
|
_logger.LogInformation("Rating saved successfully - RatingId: {RatingId}, Rating: {Rating}, UserId: {UserId}, ProcessingTime: {ProcessingTimeMs}ms",
|
|
rating.Id, rating.RatingValue, userId ?? "anonymous", stopwatch.ElapsedMilliseconds);
|
|
|
|
return Ok(new
|
|
{
|
|
success = true,
|
|
message = "Thank you for your feedback!",
|
|
ratingId = rating.Id
|
|
});
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
stopwatch.Stop();
|
|
_logger.LogError(ex, "Error saving rating - ProcessingTime: {ProcessingTimeMs}ms",
|
|
stopwatch.ElapsedMilliseconds);
|
|
|
|
return StatusCode(500, new { error = "Error saving rating" });
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// DTO for rating submission
|
|
/// </summary>
|
|
public class RatingSubmissionDto
|
|
{
|
|
public int Rating { get; set; }
|
|
public string? Name { get; set; }
|
|
public string? Email { get; set; }
|
|
public string? Comment { get; set; }
|
|
public string? Url { get; set; }
|
|
public string? UserAgent { get; set; }
|
|
}
|
|
}
|