6293fa89e3
Build and Push Docker Images / build (push) Failing after 1m36s
- New cv-search-models shared library: EF entities + CvSearchDbContext for cvSearch schema (JobSearchTokens, JobSearchSessions, JobSearchResults tables) - New cv-search-job worker service: polls DB for pending sessions, scrapes job boards via configurable HTML scraping, runs LLM scoring via cv-matcher-api, emails ranked results - cv-matcher-api: JobTokenService creates one-time tokens; JobSearchController handles link clicks and creates sessions - api: proxies job-search start endpoint, appends job search link to match result email - CI workflow updated to build and push myai-cv-search-job:staging image - CLAUDE.md documentation added for all affected services Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
57 lines
2.1 KiB
C#
57 lines
2.1 KiB
C#
using Api.Services.Contracts;
|
|
using CvMatcher.Models.Requests;
|
|
using CvMatcher.Models.Responses;
|
|
using Microsoft.AspNetCore.Mvc;
|
|
using Shared.Models.Responses;
|
|
|
|
namespace Api.Controllers;
|
|
|
|
[ApiController]
|
|
[Route("api/cv/job-search")]
|
|
public sealed class JobSearchController : ControllerBase
|
|
{
|
|
private readonly IJobTokenService _tokenService;
|
|
private readonly ILogger<JobSearchController> _logger;
|
|
|
|
public JobSearchController(IJobTokenService tokenService, ILogger<JobSearchController> logger)
|
|
{
|
|
_tokenService = tokenService;
|
|
_logger = logger;
|
|
}
|
|
|
|
[HttpPost("token")]
|
|
public async Task<ActionResult<CreateJobSearchTokenResponse>> CreateToken(
|
|
[FromBody] CreateJobSearchTokenRequest request,
|
|
CancellationToken ct)
|
|
{
|
|
try
|
|
{
|
|
if (string.IsNullOrWhiteSpace(request.CvDocumentId) || string.IsNullOrWhiteSpace(request.Email))
|
|
return BadRequest(new ErrorResponse { Error = "CvDocumentId and Email are required.", Code = "invalid_request" });
|
|
|
|
var tokenId = await _tokenService.CreateTokenAsync(request.CvDocumentId, request.Email, ct);
|
|
return Ok(new CreateJobSearchTokenResponse { TokenId = tokenId });
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_logger.LogError(ex, "Failed to create job search token.");
|
|
return StatusCode(StatusCodes.Status500InternalServerError, new ErrorResponse { Error = "Failed to create token.", Code = "token_create_failed" });
|
|
}
|
|
}
|
|
|
|
[HttpPost("token/{tokenId}/start")]
|
|
public async Task<ActionResult<StartJobSearchResponse>> Start(string tokenId, CancellationToken ct)
|
|
{
|
|
try
|
|
{
|
|
var status = await _tokenService.TriggerStartAsync(tokenId, ct);
|
|
return Ok(new StartJobSearchResponse { Status = status });
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_logger.LogError(ex, "Failed to start job search for token {TokenId}.", tokenId);
|
|
return StatusCode(StatusCodes.Status500InternalServerError, new ErrorResponse { Error = "Failed to start search.", Code = "start_failed" });
|
|
}
|
|
}
|
|
}
|