Service Layer medium complexity mobile
1
Dependencies
0
Dependents
4
Entities
0
Integrations

Description

Service that determines whether an authenticated user holds roles in more than one partner organization and resolves which organizations they have access to. Used after authentication to decide whether to auto-proceed (single org) or display the multi-org switcher (multiple orgs). Queries Supabase for the user's role assignments across all tenant schemas.

Feature: Organization Selection & Onboarding

multi-org-membership-resolver

Summaries

The Multi-Organization Membership Resolver enables the application to intelligently adapt its post-login experience based on each user's actual organizational footprint. For users affiliated with a single partner organization, the app proceeds automatically — reducing friction and improving activation rates. For users with roles across multiple organizations, the resolver surfaces a contextual switcher that empowers them to operate across organizational boundaries without requiring separate logins. This capability is a direct enabler of cross-org workflows and platform stickiness, giving the business a competitive advantage in markets where professionals move between organizations or hold advisory roles across multiple partners.

It also lays the groundwork for future upsell opportunities tied to multi-organization access tiers.

This medium-complexity service component depends on the organization-repository, which must be delivered and tested first. The resolver itself introduces session-level caching logic that requires careful design to avoid stale membership data when a user's roles change mid-session — this edge case should be explicitly scoped into QA. Timeline impact is moderate: the resolver feeds directly into the post-login routing decision, meaning the organization selection screen and the auto-proceed flow both block on this component being stable. Testing must cover single-org users (auto-proceed), multi-org users (switcher display), users with no active org roles (error/edge case handling), and cache invalidation behavior.

Coordinate with the backend team to confirm Supabase RLS policies allow the membership query to execute with the user's current auth token before frontend integration begins.

The Multi-Organization Membership Resolver queries Supabase for all role assignments belonging to the authenticated user across tenant schemas, mapping results to typed `Organization` domain models. The three primary interfaces — `getUserOrganizations`, `hasMultipleOrganizations`, and `getPrimaryOrganization` — are all async and return `Future`-wrapped types, making them safe to call from Riverpod async providers or FutureBuilder widgets. Membership results should be cached for the session duration using an in-memory store keyed by userId to avoid redundant Supabase round-trips on repeated navigation. The resolver depends on `organization-repository` for org profile hydration after role resolution.

Key implementation risk: Supabase's multi-tenant schema design may require dynamic schema switching or a cross-schema view — confirm the query strategy with backend before implementing. Expose results as a `AsyncNotifier` in Riverpod for reactive UI binding.

Responsibilities

  • Query user's organization memberships from Supabase
  • Return the list of orgs the user has active roles in
  • Determine if multi-org switcher UI should be shown
  • Cache membership list for the session duration

Interfaces

getUserOrganizations(String userId) -> Future<List<Organization>>
hasMultipleOrganizations(String userId) -> Future<bool>
getPrimaryOrganization(String userId) -> Future<Organization?>

Relationships

Dependencies (1)

Components this component depends on

API Contract

View full contract →
REST /api/v1/memberships 6 endpoints
GET /api/v1/memberships
GET /api/v1/memberships/:id
POST /api/v1/memberships
PUT /api/v1/memberships/:id
DELETE /api/v1/memberships/:id
GET /api/v1/memberships/users/:userId/organizations