useOrganization Hook

useOrganization Hook

Overview

The useOrganization hook is a custom TanStack Query hook that abstracts the data fetching logic for retrieving organization details. It intelligently selects the appropriate API endpoint based on the authenticated user’s global role.

Problem Statement

Platform Administrators and regular Organization Members require different API endpoints to access organization data. Platform Admins use a global /api/v1/organizations/:id endpoint which grants access to any organization. Organization Members use an org-scoped /api/v1/orgs/:id endpoint, which verifies their membership before returning data. Requiring UI components to manually check the user’s role and select the correct endpoint introduces boilerplate and coupling.

Solution

The useOrganization hook provides a single, unified contract for UI components. It encapsulates the role-checking logic and conditionally executes the correct query.

Implementation Details

  1. Session Role Check: The hook first retrieves the current user’s session using the authClient. It determines if the user is a Platform Admin based on the session.user.role property.
  2. Dynamic Query Selection:
    • If the user is a Platform Admin, the hook utilizes the useAdminOrganization underlying hook (which calls getAdminOrg).
    • If the user is not a Platform Admin, the hook utilizes a standard query that calls the org-scoped getOrg API method.
export function useOrganization(id: () => string) {
  const session = authClient.useSession();
  const isAdmin = () => session()?.data?.user?.role === "admin";

  return createQuery(() => ({
    queryKey: isAdmin()
      ? ["admin", "organizations", id()]
      : ["organizations", id()],
    queryFn: async () => {
      if (isAdmin()) {
        return await getAdminOrg(id());
      } else {
        return await getOrg(id());
      }
    },
    enabled: !!id() && !!session()?.data,
  }));
}

Responsibility Boundary

It’s crucial to understand the responsibility boundary of this hook:
  • The hook is strictly responsible for data fetching. It ensures the correct API endpoint is used based on the global role.
  • The hook is NOT responsible for authorization enforcement at the UI level. If an Organization Member attempts to fetch data for an organization they don’t belong to, the API will return a 403 Forbidden error.
  • Authorization and redirection are handled by the OrgAccessRoute component. The OrgAccessRoute intercepts unauthorized access attempts before the component even renders or the query has a chance to fail in a user-visible way.
  • packages/core/src/hooks/organizations/useOrganization.ts
  • packages/core/src/api/rest/organizations.ts