8.4 KiB
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, orcve. - 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
- THE Ticket_Links_Table SHALL store a source entity (source_type, source_id) and a target entity (target_type, target_id) in each row.
- 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.
- THE Ticket_Links_Table SHALL restrict source_type and target_type values to
archer,jira, orcve. - THE Ticket_Links_Table SHALL store a relationship label defaulting to
related. - THE Ticket_Links_Table SHALL record the user who created the link via a created_by foreign key to the users table.
- THE Ticket_Links_Table SHALL record the creation timestamp defaulting to the current time.
- 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
- 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.
- 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.
- 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.
- WHEN the source_type or target_type is not one of
archer,jira, orcve, THE Link_Service SHALL reject the request with a validation error. - 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.
- THE Link_Service SHALL require the user to be authenticated before creating a link.
- 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
- 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).
- THE Link_Service SHALL return each linked entity's type, ID, relationship label, creator, and creation timestamp.
- WHEN no links exist for the given entity, THE Link_Service SHALL return an empty list.
- 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
- WHEN a valid link ID is provided, THE Link_Service SHALL delete the corresponding row from the Ticket_Links_Table.
- WHEN the provided link ID does not exist, THE Link_Service SHALL return a not-found error.
- THE Link_Service SHALL require the user to be authenticated before deleting a link.
- 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
- WHILE viewing an Archer ticket detail page, THE Link_UI SHALL display a "Linked Items" section listing all entities linked to that Archer ticket.
- WHILE viewing a Jira ticket detail page, THE Link_UI SHALL display a "Linked Items" section listing all entities linked to that Jira ticket.
- WHEN no links exist for the displayed entity, THE Link_UI SHALL show an empty state message indicating no linked items.
- THE Link_UI SHALL display each linked item with its entity type, entity ID, and relationship label.
- 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
- 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.
- 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.
- 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.
- 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
- THE Link_UI SHALL display a remove control on each linked item in the Linked Items section.
- WHEN the user activates the remove control, THE Link_UI SHALL prompt for confirmation before proceeding.
- WHEN the user confirms removal, THE Link_UI SHALL call the Link_Service to delete the link and refresh the Linked Items section.
- 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
- WHEN a link is created from Entity A to Entity B, THE Link_Service SHALL return that link when queried from Entity A.
- WHEN a link is created from Entity A to Entity B, THE Link_Service SHALL return that link when queried from Entity B.
- 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
- THE Link_Service SHALL not require any entity to have links — entities with zero links remain fully functional.
- THE Link_Service SHALL not modify the existing cve_id and vendor foreign key columns on archer_tickets or jira_tickets.
- WHEN an entity has no links, THE Link_UI SHALL display the empty state without errors or warnings.