Superadmin Visibility
Superadmins are the owners of the app. Tachi Kit keeps them invisible to everyone who isn’t a superadmin: admins can’t see, count, filter, edit or delete them. This prevents an admin from locking out, impersonating or even discovering the owners.
Where it applies
Section titled “Where it applies”| Place | How superadmins are hidden |
|---|---|
| Users list | Rows are excluded (visibleTo()). |
| Role filter and role pickers | The superadmin option is removed (UserController::availableRoleNames()). |
| Dashboard stats, chart and recent users | Counts and lists use visibleTo(). |
| Activity log | Entries whose actor or subject is a superadmin are excluded. |
| Editing | UserPolicy::update returns 403 if a non-superadmin targets a superadmin. |
Superadmins see everything, including other superadmins.
The visibleTo() scope
Section titled “The visibleTo() scope”App\Models\User has a local scope that applies the rule:
#[Scope]protected function visibleTo(Builder $query, User $viewer): void{ if ($viewer->isSuperadmin()) { return; }
$query->whereDoesntHave('roles', fn (Builder $role) => $role->where('name', RoleName::Superadmin->value));}Use it for every query that lists or counts users for someone to see:
$users = User::query() ->visibleTo($request->user()) ->latest() ->paginate();Customizing
Section titled “Customizing”Applying the rule to your own features
Section titled “Applying the rule to your own features”When you build something that shows users, such as a “Team members” widget, an export or an assignee picker, start the query with visibleTo(). For data that references users, like an audit table, filter out rows that point at superadmins the way ActivityController does:
$superadminIds = User::withTrashed()->role(RoleName::Superadmin->value)->pluck('id');
$query->where(function (Builder $sub) use ($superadminIds) { $sub->whereNull('user_id')->orWhereNotIn('user_id', $superadminIds);});Turning the rule off
Section titled “Turning the rule off”If your app doesn’t need hidden owners, make the scope a no-op, or remove its calls, and drop the superadmin exclusions in UserController::availableRoleNames() and ActivityController::withoutSuperadminActivity(). The UsersTest, DashboardTest and ActivityLogTest tests that assert hiding will then fail and can be removed.