Files
social-media/docs/TASKS/organizations/001-organization-domain-foundation.md

3.5 KiB

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

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

Validation Commands

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