Files
cve-dashboard/.kiro/specs/jira-api-compliance/bugfix.md
root 27192dd69f WIP: Dashboard redesign — design system overhaul and component updates
Frontend redesign in progress: updated styles, layout, and components
across all pages to align with new design system. Includes Jira API
compliance specs, property tests, and load test script.
2026-04-29 14:20:23 +00:00

5.1 KiB

Bugfix Requirements Document

Introduction

The Jira REST API integration in the STEAM Security Dashboard was submitted for production approval and the reviewer identified three compliance violations that block approval. The searchIssues() function uses POST /rest/api/2/search instead of the required GET with query parameters. The getIssue() function performs single-issue GET /rest/api/2/issue/{key} calls, which are not allowed — all issue fetching must go through JQL search. Additionally, JQL queries do not consistently include project = <KEY> scoping, which is required for all search operations. These issues affect backend/helpers/jiraApi.js, backend/scripts/jira-uat-test.js, and docs/jira-api-use-cases.md.

Bug Analysis

Current Behavior (Defect)

1.1 WHEN searchIssues() is called with a JQL query THEN the system sends a POST /rest/api/2/search request with a JSON body containing { jql, startAt, maxResults, fields }, which is not allowed by the reviewer

1.2 WHEN searchIssuesByKeys() is called to bulk-fetch issues by key THEN the system sends a POST /rest/api/2/search request (via searchIssues()) without a project = <KEY> clause in the JQL

1.3 WHEN getIssue() is called with a single issue key THEN the system sends a GET /rest/api/2/issue/{key}?fields=... request, which is a single-issue GET that the reviewer does not allow

1.4 WHEN the UAT test script exercises use case 3 ("Get Single Issue") THEN it calls getIssue() which performs the non-compliant single-issue GET pattern

1.5 WHEN the UAT test script exercises use case 8 ("JQL Search") THEN it calls searchIssues() which performs the non-compliant POST to /rest/api/2/search

1.6 WHEN the API documentation describes the JQL Search use case THEN it lists the endpoint as POST /rest/api/2/search, which does not match the required compliant pattern

1.7 WHEN the API documentation describes the "Get Single Issue" and "Issue Lookup" use cases THEN it lists the endpoint as GET /rest/api/2/issue/{issueKey}?fields=..., which is the non-compliant single-issue GET pattern

Expected Behavior (Correct)

2.1 WHEN searchIssues() is called with a JQL query THEN the system SHALL send a GET /rest/api/2/search request with query parameters ?jql=<encoded-jql>&fields=<comma-separated-fields>&maxResults=1000&startAt=0 instead of a POST with a JSON body

2.2 WHEN searchIssuesByKeys() is called to bulk-fetch issues by key THEN the system SHALL include a project = <JIRA_PROJECT_KEY> clause in the JQL query alongside the key in (...) clause

2.3 WHEN getIssue() is called with a single issue key THEN the system SHALL perform a JQL search using GET /rest/api/2/search?jql=key="ISSUE-KEY" AND project=<JIRA_PROJECT_KEY>&fields=<fields>&maxResults=1 instead of a direct single-issue GET

2.4 WHEN the UAT test script exercises the single-issue fetch use case THEN it SHALL call the refactored getIssue() which uses JQL search, and the test name SHALL reflect the compliant pattern

2.5 WHEN the UAT test script exercises the JQL search use case THEN it SHALL call searchIssues() which uses GET /rest/api/2/search with query parameters, and the JQL SHALL include project = <JIRA_PROJECT_KEY> scoping

2.6 WHEN the API documentation describes the JQL Search use case THEN it SHALL list the endpoint as GET /rest/api/2/search with query parameters ?jql=, &fields=, &maxResults=, &startAt=

2.7 WHEN the API documentation describes the single-issue fetch use case THEN it SHALL describe it as a JQL search using GET /rest/api/2/search?jql=key="ISSUE-KEY" AND project=<KEY>&fields=...&maxResults=1 and SHALL NOT reference GET /rest/api/2/issue/{key}

Unchanged Behavior (Regression Prevention)

3.1 WHEN createIssue() is called THEN the system SHALL CONTINUE TO send a POST /rest/api/2/issue request with the issue fields in the JSON body

3.2 WHEN updateIssue() is called THEN the system SHALL CONTINUE TO send a PUT /rest/api/2/issue/{key} request to update a single issue

3.3 WHEN addComment() is called THEN the system SHALL CONTINUE TO send a POST /rest/api/2/issue/{key}/comment request

3.4 WHEN transitionIssue() is called THEN the system SHALL CONTINUE TO send a POST /rest/api/2/issue/{key}/transitions request

3.5 WHEN getTransitions() is called THEN the system SHALL CONTINUE TO send a GET /rest/api/2/issue/{key}/transitions request

3.6 WHEN testConnection() is called THEN the system SHALL CONTINUE TO send a GET /rest/api/2/myself request

3.7 WHEN the rate limiter checks request counts THEN the system SHALL CONTINUE TO enforce the 1,440 requests/day daily limit and 60 requests/minute burst limit

3.8 WHEN inter-request delays are applied THEN the system SHALL CONTINUE TO enforce 1 second delay between GET requests and 2 second delay between write requests

3.9 WHEN a blocked endpoint path is requested THEN the system SHALL CONTINUE TO reject calls to /rest/api/2/field and /rest/api/2/issue/bulk

3.10 WHEN searchIssues() returns results THEN the system SHALL CONTINUE TO return the same { ok, data } response shape so that all callers remain compatible