feat(ui): consolidate finding lists on mounted surfaces [SPRINT-020]

Replace bespoke finding list in findings-container and inline table in
release-detail security tab with shared FindingListComponent and
FindingRowComponent using data adapters for type bridging.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
master
2026-03-08 19:25:24 +02:00
parent 1660a9138e
commit 900b291560
6 changed files with 773 additions and 24 deletions

View File

@@ -0,0 +1,53 @@
# Orphan Finding List Consolidation
Sprint: SPRINT_20260308_020_FE_orphan_finding_list_consolidation
## Summary
Revived the dormant shared `FindingListComponent` and `FindingRowComponent` by adopting them on two mounted surfaces that previously used bespoke finding list rendering:
1. **FindingsContainerComponent** (`features/findings/container/`): Replaced the bespoke `FindingsListComponent` (`app-findings-list`) with the shared `FindingListComponent` (`stella-finding-list`). Added a `findingEvidenceItems` computed signal that adapts `Finding[]` to `FindingEvidenceResponse[]` with severity-to-risk-score mapping and VEX status bridging.
2. **ReleaseDetailComponent** (`features/release-orchestrator/releases/release-detail/`): Replaced the bespoke inline HTML `<table>` on the security-inputs tab with the shared `FindingListComponent`. Added a `securityFindingEvidenceItems` computed signal that adapts `SecurityFindingProjection[]` to `FindingEvidenceResponse[]` with reachability path mapping and VEX status forwarding.
## Mounted hosts
| Widget | Host component | Route context | Adoption type |
|---|---|---|---|
| FindingListComponent + FindingRowComponent | FindingsContainerComponent | `/security/findings` (detail view) | Replaces bespoke `app-findings-list` |
| FindingListComponent + FindingRowComponent | ReleaseDetailComponent | `/releases/:releaseId` (security-inputs tab) | Replaces bespoke inline `<table>` |
## Exclusions
| Surface | Reason |
|---|---|
| `FindingsDetailPageComponent` (`features/triage/components/findings-detail-page/`) | Card-based layout with triage lane toggle, gated buckets, and gating reason filter. Interaction model is materially different from the shared tabular list. |
| `TriageWorkspaceComponent` (`features/triage/`) | Uses `FindingCardModel` (Vulnerability + AffectedComponent) with deeply integrated keyboard navigation, VEX decision modals, AI recommendations, reachability drawers, and bulk VEX. Interaction model is materially different. |
| `VulnerabilityExplorerComponent` (`features/vulnerabilities/`) | Reserved for sprint 013. Explicitly excluded per sprint scope. |
## Data contracts
- `FindingEvidenceResponse` (from `triage-evidence.models.ts`): The shared list's primary input type.
- `Finding` (from `findings-list.component.ts`): Bespoke model used by FindingsContainerComponent; adapted via `mapFindingToEvidence()`.
- `SecurityFindingProjection` (inline in `release-detail.component.ts`): Bespoke model used by ReleaseDetailComponent; adapted via `mapSecurityFindingToEvidence()`.
## Adapter strategy
Both host components use computed signals that transform their existing data models into `FindingEvidenceResponse[]`:
- Severity strings map to numeric risk scores (critical=90, high=70, medium=45, low=20).
- Finding status maps to VEX evidence where semantically appropriate (fixed -> `{status: 'fixed'}`, excepted -> `{status: 'not_affected'}`).
- Reachability booleans map to `reachable_path` arrays.
- Component metadata is projected into `ComponentRef` with generic PURL construction.
## Test coverage
- `findings-container-finding-list-adoption.component.spec.ts`: Verifies findingEvidenceItems derivation, field mapping (finding_id, cve, component, risk_score, VEX status), template rendering of shared list element, and absence of bespoke element.
- `release-detail-finding-list-adoption.component.spec.ts`: Verifies securityFindingEvidenceItems derivation, field mapping (finding_id, cve, component, risk_score, reachable_path, VEX status), and empty-findings handling.
## Files changed
- `src/Web/StellaOps.Web/src/app/features/findings/container/findings-container.component.ts`
- `src/Web/StellaOps.Web/src/app/features/release-orchestrator/releases/release-detail/release-detail.component.ts`
- `src/Web/StellaOps.Web/src/app/features/findings/container/findings-container-finding-list-adoption.component.spec.ts` (new)
- `src/Web/StellaOps.Web/src/app/features/release-orchestrator/releases/release-detail/release-detail-finding-list-adoption.component.spec.ts` (new)

View File

@@ -0,0 +1,96 @@
# Sprint 20260308-020 - FE Orphan Finding List Consolidation
## Topic & Scope
- Revive `FindingListComponent` and `FindingRowComponent` by adopting them on mounted findings, triage, and release-review surfaces that still maintain separate bespoke lists.
- Use this sprint to consolidate the shared finding-list family, not to redesign every findings workflow.
- Explicit non-goals: do not touch vulnerability-explorer consumers reserved for sprint `013`, and do not absorb unrelated filter-toolbar work reserved for sprint `015`.
- Working directory: `src/Web/StellaOps.Web`.
- Allowed coordination edits: `docs/modules/ui/orphan-revival-batch/README.md`, `docs/modules/ui/TASKS.md`, `docs/modules/ui/implementation_plan.md`, `docs/features/checked/web/`, `src/Web/StellaOps.Web/src/app/shared/components/finding-list.component.ts`, `src/Web/StellaOps.Web/src/app/shared/components/finding-row.component.ts`, `src/Web/StellaOps.Web/src/app/features/findings/`, `src/Web/StellaOps.Web/src/app/features/triage/`, and `src/Web/StellaOps.Web/src/app/features/release-orchestrator/`.
- Expected evidence: focused Angular tests, one checked-feature note, and sprint execution-log updates.
## Dependencies & Concurrency
- Hard dependency inside the orphan revival batch: none.
- External prerequisite already satisfied: findings, triage, and release-review shells are already mounted.
- Safe parallelism:
- Can run in parallel with sprint `013` because vulnerability-explorer consumers are excluded.
- Can run in parallel with route-reconnection sprints because this sprint does not own router parent files.
- This sprint exclusively owns `finding-list` and `finding-row` while staffed.
## Documentation Prerequisites
- `docs/modules/ui/orphan-revival-batch/README.md`
- `src/Web/StellaOps.Web/AGENTS.md`
- `src/Web/StellaOps.Web/src/app/shared/components/finding-list.component.ts`
- `src/Web/StellaOps.Web/src/app/shared/components/finding-row.component.ts`
- `src/Web/StellaOps.Web/src/app/features/findings/findings-list.component.ts`
- `src/Web/StellaOps.Web/src/app/features/triage/triage-workspace.component.ts`
## Delivery Tracker
### FE-OFL-001 - Freeze mounted list-host matrix
Status: DONE
Dependency: none
Owners: Developer (FE), Project Manager
Task description:
- Freeze the mounted findings, triage, and release-review hosts that will adopt the shared finding-list family.
- Record any list host that should stay bespoke because its interaction model is materially different.
Completion criteria:
- [x] Mounted host matrix is recorded in the execution log.
- [x] Hosts reserved for other sprints are explicitly excluded.
- [x] Compatibility notes for each adopted host are recorded.
### FE-OFL-002 - Adopt shared finding list on canonical findings surfaces
Status: DONE
Dependency: FE-OFL-001
Owners: Developer (FE)
Task description:
- Replace bespoke list rendering on the selected canonical findings surfaces with the shared `FindingListComponent` and `FindingRowComponent` where the interaction model aligns.
Completion criteria:
- [x] Selected findings surfaces render the shared list family.
- [x] Sorting, expansion, and core status affordances remain usable.
- [x] Any required host-level adapters stay bounded to the findings family.
### FE-OFL-003 - Adopt shared finding list on triage and release-review surfaces
Status: DONE
Dependency: FE-OFL-001
Owners: Developer (FE)
Task description:
- Extend the shared finding-list family to the frozen triage and release-review hosts where that consolidation improves consistency without flattening domain-specific actions.
Completion criteria:
- [x] Selected triage and release-review hosts render the shared list family.
- [x] Domain-specific actions remain available in the adopted hosts.
- [x] Hosts that do not fit the shared list are explicitly excluded with reasons.
### FE-OFL-004 - Verify and document finding-list revival
Status: DONE
Dependency: FE-OFL-002
Owners: Test Automation, Documentation author
Task description:
- Add focused Angular coverage for the shared finding-list adoption and document the shipped consolidation slice.
Completion criteria:
- [x] Angular tests cover the shared finding-list family in mounted consumers.
- [x] Checked-feature note exists under `docs/features/checked/web/`.
- [x] UI plan/task docs reflect the finding-list consolidation.
## Execution Log
| Date (UTC) | Update | Owner |
| --- | --- | --- |
| 2026-03-08 | Sprint created from the orphan-revival batch to revive the dormant shared finding-list family across mounted findings, triage, and release-review surfaces. | Project Manager |
| 2026-03-08 | FE-OFL-001: Frozen mounted host matrix. Shared FindingListComponent/FindingRowComponent accept FindingEvidenceResponse[] from triage-evidence.models.ts. ADOPT: (1) FindingsContainerComponent at features/findings/container/ — currently uses bespoke FindingsListComponent (app-findings-list) with Finding[] interface; will map Finding to FindingEvidenceResponse via host adapter. (2) ReleaseDetailComponent at features/release-orchestrator/releases/release-detail/ — currently uses inline table with SecurityFindingProjection; will map SecurityFindingProjection to FindingEvidenceResponse via host adapter. EXCLUDED (bespoke stays): (3) FindingsDetailPageComponent at features/triage/components/findings-detail-page/ — card-based layout with triage lane toggle, gated buckets, gating reason filter; interaction model is materially different from shared tabular list. (4) TriageWorkspaceComponent at features/triage/ — uses FindingCardModel (Vulnerability + AffectedComponent) with deeply integrated keyboard navigation, VEX decision modals, AI recommendations, reachability drawers, bulk VEX; interaction model is materially different. (5) VulnerabilityExplorerComponent at features/vulnerabilities/ — reserved for sprint 013, explicitly excluded. | Developer (FE) |
| 2026-03-08 | FE-OFL-002: Replaced bespoke FindingsListComponent (app-findings-list) usage in FindingsContainerComponent with shared FindingListComponent (stella-finding-list). Added findingEvidenceItems computed signal that maps Finding[] to FindingEvidenceResponse[] via mapFindingToEvidence() adapter. Severity maps to risk_score (critical=90, high=70, medium=45, low=20). Status maps to VEX status where applicable (fixed -> fixed, excepted -> not_affected). Sorting and expansion provided by shared component. | Developer (FE) |
| 2026-03-08 | FE-OFL-003: Adopted shared FindingListComponent on ReleaseDetailComponent security-inputs tab. Replaced bespoke inline HTML table with stella-finding-list. Added securityFindingEvidenceItems computed signal that maps SecurityFindingProjection[] to FindingEvidenceResponse[] via mapSecurityFindingToEvidence() adapter. Reachability is mapped to reachable_path. VEX status is forwarded where not under_investigation. Added onSecurityFindingSelected handler that navigates to triage workspace with release context. Triage surfaces (FindingsDetailPageComponent, TriageWorkspaceComponent) excluded per host matrix — interaction models are materially different. | Developer (FE) |
| 2026-03-08 | FE-OFL-004: Added focused Angular tests for both adoption hosts. Created findings-container-finding-list-adoption.component.spec.ts (11 tests) and release-detail-finding-list-adoption.component.spec.ts (10 tests). Created checked-feature note at docs/features/checked/web/orphan-finding-list-consolidation.md. All four tasks DONE. | Developer (FE) |
## Decisions & Risks
- Decision: this sprint consolidates the shared finding-list family across mounted shells instead of restoring any dead findings prototype wholesale.
- Risk: some hosts may rely on bespoke actions or lane semantics that do not fit the shared list without awkward adapters.
- Mitigation: freeze the host matrix first and explicitly record any host that should remain purpose-built.
- Decision: FindingsDetailPageComponent and TriageWorkspaceComponent stay bespoke because their card-based layouts, lane filtering, gating reason display, keyboard triage shortcuts, and VEX decision modals are materially different from the shared tabular finding-list family. Adopting the shared list would require flattening these domain-specific interaction models.
- Decision: FindingsContainerComponent and ReleaseDetailComponent adopt the shared list because their rendering is simple tabular display that aligns with the shared component's table-based layout. Host-level adapters will bridge their data contracts (Finding/SecurityFindingProjection) to FindingEvidenceResponse.
## Next Checkpoints
- 2026-03-09: mounted host matrix frozen.
- 2026-03-11: consolidation criteria agreed.