using System.Net; using AutopilotMonitor.Functions.Helpers; using AutopilotMonitor.Functions.Services; using Microsoft.Azure.Functions.Worker; using Microsoft.Azure.Functions.Worker.Http; using Microsoft.Extensions.Logging; using Newtonsoft.Json; using Newtonsoft.Json.Linq; namespace AutopilotMonitor.Functions.Functions { /// /// Allows Galactic Admins to add or update an admin note on a submitted session report. /// public class UpdateSessionReportNoteFunction { private readonly ILogger _logger; private readonly SessionReportService _sessionReportService; private readonly GalacticAdminService _galacticAdminService; public UpdateSessionReportNoteFunction( ILogger logger, SessionReportService sessionReportService, GalacticAdminService galacticAdminService) { _logger = logger; _sessionReportService = sessionReportService; _galacticAdminService = galacticAdminService; } [Function("UpdateSessionReportNote")] public async Task Run( [HttpTrigger(AuthorizationLevel.Anonymous, "patch", Route = "galactic/session-reports/{reportId}/note")] HttpRequestData req, string reportId) { try { if (!TenantHelper.IsAuthenticated(req)) { var unauthorizedResponse = req.CreateResponse(HttpStatusCode.Unauthorized); await unauthorizedResponse.WriteAsJsonAsync(new { success = false, message = "Authentication required." }); return unauthorizedResponse; } var userIdentifier = TenantHelper.GetUserIdentifier(req); var isGalacticAdmin = await _galacticAdminService.IsGalacticAdminAsync(userIdentifier); if (!isGalacticAdmin) { var forbiddenResponse = req.CreateResponse(HttpStatusCode.Forbidden); await forbiddenResponse.WriteAsJsonAsync(new { success = false, message = "Access denied. Galactic Admin role required." }); return forbiddenResponse; } if (string.IsNullOrEmpty(reportId)) { var badRequest = req.CreateResponse(HttpStatusCode.BadRequest); await badRequest.WriteAsJsonAsync(new { success = false, message = "reportId is required." }); return badRequest; } string body = await req.ReadAsStringAsync() ?? string.Empty; JObject json; try { json = JObject.Parse(body); } catch (JsonException) { var badRequest = req.CreateResponse(HttpStatusCode.BadRequest); await badRequest.WriteAsJsonAsync(new { success = false, message = "Invalid JSON body." }); return badRequest; } var adminNote = json["adminNote"]?.ToString() ?? string.Empty; var updated = await _sessionReportService.UpdateAdminNoteAsync(reportId, adminNote); if (!updated) { var notFoundResponse = req.CreateResponse(HttpStatusCode.NotFound); await notFoundResponse.WriteAsJsonAsync(new { success = false, message = "Report not found." }); return notFoundResponse; } _logger.LogInformation("Admin note updated for report {ReportId} by {User}", reportId, userIdentifier); var response = req.CreateResponse(HttpStatusCode.OK); await response.WriteAsJsonAsync(new { success = true }); return response; } catch (Exception ex) { _logger.LogError(ex, "Error updating admin note for report {ReportId}", reportId); var errorResponse = req.CreateResponse(HttpStatusCode.InternalServerError); await errorResponse.WriteAsJsonAsync(new { success = false, message = "Internal server error." }); return errorResponse; } } } }