diff --git a/docs/Reservations.md b/docs/Reservations.md index d835e50b..0b48980b 100644 --- a/docs/Reservations.md +++ b/docs/Reservations.md @@ -52,7 +52,7 @@ is refreshed, and they are eventually *released* — but never silently deleted. | `ClusterId` | The first cluster to publish the reservation. | | `FirstPublishedAt` / `FirstPublishedBy` | When and by whom the claim was first made. | | `LastPublishedAt` | Refreshed on every subsequent publish that re-asserts the same `(Kind, Value, EquipmentUuid)`. | -| `ReleasedAt` / `ReleasedBy` / `ReleaseReason` | Non-null once a FleetAdmin explicitly releases the claim. A row with `ReleasedAt IS NULL` is *active*. | +| `ReleasedAt` / `ReleasedBy` / `ReleaseReason` | Non-null once an Administrator explicitly releases the claim. `ReleasedBy` is the LDAP operator name (passed explicitly as `@ReleasedBy`; not `SUSER_SNAME()`). A row with `ReleasedAt IS NULL` is *active*. | There is no foreign key from `EquipmentUuid` / `ClusterId` to their tables — by design, so a reservation survives the deletion or disabling of the equipment @@ -99,14 +99,16 @@ being disabled, the generation being superseded, or a rollback. ### 4. Release -Reusing an identifier for a **different** piece of equipment requires a -FleetAdmin to explicitly release the existing claim. Release runs +Reusing an identifier for a **different** piece of equipment requires an +Administrator to explicitly release the existing claim. Release runs `sp_ReleaseExternalIdReservation`, which: - Requires a non-empty **reason** — a hard audit invariant; the procedure raises an error without one. -- Stamps `ReleasedAt`, `ReleasedBy` (`SUSER_SNAME()`), and `ReleaseReason` - rather than deleting the row, so the history is preserved. +- Requires a non-empty **`@ReleasedBy`** — the LDAP operator name supplied + by the caller; the procedure raises an error without it. +- Stamps `ReleasedAt`, `ReleasedBy` (the supplied operator name), and + `ReleaseReason` rather than deleting the row, so the history is preserved. - Once released, the `(Kind, Value)` pair is free — a different `EquipmentUuid` can claim it on a future publish. @@ -116,20 +118,19 @@ permanent for the life of the asset. ## The Admin page -`/reservations` (Admin UI) is the operator surface. It is **FleetAdmin-only** -(the `CanPublish` policy). +`/reservations` (Admin UI) is the operator surface. It requires authentication +(`[Authorize]`) but is not restricted to a specific Admin UI role — any signed-in +user can view it. -- **Active** table — every reservation with `ReleasedAt IS NULL`: kind, value, - owning `EquipmentUuid`, cluster, and the first/last publish stamps. Each row - has a **Release…** action. -- **Released** table — the 100 most recently released reservations, with the - releasing user and reason. -- **Release dialog** — opened from an active row; it requires a reason before - the Release button will submit, mirroring the procedure's audit invariant. +The page is a **read-only flat list** of all `ExternalIdReservation` rows, +ordered by Kind then Value. It shows Kind, Value, owning `EquipmentUuid`, and +Cluster. There is no Active/Released split, no Release action, and no Release +dialog on this page. You cannot *create* a reservation from this page — reservations only ever come -into existence as a side-effect of publishing a generation. The page is for -inspection and for the release flow. +into existence as a side-effect of publishing a generation. The release flow +is described in `docs/v2/admin-ui.md` § "Release an external-ID reservation" +and runs via `sp_ReleaseExternalIdReservation`. ## Related