"""Organization-related API endpoints.""" from __future__ import annotations from fastapi import APIRouter, Depends, HTTPException, status from pydantic import BaseModel, EmailStr from app.api.deps import ( get_current_user, get_organization_context, get_organization_repository, get_organization_service, get_user_repository, ) from app.models.organization import OrganizationRead from app.models.organization_member import OrganizationMemberRead, OrganizationRole from app.models.user import User from app.repositories.org_repo import OrganizationRepository from app.repositories.user_repo import UserRepository from app.services.organization_service import ( OrganizationContext, OrganizationForbiddenError, OrganizationMemberAlreadyExistsError, OrganizationService, ) router = APIRouter(prefix="/organizations", tags=["organizations"]) class AddMemberPayload(BaseModel): email: EmailStr role: OrganizationRole = OrganizationRole.MEMBER @router.get("/me", response_model=list[OrganizationRead]) async def list_user_organizations( current_user: User = Depends(get_current_user), repo: OrganizationRepository = Depends(get_organization_repository), ) -> list[OrganizationRead]: """Return organizations the authenticated user belongs to.""" organizations = await repo.list_for_user(current_user.id) return [OrganizationRead.model_validate(org) for org in organizations] @router.post("/members", response_model=OrganizationMemberRead, status_code=status.HTTP_201_CREATED) async def add_member_to_organization( payload: AddMemberPayload, context: OrganizationContext = Depends(get_organization_context), service: OrganizationService = Depends(get_organization_service), user_repo: UserRepository = Depends(get_user_repository), ) -> OrganizationMemberRead: """Allow owners/admins to add existing users to their organization.""" user = await user_repo.get_by_email(payload.email) if user is None: raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="User not found") try: membership = await service.add_member(context=context, user_id=user.id, role=payload.role) except OrganizationMemberAlreadyExistsError as exc: raise HTTPException(status_code=status.HTTP_409_CONFLICT, detail=str(exc)) from exc except OrganizationForbiddenError as exc: raise HTTPException(status_code=status.HTTP_403_FORBIDDEN, detail=str(exc)) from exc return OrganizationMemberRead.model_validate(membership)