'boolean', 'present' => 'boolean', 'last_handshake_at' => 'datetime', 'observed_at' => 'datetime', 'rx_bytes' => 'integer', 'tx_bytes' => 'integer', ]; } public function uniqueIds(): array { return ['uuid']; } public function host(): BelongsTo { return $this->belongsTo(Host::class); } public function creator(): BelongsTo { return $this->belongsTo(User::class, 'created_by'); } public function isOnline(): bool { return $this->enabled && $this->present && $this->last_handshake_at !== null && $this->last_handshake_at->gt(now()->subMinutes(self::ONLINE_AFTER_MINUTES)); } /** * blocked — operator revoked it; it must not be on the hub * pending — desired and observed state disagree; a job is still applying it * online — configured and handshaking * idle — configured, but no recent handshake */ public function status(): string { if (! $this->enabled) { return $this->present ? 'pending' : 'blocked'; } if (! $this->present) { return 'pending'; } return $this->isOnline() ? 'online' : 'idle'; } }