mirror of
https://github.com/Sea-Haven-Industries/shoc-backend.git
synced 2026-09-30 18:53:12 +00:00
* 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>
59 lines
1.8 KiB
C#
59 lines
1.8 KiB
C#
using Data.SeaHavenIndustries;
|
|
using Microsoft.EntityFrameworkCore;
|
|
using SeaHaven.DataServices.Interfaces;
|
|
|
|
namespace SeaHaven.DataServices.Implementation
|
|
{
|
|
public class UserDataService : IUserDataService
|
|
{
|
|
private readonly ApplicationDbContext _context;
|
|
|
|
public UserDataService(ApplicationDbContext context)
|
|
{
|
|
_context = context;
|
|
}
|
|
|
|
public async Task<ApplicationUser?> GetByIdAsync(string id)
|
|
{
|
|
return await _context.Users.FindAsync(id);
|
|
}
|
|
|
|
public async Task<IEnumerable<ApplicationUser>> GetAllAsync()
|
|
{
|
|
return await _context.Users.ToListAsync();
|
|
}
|
|
|
|
public async Task<ApplicationUser?> GetByEmailAsync(string email)
|
|
{
|
|
return await _context.Users
|
|
.FirstOrDefaultAsync(u => u.Email == email);
|
|
}
|
|
|
|
public async Task<bool> ExistsAsync(string id)
|
|
{
|
|
return await _context.Users.AnyAsync(u => u.Id == id);
|
|
}
|
|
|
|
public async Task<IReadOnlyDictionary<string, string>> GetDisplayNamesByIdsAsync(IEnumerable<string> ids)
|
|
{
|
|
var idList = ids
|
|
.Where(id => !string.IsNullOrWhiteSpace(id))
|
|
.Distinct(StringComparer.Ordinal)
|
|
.ToList();
|
|
|
|
if (idList.Count == 0)
|
|
return new Dictionary<string, string>(StringComparer.Ordinal);
|
|
|
|
var users = await _context.Users
|
|
.AsNoTracking()
|
|
.Where(u => idList.Contains(u.Id))
|
|
.Select(u => new { u.Id, u.FirstName, u.LastName })
|
|
.ToListAsync();
|
|
|
|
return users.ToDictionary(
|
|
u => u.Id,
|
|
u => $"{u.FirstName ?? ""} {u.LastName ?? ""}".Trim(),
|
|
StringComparer.Ordinal);
|
|
}
|
|
}
|
|
}
|