# Task: Organization membership and inherited permissions ## Feature `docs/FEATURES/organizations.md` ## Goal Model organization-level memberships and inherited workspace permissions with workspace-level overrides. ## Context Users have global accounts. A user can have rights in multiple organizations and direct access to individual workspaces. Organization membership grants company-level access and inherited workspace permissions. Workspace membership can grant direct access or override workspace-specific inherited permissions. ## Scope - Add organization membership persistence. - Add organization-level roles or permissions for: - organization owner/admin - organization member management - workspace creation/administration - billing manager - connector manager - Define how organization permissions map to inherited workspace permissions. - Preserve workspace participant relationship categories: `Organization Member` and `External Collaborator`. - Allow workspace memberships to override applicable inherited workspace permissions. - Ensure billing and connector permissions remain organization-level only. - Update access checks used by workspace APIs to consider inherited organization permissions. - Add tests for inherited access, direct workspace access, external collaborator access, and override behavior. ## Constraints - Do not implement billing pages or billing provider integration in this task. - Do not implement connector APIs in this task. - Do not remove direct workspace membership support. - External collaborators must not become organization members automatically. - Keep permission names explicit; avoid magic strings where local patterns provide constants. ## Permission Model Use explicit constants in the Organizations module rather than raw strings in handlers. Initial organization permissions: - `ManageOrganizationSettings` - `ManageOrganizationMembers` - `CreateWorkspaces` - `ManageWorkspaces` - `ManageBilling` - `ManageConnectors` - `AccessOwnedWorkspaces` Initial organization roles should map to permissions in code: - `Owner`: all organization permissions. - `Admin`: organization settings, organization members, workspace creation, workspace administration, connector management, and owned workspace access. Billing is not included unless explicitly assigned. - `BillingManager`: billing and owned workspace access. - `ConnectorManager`: connector management and owned workspace access. - `Member`: owned workspace access only. Workspace-specific permissions may be overridden at the workspace level after inherited organization access is resolved. Billing and connector permissions must never be granted from workspace-level overrides. Direct workspace members who are not organization members should be labeled `External Collaborator` in workspace membership responses. Organization members with inherited or direct workspace access should be labeled `Organization Member`. ## Implementation Notes - Add an `OrganizationMembership` persistence model with `OrganizationId`, `UserId`, role/permission data, and `CreatedAt`. - Prefer a small Organizations access service for organization access checks and inherited workspace permission calculation instead of adding ad hoc queries to every handler. - Update JWT claims only if a task proves claims are needed; permission checks can query current database state first. - Preserve existing global Identity roles while introducing organization-scoped roles. Do not reuse global `manager`, `client`, or `provider` roles as organization roles. - Add unit tests for role-to-permission mapping and handler/integration tests for access rejection where existing test infrastructure supports it. ## Likely Files - `backend/src/Socialize.Api/Modules/Organizations/**` - `backend/src/Socialize.Api/Modules/Workspaces/**` - `backend/src/Socialize.Api/Modules/Identity/**` - `backend/src/Socialize.Api/Data/AppDbContext.cs` - `backend/tests/Socialize.Tests/**` ## Done When - [x] Organization memberships are persisted. - [x] Organization roles/permissions include billing manager. - [x] Organization-level access can grant inherited access to owned workspaces. - [x] Direct workspace-only external collaborators remain supported. - [x] Workspace-level overrides apply to workspace-specific permissions. - [x] Billing and connector permissions cannot be granted through workspace overrides. - [ ] Backend tests cover inherited, direct, external collaborator, and override access paths. ## Validation Commands ```bash dotnet build backend/Socialize.slnx dotnet test backend/Socialize.slnx ```