64 lines
2.5 KiB
C#
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;
|
|
}
|