false, 'ERROR' => 'missing_grantid', 'MESSAGE' => 'GrantID is required.']); } if ($userId <= 0) { apiAbort(['OK' => false, 'ERROR' => 'not_authenticated']); } $qGrant = queryOne( "SELECT g.ID, g.OwnerBusinessID, g.GuestBusinessID, g.StatusID, b.UserID AS OwnerUserID FROM ServicePointGrants g JOIN Businesses b ON b.ID = g.OwnerBusinessID WHERE g.ID = ? LIMIT 1", [$grantID] ); if (!$qGrant) { apiAbort(['OK' => false, 'ERROR' => 'not_found', 'MESSAGE' => 'Grant not found.']); } if ((int) $qGrant['OwnerUserID'] !== $userId) { apiAbort(['OK' => false, 'ERROR' => 'not_owner', 'MESSAGE' => 'Only the owner business can revoke a grant.']); } $statusID = (int) $qGrant['StatusID']; if ($statusID === 3) { apiAbort(['OK' => true, 'MESSAGE' => 'Grant is already revoked.', 'GrantID' => $grantID]); } if ($statusID !== 0 && $statusID !== 1) { apiAbort(['OK' => false, 'ERROR' => 'bad_state', 'MESSAGE' => 'Only pending or active grants can be revoked.']); } queryTimed("UPDATE ServicePointGrants SET StatusID = 3, RevokedOn = NOW() WHERE ID = ?", [$grantID]); recordGrantHistory( $grantID, 'revoked', $userId, (int) $qGrant['OwnerBusinessID'], ['StatusID' => $statusID], ['StatusID' => 3] ); jsonResponse([ 'OK' => true, 'GrantID' => $grantID, 'MESSAGE' => 'Grant revoked. All access stopped immediately.', ]);