Files
trakqr/src/api/Features/QRCodes/Endpoints/PreviewQRCodeEndpoint.cs

68 lines
2.1 KiB
C#

using System.Security.Claims;
using System.Text.Json;
using api.Data;
using api.Features.Auth.Common;
using api.Features.QRCodes.Common;
using api.Features.QRCodes.Services;
using FastEndpoints;
using Microsoft.EntityFrameworkCore;
namespace api.Features.QRCodes.Endpoints;
public class PreviewQRCodeRequest
{
public Guid WorkspaceId { get; set; }
public Guid Id { get; set; }
public int? Size { get; set; }
}
public class PreviewQRCodeEndpoint(AppDbContext db, IQRCodeGeneratorService qrGenerator)
: Endpoint<PreviewQRCodeRequest, QRCodePreviewResponse>
{
public override void Configure()
{
Get("/workspaces/{WorkspaceId}/qrcodes/{Id}/preview");
}
public override async Task HandleAsync(PreviewQRCodeRequest req, CancellationToken ct)
{
var userId = Guid.Parse(User.FindFirstValue(ClaimTypes.NameIdentifier)!);
var qrCode = await db.QrCodeDesigns
.Include(q => q.ShortLink)
.Where(q => q.Id == req.Id && q.WorkspaceId == req.WorkspaceId && q.Workspace.OwnerUserId == userId)
.FirstOrDefaultAsync(ct);
if (qrCode is null)
{
await HttpContext.Response.SendAsync(new MessageResponse("QR code not found"), 404, cancellation: ct);
return;
}
if (qrCode.ShortLink is null)
{
await HttpContext.Response.SendAsync(new MessageResponse("QR code has no associated link"), 400, cancellation: ct);
return;
}
var style = JsonSerializer.Deserialize<QRCodeStyle>(qrCode.StyleJson) ?? new QRCodeStyle();
var size = req.Size ?? 256;
// Build the short link URL
// TODO: Use actual domain configuration
var baseUrl = $"{HttpContext.Request.Scheme}://{HttpContext.Request.Host}";
var linkUrl = $"{baseUrl}/{qrCode.ShortLink.Slug}";
var dataUrl = qrGenerator.GenerateDataUrl(linkUrl, style, size);
var response = new QRCodePreviewResponse(
DataUrl: dataUrl,
Format: "png",
Width: size,
Height: size
);
await HttpContext.Response.SendAsync(response, 200, cancellation: ct);
}
}