ownerRef(); $member = Member::where('user_ref', $ref)->first(); if ($member) { return Organization::find($member->organization_id); } return Organization::owned($ref)->first(); } public function forUser(User $user): Organization { return $this->resolveForUser($user) ?? throw new \RuntimeException('No organization for user.'); } public function isOnboarded(User $user): bool { $organization = $this->resolveForUser($user); return $organization !== null && (bool) data_get($organization->settings, 'onboarded', false); } public function memberFor(User $user, ?Organization $organization = null): ?Member { $organization ??= $this->resolveForUser($user); if (! $organization) { return null; } return Member::where('organization_id', $organization->id) ->where('user_ref', $user->ownerRef()) ->first(); } public function ensureOwnerMember(User $user, Organization $organization): Member { return Member::firstOrCreate( [ 'organization_id' => $organization->id, 'user_ref' => $user->ownerRef(), ], [ 'owner_ref' => $user->ownerRef(), 'role' => 'org_admin', ], ); } /** * @param array $data */ public function completeOnboarding(User $user, array $data): Organization { $ref = $user->ownerRef(); $organization = Organization::create([ 'owner_ref' => $ref, 'name' => $data['organization_name'], 'slug' => Str::slug($data['organization_name']).'-'.substr($ref, 0, 6), 'timezone' => $data['timezone'] ?? config('app.timezone', 'UTC'), 'settings' => [ 'onboarded' => true, 'badge_expiry_hours' => (int) ($data['badge_expiry_hours'] ?? config('frontdesk.badge.default_expiry_hours', 8)), 'kiosk_reset_seconds' => (int) ($data['kiosk_reset_seconds'] ?? config('frontdesk.kiosk.inactivity_reset_seconds', 120)), 'notification_channels' => ['email'], 'visitor_policy' => $data['visitor_policy'] ?? null, ], ]); $this->ensureOwnerMember($user, $organization); Branch::create([ 'owner_ref' => $ref, 'organization_id' => $organization->id, 'name' => $data['branch_name'], 'address' => $data['branch_address'] ?? null, 'is_active' => true, ]); return $organization; } public function hostFor(User $user): ?Host { $organization = $this->resolveForUser($user); if (! $organization) { return null; } return Host::where('organization_id', $organization->id) ->where('user_ref', $user->ownerRef()) ->first(); } /** Branch ID the member may access; null = all branches. */ public function branchScope(?Member $member): ?int { if ($member === null) { return null; } if (in_array($member->role, ['super_admin', 'org_admin', 'auditor'], true)) { return null; } return $member->branch_id; } }