Files
cve-dashboard/.kiro/specs/jira-api-compliance-cleanup/design.md

134 lines
6.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Design Document
## Overview
This design addresses two compliance issues flagged during the Charter Jira Data Center service account approval review (ATLSUP ticket), plus the corresponding documentation update. The changes are minimal and surgical — removing one Express route, changing one string literal, and updating one documentation file.
## Architecture
### Current State
The Jira integration has three layers:
1. **Helper layer** (`backend/helpers/jiraApi.js`): Low-level HTTP functions (`jiraGet`, `jiraPost`, etc.) and high-level operations (`getIssue`, `searchIssuesByKeys`, `searchIssues`, `createIssue`, etc.). All Charter compliance enforcement (rate limits, delays, blocked paths, explicit fields) lives here.
2. **Route layer** (`backend/routes/jiraTickets.js`): Express routes mounted at `/api/jira`. Includes both Jira API integration routes (connection-test, lookup, search, create-in-jira, sync-all, single sync) and local CRUD routes.
3. **Documentation layer** (`docs/api/jira-api-use-cases.md`): Documents all Jira API use cases, compliance posture, and estimated daily usage for the ATLSUP reviewer.
### Changes Required
#### Change 1: Remove `POST /api/jira/search` route
**File:** `backend/routes/jiraTickets.js`
**Action:** Delete the entire `router.post('/search', ...)` handler (approximately lines 136196). This route accepts arbitrary JQL from the frontend and passes it to `jiraApi.searchIssues()`. No frontend code references this endpoint (confirmed via codebase search). The underlying `searchIssues()` helper function in `jiraApi.js` is NOT removed — it is still called internally by `getIssue()` and `searchIssuesByKeys()`.
**Impact:** None on existing workflows. The four actual workflows (create, lookup, single sync, bulk sync) use dedicated routes that do not depend on the search route.
#### Change 2: Widen JQL window from `-24h` to `-72h`
**File:** `backend/helpers/jiraApi.js`
**Action:** In the `searchIssuesByKeys()` function, change the JQL string literal from:
```
`key in (${keyList}) AND updated >= -24h AND project = ${JIRA_PROJECT_KEY}`
```
to:
```
`key in (${keyList}) AND updated >= -72h AND project = ${JIRA_PROJECT_KEY}`
```
**Impact:** The bulk sync-all flow will now pick up tickets that were updated over the weekend. This increases the potential result set size for Monday morning syncs but remains well within the 1000-result cap (the team tracks dozens to low hundreds of tickets, not thousands).
#### Change 3: Update API documentation
**File:** `docs/api/jira-api-use-cases.md`
**Actions:**
- Remove the entire "Use Case 8: JQL Search (Bulk Sync)" section that references `POST /rest/api/2/search` with arbitrary JQL, and renumber it to describe only the scoped bulk sync via `GET /rest/api/2/search` with the predefined key-based JQL pattern
- Update the JQL pattern in the bulk sync use case from `updated >= -24h` to `updated >= -72h`
- Update the Compliance Summary Table: change the "Bulk reads via JQL" row to clarify that JQL is predefined/scoped (not arbitrary)
- Update the "JQL scoping" row to reflect the `-72h` window
- Remove the "JQL search (sync)" row from the Estimated Daily API Usage table or update it to reflect only the scoped bulk sync
- Recalculate the total estimated daily API call range
- Add `POST /rest/api/2/search` to the Blocked Endpoints section since arbitrary JQL search via POST is no longer used
## Correctness Properties
### Property 1: JQL window is always 72 hours in bulk sync (Invariant)
**Requirement:** 2.1, 2.3
**Property:** For any non-empty array of issue keys passed to `searchIssuesByKeys()`, the generated JQL string SHALL contain the substring `updated >= -72h` and SHALL contain the substring `project =`.
**Type:** Property-based test — the JQL structure must hold for any valid input array of keys.
**Test approach:** Mock `searchIssues()` to capture the JQL argument. Generate random arrays of valid-looking issue keys (e.g., `KEY-1` through `KEY-N`). Assert the JQL always contains `updated >= -72h` and `project =`.
### Property 2: Search route is absent from router (Example)
**Requirement:** 1.1, 1.2
**Property:** After the route removal, a `POST` request to `/api/jira/search` SHALL return HTTP 404.
**Type:** Example-based test — single request, single assertion.
**Test approach:** Mount the router in a test Express app, send `POST /api/jira/search` with a body, assert 404.
### Property 3: Existing routes remain functional after search route removal (Example)
**Requirement:** 1.3, 1.4, 1.5, 1.6
**Property:** The routes `GET /api/jira/lookup/:issueKey`, `POST /api/jira/sync-all`, `POST /api/jira/:id/sync`, and `POST /api/jira/create-in-jira` SHALL continue to respond with non-404 status codes.
**Type:** Example-based test — verify each route is still registered.
**Test approach:** Mount the router, send requests to each endpoint, assert none return 404 (they may return 503 if Jira is not configured, which is fine — the point is the route exists).
### Property 4: searchIssues helper remains exported (Example)
**Requirement:** 4.1
**Property:** The `jiraApi` module SHALL export `searchIssues` as a function.
**Type:** Example-based test — single assertion on module exports.
### Property 5: Documentation does not reference removed endpoint (Example)
**Requirement:** 3.1, 3.3, 3.4
**Property:** The file `docs/api/jira-api-use-cases.md` SHALL NOT contain the string `POST /api/jira/search` or `POST /rest/api/2/search` as an active use case.
**Type:** Example-based test — read file, assert absence of the string.
### Property 6: Documentation reflects 72-hour window (Example)
**Requirement:** 3.2
**Property:** The file `docs/api/jira-api-use-cases.md` SHALL contain `updated >= -72h` in the bulk sync use case and SHALL NOT contain `updated >= -24h`.
**Type:** Example-based test — read file, assert string presence/absence.
## File Changes
| File | Change Type | Description |
|---|---|---|
| `backend/routes/jiraTickets.js` | Modify | Remove the `router.post('/search', ...)` handler (~60 lines) |
| `backend/helpers/jiraApi.js` | Modify | Change `-24h` to `-72h` in `searchIssuesByKeys()` (1 line) |
| `docs/api/jira-api-use-cases.md` | Modify | Remove search use case, update JQL window, update compliance table, update usage estimates, add POST search to blocked endpoints |
## Dependencies
No new dependencies. No changes to `package.json`. No database migrations. No frontend changes required (no frontend code references the search endpoint).
## Risk Assessment
**Low risk.** All three changes are removals or single-line edits in well-understood code paths:
- The search route removal has zero callers in the frontend codebase
- The JQL window change is a single string literal with no behavioral side effects beyond returning a larger result set
- The documentation changes are purely textual
The only regression risk is if an undiscovered caller depends on `POST /api/jira/search`. The codebase search confirmed no such caller exists.