using Microsoft.Data.SqlClient; using Microsoft.EntityFrameworkCore; using ZB.MOM.WW.OtOpcUa.Configuration; using ZB.MOM.WW.OtOpcUa.Configuration.Entities; namespace ZB.MOM.WW.OtOpcUa.Admin.Services; /// /// Fleet-wide external-ID reservation inspector + FleetAdmin-only release flow per /// admin-ui.md ยง"Release an external-ID reservation". Release is audit-logged /// () via sp_ReleaseExternalIdReservation. /// public sealed class ReservationService(OtOpcUaConfigDbContext db) { public Task> ListActiveAsync(CancellationToken ct) => db.ExternalIdReservations.AsNoTracking() .Where(r => r.ReleasedAt == null) .OrderBy(r => r.Kind).ThenBy(r => r.Value) .ToListAsync(ct); public Task> ListReleasedAsync(CancellationToken ct) => db.ExternalIdReservations.AsNoTracking() .Where(r => r.ReleasedAt != null) .OrderByDescending(r => r.ReleasedAt) .Take(100) .ToListAsync(ct); public async Task ReleaseAsync(string kind, string value, string reason, CancellationToken ct) { if (string.IsNullOrWhiteSpace(reason)) throw new ArgumentException("ReleaseReason is required (audit invariant)", nameof(reason)); await db.Database.ExecuteSqlRawAsync( "EXEC dbo.sp_ReleaseExternalIdReservation @Kind = {0}, @Value = {1}, @ReleaseReason = {2}", [kind, value, reason], ct); } }