Skip to content

Org Units & Administrators ​

core.org_units is the institution's administrative tree — president, vice-presidential areas, colleges and schools, offices, departments. core.unit_administrators records who runs each one, with dates.

This is separate from the academic structures beside it. Colleges and Departments are academic entities that each point at an org unit; the org unit is the administrative node.

The tree ​

70 units in five levels:

Unit typeCount
Institution1
Division / VP Area5
College / School3
Office42
Department19

Migration 208 seeded the VP-and-office half of the tree, taking it from 23 units to 70. Officers were keyed on their @puc.edu email address.

FieldNotes
unit_code, name
unit_type_idOne of the five types above
parent_unit_idSelf-reference; this is what makes it a tree
sort_order, is_active

Administrators ​

core.unit_administrators (25 rows) replaced the older department_administrators in July 2026 — the old table could only describe a department, and the tree is wider than that.

FieldNotes
person_idWho
org_unit_idWhich unit
admin_level_idTheir role at that unit — see below
effective_date, end_dateAppointments are dated
is_active

Levels come from core.lookup_org_admin_level: PRESIDENT, VP, DEAN, ASSOC_DEAN, CHAIR, DIRECTOR, REGISTRAR, CHAPLAIN, CONTROLLER, GENERAL_MANAGER, SUPERVISOR, MANAGER, COORDINATOR, ADMIN.

Migration 207 allowed one person to hold an appointment across multiple terms, and migration 214 gave the screen its permission node, ADMIN.UNIT_ADMINS.

Acting appointment: one hat at a time ​

Someone can legitimately administer more than one unit — a dean who also chairs a department. But a permission scoped to "your unit" then has no single answer.

Migration 206 resolved that by making the acting appointment explicit. core.user_active_role.active_admin_id records which appointment the user is currently acting under, alongside which role they are acting in.

UNIT scope fails closed when no appointment is chosen

If a user has not selected an acting appointment, a UNIT-scoped permission resolves to nothing, not to everything. That is deliberate: the alternative — falling back to all units — would silently widen access for exactly the people who hold several appointments.

Selecting an appointment is part of switching role, not a separate setting to remember.

Changing the acting appointment invalidates the user's permission cache; the cache key is versioned (v3) for that reason.

Scoped permissions read the tree ​

role_permissions.scope (migration 113) can restrict a grant to the acting administrator's unit. includes_children on a grant means the scope follows the tree downward, so a VP's grant reaches the offices beneath their area without enumerating them.

A bare column in a scope predicate becomes a tautology

When scope predicates were first written, some compared a bare column name that resolved to the outer query's column rather than the correlated subquery's — so UNIT filters silently matched everything. The working shape is IN (SELECT ...), and any new scope predicate should follow it.

A scope filter that appears to have no effect is almost certainly this bug, not a missing grant.

See Roles and Permissions.

ACADEMIC_ADMIN follows the tree ​

The ACADEMIC_ADMIN derived role is computed from the org-unit hierarchy rather than assigned by hand, so an appointment change is reflected without a separate grant step.

Student Information System Documentation