Files
myAi/Apis/cv-matcher-api/Controllers/JobSearchController.cs
T
claude 6293fa89e3
Build and Push Docker Images / build (push) Failing after 1m36s
Add internet job search feature (cv-search-job)
- 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>
2026-05-22 17:56:23 +03:00

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" });
}
}
}