Files
Extrudex/backend/API/Controllers/QrController.cs

101 lines
3.8 KiB
C#
Raw Normal View History

2026-04-25 18:51:05 +00:00
using Extrudex.Domain.Enums;
using Extrudex.Domain.Interfaces;
using Microsoft.AspNetCore.Mvc;
namespace Extrudex.API.Controllers;
/// <summary>
/// Controller for generating QR codes for Extrudex resources (spools, printers, locations).
/// Returns QR codes as PNG or SVG images optimized for small label printing.
/// QR codes encode deep links that resolve to the resource's detail page.
/// </summary>
[ApiController]
[Route("api/qr")]
public class QrController : ControllerBase
{
private readonly IQrCodeService _qrCodeService;
private readonly ILogger<QrController> _logger;
/// <summary>
/// Initializes a new instance of the <see cref="QrController"/> class.
/// </summary>
/// <param name="qrCodeService">The QR code generation service.</param>
/// <param name="logger">The logger for diagnostic output.</param>
public QrController(IQrCodeService qrCodeService, ILogger<QrController> logger)
{
_qrCodeService = qrCodeService;
_logger = logger;
}
/// <summary>
/// Generates a QR code for the specified resource type and ID.
/// Returns the QR code as a PNG image by default, or as SVG when
/// the <c>format</c> query parameter is set to "svg".
/// </summary>
/// <param name="resourceType">
/// The type of resource: <c>spool</c>, <c>printer</c>, or <c>location</c>.
/// </param>
/// <param name="id">The unique identifier of the resource.</param>
/// <param name="format">
/// Optional output format: <c>png</c> (default) or <c>svg</c>.
/// SVG is resolution-independent and ideal for printing at any scale.
/// </param>
/// <param name="size">
/// Optional pixel density per QR module for PNG output (default: 20).
/// Ignored for SVG output. Range: 440.
/// </param>
/// <returns>The QR code image in the requested format.</returns>
/// <response code="200">Returns the QR code image.</response>
/// <response code="400">If the resource type is invalid or parameters are out of range.</response>
[HttpGet("{resourceType}/{id:guid}")]
[ProducesResponseType(typeof(FileContentResult), StatusCodes.Status200OK, "image/png")]
[ProducesResponseType(typeof(FileContentResult), StatusCodes.Status200OK, "image/svg+xml")]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
public IActionResult GetQrCode(
string resourceType,
Guid id,
[FromQuery] string format = "png",
[FromQuery] int size = 20)
{
_logger.LogDebug("Generating QR code: resourceType={ResourceType}, id={Id}, format={Format}, size={Size}",
resourceType, id, format, size);
// Parse resource type
if (!Enum.TryParse<QrResourceType>(resourceType, ignoreCase: true, out var parsedType))
{
return BadRequest(new
{
error = $"Invalid resource type: '{resourceType}'. " +
$"Valid values are: spool, printer, location."
});
}
// Validate format
format = format.ToLowerInvariant();
if (format is not ("png" or "svg"))
{
return BadRequest(new
{
error = $"Invalid format: '{format}'. Valid values are: png, svg."
});
}
// Validate size for PNG
if (format == "png" && (size < 4 || size > 40))
{
return BadRequest(new
{
error = $"Size must be between 4 and 40. Received: {size}."
});
}
if (format == "svg")
{
var svg = _qrCodeService.GenerateSvg(parsedType, id);
return Content(svg, "image/svg+xml");
}
var pngBytes = _qrCodeService.GeneratePng(parsedType, id, size);
return File(pngBytes, "image/png");
}
}