# 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
```
