# Task: Organization domain foundation

## Feature

`docs/FEATURES/organizations.md`

## Goal

Add the backend foundation for organizations as the SaaS account boundary and make workspaces belong to an organization.

## Context

Current docs and code treat `Workspace` as the top-level boundary. The product model now requires `Organization` above workspace for billing, subscriptions, connectors, limits, and workspace ownership.

Existing local data does not need to be preserved.

## Scope

- Add an `Organizations` backend module or follow the existing ownership pattern if organization code belongs with `Workspaces`.
- Add an organization persistence model with `Id`, `Name`, `OwnerUserId`, and `CreatedAt`, matching local conventions.
- Require every workspace to belong to exactly one organization.
- Update workspace create/list/detail APIs to include organization ownership.
- Add current-user organization read APIs:
  - `GET /api/organizations`
  - `GET /api/organizations/{organizationId}`
- Add backend validation that users cannot access organizations they have no relationship with.
- Seed or development bootstrap data should create at least one organization and owned workspace when local development data is empty.
- Update OpenAPI after backend contracts change.

## Constraints

- Keep backend code under `backend/src/Socialize.Api`.
- Preserve FastEndpoints module structure.
- Do not implement billing provider integration in this task.
- Do not implement connector storage in this task.
- Do not implement full organization membership override behavior in this task.
- Do not implement organization settings UI in this task.
- Existing development data may be wiped; do not spend scope on compatibility migration behavior.

## Implementation Notes

- Place organization-owned backend code under `backend/src/Socialize.Api/Modules/Organizations`.
- Add `DbSet<Organization>` and `ConfigureOrganizationsModule()` to `AppDbContext`.
- Keep `Workspace.OwnerUserId` for the existing creator/owner convention unless a later task explicitly replaces it.
- Add a required `Workspace.OrganizationId` property and database index.
- The first implementation may grant organization access through `Organization.OwnerUserId == currentUserId` and existing manager/administrator access. Full organization membership belongs to task 002.
- `CreateWorkspaceRequest` should require `OrganizationId`; reject creation when the user cannot manage that organization.
- `WorkspaceDto` should include `OrganizationId`.
- Use tests for unauthorized organization detail access and workspace creation under an inaccessible organization.

## Likely Files

- `backend/src/Socialize.Api/Data/AppDbContext.cs`
- `backend/src/Socialize.Api/Modules/Organizations/**`
- `backend/src/Socialize.Api/Modules/Workspaces/**`
- `backend/src/Socialize.Api/Migrations/**`
- `backend/tests/Socialize.Tests/**`
- `shared/openapi/openapi.json`
- `frontend/src/api/schema.d.ts`

## Done When

- [x] Organization entity is persisted.
- [x] Workspace requires `OrganizationId`.
- [x] Workspace APIs expose organization ownership.
- [x] Current user can list accessible organizations.
- [x] Current user can get accessible organization details.
- [x] Unauthorized organization access is rejected.
- [x] Development seed data creates an organization with owned workspaces.
- [x] Backend build and tests pass.
- [x] OpenAPI and generated frontend schema are updated.

## Validation Commands

```bash
dotnet build backend/Socialize.slnx
dotnet test backend/Socialize.slnx
./scripts/update-openapi.sh
```
