Files
jobtrackingapp/JobTrackerApi/Controllers/ApplicationIntelligenceController.cs
T

64 lines
2.5 KiB
C#

using JobTrackerApi.Models;
using JobTrackerApi.Services;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
namespace JobTrackerApi.Controllers;
// Phase 5.3 — Application Intelligence. Three read-only endpoints on the application:
// timeline (interprets JobEvent), analysis (reads the advert), match (reads the master profile).
//
// None of them write anything. The AI narrative for analysis and match stays on the existing
// /api/jobapplications/{id}/ai routes, which are suggestion-only and versioned by AiInteraction.
// docs/architecture/overview.md.
[ApiController]
[Route("api/jobapplications/{jobId:int}")]
[Authorize(AuthenticationSchemes = "local")]
public sealed class ApplicationIntelligenceController : ControllerBase
{
private readonly UserManager<ApplicationUser> _users;
private readonly IApplicationTimelineService _timeline;
private readonly IApplicationIntelligenceService _intelligence;
public ApplicationIntelligenceController(
UserManager<ApplicationUser> users,
IApplicationTimelineService timeline,
IApplicationIntelligenceService intelligence)
{
_users = users;
_timeline = timeline;
_intelligence = intelligence;
}
[HttpGet("timeline")]
public async Task<ActionResult<TimelineDto>> GetTimeline(
int jobId, [FromQuery] string? category, [FromQuery] bool milestonesOnly, CancellationToken ct)
{
var userId = await CurrentUserIdAsync();
if (userId is null) return Unauthorized();
var result = await _timeline.GetAsync(userId, jobId, category, milestonesOnly, ct);
return result is null ? NotFound() : Ok(result);
}
[HttpGet("analysis")]
public async Task<ActionResult<JobAnalysisDto>> GetAnalysis(int jobId, CancellationToken ct)
{
var userId = await CurrentUserIdAsync();
if (userId is null) return Unauthorized();
var result = await _intelligence.AnalyzeAsync(userId, jobId, ct);
return result is null ? NotFound() : Ok(result);
}
[HttpGet("match")]
public async Task<ActionResult<CareerMatchDto>> GetMatch(int jobId, CancellationToken ct)
{
var userId = await CurrentUserIdAsync();
if (userId is null) return Unauthorized();
var result = await _intelligence.MatchAsync(userId, jobId, ct);
return result is null ? NotFound() : Ok(result);
}
private async Task<string?> CurrentUserIdAsync() => (await _users.GetUserAsync(User))?.Id;
}