Files
cve-dashboard/.kiro/specs/ticket-linking/requirements.md

124 lines
8.4 KiB
Markdown

# Requirements Document
## Introduction
The CVE Dashboard currently tracks three entity types — Archer tickets (risk acceptance exceptions), Jira tickets (work items), and CVEs (vulnerabilities) — but relationships between them are limited to a single primary CVE foreign key on each ticket. This feature introduces a generic `ticket_links` table that enables bidirectional, many-to-many associations between any combination of these entities. Users will be able to view, create, and remove links from ticket detail views in the UI.
## Glossary
- **Link_Service**: The backend service responsible for creating, querying, and deleting ticket links.
- **Link_UI**: The frontend component that displays linked items and provides controls for adding/removing links.
- **Ticket_Links_Table**: The PostgreSQL table storing associations between entities.
- **Entity**: One of the three linkable types in the system — an Archer ticket, a Jira ticket, or a CVE.
- **Source**: The entity on the left side of a link record.
- **Target**: The entity on the right side of a link record.
- **Entity_Type**: A classification string identifying the kind of entity: `archer`, `jira`, or `cve`.
- **Entity_ID**: The unique identifier for an entity within its type (e.g., `EXC-6056`, `STEAM-1234`, `CVE-2025-0905`).
- **Relationship**: A label describing the nature of a link (e.g., `related`, `spawned_by`, `blocks`).
## Requirements
### Requirement 1: Create the ticket_links Table
**User Story:** As a database administrator, I want a dedicated table for storing entity associations, so that any entity can be linked to any other entity without schema changes.
#### Acceptance Criteria
1. THE Ticket_Links_Table SHALL store a source entity (source_type, source_id) and a target entity (target_type, target_id) in each row.
2. THE Ticket_Links_Table SHALL enforce a UNIQUE constraint on the combination of (source_type, source_id, target_type, target_id) to prevent duplicate links.
3. THE Ticket_Links_Table SHALL restrict source_type and target_type values to `archer`, `jira`, or `cve`.
4. THE Ticket_Links_Table SHALL store a relationship label defaulting to `related`.
5. THE Ticket_Links_Table SHALL record the user who created the link via a created_by foreign key to the users table.
6. THE Ticket_Links_Table SHALL record the creation timestamp defaulting to the current time.
7. THE Ticket_Links_Table SHALL include indexes on (source_type, source_id) and (target_type, target_id) to support efficient bidirectional queries.
### Requirement 2: Create a Link
**User Story:** As a security analyst, I want to create a link between two entities, so that I can document relationships between Archer exceptions, Jira work items, and CVEs.
#### Acceptance Criteria
1. WHEN a valid source entity, target entity, and relationship are provided, THE Link_Service SHALL insert a new row into the Ticket_Links_Table and return the created link record.
2. WHEN the source entity and target entity are identical (same type and same ID), THE Link_Service SHALL reject the request with a validation error.
3. WHEN a link between the same source and target already exists, THE Link_Service SHALL reject the request with a conflict error indicating the duplicate.
4. WHEN the source_type or target_type is not one of `archer`, `jira`, or `cve`, THE Link_Service SHALL reject the request with a validation error.
5. WHEN the entity ID format does not match the expected pattern for its type, THE Link_Service SHALL reject the request with a validation error.
6. THE Link_Service SHALL require the user to be authenticated before creating a link.
7. THE Link_Service SHALL log an audit entry when a link is successfully created.
### Requirement 3: Query Links for an Entity
**User Story:** As a security analyst, I want to see all items linked to a given entity, so that I can understand the full context of a ticket or vulnerability.
#### Acceptance Criteria
1. WHEN an entity type and entity ID are provided, THE Link_Service SHALL return all links where the entity appears as either source or target (bidirectional query).
2. THE Link_Service SHALL return each linked entity's type, ID, relationship label, creator, and creation timestamp.
3. WHEN no links exist for the given entity, THE Link_Service SHALL return an empty list.
4. THE Link_Service SHALL require the user to be authenticated before querying links.
### Requirement 4: Delete a Link
**User Story:** As a security analyst, I want to remove a link between two entities, so that I can correct mistakes or remove outdated associations.
#### Acceptance Criteria
1. WHEN a valid link ID is provided, THE Link_Service SHALL delete the corresponding row from the Ticket_Links_Table.
2. WHEN the provided link ID does not exist, THE Link_Service SHALL return a not-found error.
3. THE Link_Service SHALL require the user to be authenticated before deleting a link.
4. THE Link_Service SHALL log an audit entry when a link is successfully deleted.
### Requirement 5: Display Linked Items in the UI
**User Story:** As a security analyst, I want to see a "Linked Items" section on ticket detail views, so that I can quickly navigate between related entities.
#### Acceptance Criteria
1. WHILE viewing an Archer ticket detail page, THE Link_UI SHALL display a "Linked Items" section listing all entities linked to that Archer ticket.
2. WHILE viewing a Jira ticket detail page, THE Link_UI SHALL display a "Linked Items" section listing all entities linked to that Jira ticket.
3. WHEN no links exist for the displayed entity, THE Link_UI SHALL show an empty state message indicating no linked items.
4. THE Link_UI SHALL display each linked item with its entity type, entity ID, and relationship label.
5. THE Link_UI SHALL render each linked item's entity ID as a navigable link to that entity's detail view.
### Requirement 6: Add a Link from the UI
**User Story:** As a security analyst, I want an "Add Link" button on ticket detail views, so that I can create associations without leaving the page.
#### Acceptance Criteria
1. WHEN the user clicks the "Add Link" button, THE Link_UI SHALL display a form allowing the user to enter a target entity key and select a relationship type.
2. WHEN the user submits the form with a valid entity key, THE Link_UI SHALL call the Link_Service to create the link and refresh the Linked Items section.
3. WHEN the Link_Service returns a validation or conflict error, THE Link_UI SHALL display the error message to the user without clearing the form.
4. THE Link_UI SHALL auto-detect the entity type from the entered key format (EXC-XXXX for Archer, PROJECT-XXXX for Jira, CVE-YYYY-NNNNN for CVE).
### Requirement 7: Remove a Link from the UI
**User Story:** As a security analyst, I want to remove a link directly from the Linked Items section, so that I can manage associations without navigating away.
#### Acceptance Criteria
1. THE Link_UI SHALL display a remove control on each linked item in the Linked Items section.
2. WHEN the user activates the remove control, THE Link_UI SHALL prompt for confirmation before proceeding.
3. WHEN the user confirms removal, THE Link_UI SHALL call the Link_Service to delete the link and refresh the Linked Items section.
4. WHEN the Link_Service returns an error during removal, THE Link_UI SHALL display the error message to the user.
### Requirement 8: Bidirectional Link Symmetry
**User Story:** As a security analyst, I want links to be visible from both sides of the association, so that navigating from either entity shows the connection.
#### Acceptance Criteria
1. WHEN a link is created from Entity A to Entity B, THE Link_Service SHALL return that link when queried from Entity A.
2. WHEN a link is created from Entity A to Entity B, THE Link_Service SHALL return that link when queried from Entity B.
3. THE Link_Service SHALL treat (source=A, target=B) and (source=B, target=A) as the same logical link — creating one SHALL prevent creating the other.
### Requirement 9: Links are Optional
**User Story:** As a security analyst, I want the linking feature to be purely additive, so that existing tickets without links continue to function normally.
#### Acceptance Criteria
1. THE Link_Service SHALL not require any entity to have links — entities with zero links remain fully functional.
2. THE Link_Service SHALL not modify the existing cve_id and vendor foreign key columns on archer_tickets or jira_tickets.
3. WHEN an entity has no links, THE Link_UI SHALL display the empty state without errors or warnings.