Files
jobtrackingapp/JobTrackerApi/Controllers/PublicCvController.cs
T
cesnimda 4cf26405f6
CI and Deploy / test (push) Failing after 1m6s
CI and Deploy / deploy (push) Has been skipped
feat: complete phase 3 career workspace
2026-07-30 22:19:13 +02:00

50 lines
1.9 KiB
C#

using JobTrackerApi.Models;
using JobTrackerApi.Services;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
namespace JobTrackerApi.Controllers;
// Anonymous read-only surface for public CVs: /cv/{slug} in the SPA fetches this. Only variants the
// owner has explicitly toggled public are served; noindex by default. docs/architecture/cv-builder.md.
[ApiController]
[Route("api/public-cv")]
[AllowAnonymous]
public sealed class PublicCvController : ControllerBase
{
private readonly UserManager<ApplicationUser> _users;
private readonly ICvVariantService _variants;
public PublicCvController(UserManager<ApplicationUser> users, ICvVariantService variants)
{
_users = users;
_variants = variants;
}
[HttpGet("{slug}")]
public async Task<IActionResult> Get(string slug, CancellationToken ct)
{
var ownerId = await _variants.GetPublicOwnerAsync(slug, ct);
if (ownerId is null) return NotFound();
var owner = await _users.FindByIdAsync(ownerId);
var person = Person(owner);
var result = await _variants.RenderPublicAsync(slug, person, ct);
if (result is null) return NotFound();
Response.Headers["X-Robots-Tag"] = "noindex, nofollow";
return Ok(new { html = result.Value.render.Html, name = person.FallbackName });
}
private static CvRenderPerson Person(ApplicationUser? user)
{
if (user is null) return new CvRenderPerson("Candidate", null);
var name = string.Join(" ", new[] { user.FirstName?.Trim(), user.LastName?.Trim() }.Where(x => !string.IsNullOrWhiteSpace(x)));
if (string.IsNullOrWhiteSpace(name)) name = user.DisplayName?.Trim();
if (string.IsNullOrWhiteSpace(name)) name = user.UserName?.Trim();
if (string.IsNullOrWhiteSpace(name)) name = "Candidate";
return new CvRenderPerson(name!, AvatarStorage.Resolve(user.AvatarImageDataUrl));
}
}