""" Teams Handler - manages Appwrite teams and memberships Phase I.2: 10 tools - Teams: 5 (list, get, create, update, delete) - Memberships: 5 (list_memberships, create_membership, update_membership, delete_membership, get_membership_status) """ import json from typing import Any from plugins.appwrite.client import AppwriteClient def get_tool_specifications() -> list[dict[str, Any]]: """Return tool specifications for ToolGenerator (10 tools)""" return [ # ===================== # TEAMS (5) # ===================== { "name": "list_teams", "method_name": "list_teams", "description": "List all teams in the project.", "schema": { "type": "object", "properties": { "queries": { "anyOf": [{"type": "array", "items": {"type": "string"}}, {"type": "null"}], "description": "Query strings for filtering", }, "search": { "anyOf": [{"type": "string"}, {"type": "null"}], "description": "Search term to filter teams by name", }, }, "required": [], }, "scope": "read", }, { "name": "get_team", "method_name": "get_team", "description": "Get team details by ID.", "schema": { "type": "object", "properties": {"team_id": {"type": "string", "description": "Team ID"}}, "required": ["team_id"], }, "scope": "read", }, { "name": "create_team", "method_name": "create_team", "description": "Create a new team. Use 'unique()' for auto-generated team ID.", "schema": { "type": "object", "properties": { "team_id": { "type": "string", "description": "Unique team ID. Use 'unique()' for auto-generation", }, "name": {"type": "string", "description": "Team name"}, "roles": { "anyOf": [{"type": "array", "items": {"type": "string"}}, {"type": "null"}], "description": "Array of roles available in this team (e.g., ['owner', 'editor', 'viewer'])", }, }, "required": ["team_id", "name"], }, "scope": "write", }, { "name": "update_team", "method_name": "update_team", "description": "Update team name.", "schema": { "type": "object", "properties": { "team_id": {"type": "string", "description": "Team ID"}, "name": {"type": "string", "description": "New team name"}, }, "required": ["team_id", "name"], }, "scope": "write", }, { "name": "delete_team", "method_name": "delete_team", "description": "Delete a team and all its memberships. This action is irreversible.", "schema": { "type": "object", "properties": {"team_id": {"type": "string", "description": "Team ID to delete"}}, "required": ["team_id"], }, "scope": "admin", }, # ===================== # MEMBERSHIPS (5) # ===================== { "name": "list_team_memberships", "method_name": "list_team_memberships", "description": "List all memberships (members) of a team.", "schema": { "type": "object", "properties": { "team_id": {"type": "string", "description": "Team ID"}, "queries": { "anyOf": [{"type": "array", "items": {"type": "string"}}, {"type": "null"}], "description": "Query strings for filtering", }, "search": { "anyOf": [{"type": "string"}, {"type": "null"}], "description": "Search term to filter members", }, }, "required": ["team_id"], }, "scope": "read", }, { "name": "create_team_membership", "method_name": "create_team_membership", "description": "Invite a user to join a team. Can invite by email, phone, or existing user ID.", "schema": { "type": "object", "properties": { "team_id": {"type": "string", "description": "Team ID"}, "roles": { "type": "array", "items": {"type": "string"}, "description": "Roles to assign to the member", }, "email": { "anyOf": [{"type": "string", "format": "email"}, {"type": "null"}], "description": "Email address to invite", }, "user_id": { "anyOf": [{"type": "string"}, {"type": "null"}], "description": "Existing user ID to add", }, "phone": { "anyOf": [{"type": "string"}, {"type": "null"}], "description": "Phone number to invite", }, "url": { "anyOf": [{"type": "string"}, {"type": "null"}], "description": "Redirect URL after accepting invitation", }, "name": { "anyOf": [{"type": "string"}, {"type": "null"}], "description": "Name of the invitee", }, }, "required": ["team_id", "roles"], }, "scope": "write", }, { "name": "update_membership", "method_name": "update_membership", "description": "Update team membership roles.", "schema": { "type": "object", "properties": { "team_id": {"type": "string", "description": "Team ID"}, "membership_id": {"type": "string", "description": "Membership ID"}, "roles": { "type": "array", "items": {"type": "string"}, "description": "New roles for the member", }, }, "required": ["team_id", "membership_id", "roles"], }, "scope": "write", }, { "name": "delete_membership", "method_name": "delete_membership", "description": "Remove a member from a team.", "schema": { "type": "object", "properties": { "team_id": {"type": "string", "description": "Team ID"}, "membership_id": {"type": "string", "description": "Membership ID to remove"}, }, "required": ["team_id", "membership_id"], }, "scope": "write", }, { "name": "get_team_prefs", "method_name": "get_team_prefs", "description": "Get team preferences/settings.", "schema": { "type": "object", "properties": {"team_id": {"type": "string", "description": "Team ID"}}, "required": ["team_id"], }, "scope": "read", }, ] # ===================== # HANDLER FUNCTIONS # ===================== async def list_teams( client: AppwriteClient, queries: list[str] | None = None, search: str | None = None ) -> str: """List all teams.""" try: result = await client.list_teams(queries=queries, search=search) teams = result.get("teams", []) response = {"success": True, "total": result.get("total", len(teams)), "teams": teams} return json.dumps(response, indent=2, ensure_ascii=False) except Exception as e: return json.dumps({"success": False, "error": str(e)}, indent=2) async def get_team(client: AppwriteClient, team_id: str) -> str: """Get team by ID.""" try: result = await client.get_team(team_id) return json.dumps({"success": True, "team": result}, indent=2, ensure_ascii=False) except Exception as e: return json.dumps({"success": False, "error": str(e)}, indent=2) async def create_team( client: AppwriteClient, team_id: str, name: str, roles: list[str] | None = None ) -> str: """Create a new team.""" try: result = await client.create_team(team_id=team_id, name=name, roles=roles) return json.dumps( {"success": True, "message": f"Team '{name}' created successfully", "team": result}, indent=2, ensure_ascii=False, ) except Exception as e: return json.dumps({"success": False, "error": str(e)}, indent=2) async def update_team(client: AppwriteClient, team_id: str, name: str) -> str: """Update team name.""" try: result = await client.update_team(team_id=team_id, name=name) return json.dumps( {"success": True, "message": "Team updated successfully", "team": result}, indent=2, ensure_ascii=False, ) except Exception as e: return json.dumps({"success": False, "error": str(e)}, indent=2) async def delete_team(client: AppwriteClient, team_id: str) -> str: """Delete team.""" try: await client.delete_team(team_id) return json.dumps( {"success": True, "message": f"Team '{team_id}' deleted successfully"}, indent=2 ) except Exception as e: return json.dumps({"success": False, "error": str(e)}, indent=2) async def list_team_memberships( client: AppwriteClient, team_id: str, queries: list[str] | None = None, search: str | None = None, ) -> str: """List team memberships.""" try: result = await client.list_team_memberships(team_id=team_id, queries=queries, search=search) memberships = result.get("memberships", []) response = { "success": True, "team_id": team_id, "total": result.get("total", len(memberships)), "memberships": memberships, } return json.dumps(response, indent=2, ensure_ascii=False) except Exception as e: return json.dumps({"success": False, "error": str(e)}, indent=2) async def create_team_membership( client: AppwriteClient, team_id: str, roles: list[str], email: str | None = None, user_id: str | None = None, phone: str | None = None, url: str | None = None, name: str | None = None, ) -> str: """Create team membership (invite).""" try: result = await client.create_team_membership( team_id=team_id, roles=roles, email=email, user_id=user_id, phone=phone, url=url, name=name, ) target = email or user_id or phone or "user" return json.dumps( { "success": True, "message": f"Membership created/invitation sent to {target}", "membership": result, }, indent=2, ensure_ascii=False, ) except Exception as e: return json.dumps({"success": False, "error": str(e)}, indent=2) async def update_membership( client: AppwriteClient, team_id: str, membership_id: str, roles: list[str] ) -> str: """Update membership roles.""" try: result = await client.update_membership( team_id=team_id, membership_id=membership_id, roles=roles ) return json.dumps( { "success": True, "message": f"Membership roles updated to: {roles}", "membership": result, }, indent=2, ensure_ascii=False, ) except Exception as e: return json.dumps({"success": False, "error": str(e)}, indent=2) async def delete_membership(client: AppwriteClient, team_id: str, membership_id: str) -> str: """Delete membership.""" try: await client.delete_membership(team_id, membership_id) return json.dumps( {"success": True, "message": f"Membership '{membership_id}' removed from team"}, indent=2, ) except Exception as e: return json.dumps({"success": False, "error": str(e)}, indent=2) async def get_team_prefs(client: AppwriteClient, team_id: str) -> str: """Get team preferences (placeholder - requires team prefs endpoint).""" try: # Note: Team prefs endpoint may vary by Appwrite version # This is a simplified version that returns team info result = await client.get_team(team_id) return json.dumps( {"success": True, "team_id": team_id, "prefs": result.get("prefs", {}), "team": result}, indent=2, ensure_ascii=False, ) except Exception as e: return json.dumps({"success": False, "error": str(e)}, indent=2)