using Data.SeaHavenIndustries; namespace SeaHaven.DataServices.Interfaces { public record SiteOptionRow(int Id, string? Code, string? City, string? State); public interface ILocationDataService { Task GetByIdAsync(int id); Task GetByIdWithDetailsAsync(int id); Task> GetAllAsync(); Task> GetByAccountIdAsync(int accountId); // Paged results returning DTOs Task<(IEnumerable Items, int TotalCount)> GetPagedAsync(int page, int pageSize, string? search = null); // For addressbook endpoint - returns simplified DTO Task<(IEnumerable Items, int TotalCount)> GetAddressbookPagedAsync(int page, int pageSize, string? search = null); Task> GetSiteOptionsAsync( string? search = null, CancellationToken cancellationToken = default); /// /// Exists is false when the row is missing. AccountId is null when the site has no account. /// Task<(bool Exists, int? AccountId)> GetAccountScopeAsync( int locationId, CancellationToken cancellationToken = default); Task AddAsync(Locations location); Task UpdateAsync(Locations location); Task DeleteAsync(int id); Task ExistsAsync(int id); Task CountAsync(); /// /// Sort keys are validated upstream; unknown or null keys fall back to the legacy code order. /// Sort options trail the token so existing call sites stay source-compatible. /// Task<(List Items, int TotalCount)> GetListPagedAsync(int page, int pageSize, string? search, IReadOnlyCollection? states, CancellationToken cancellationToken, string? sortBy = null, string? sortDirection = null); Task GetDetailByIdAsync(int id, CancellationToken cancellationToken); Task GetByIdForUpdateAsync(int id, CancellationToken cancellationToken); /// /// SH-138: single bounded read of active site contacts for a page of locations, /// ordered by SiteContactOrder then Id. Deleted contacts are excluded. /// Task> GetSiteContactsByLocationIdsAsync( IReadOnlyCollection locationIds, CancellationToken cancellationToken); Task AddAsync(Locations location, CancellationToken cancellationToken); Task UpdateAsync(Locations location, CancellationToken cancellationToken); /// /// True when a live (not deleted) site of the same account already uses /// , compared trimmed and case-insensitively. /// A null account matches only other sites without an account. /// Task SiteCodeExistsAsync( string siteCode, int? accountId, int? excludeLocationId, CancellationToken cancellationToken); /// /// Open (not Completed or Canceled, legacy status aware) and not deleted work /// orders that reference the site by id, or by site code when they carry no /// location id and no other account. /// narrows to one account. Returns the full count and at most /// ids, ascending. /// Task<(int Count, IReadOnlyList Ids)> GetOpenWorkOrderIdsAsync( int locationId, string? siteCode, int? siteAccountId, int? callerAccountId, int maxIds, CancellationToken cancellationToken); } }