Org Users
A read-only view of all users in an organization, with filtering by role, project assignment, and search. This page provides administrators with visibility into their team and each user’s project involvement.
User List
The Users page (/org-dashboard/{orgId}/users) displays a paginated table of all org users with their roles, statuses, and project counts.
Table Columns
| Column | Description |
|---|---|
| Name | User display name (bold) |
| User email (muted text) | |
| Role | Org role displayed as a badge (outline variant) |
| Status | active (green), pending (gray), inactive (red) |
| Projects | Count of projects the user is assigned to |
Role Display
Role values are formatted for display: underscores replaced with spaces and each word capitalized. For example, organisational_manager becomes Organisational Manager.
Filters
| Parameter | Type | Description |
|---|---|---|
role | string | Filter by user role (dropdown with all 14 roles) |
search | string | Substring match on name or email (ILIKE) |
project_id | UUID | Filter to users assigned to a specific project |
page | int | Page number (default 1) |
page_size | int | Items per page (default 25, max 100) |
Role Filter Options
Master Admin, Org Manager, Project Manager, Foreman, Worker, Unassigned — and the full set of 14 roles defined in the user_role enum.
Query Strategy
Two query paths depending on filters:
| Filter | Query Used | Pagination |
|---|---|---|
| No project | ListOrgUsers | Yes |
| With project | ListOrgUsersByProject | No (returns all) |
The ListOrgUsers query includes a subquery for project_count:
SELECT u.*, (SELECT COUNT(*) FROM project_members pm WHERE pm.user_id = u.id)::int AS project_count
FROM users u
WHERE u.org_id = $1
AND ($2::text = '' OR u.role = $2::user_role)
AND ($3::text = '' OR u.name ILIKE '%' || $3 || '%' OR u.email ILIKE '%' || $3 || '%')
ORDER BY u.created_at DESC
LIMIT $4 OFFSET $5;Pagination
Standard previous/next pagination with “Showing X-Y of Z” display. URL search params are updated on filter changes, with page reset to 1 when filters change.
API Endpoint
| Method | Path | Auth | Description |
|---|---|---|---|
GET | /v1/orgs/{orgId}/users | BearerAuth | List org users with filters |
Security
- Tenant isolation — All queries scoped to
org_idfrom JWT claims. - Read-only — This endpoint only lists users. User creation happens via the Org Onboarding setup wizard or the Entra directory import in the Members feature.
Key Files
| File | Purpose |
|---|---|
backend/db/queries/users.sql | ListOrgUsers, CountOrgUsers, ListOrgUsersByProject |
backend/api/internal/orguser/handler.go | HTTP handler for user listing |
backend/api/internal/orguser/service.go | Business logic: filters, pagination |
apps/web/src/actions/users.ts | BFF server actions: listOrgUsers |
apps/web/src/app/org-dashboard/[orgId]/users/page.tsx | Users page (RSC + Suspense) |
apps/web/src/app/org-dashboard/[orgId]/users/_components/users-table.tsx | Users table with role filter, search, pagination |