mirror of
https://github.com/okieselbach/AutopilotMonitor.git
synced 2026-10-25 13:10:13 +00:00
9fd343d328
Six functions wrote their responses through a private wrapper taking the body as object, which no typed-response guard could see. Their error bodies carried the code in the error slot, no correlation id, and RestoreRow returned the raw exception text on a 500. - Backup job status, row restore and backup trigger answer through ResponseHelper: errors are the envelope, the 500 is sanitized, the 202 body is BackupTriggerResponse. - Same for the session-deletion maintenance trigger, RestoreSession's three error sites and the delegation acknowledgements (MessageResponse). - Backup codes are constants (Constants.BackupErrorCodes) and part of apiErrorCodes; RunAlreadyActive and EnqueueFailed join ApiErrorCodes. - TypedResponseGuardTests gains guard F: no HttpResponseData-returning method with an object parameter. BackupWireParityTests pins that the move from the backup serializer options to the worker pipeline leaves the wire unchanged. - Web reads BackupTriggerResponse from the generated wire types. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
45 lines
1.8 KiB
C#
45 lines
1.8 KiB
C#
using System.Threading.Tasks;
|
|
using AutopilotMonitor.Functions.DataAccess.TableStorage;
|
|
using AutopilotMonitor.Functions.Helpers;
|
|
using AutopilotMonitor.Shared;
|
|
using AutopilotMonitor.Shared.Models.Backup;
|
|
using Microsoft.Azure.Functions.Worker;
|
|
using Microsoft.Azure.Functions.Worker.Http;
|
|
using Microsoft.Extensions.Logging;
|
|
|
|
namespace AutopilotMonitor.Functions.Functions.Backup
|
|
{
|
|
/// <summary>
|
|
/// <c>GET /api/global/backups/jobs/{jobId}</c> — polling endpoint for the
|
|
/// 202-Accepted async backup workflow. GA-only via <c>EndpointAccessPolicyCatalog</c>.
|
|
/// Returns the live <see cref="BackupJobStatus"/> DTO including
|
|
/// <c>backupOutcome</c> (Success / Partial) and <c>lastHeartbeatUtc</c> so the
|
|
/// UI can render Completed / Partial / Failed banners and the operator can spot
|
|
/// stalled jobs at a glance.
|
|
/// </summary>
|
|
public class GetBackupJobStatusFunction
|
|
{
|
|
private readonly BackupJobsRepository _jobs;
|
|
private readonly ILogger<GetBackupJobStatusFunction> _logger;
|
|
|
|
public GetBackupJobStatusFunction(BackupJobsRepository jobs, ILogger<GetBackupJobStatusFunction> logger)
|
|
{
|
|
_jobs = jobs;
|
|
_logger = logger;
|
|
}
|
|
|
|
[Function("GetBackupJobStatus")]
|
|
public async Task<HttpResponseData> Run(
|
|
[HttpTrigger(AuthorizationLevel.Anonymous, "get", Route = "global/backups/jobs/{jobId}")] HttpRequestData req,
|
|
string jobId)
|
|
{
|
|
var (job, _) = await _jobs.GetWithETagAsync(jobId, req.FunctionContext.CancellationToken);
|
|
if (job is null)
|
|
{
|
|
return await req.NotFoundAsync($"Backup job {jobId} not found.", Constants.BackupErrorCodes.JobNotFound);
|
|
}
|
|
return await req.OkAsync(job);
|
|
}
|
|
}
|
|
}
|