fix(work-orders): align stacked services with CI build

This commit is contained in:
Arthur Bassi 2026-07-17 13:38:57 -03:00
parent 933948c53e
commit 5f5fd6445d
2 changed files with 66 additions and 5 deletions

View file

@ -1,4 +1,4 @@
using Data.SeaHavenIndustries;
using Data.SeaHavenIndustries;
using SeaHaven.DataServices.Interfaces;
using SeaHaven.Services.DTOs;
using SeaHaven.Services.Exceptions;
@ -11,13 +11,16 @@ namespace SeaHaven.Services.Implementation
{
private readonly IWorkOrderDetailDataService _detailData;
private readonly ICommentDataService _commentData;
private readonly IUserDataService _userDataService;
public WorkOrderCommentService(
IWorkOrderDetailDataService detailData,
ICommentDataService commentData)
ICommentDataService commentData,
IUserDataService userDataService)
{
_detailData = detailData;
_commentData = commentData;
_userDataService = userDataService;
}
public async Task<IReadOnlyList<WorkOrderCommentDto>?> GetCommentsAsync(int workOrderId)
@ -26,7 +29,8 @@ namespace SeaHaven.Services.Implementation
return null;
var comments = await _detailData.GetCommentsAsync(workOrderId);
return WorkOrderCommentProjection.ToDtos(comments);
var authorNames = await ResolveAuthorNamesAsync(comments);
return WorkOrderCommentProjection.ToDtos(comments, authorNames);
}
public async Task<WorkOrderCommentDto> AddCommentAsync(
@ -53,7 +57,58 @@ namespace SeaHaven.Services.Implementation
};
var saved = await _commentData.AddAsync(comment);
return WorkOrderCommentProjection.ToDto(saved);
var authorNames = await ResolveAuthorNamesAsync(new[] { saved });
return WorkOrderCommentProjection.ToDto(saved, authorNames);
}
public async Task<WorkOrderCommentDto> UpdateCommentAsync(
int workOrderId,
int commentId,
WorkOrderCommentCreateDto request,
string? actorId,
bool isAdmin)
{
var workOrder = await _detailData.GetWorkOrderForMediaAsync(workOrderId);
if (workOrder == null)
throw new WorkOrderBoardValidationException("NotFound", "Work order not found.");
if (WorkOrderBoardMutationRules.IsReadOnly(workOrder.LifecycleStatus))
throw new WorkOrderBoardValidationException("ReadOnly", "Work order is read-only in its current status.");
if (string.IsNullOrWhiteSpace(request.Text))
throw new WorkOrderBoardValidationException("InvalidValue", "Comment text is required.");
var comment = await _commentData.GetByIdAsync(commentId);
if (comment == null || comment.WorkerOrderId != workOrderId || comment.IsDeleted == true)
throw new WorkOrderBoardValidationException("NotFound", "Comment not found.");
if (!IsBoardEditableComment(comment))
throw new WorkOrderBoardValidationException(
"NotEditable",
"Only board comments (CommentType General) can be edited via this endpoint.");
var isAuthor = !string.IsNullOrWhiteSpace(actorId)
&& string.Equals(comment.UserId, actorId, StringComparison.Ordinal);
if (!isAuthor && !isAdmin)
throw new WorkOrderBoardValidationException("Forbidden", "You are not allowed to edit this comment.");
comment.Commenttext = request.Text.Trim();
comment.LastModificationTime = DateTime.UtcNow;
await _commentData.UpdateAsync(comment);
var authorNames = await ResolveAuthorNamesAsync(new[] { comment });
return WorkOrderCommentProjection.ToDto(comment, authorNames);
}
private static bool IsBoardEditableComment(Comments comment)
=> string.Equals(comment.CommentType, "General", StringComparison.OrdinalIgnoreCase)
&& string.Equals(comment.RecordType, "WorkOrder", StringComparison.OrdinalIgnoreCase);
private async Task<IReadOnlyDictionary<string, string>> ResolveAuthorNamesAsync(
IEnumerable<Comments> comments)
{
var authorIds = WorkOrderCommentProjection.CollectAuthorUserIds(comments);
return await _userDataService.GetDisplayNamesByIdsAsync(authorIds);
}
}
}

View file

@ -1,4 +1,4 @@
using Data.SeaHavenIndustries.Enums;
using Data.SeaHavenIndustries.Enums;
using SeaHaven.Services.DTOs;
namespace SeaHaven.Services.Interfaces
@ -7,5 +7,11 @@ namespace SeaHaven.Services.Interfaces
{
Task<IReadOnlyList<WorkOrderCommentDto>?> GetCommentsAsync(int workOrderId);
Task<WorkOrderCommentDto> AddCommentAsync(int workOrderId, WorkOrderCommentCreateDto request, string? actorId, string? documentUrl = null);
Task<WorkOrderCommentDto> UpdateCommentAsync(
int workOrderId,
int commentId,
WorkOrderCommentCreateDto request,
string? actorId,
bool isAdmin);
}
}