"""Projects Handler - OpenPanel project management (8 tools)""" import json from typing import Any from plugins.openpanel.client import OpenPanelClient def get_tool_specifications() -> list[dict[str, Any]]: """Return tool specifications for ToolGenerator (8 tools)""" return [ { "name": "list_projects", "method_name": "list_projects", "description": "List all OpenPanel projects.", "schema": {"type": "object", "properties": {}}, "scope": "read", }, { "name": "get_project", "method_name": "get_project", "description": "Get project details including settings and statistics.", "schema": { "type": "object", "properties": {"project_id": {"type": "string", "description": "Project ID"}}, "required": ["project_id"], }, "scope": "read", }, { "name": "create_project", "method_name": "create_project", "description": "Create a new OpenPanel project.", "schema": { "type": "object", "properties": { "name": {"type": "string", "description": "Project name"}, "domain": { "anyOf": [{"type": "string"}, {"type": "null"}], "description": "Primary domain for the project", }, "timezone": { "type": "string", "description": "Project timezone", "default": "UTC", }, }, "required": ["name"], }, "scope": "admin", }, { "name": "update_project", "method_name": "update_project", "description": "Update project settings.", "schema": { "type": "object", "properties": { "project_id": {"type": "string", "description": "Project ID"}, "name": { "anyOf": [{"type": "string"}, {"type": "null"}], "description": "New project name", }, "domain": { "anyOf": [{"type": "string"}, {"type": "null"}], "description": "New primary domain", }, "timezone": { "anyOf": [{"type": "string"}, {"type": "null"}], "description": "New timezone", }, }, "required": ["project_id"], }, "scope": "admin", }, { "name": "delete_project", "method_name": "delete_project", "description": "Delete a project and all its data.", "schema": { "type": "object", "properties": { "project_id": {"type": "string", "description": "Project ID to delete"}, "confirm": {"type": "boolean", "description": "Confirm deletion (required)"}, }, "required": ["project_id", "confirm"], }, "scope": "admin", }, { "name": "get_project_stats", "method_name": "get_project_stats", "description": "Get project statistics (events, users, storage).", "schema": { "type": "object", "properties": { "project_id": {"type": "string", "description": "Project ID"}, "date_range": { "type": "string", "description": "Date range. Common: today, yesterday, 7d, 14d, 30d, 60d, 90d, 6m, 12m, yearToDate, all", "default": "30d", }, }, "required": ["project_id"], }, "scope": "read", }, { "name": "get_project_settings", "method_name": "get_project_settings", "description": "Get project configuration settings.", "schema": { "type": "object", "properties": {"project_id": {"type": "string", "description": "Project ID"}}, "required": ["project_id"], }, "scope": "read", }, { "name": "update_project_settings", "method_name": "update_project_settings", "description": "Update project configuration.", "schema": { "type": "object", "properties": { "project_id": {"type": "string", "description": "Project ID"}, "settings": { "type": "object", "description": "Settings to update", "properties": { "cors_domains": {"type": "array", "items": {"type": "string"}}, "ip_anonymization": {"type": "boolean"}, "data_retention_days": {"type": "integer"}, }, }, }, "required": ["project_id", "settings"], }, "scope": "admin", }, ] # ===================== # Project Functions (8) # ===================== async def list_projects(client: OpenPanelClient) -> str: """List all projects""" try: return json.dumps( { "success": True, "note": "Project listing requires dashboard tRPC API. Use OpenPanel dashboard to view projects.", "message": "Project list request processed", }, indent=2, ensure_ascii=False, ) except Exception as e: return json.dumps({"success": False, "error": str(e)}, indent=2, ensure_ascii=False) async def get_project(client: OpenPanelClient, project_id: str) -> str: """Get project details""" try: return json.dumps( { "success": True, "project_id": project_id, "note": "Project details require dashboard tRPC API. Use OpenPanel dashboard for full project view.", "message": "Project details request processed", }, indent=2, ensure_ascii=False, ) except Exception as e: return json.dumps({"success": False, "error": str(e)}, indent=2, ensure_ascii=False) async def create_project( client: OpenPanelClient, name: str, domain: str | None = None, timezone: str = "UTC" ) -> str: """Create a new project""" try: project_config = {"name": name, "domain": domain, "timezone": timezone} return json.dumps( { "success": True, "project": project_config, "note": "Project creation requires dashboard tRPC API. Use OpenPanel dashboard to create projects.", "message": f"Project '{name}' configuration created", }, indent=2, ensure_ascii=False, ) except Exception as e: return json.dumps({"success": False, "error": str(e)}, indent=2, ensure_ascii=False) async def update_project( client: OpenPanelClient, project_id: str, name: str | None = None, domain: str | None = None, timezone: str | None = None, ) -> str: """Update project settings""" try: updates = {} if name: updates["name"] = name if domain: updates["domain"] = domain if timezone: updates["timezone"] = timezone return json.dumps( { "success": True, "project_id": project_id, "updates": updates, "note": "Project updates require dashboard tRPC API. Use OpenPanel dashboard to modify projects.", "message": "Project update configuration created", }, indent=2, ensure_ascii=False, ) except Exception as e: return json.dumps({"success": False, "error": str(e)}, indent=2, ensure_ascii=False) async def delete_project(client: OpenPanelClient, project_id: str, confirm: bool = False) -> str: """Delete a project""" try: if not confirm: return json.dumps( { "success": False, "error": "Deletion not confirmed. Set confirm=true to proceed.", "warning": "This will permanently delete all project data including events, users, and settings.", }, indent=2, ensure_ascii=False, ) return json.dumps( { "success": True, "project_id": project_id, "confirmed": confirm, "note": "Project deletion requires dashboard tRPC API. Use OpenPanel dashboard to delete projects.", "message": "Project deletion request processed", }, indent=2, ensure_ascii=False, ) except Exception as e: return json.dumps({"success": False, "error": str(e)}, indent=2, ensure_ascii=False) async def get_project_stats( client: OpenPanelClient, project_id: str, date_range: str = "30d" ) -> str: """Get project statistics""" try: # Get basic stats via export API metrics = {} # Total events events_config = [{"name": "*", "segment": "event"}] events_result = await client.export_charts( project_id=project_id, events=events_config, interval="day", date_range=date_range ) total_events = 0 if isinstance(events_result, dict) and "data" in events_result: for point in events_result.get("data", []): total_events += point.get("count", 0) metrics["total_events"] = total_events # Unique users users_config = [{"name": "*", "segment": "user"}] users_result = await client.export_charts( project_id=project_id, events=users_config, interval="day", date_range=date_range ) if isinstance(users_result, dict) and "data" in users_result: data = users_result.get("data", []) metrics["unique_users"] = data[-1].get("count", 0) if data else 0 return json.dumps( { "success": True, "project_id": project_id, "date_range": date_range, "stats": metrics, "message": "Project stats retrieved", }, indent=2, ensure_ascii=False, ) except Exception as e: return json.dumps({"success": False, "error": str(e)}, indent=2, ensure_ascii=False) async def get_project_settings(client: OpenPanelClient, project_id: str) -> str: """Get project settings""" try: return json.dumps( { "success": True, "project_id": project_id, "note": "Project settings require dashboard tRPC API. Use OpenPanel dashboard for settings.", "message": "Project settings request processed", }, indent=2, ensure_ascii=False, ) except Exception as e: return json.dumps({"success": False, "error": str(e)}, indent=2, ensure_ascii=False) async def update_project_settings( client: OpenPanelClient, project_id: str, settings: dict[str, Any] ) -> str: """Update project settings""" try: return json.dumps( { "success": True, "project_id": project_id, "settings": settings, "note": "Settings update requires dashboard tRPC API. Use OpenPanel dashboard to configure.", "message": "Project settings update configuration created", }, indent=2, ensure_ascii=False, ) except Exception as e: return json.dumps({"success": False, "error": str(e)}, indent=2, ensure_ascii=False)