diff --git a/surfsense_backend/app/connectors/linear_connector.py b/surfsense_backend/app/connectors/linear_connector.py index 534d70b89..1c34ce946 100644 --- a/surfsense_backend/app/connectors/linear_connector.py +++ b/surfsense_backend/app/connectors/linear_connector.py @@ -588,6 +588,108 @@ class LinearConnector: return formatted + async def create_issue( + self, + team_id: str, + title: str, + description: str | None = None, + state_id: str | None = None, + assignee_id: str | None = None, + priority: int | None = None, + label_ids: list[str] | None = None, + ) -> dict[str, Any]: + mutation = """ + mutation IssueCreate($input: IssueCreateInput!) { + issueCreate(input: $input) { + success + issue { id identifier title url } + } + } + """ + input_data: dict[str, Any] = {"teamId": team_id, "title": title} + if description is not None: + input_data["description"] = description + if state_id is not None: + input_data["stateId"] = state_id + if assignee_id is not None: + input_data["assigneeId"] = assignee_id + if priority is not None: + input_data["priority"] = priority + if label_ids: + input_data["labelIds"] = label_ids + + result = await self.execute_graphql_query(mutation, {"input": input_data}) + payload = result.get("data", {}).get("issueCreate", {}) + if not payload.get("success"): + errors = result.get("errors", []) + msg = ( + errors[0].get("message", "Unknown error") if errors else "Unknown error" + ) + raise Exception(f"issueCreate failed: {msg}") + return payload.get("issue", {}) + + async def update_issue( + self, + issue_id: str, + title: str | None = None, + description: str | None = None, + state_id: str | None = None, + assignee_id: str | None = None, + priority: int | None = None, + label_ids: list[str] | None = None, + ) -> dict[str, Any]: + mutation = """ + mutation IssueUpdate($id: String!, $input: IssueUpdateInput!) { + issueUpdate(id: $id, input: $input) { + success + issue { id identifier title url } + } + } + """ + input_data: dict[str, Any] = {} + if title is not None: + input_data["title"] = title + if description is not None: + input_data["description"] = description + if state_id is not None: + input_data["stateId"] = state_id + if assignee_id is not None: + input_data["assigneeId"] = assignee_id + if priority is not None: + input_data["priority"] = priority + if label_ids is not None: + input_data["labelIds"] = label_ids + + result = await self.execute_graphql_query( + mutation, {"id": issue_id, "input": input_data} + ) + payload = result.get("data", {}).get("issueUpdate", {}) + if not payload.get("success"): + errors = result.get("errors", []) + msg = ( + errors[0].get("message", "Unknown error") if errors else "Unknown error" + ) + raise Exception(f"issueUpdate failed: {msg}") + return payload.get("issue", {}) + + async def archive_issue(self, issue_id: str) -> bool: + mutation = """ + mutation IssueArchive($id: String!) { + issueArchive(id: $id) { + success + } + } + """ + result = await self.execute_graphql_query(mutation, {"id": issue_id}) + payload = result.get("data", {}).get("issueArchive", {}) + if not payload.get("success"): + errors = result.get("errors", []) + msg = ( + errors[0].get("message", "Unknown error") if errors else "Unknown error" + ) + raise Exception(f"issueArchive failed: {msg}") + return True + def format_issue_to_markdown(self, issue: dict[str, Any]) -> str: """ Convert an issue to markdown format.