macOS fix: #201.
Problem
A background refresh that cannot renew a sign-in silently (or otherwise cannot read a tenant) keeps that tenant's last-known active rows. Nothing checks their end times, so after a long sleep expired activations stay listed as active, with a Deactivate that can only fail, until an interactive refresh signs in again. Seen on macOS with a loopback (browser sign-in) account after ~12 h of sleep.
macOS fix (#201)
- Core:
ActiveAssignment.hasLapsed(at:): Active or Scheduled with an end at or before now. Pending approval, provisioning and failed never lapse.
- App: the 30 s clock tick drops rows a minute past their end (grace so the "expired" toast, due 5 s after the end, is not withdrawn by the reschedule), stops their propagation watches and reschedules notifications.
Parity work
- Elevate.Core (C#): add
ActiveAssignment.HasLapsed(DateTimeOffset now) in src/Elevate.Core/Models/Roles.cs, with tests mirroring LapsedAssignmentTests.
- Windows app:
AppModel.Refresh.cs has the same keep-known-rows behaviour for tenants awaiting sign-in (AppModelSilentRefreshTests). Drop lapsed rows on the app's clock tick, the same way as macOS.
- CLI
elevate watch: renders session.Active every second and re-reads every --interval. A failed re-read leaves expired rows in the table. Filter lapsed rows before rendering (or drop them from the session). status reads once and is probably unaffected; worth a check.
Not verified on Windows or the CLI; inferred from the code.
macOS fix: #201.
Problem
A background refresh that cannot renew a sign-in silently (or otherwise cannot read a tenant) keeps that tenant's last-known active rows. Nothing checks their end times, so after a long sleep expired activations stay listed as active, with a Deactivate that can only fail, until an interactive refresh signs in again. Seen on macOS with a loopback (browser sign-in) account after ~12 h of sleep.
macOS fix (#201)
ActiveAssignment.hasLapsed(at:):ActiveorScheduledwith an end at or beforenow. Pending approval, provisioning and failed never lapse.Parity work
ActiveAssignment.HasLapsed(DateTimeOffset now)insrc/Elevate.Core/Models/Roles.cs, with tests mirroringLapsedAssignmentTests.AppModel.Refresh.cshas the same keep-known-rows behaviour for tenants awaiting sign-in (AppModelSilentRefreshTests). Drop lapsed rows on the app's clock tick, the same way as macOS.elevate watch: renderssession.Activeevery second and re-reads every--interval. A failed re-read leaves expired rows in the table. Filter lapsed rows before rendering (or drop them from the session).statusreads once and is probably unaffected; worth a check.Not verified on Windows or the CLI; inferred from the code.