Files
jobtrackingapp/JobTrackerApi/Controllers/ApplicationWorkspaceController.cs
T
cesnimda e55a6e86b7
CI and Deploy / test (push) Failing after 1m13s
CI and Deploy / deploy (push) Has been skipped
feat(workspace): Application Workspace foundation (Phase 5 milestone 1)
Every JobApplication gets a dedicated workspace at /applications/{id} — a
surface, not a new data store. It owns no data and duplicates none: CV comes
from the Phase 4 CvVariant lens, analysis/match/interview from the existing
AiWorkspacePanel, documents from Attachments, communication from
Correspondence, activity from JobEvent, stage semantics from JobPipeline. No
career data is copied and nothing here writes.

- GET /api/jobapplications/{id}/workspace: one aggregate read (role, company,
  stage, dates, attached CV variant, cover letter, documents, AI history,
  recent activity) replacing the page fanning out across endpoints
- Next recommended action: ordered rules answering "what do I do next?", the
  core product principle for this phase
- ApplicationWorkspacePage: left nav + linkable ?section=, reusing the existing
  component for each domain; later-milestone sections say so rather than faking
- Entry point from the job dialog via an optional onOpenWorkspace callback —
  the dialog must not depend on router context (it is mounted without a
  <Router> in several suites), so the caller owns navigation
- 8 backend tests (aggregate, CV variant surfacing, counts, activity ordering,
  next-step rules, tenant scoping)

Local: 314 backend, 88/88 frontend (31 suites), tsc clean, production build ok.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-18 23:57:24 +02:00

35 lines
1.3 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 Milestone 1 — one aggregate read for the Application Workspace overview, so the page loads
// from a single call instead of fanning out. Read-only; owns no data.
// docs/architecture/application-workspace.md.
[ApiController]
[Route("api/jobapplications/{jobId:int}/workspace")]
[Authorize(AuthenticationSchemes = "local")]
public sealed class ApplicationWorkspaceController : ControllerBase
{
private readonly UserManager<ApplicationUser> _users;
private readonly IApplicationWorkspaceService _workspace;
public ApplicationWorkspaceController(UserManager<ApplicationUser> users, IApplicationWorkspaceService workspace)
{
_users = users;
_workspace = workspace;
}
[HttpGet]
public async Task<ActionResult<WorkspaceOverviewDto>> GetOverview(int jobId, CancellationToken ct)
{
var user = await _users.GetUserAsync(User);
if (user is null) return Unauthorized();
var overview = await _workspace.GetOverviewAsync(user.Id, jobId, ct);
return overview is null ? NotFound() : Ok(overview);
}
}