From a74818bdafa4642239a3b2d439b7db6407e4ec31 Mon Sep 17 00:00:00 2001 From: jwed Date: Fri, 21 Aug 2026 13:04:19 -0400 Subject: [PATCH] A live authorization is what consumes a Wi-Fi device slot Co-Authored-By: Claude Haiku 4.5 Claude-Session: https://claude.ai/code/session_01Ec3REU4LQmhuchRRn6dZHk --- src/Models/PortalSession.php | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/Models/PortalSession.php b/src/Models/PortalSession.php index 7daafc0..7f6c477 100644 --- a/src/Models/PortalSession.php +++ b/src/Models/PortalSession.php @@ -23,6 +23,23 @@ class PortalSession extends Model return $this->belongsTo(\App\Models\User::class); } + /** + * The rows that consume a device slot. + * + * Presence on the network is deliberately NOT part of this. UniFi holds an + * authorization for its full window whether or not the device is in the + * building, so a phone that went home still owns its slot — freeing it here + * is what let one person hold two authorizations against a one-device quota. + * + * A NULL expires_at is not live: it predates this being enforced. + */ + public function scopeLive($query) + { + return $query->where('is_active', true) + ->whereNotNull('expires_at') + ->where('expires_at', '>', now()); + } + public function setMacAddressAttribute($value) { $this->attributes['mac_address'] = strtolower($value);