Files
cve-dashboard/.kiro/specs/flexible-jira-ticket-creation/tasks.md
Jordan Ramos a61d254ff9 Sync .kiro/ from master — v2.2.0 release batch
New specs: archer-template-library, ccp-metrics-view-restructure,
compliance-list-stale-after-sidebar-edit, compliance-metric-estimated-resolution-date,
compliance-remediation-display-fix, flexible-jira-ticket-creation,
forecast-burndown-chart, granite-loader-export, ivanti-queue-clear-completed-fix,
multi-item-jira-ticket, queue-collapsible-sections, vendor-issue-type-dropdown

New steering: archer-template-gen.md

Updated: migration-registration-check hook, remediation-plan-history spec,
gitlab-workflow, tech, versioning steering files
2026-06-04 11:27:31 -06:00

9.1 KiB
Raw Blame History

Implementation Plan: Flexible Jira Ticket Creation

Overview

This plan implements flexible Jira ticket creation by making CVE ID and Vendor optional, adding source_context tracking, updating the creation modal, exposing "Create Jira Ticket" actions from Ivanti queue and Archer detail views, and updating the ticket list with source context display and filtering. The implementation proceeds from database migration → backend validation → frontend modal updates → integration points → list view enhancements.

Tasks

  • 1. Database migration for schema changes

    • 1.1 Create migration file backend/migrations/add_flexible_jira_ticket_creation.js
      • Drop NOT NULL constraint on cve_id column
      • Drop NOT NULL constraint on vendor column
      • Add source_context TEXT DEFAULT 'manual' column with IF NOT EXISTS
      • Add CHECK constraint for allowed source_context values (cve, archer, ivanti_queue, email, manual) with idempotent guard
      • Backfill existing rows with source_context = 'manual' where NULL
      • Add index on source_context column
      • Verify jira_tickets table exists before proceeding; exit with error if missing
      • Ensure full idempotency — safe to run multiple times
      • Requirements: 1.5, 2.4, 3.1, 3.5, 7.1, 7.2, 7.3, 7.4, 7.5, 7.6
  • 2. Update backend validation and creation endpoint

    • 2.1 Update POST /api/jira-tickets/create-in-jira validation logic in backend/routes/jiraTickets.js

      • Make cve_id optional: accept absent, null, or empty string as NULL; validate format CVE-YYYY-NNNN+ only when non-empty
      • Make vendor optional: accept absent, null, empty, or whitespace-only as NULL; trim and validate max 200 chars when non-empty
      • Add source_context validation: must be in allowed set if provided, default to manual if absent
      • Update INSERT query to include source_context column
      • Update 201 response to include source_context in returned JSON
      • Update audit log details to include source_context
      • Requirements: 1.1, 1.2, 1.3, 1.4, 2.1, 2.2, 2.3, 2.5, 3.2, 3.3, 3.4
    • 2.2 Update PUT /api/jira-tickets/:id to reject source_context changes

      • If request body contains source_context field, return 400 with "source_context is immutable after creation"
      • Requirements: 3.6
    • 2.3 Update GET /api/jira-tickets to include source_context in response

      • Ensure source_context is included in SELECT query and returned in ticket objects
      • Requirements: 3.4
    • * 2.4 Write property tests for CVE ID validation (Property 1 and Property 2)

      • Property 1: CVE ID validation and storage — For any payload with absent/null/empty cve_id, service accepts and stores NULL; for valid CVE format, stores exact value
      • Property 2: Invalid CVE ID rejection — For any non-empty string not matching CVE-YYYY-NNNN+, service rejects with 400
      • Validates: Requirements 1.1, 1.2, 1.3, 1.4
      • File: backend/__tests__/jira-flexible-cve-validation.property.test.js
    • * 2.5 Write property tests for Vendor validation (Property 3 and Property 4)

      • Property 3: Vendor validation and storage — For any payload with absent/null/empty/whitespace vendor, stores NULL; for 1200 char string after trim, stores trimmed value
      • Property 4: Over-length vendor rejection — For any string exceeding 200 chars after trim, service rejects with validation error
      • Validates: Requirements 2.1, 2.2, 2.3
      • File: backend/__tests__/jira-flexible-vendor-validation.property.test.js
    • * 2.6 Write property tests for source_context validation (Property 5, Property 6, Property 7)

      • Property 5: Invalid source_context rejection — For any string not in allowed set, service rejects with 400
      • Property 6: source_context round-trip persistence — For any valid source_context, creating then fetching returns same value
      • Property 7: source_context immutability — For any existing ticket, update with source_context field is rejected with 400
      • Validates: Requirements 3.3, 3.4, 3.6
      • File: backend/__tests__/jira-flexible-source-context.property.test.js
  • 3. Checkpoint - Ensure all tests pass

    • Ensure all tests pass, ask the user if questions arise.
  • 4. Update frontend Creation Modal for optional fields

    • 4.1 Update the create Jira ticket modal in frontend/src/components/pages/JiraPage.js
      • Change CVE ID label to "CVE ID (optional)" with placeholder "e.g. CVE-2024-12345"
      • Change Vendor label to "Vendor (optional)" with placeholder "e.g. Microsoft"
      • Add Source Context dropdown with options: CVE → cve, Archer Request → archer, Ivanti Queue → ivanti_queue, Email → email, Manual → manual; no default selection
      • Allow form submission when CVE ID and Vendor are both empty
      • Keep Summary as required with inline error on empty submit (max 255 chars)
      • Send source_context in payload only when selected; omit if no selection (backend defaults to manual)
      • Support pre-populated field values and locked source_context (read-only when set externally)
      • Preserve form field values on API error for retry
      • Requirements: 4.1, 4.2, 4.3, 4.4, 4.5, 4.6, 4.7, 5.6, 6.5
  • 5. Add "Create Jira Ticket" action from Ivanti Queue

    • 5.1 Add "Create Jira Ticket" button to Ivanti queue items in frontend/src/components/pages/IvantiTodoQueuePage.js

      • Add button/action to each queue item row
      • On click, open Creation Modal with: summary pre-populated from finding_title (truncated to 255 chars), source_context locked to ivanti_queue, cve_id from first element of cves_json (if non-empty), vendor from queue item's vendor (if present)
      • Leave CVE ID blank if cves_json is empty or null
      • Requirements: 5.1, 5.2, 5.3, 5.4, 5.5
    • * 5.2 Write property test for summary truncation (Property 8)

      • Property 8: Summary pre-population truncation from Ivanti queue — For any finding_title of arbitrary length, pre-populated summary is at most 255 chars and equals first 255 chars of finding_title
      • Validates: Requirements 5.2
      • File: backend/__tests__/jira-flexible-summary-truncation.property.test.js
  • 6. Add "Create Jira Ticket" action from Archer Detail View

    • 6.1 Add "Create Jira Ticket" button to Archer ticket detail view in frontend/src/components/pages/ArcherPage.js
      • Show button only for users with editor or admin role
      • On click, open Creation Modal with: summary pre-populated with exc_number (e.g., "EXC-1234"), source_context locked to archer, cve_id from Archer ticket's cve_id (if present), vendor from Archer ticket's vendor (if present)
      • Requirements: 6.1, 6.2, 6.3, 6.4, 6.5
  • 7. Update ticket list with source context display and filtering

    • 7.1 Add source context badge column to ticket list in frontend/src/components/pages/JiraPage.js

      • Add "Source" column between Vendor and Summary columns
      • Display color-coded badge per source_context value: cve → blue (#0EA5E9), archer → purple (#8B5CF6), ivanti_queue → amber (#F59E0B), email → green (#10B981), manual → gray (#94A3B8)
      • Display "CVE" badge (blue) for null/empty source_context (legacy tickets)
      • Requirements: 8.1, 8.2
    • 7.2 Add source context dropdown filter to ticket list

      • Add dropdown filter consistent with existing status filter pattern
      • Include "All" option showing all tickets plus one option per distinct source_context value
      • Requirements: 8.3
    • 7.3 Include source_context in ticket search

      • Add source_context to the set of searchable fields alongside ticket_key, cve_id, vendor, and summary
      • Requirements: 8.4
    • * 7.4 Write property test for search includes source_context (Property 9)

      • Property 9: Search includes source_context — For any ticket whose source_context contains the search term as a substring, that ticket appears in filtered results
      • Validates: Requirements 8.4
      • File: backend/__tests__/jira-flexible-search-source-context.property.test.js
  • 8. Final checkpoint - Ensure all tests pass

    • Ensure all tests pass, ask the user if questions arise.

Notes

  • Tasks marked with * are optional and can be skipped for faster MVP
  • Each task references specific requirements for traceability
  • Checkpoints ensure incremental validation
  • Property tests validate universal correctness properties from the design document
  • Unit tests validate specific examples and edge cases
  • The migration must run before backend changes are tested against a real database
  • The Creation Modal is shared across all three entry points (Jira page, Ivanti queue, Archer detail) — task 4.1 builds the reusable foundation, tasks 5.1 and 6.1 wire it from their respective contexts

Task Dependency Graph

{
  "waves": [
    { "id": 0, "tasks": ["1.1"] },
    { "id": 1, "tasks": ["2.1", "2.2", "2.3"] },
    { "id": 2, "tasks": ["2.4", "2.5", "2.6"] },
    { "id": 3, "tasks": ["4.1"] },
    { "id": 4, "tasks": ["5.1", "6.1"] },
    { "id": 5, "tasks": ["5.2", "7.1", "7.2", "7.3"] },
    { "id": 6, "tasks": ["7.4"] }
  ]
}