using Extrudex.Domain.Enums; using Extrudex.Domain.Interfaces; using Microsoft.AspNetCore.Mvc; namespace Extrudex.API.Controllers; /// /// 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. /// [ApiController] [Route("api/qr")] public class QrController : ControllerBase { private readonly IQrCodeService _qrCodeService; private readonly ILogger _logger; /// /// Initializes a new instance of the class. /// /// The QR code generation service. /// The logger for diagnostic output. public QrController(IQrCodeService qrCodeService, ILogger logger) { _qrCodeService = qrCodeService; _logger = logger; } /// /// 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 format query parameter is set to "svg". /// /// /// The type of resource: spool, printer, or location. /// /// The unique identifier of the resource. /// /// Optional output format: png (default) or svg. /// SVG is resolution-independent and ideal for printing at any scale. /// /// /// Optional pixel density per QR module for PNG output (default: 20). /// Ignored for SVG output. Range: 4–40. /// /// The QR code image in the requested format. /// Returns the QR code image. /// If the resource type is invalid or parameters are out of range. [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(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"); } }