From 875924e5fd21a1132e59f39c3259f569755a2478 Mon Sep 17 00:00:00 2001 From: CREDO23 Date: Thu, 4 Dec 2025 00:38:13 +0200 Subject: [PATCH 1/6] jira-connector: update make_api_request to accespt POST with payload --- surfsense_backend/app/connectors/jira_connector.py | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/surfsense_backend/app/connectors/jira_connector.py b/surfsense_backend/app/connectors/jira_connector.py index ef0e00329..2a68c21f1 100644 --- a/surfsense_backend/app/connectors/jira_connector.py +++ b/surfsense_backend/app/connectors/jira_connector.py @@ -92,7 +92,11 @@ class JiraConnector: } def make_api_request( - self, endpoint: str, params: dict[str, Any] | None = None + self, + endpoint: str, + params: dict[str, Any] | None = None, + method: str = "GET", + json_payload: dict[str, Any] | None = None, ) -> dict[str, Any]: """ Make a request to the Jira API. @@ -116,7 +120,12 @@ class JiraConnector: url = f"{self.base_url}/rest/api/{self.api_version}/{endpoint}" headers = self.get_headers() - response = requests.get(url, headers=headers, params=params, timeout=500) + if method.upper() == "POST": + response = requests.post( + url, headers=headers, json=json_payload, timeout=500 + ) + else: + response = requests.get(url, headers=headers, params=params, timeout=500) if response.status_code == 200: return response.json() From 4df6b09db9398e1508663ce8d7f0e31564b01651 Mon Sep 17 00:00:00 2001 From: CREDO23 Date: Thu, 4 Dec 2025 00:42:10 +0200 Subject: [PATCH 2/6] jira-connector: update get all issues method --- .../app/connectors/jira_connector.py | 20 +++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/surfsense_backend/app/connectors/jira_connector.py b/surfsense_backend/app/connectors/jira_connector.py index 2a68c21f1..3578abca1 100644 --- a/surfsense_backend/app/connectors/jira_connector.py +++ b/surfsense_backend/app/connectors/jira_connector.py @@ -178,19 +178,23 @@ class JiraConnector: "project", ] - params = { - "jql": jql, - "fields": ",".join(fields), - "maxResults": 100, - "startAt": 0, - } + all_issues = [] + start_at = 0 + max_results = 100 all_issues = [] start_at = 0 while True: - params["startAt"] = start_at - result = self.make_api_request("search", params) + json_payload = { + "jql": jql, + "fields": fields, # API accepts list + "maxResults": max_results, + "startAt": start_at, + } + result = self.make_api_request( + "search/jql", json_payload=json_payload, method="POST" + ) if not isinstance(result, dict) or "issues" not in result: raise Exception("Invalid response from Jira API") From abf017eabb2278b96eb3952112676faaf4390e53 Mon Sep 17 00:00:00 2001 From: CREDO23 Date: Thu, 4 Dec 2025 00:48:54 +0200 Subject: [PATCH 3/6] jira-connector: update get_issues_by_date_range method --- .../app/connectors/jira_connector.py | 51 ++++++++++--------- 1 file changed, 26 insertions(+), 25 deletions(-) diff --git a/surfsense_backend/app/connectors/jira_connector.py b/surfsense_backend/app/connectors/jira_connector.py index 3578abca1..c0bc080fd 100644 --- a/surfsense_backend/app/connectors/jira_connector.py +++ b/surfsense_backend/app/connectors/jira_connector.py @@ -6,6 +6,7 @@ Allows fetching issue lists and their comments, projects and more. """ import base64 +import re from datetime import datetime from typing import Any @@ -220,7 +221,7 @@ class JiraConnector: project_key: str | None = None, ) -> tuple[list[dict[str, Any]], str | None]: """ - Fetch issues within a date range. + Fetch issues created OR updated within a date range using /search/jql. Args: start_date: Start date in YYYY-MM-DD format @@ -232,20 +233,20 @@ class JiraConnector: Tuple containing (issues list, error message or None) """ try: - # Build JQL query for date range - # Query issues that were either created OR updated within the date range - date_filter = ( - f"(createdDate >= '{start_date}' AND createdDate <= '{end_date}')" + # Validate date format (simple YYYY-MM-DD check) + for d in (start_date, end_date): + if not re.match(r"^\d{4}-\d{2}-\d{2}$", d): + return [], f"Invalid date format: {d}. Expected YYYY-MM-DD." + + # Build JQL: issues created OR updated within date range + date_jql = ( + f'(created >= "{start_date}" AND created <= "{end_date}") ' + f'OR (updated >= "{start_date}" AND updated <= "{end_date}")' ) - # TODO : This JQL needs some improvement to work as expected - - _jql = f"{date_filter}" + jql = f"({date_jql}) ORDER BY created DESC" if project_key: - _jql = ( - f'project = "{project_key}" AND {date_filter} ORDER BY created DESC' - ) + jql = f'project = "{project_key}" AND {jql}' - # Define fields to retrieve fields = [ "summary", "description", @@ -258,24 +259,25 @@ class JiraConnector: "issuetype", "project", ] - if include_comments: fields.append("comment") - params = { - # "jql": "", TODO : Add a JQL query to filter from a date range - "fields": ",".join(fields), - "maxResults": 100, - "startAt": 0, - } - - all_issues = [] + all_issues: list[dict[str, Any]] = [] start_at = 0 + max_results = 100 while True: - params["startAt"] = start_at + json_payload = { + "jql": jql, + "fields": fields, # pass as list + "maxResults": max_results, + "startAt": start_at, + } - result = self.make_api_request("search", params) + # Call new endpoint with POST + result = self.make_api_request( + "search/jql", json_payload=json_payload, method="POST" + ) if not isinstance(result, dict) or "issues" not in result: return [], "Invalid response from Jira API" @@ -283,9 +285,8 @@ class JiraConnector: issues = result["issues"] all_issues.extend(issues) - # Check if there are more issues to fetch total = result.get("total", 0) - if start_at + len(issues) >= total: + if start_at + len(issues) >= total or len(issues) == 0: break start_at += len(issues) From 107f013ff9934fc7d51484b997dbd9021860539b Mon Sep 17 00:00:00 2001 From: CREDO23 Date: Thu, 4 Dec 2025 01:21:46 +0200 Subject: [PATCH 4/6] jira-connector: update get_issues_by_date_range method --- .../app/connectors/jira_connector.py | 55 ++++++++++--------- 1 file changed, 28 insertions(+), 27 deletions(-) diff --git a/surfsense_backend/app/connectors/jira_connector.py b/surfsense_backend/app/connectors/jira_connector.py index c0bc080fd..d9474ee79 100644 --- a/surfsense_backend/app/connectors/jira_connector.py +++ b/surfsense_backend/app/connectors/jira_connector.py @@ -6,7 +6,6 @@ Allows fetching issue lists and their comments, projects and more. """ import base64 -import re from datetime import datetime from typing import Any @@ -221,7 +220,7 @@ class JiraConnector: project_key: str | None = None, ) -> tuple[list[dict[str, Any]], str | None]: """ - Fetch issues created OR updated within a date range using /search/jql. + Fetch issues within a date range. Args: start_date: Start date in YYYY-MM-DD format @@ -233,20 +232,20 @@ class JiraConnector: Tuple containing (issues list, error message or None) """ try: - # Validate date format (simple YYYY-MM-DD check) - for d in (start_date, end_date): - if not re.match(r"^\d{4}-\d{2}-\d{2}$", d): - return [], f"Invalid date format: {d}. Expected YYYY-MM-DD." - - # Build JQL: issues created OR updated within date range - date_jql = ( - f'(created >= "{start_date}" AND created <= "{end_date}") ' - f'OR (updated >= "{start_date}" AND updated <= "{end_date}")' + # Build JQL query for date range + # Query issues that were either created OR updated within the date range + date_filter = ( + f"(createdDate >= '{start_date}' AND createdDate <= '{end_date}')" ) - jql = f"({date_jql}) ORDER BY created DESC" - if project_key: - jql = f'project = "{project_key}" AND {jql}' + # TODO : This JQL needs some improvement to work as expected + _jql = f"{date_filter}" + if project_key: + _jql = ( + f'project = "{project_key}" AND {date_filter} ORDER BY created DESC' + ) + + # Define fields to retrieve fields = [ "summary", "description", @@ -259,25 +258,26 @@ class JiraConnector: "issuetype", "project", ] + if include_comments: fields.append("comment") - all_issues: list[dict[str, Any]] = [] + print(f"JQL query: {_jql}") + + params = { + "jql": _jql, + "fields": ",".join(fields), + "maxResults": 100, + "startAt": 0, + } + + all_issues = [] start_at = 0 - max_results = 100 while True: - json_payload = { - "jql": jql, - "fields": fields, # pass as list - "maxResults": max_results, - "startAt": start_at, - } + params["startAt"] = start_at - # Call new endpoint with POST - result = self.make_api_request( - "search/jql", json_payload=json_payload, method="POST" - ) + result = self.make_api_request("search/jql", params) if not isinstance(result, dict) or "issues" not in result: return [], "Invalid response from Jira API" @@ -285,8 +285,9 @@ class JiraConnector: issues = result["issues"] all_issues.extend(issues) + # Check if there are more issues to fetch total = result.get("total", 0) - if start_at + len(issues) >= total or len(issues) == 0: + if start_at + len(issues) >= total: break start_at += len(issues) From 521cea3ef0f79693958a9a263aa4ebaab0c0406c Mon Sep 17 00:00:00 2001 From: CREDO23 Date: Thu, 4 Dec 2025 12:53:18 +0200 Subject: [PATCH 5/6] update query parmas for get issues by date range method --- surfsense_backend/app/connectors/jira_connector.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/surfsense_backend/app/connectors/jira_connector.py b/surfsense_backend/app/connectors/jira_connector.py index d9474ee79..18193fce1 100644 --- a/surfsense_backend/app/connectors/jira_connector.py +++ b/surfsense_backend/app/connectors/jira_connector.py @@ -239,9 +239,9 @@ class JiraConnector: ) # TODO : This JQL needs some improvement to work as expected - _jql = f"{date_filter}" + jql = f"{date_filter}" if project_key: - _jql = ( + jql = ( f'project = "{project_key}" AND {date_filter} ORDER BY created DESC' ) @@ -262,10 +262,10 @@ class JiraConnector: if include_comments: fields.append("comment") - print(f"JQL query: {_jql}") + print(f"JQL query: {jql}") params = { - "jql": _jql, + "jql": jql, "fields": ",".join(fields), "maxResults": 100, "startAt": 0, From 803f792a9d9f79e57b21c67f24073f1798c4bb7c Mon Sep 17 00:00:00 2001 From: CREDO23 Date: Thu, 4 Dec 2025 12:55:19 +0200 Subject: [PATCH 6/6] clean up --- surfsense_backend/app/connectors/jira_connector.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/surfsense_backend/app/connectors/jira_connector.py b/surfsense_backend/app/connectors/jira_connector.py index 18193fce1..e73198e79 100644 --- a/surfsense_backend/app/connectors/jira_connector.py +++ b/surfsense_backend/app/connectors/jira_connector.py @@ -262,8 +262,6 @@ class JiraConnector: if include_comments: fields.append("comment") - print(f"JQL query: {jql}") - params = { "jql": jql, "fields": ",".join(fields),