"""Workspace API. Product language: workspace/space. Database compatibility: tenants. """ from __future__ import annotations from pydantic import BaseModel, Field from fastapi import APIRouter, Depends from sqlalchemy.ext.asyncio import AsyncSession from ..core.database import get_db from ..core.response import success_response from ..dependencies import get_current_user, get_optional_current_user from ..models import User from ..services.workspace_service import ( accept_invitation, create_invitation, create_team_workspace, leave_workspace, list_user_workspaces, switch_workspace, ) router = APIRouter(prefix="/workspaces", tags=["workspaces"]) class TeamWorkspaceCreateRequest(BaseModel): name: str = Field(min_length=1, max_length=120) class WorkspaceSwitchRequest(BaseModel): tenant_id: int class WorkspaceInvitationCreateRequest(BaseModel): phone_country_code: str = "+86" phone_number: str email: str | None = None role: str = "BUILDER" project_ids: list[int] = Field(default_factory=list) class WorkspaceInvitationNewUserRequest(BaseModel): username: str password: str name: str email: str class WorkspaceInvitationAcceptRequest(BaseModel): token: str user: WorkspaceInvitationNewUserRequest | None = None @router.get("/me") async def get_my_workspaces( current_user: User = Depends(get_current_user), db: AsyncSession = Depends(get_db), ): return success_response(await list_user_workspaces(db, user=current_user)) @router.post("/teams") async def create_team( body: TeamWorkspaceCreateRequest, current_user: User = Depends(get_current_user), db: AsyncSession = Depends(get_db), ): return success_response(await create_team_workspace(db, current_user=current_user, name=body.name)) @router.post("/switch") async def switch_current_workspace( body: WorkspaceSwitchRequest, current_user: User = Depends(get_current_user), db: AsyncSession = Depends(get_db), ): return success_response(await switch_workspace(db, current_user=current_user, tenant_id=body.tenant_id)) @router.post("/invitations") async def invite_member( body: WorkspaceInvitationCreateRequest, current_user: User = Depends(get_current_user), db: AsyncSession = Depends(get_db), ): return success_response( await create_invitation( db, current_user=current_user, email=body.email, phone_country_code=body.phone_country_code, phone_number=body.phone_number, role=body.role, project_ids=body.project_ids, ) ) @router.post("/invitations/accept") async def accept_member_invitation( body: WorkspaceInvitationAcceptRequest, current_user: User | None = Depends(get_optional_current_user), db: AsyncSession = Depends(get_db), ): return success_response(await accept_invitation(db, token=body.token, current_user=current_user, new_user=body.user)) @router.post("/{tenant_id}/leave") async def leave_current_workspace( tenant_id: int, current_user: User = Depends(get_current_user), db: AsyncSession = Depends(get_db), ): return success_response(await leave_workspace(db, current_user=current_user, tenant_id=tenant_id))