shoc-backend/SeaHaven.Services/Helpers/WorkOrderCommentProjection.cs
Arthur Bassi f4985378fc
feat(work-orders): add structured service notes POC and vendor fields (#21)
* fix(migrations): make Phase6 completion slide-over migration idempotent

Use IF EXISTS / IF COL_LENGTH guards and explicit EF migration metadata
so partial environments can apply Phase 6 safely.

* feat(locations): add sites options endpoint and vendor contactName

Expose GET /api/locations/sites for the WO create wizard and include
vendor contactName on dropdown responses.

* feat(work-orders): add structured service notes POC and vendor fields

Persist primary/extra services, service notes, free-text POC, and
tech/vendor notes on create/patch/board/detail instead of embedding
them in description.

* fix(work-orders): make stacked tip build for CI quality gates

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

* fix(work-orders): keep FlagColor out of structured-notes slice

Remove FlagColor model/API/tests from this PR so schema and EF model stay aligned with the structured-fields migration. FlagColor remains in the follow-on PR that adds its migration.

---------

Co-authored-by: Arthur Bassi <arthur.winiarski.ranger@outlook.com>
2026-07-22 17:36:46 -03:00

52 lines
1.8 KiB
C#

using Data.SeaHavenIndustries;
using SeaHaven.Services.DTOs;
namespace SeaHaven.Services.Helpers
{
public static class WorkOrderCommentProjection
{
public static WorkOrderCommentDto ToDto(
Comments comment,
IReadOnlyDictionary<string, string>? displayNames = null)
{
return new WorkOrderCommentDto
{
Id = comment.Id,
AuthorId = comment.UserId,
AuthorName = ResolveAuthorName(comment, displayNames),
Text = comment.Commenttext ?? "",
Time = (comment.CreatedDate ?? DateTime.UtcNow).ToUniversalTime().ToString("o"),
Documents = comment.Documents
};
}
public static List<WorkOrderCommentDto> ToDtos(
IEnumerable<Comments> comments,
IReadOnlyDictionary<string, string>? displayNames = null)
=> comments.Select(c => ToDto(c, displayNames)).ToList();
public static IEnumerable<string> CollectAuthorUserIds(IEnumerable<Comments> comments)
=> comments
.Where(c => !string.IsNullOrWhiteSpace(c.UserId))
.Select(c => c.UserId!)
.Distinct(StringComparer.Ordinal);
private static string? ResolveAuthorName(
Comments comment,
IReadOnlyDictionary<string, string>? displayNames)
{
if (!string.IsNullOrWhiteSpace(comment.UserId)
&& displayNames != null
&& displayNames.TryGetValue(comment.UserId, out var name)
&& !string.IsNullOrWhiteSpace(name))
{
return name;
}
if (!string.IsNullOrWhiteSpace(comment.Commenter))
return comment.Commenter.Trim();
return null;
}
}
}