Assigning leaders and shepherds β
There are two distinct things you might mean when you say "Jane leads the North Branch." GCM stores them in two different tables and they do very different jobs.
- Leader of a unit β a single member's name shows in the unit's hero card, leader badge, and reports. Stored on
org_units.leader_member_id. - User scoped to a unit β a user's login is restricted to seeing only the data in (and below) that unit. Stored in
user_unit_assignments_v2.
A leader is a display relationship. A user scope is a security relationship. They're often the same person, but they don't have to be β and when they're not, you'll see the value of the split.

Setting a leader β
On the org tree, every unit row has a Set Leader button to the right of its name (or Change Leader if one is already assigned). Click it to open a small popover with a member search.
- Type two characters to fire the
search_membersRPC. - Pick a result to write
leader_member_idon the unit. - A toast confirms; the row updates immediately with the new name and a small avatar.
- To clear, open the popover on a unit that already has a leader and click Remove leader.
The button uses a soft amber outline when no leader is assigned, drawing your eye to the gaps. On big trees that's how you spot unstaffed cells without scrolling.
What setting a leader does:
- The leader's name + avatar shows on the unit card, the unit detail hero, and every place the unit is mentioned in reports.
- The leader's photo and lost/active status ring render via the shared
MemberAvatarcomponent, so a leader who's gone "lost" gets a visual cue. - The
unit_with_leaderview powers the "leaders assigned" ratio on the level page (e.g. "2 / 7 leaders assigned"). - It does not change what that member's user-login can see. That's the next section.
Scoping a user to a unit β
This is the security half. A user account (not a member record) gets a row in user_unit_assignments_v2 per unit you grant them. Their visible scope is the union of their assigned units and every descendant.
Where to set it β
Go to Users & Roles β Users, find the row, and click Edit assignments. The picker shows your full hierarchy with checkboxes. Tick every unit they should see.
A typical pattern:
- An org admin has zero rows in the table β they see everything.
- A regional pastor has one row at level 1 (a region). They see that region's branches, centers, cells, and members.
- A cell shepherd has one row at level 3 (a cell). They see only their cell.
- A multi-campus worship director has two rows at level 2. They see both campuses' subtrees.
How the scope is enforced β
When a non-admin user is signed in, the frontend calls a Postgres RPC named user_visible_unit_ids that walks the tree and returns every unit-id they can touch. The useUnitScope hook caches the result for 2 minutes.
Every list page in GCM filters by org_unit_id IN (visible_unit_ids) before rendering. RLS policies on the underlying tables do the same. A shepherd who edits their browser's network requests cannot pull rows outside their scope β the database refuses them.
Fail-closed default
If the RPC fails or hasn't returned yet, the hook treats scope as empty rather than open. A network blip won't accidentally show a shepherd the senior pastor's data β they'll just see an empty list until the RPC resolves.
When the leader and the user-scope diverge β
Common cases where these two are intentionally not the same person:
- The leader of a small group is the recognized shepherd you'd announce from the pulpit, but they don't use the app. No
user_unit_assignments_v2row exists for them. - An administrative assistant has user scope to enter data for a branch but isn't the public leader. They get a
user_unit_assignments_v2row butleader_member_idpoints to the pastor. - A regional pastor is the leader of their region (level 1) and has user scope at that level too. The two records match. This is the most common case.
GCM never auto-syncs the two. Setting a leader doesn't create a user-scope row, and giving a user scope doesn't set them as the leader. You make both calls deliberately.
The narrowest level β
When a user has assignments at multiple levels, GCM picks the narrowest (highest-numbered level index) as their default filter on cascading pickers. This means a user assigned to a region and a specific cell defaults to the cell view, with a manual toggle to widen.
useUnitScope exposes this as narrowestLevel. Pickers above that level may be locked to the user's single assignment if they only have one at that level.
Permissions overview β
| Action | Admin | Regional pastor | Cell shepherd | Member |
|---|---|---|---|---|
| Assign a leader to a unit | yes | within scope | no | no |
| Set user scope to a unit | yes | within scope | no | no |
| See unit members | global | within scope | within scope | own only |
| See unit attendance | global | within scope | within scope | own only |
| See unit giving (if not privacy-locked) | global | within scope | configurable | own only |
"Within scope" means the user can only touch units that are in their own visible subtree. They can grant a scope no broader than their own.
Common questions β
Can a leader see the member list of their unit even without user scope? Only if their user account has scope. Setting leader_member_id to a member doesn't grant them a login or scope. If they don't have a login yet, invite them via Users & Roles and pick the unit during the invite flow β GCM creates the user_unit_assignments_v2 row for you.
What if I assign a leader who isn't a member? You can't. The leader picker only shows existing members. Add them as a member first.
Does archiving a unit clear its leader? No β the leader_member_id stays. When the unit is restored, the leader is still attached. Archiving also doesn't remove user-scope rows; restored units come back fully wired.
Can the same member lead multiple units? Yes. There's no uniqueness constraint on leader_member_id. A pastor can lead a region and a cell at the same time β common when a senior pastor also runs a discipleship group.
Next steps β
- Archive and restore when team composition changes.
- Read the users-roles overview for the user-management side of the picture.
- Invite team members and set their scope in one flow.
