Files
cve-dashboard/.kiro/specs/cve-tooltip-hover/tasks.md

108 lines
5.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.
# Implementation Plan: CVE Tooltip Hover
## Overview
Implement a hover tooltip for CVE badges in the Reporting Page findings table. The feature spans a backend endpoint (`GET /api/cves/:cveId/tooltip`) and a frontend `CveTooltip` portal component with in-memory caching and 300ms hover delay. Tasks are ordered backend-first, then frontend component, then integration, with property tests alongside each layer.
## Tasks
- [x] 1. Add backend tooltip endpoint
- [x] 1.1 Add `GET /api/cves/:cveId/tooltip` route inline in `backend/server.js`
- Place it alongside existing CVE endpoints (after `/api/cves/:cveId/vendors`)
- Validate `:cveId` against existing `CVE_ID_PATTERN`; return 400 for invalid format
- Query: `SELECT cve_id, description, severity FROM cves WHERE cve_id = ? LIMIT 1`
- If no row: return `{ exists: false }` with status 200
- If row found: truncate `description` to 300 chars + "…" if needed, return `{ exists: true, cve_id, description, severity }`
- Protect with `requireAuth(db)` middleware
- _Requirements: 1.1, 1.2, 1.3, 1.4, 1.5_
- [ ]* 1.2 Write property test for tooltip endpoint data correctness
- **Property 1: Tooltip endpoint returns correct data for existing CVEs**
- Install `fast-check` as dev dependency in `frontend/` (shared test runner)
- Generate random CVE records with description lengths 01000 and all 4 severity levels
- Verify response shape, truncation at 300 chars, and prefix preservation
- **Validates: Requirements 1.1, 1.3, 1.5**
- [ ]* 1.3 Write property test for description truncation
- **Property 2: Description truncation preserves content and enforces length**
- Extract truncation logic into a testable pure function
- Generate random strings of length 02000, verify length invariant and prefix match
- **Validates: Requirements 1.5**
- [x] 2. Checkpoint — Verify backend endpoint
- Ensure all tests pass, ask the user if questions arise.
- [x] 3. Create CveTooltip frontend component
- [x] 3.1 Create `frontend/src/components/CveTooltip.js`
- Portal-rendered component using `ReactDOM.createPortal` to `document.body`
- Props: `cveId` (string|null), `anchorRect` (DOMRect|null), `cache` (useRef Map)
- Internal state: `data`, `loading`
- On `cveId` change: check cache → if miss, fetch from `/api/cves/:cveId/tooltip` with AbortController
- If cached `exists: false` or fetch returns `exists: false`, render nothing
- Show loading spinner (Loader from lucide-react) while fetching
- Display: CVE ID in monospace, severity badge with design system colors, description text
- Max-width 320px, dark theme gradient background, accent border, directional arrow
- Position above anchor by default; flip below if insufficient viewport space above
- Do not cache transient errors (network failures)
- _Requirements: 2.1, 2.2, 2.3, 2.4, 2.5, 2.6, 3.1, 3.2, 3.3, 3.4, 3.5_
- [ ]* 3.2 Write property test for tooltip positioning logic
- **Property 3: Tooltip positioning flips based on available viewport space**
- Extract positioning calculation into a pure function
- Generate random anchorRect.top (02000), tooltip height (50200), viewport height (4001200)
- Verify tooltip never overflows top or bottom of viewport
- **Validates: Requirements 3.1, 3.2**
- [ ]* 3.3 Write unit tests for CveTooltip component
- Test loading state renders spinner
- Test `exists: false` renders nothing
- Test severity badge uses correct color per level
- Test max-width constraint
- Test directional arrow element is present
- _Requirements: 2.4, 2.5, 2.6, 3.3, 3.5_
- [x] 4. Checkpoint — Verify CveTooltip component
- Ensure all tests pass, ask the user if questions arise.
- [x] 5. Integrate tooltip into ReportingPage
- [x] 5.1 Add hover state and cache ref to ReportingPage
- Add state: `tooltipCveId` (string|null), `tooltipAnchorRect` (DOMRect|null)
- Add `useRef(new Map())` for tooltip cache
- Add `useRef` for hover delay timer
- Clear cache when findings data is re-synced (inside existing sync callback)
- _Requirements: 4.1, 4.4, 5.1_
- [x] 5.2 Add mouseenter/mouseleave handlers to CVE badge spans
- In the `renderCell` function for the `'cves'` column case, wrap each CVE badge `<span>` with `onMouseEnter` and `onMouseLeave`
- `onMouseEnter`: start 300ms setTimeout; on fire, set `tooltipCveId` and `tooltipAnchorRect` from `getBoundingClientRect()`
- `onMouseLeave`: clear timeout, set `tooltipCveId` to null
- _Requirements: 2.1, 2.2, 5.1, 5.2_
- [x] 5.3 Render CveTooltip instance in ReportingPage
- Add single `<CveTooltip>` at the bottom of the ReportingPage return, passing `tooltipCveId`, `tooltipAnchorRect`, and cache ref
- _Requirements: 2.1, 4.2, 4.3_
- [ ]* 5.4 Write property test for cache round-trip behavior
- **Property 4: Cache round-trip — fetch then cache-hit avoids network call**
- Generate random CVE IDs and response payloads, store in Map, verify lookups return identical objects
- **Validates: Requirements 4.1, 4.2**
- [ ]* 5.5 Write unit tests for hover delay and cache integration
- Test tooltip appears after 300ms delay (use fake timers)
- Test tooltip cancelled if mouseout before 300ms
- Test cached `exists: false` suppresses tooltip and API call
- Test cache cleared on data sync/refresh
- _Requirements: 4.3, 4.4, 5.1, 5.2_
- [x] 6. 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 project uses plain JavaScript (no TypeScript), fast-check for PBT, and react-scripts test (Jest)