> ## Documentation Index
> Fetch the complete documentation index at: https://docs.azalt.co/llms.txt
> Use this file to discover all available pages before exploring further.

# Organization User

> Membership record that links a User to an Organization with role, status, and site access.

### Organization User

Organization User is a user's membership in a specific organization, including org-level role, membership status, and site assignments.

```typescript theme={null}
// apps/azalt/src/server/db/types/organization.ts (simplified)
interface OrganizationUser {
  id: string;
  organizationId: string;
  userId: string;
  role: "VIEWER" | "COLLECTOR" | "APPROVER" | "MANAGER" | "OWNER";
  status: "ACTIVE" | "INVITED" | "INACTIVE";
  invitationToken?: string | null;
  invitationExpiresAt?: Date | null;
  tags?: string[] | null;
  createdAt: Date;
  updatedAt: Date;
}
```

#### At a Glance

* One membership per (organization, user) pair
* Role (RBAC) drives permissions; site assignments scope them
* Status lifecycle: `INVITED → ACTIVE → INACTIVE`
* Tags allow lightweight categorization/filters

#### Roles (RBAC)

* Viewer: read-only access to assigned sites
* Collector: can submit/edit data on assigned sites
* Approver: can approve submissions within assigned sites
* Manager: manage users, sites, forms within assigned sites
* Owner: full organizational control

These roles drive authorization across server procedures via site- and role-scoped guards.

#### Status Lifecycle

* INVITED (default): created via invitation; limited until acceptance
* ACTIVE: full membership; operations allowed per role/scope
* INACTIVE: disabled membership; no access

Invitations are email-based and time-limited. Accepting an invitation activates the membership and may set the user's current organization if unset.

#### Constraints & Integrity

* Unique membership per organization: `(organizationId, userId)`
* Deleting a membership cascades its site assignments (via `OrganizationUserSite` FK)
* Owner cannot grant themselves more than OWNER; privilege changes follow role guard rules

#### Site Access (ABAC)

Site access is assigned via the Organization User Site junction. Effective access includes all descendants of the directly assigned sites (computed with a recursive query). Assigning the root site grants access to the entire organization.

#### Typical Operations

* List organization users (filtered by caller’s site access)
* Invite a user with role and site assignments
* Update a user’s role and optionally (re)assign sites
* Assign sites to multiple users (bulk: replace/add/remove)

```typescript theme={null}
// tRPC (apps/azalt/src/server/api/routers/organization)
organizations.listUsers(): Array<{
  id, name, email, phone, image, status, role,
  createdAt, ownerId, assignedSites: { id, name }[]
}>

organizations.inviteUser({ email, role, assignedSiteIds })
organizations.updateUserRole({ userId, role, assignedSiteIds? })
organizations.updateUserSites({ userId, assignedSiteIds })
organizations.bulkUpdateUserRoles({ userIds, role })
organizations.bulkUpdateUserSites({ userIds, siteIds, operation: "replace" | "add" | "remove" })
```

#### Security & Filtering

* Reads are restricted: viewers/collectors see users inside their accessible site tree; managers/owners see all.
* Writes are restricted to managers/owners and only within sites they can access.
* Row Level Security (RLS) and helper guards ensure context safety.

#### Tips & Edge Cases

* Users with no site assignments still appear in lists (visible to managers/owners); their effective access is empty.
* Inviting a user to the root site implicitly grants full organization access (root + descendants).
* Bulk operations support `replace`, `add`, and `remove` semantics—prefer `replace` for idempotent updates.

#### Related Concepts

* User — global identity and profile
* Organization User Site — site-level access for a membership
