high priority low complexity frontend pending frontend specialist Tier 3

Acceptance Criteria

Warning section is hidden entirely when AggregationSummaryData.unmappedActivities is null or empty
Warning section is visible when at least one unmapped activity exists
Each unmapped activity entry shows the activity type name and the count of unmapped occurrences (e.g., 'Telephone support — 12 activities')
An explanatory text reads: 'These activity types are not mapped to a Bufdir category and will not be included in the report.' (or Norwegian equivalent per org labels system)
Warning container uses the amber/warning design token color — no hardcoded hex values
A warning icon (Icons.warning_amber_rounded or equivalent) is displayed to the left of the section title
The warning section container has Semantics(label: 'Warning: unmapped activities', role: SemanticsRole.alert) or equivalent Flutter Semantics wrapper
Warning count badge (e.g., '3 unmapped types') is shown in the section header for quick scanning
Section is keyboard/screen-reader navigable — each row is individually focusable with a descriptive semantic label
Widget passes flutter_test golden snapshot with warning section visible and with it hidden

Technical Requirements

frameworks
Flutter
Flutter Semantics API
data models
activity_type (name for display in warning list)
bufdir_column_schema (to identify unmapped activity_type_ids)
performance requirements
Warning section must render in the same frame as the rest of the widget — no async work
Unmapped list uses ListView.builder if count exceeds 5 entries
security requirements
Activity type names displayed are non-PII configuration data — safe to display
Do not display activity IDs (UUIDs) in the warning list — display names only
ui components
Warning banner container with amber design token background
Icons.warning_amber_rounded icon widget
Semantics widget wrapper with alert role
CompactListItem or ListTile for each unmapped activity row
Badge/chip widget for unmapped count summary

Execution Context

Execution Tier
Tier 3

Tier 3 - 413 tasks

Can start after Tier 2 completes

Implementation Notes

Add an `unmappedActivities` field to AggregationSummaryData as a List where UnmappedActivityEntry has activityTypeName (String) and occurrenceCount (int). Extend the existing _build* pattern from task-005 with a new _buildUnmappedWarnings() method that returns an empty SizedBox.shrink() when the list is empty — this avoids conditional rendering complexity in the main build Column. For the Semantics wrapper, use: Semantics(container: true, liveRegion: true, label: 'Warning: ${count} unmapped activity types will be excluded from Bufdir report'). Use the design token color token (e.g., AppColors.warning or AppColors.amber) — never hardcode.

The warning icon should be visually consistent with the rest of the app's icon set.

Testing Requirements

Widget tests using flutter_test: (1) empty unmappedActivities — assert warning section finder returns zero widgets; (2) one unmapped activity — assert section appears, activity name and count are present via find.text; (3) five unmapped activities — assert all five rows rendered; (4) Semantics test — use flutter_test SemanticsHandle to assert alert role is present on warning container; (5) golden test for both states (with/without warnings). All tests should reuse the existing AggregationSummaryWidget test harness from task-008.

Component
Aggregation Summary Widget
ui medium
Epic Risks (2)
medium impact high prob scope

For NHF with 1,400 local chapters, rendering a geographic breakdown as a flat list in the AggregationSummaryWidget would produce an unscrollable wall of data that is unusable on a mobile screen. Coordinators need to verify geographic completeness before export, but the raw chapter list is too long to review.

Mitigation & Contingency

Mitigation: Design the geographic distribution section as a collapsible two-level hierarchy: regions are shown expanded by default with their aggregate count, individual chapters are collapsed under each region and expandable on tap. Show only non-zero regions by default with a 'show empty regions' toggle.

Contingency: If the hierarchical display is too complex to implement before the submission deadline, fall back to a region-only summary view with a total count of active chapters per region and a note that chapter-level detail is available in the full export file.

medium impact medium prob technical

The aggregation BLoC must handle a multi-stage async pipeline with partial success states, warning accumulation across stages, and retry logic for individual failed stages. If the state model is too simplistic (e.g., loading/success/error), warning states and partial results will be lost on retry, confusing coordinators who see warnings disappear and reappear.

Mitigation & Contingency

Mitigation: Model the BLoC state as a rich sealed class hierarchy: AggregationIdle, AggregationRunning(stage, completedStages, accumulatedWarnings), AggregationComplete(result, warnings), AggregationFailed(failedStage, accumulatedWarnings, error). Accumulated warnings persist across retry attempts so coordinators see the full warning history.

Contingency: If state management complexity causes repeated bugs near the deadline, simplify to a single AggregationResult value object that captures success, warnings, and error as nullable fields, and drive both UI components from that single object rather than a live BLoC stream.