feat: dev-only OpenAPI document at /openapi/v1.json

- AddOpenApi/MapOpenApi (anonymous, Development environment only).
- security: mark ProfileCvController.ProcessQueuedRunAsync [NonAction] -
  the controller-level [Route] exposed this background-service hook as a
  routable any-verb endpoint, which also broke OpenAPI generation.

96 endpoint paths documented.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
cesnimda
2026-07-02 22:00:27 +02:00
parent c41d1e8d0f
commit 8f174cb767
3 changed files with 12 additions and 0 deletions
@@ -883,6 +883,10 @@ public sealed class ProfileCvController : ControllerBase
return run;
}
// Invoked by CvProcessingHostedService (this controller is also registered as a
// transient service). NonAction keeps it off the HTTP surface: without it the
// controller-level [Route] exposes it as an any-verb endpoint.
[NonAction]
public async Task ProcessQueuedRunAsync(int runId, CancellationToken cancellationToken)
{
var run = await _db.CvExtractionRuns.FirstOrDefaultAsync(x => x.Id == runId, cancellationToken);
+1
View File
@@ -11,6 +11,7 @@
<Compile Remove="Controllers\**\*.cs" />
<Compile Remove="Services\**\*.cs" />
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="9.0.14" />
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="9.0.14" />
<PackageReference Include="Pomelo.EntityFrameworkCore.MySql" Version="9.0.0" />
</ItemGroup>
+7
View File
@@ -112,6 +112,7 @@ builder.Services.AddCors(options =>
// Add controllers
builder.Services.AddControllers();
builder.Services.AddOpenApi();
var dataRoot = (builder.Configuration["Data:Root"] ?? "").Trim();
if (string.IsNullOrWhiteSpace(dataRoot))
{
@@ -441,4 +442,10 @@ app.UseAuthentication();
app.UseAuthorization();
app.MapControllers();
// API schema for tooling/docs. Dev-only: not exposed in production deployments.
if (app.Environment.IsDevelopment())
{
app.MapOpenApi().AllowAnonymous();
}
app.Run();