high priority low complexity frontend pending frontend specialist Tier 2

Acceptance Criteria

Label key rows with no organization-specific override are rendered with a visually distinct background color or left-border accent using design tokens (not hardcoded hex values)
A warning badge (e.g., 'DEFAULT' chip) is displayed inline on each missing-override row
A summary banner is rendered at the top of the list (above the search field or between search and list) showing 'X of Y labels using default values'
When all labels have overrides the summary banner shows a success state ('All labels configured') with a green/success design token color
When zero labels have overrides the banner shows the full count and uses a warning/amber design token color
Highlighting and banner count update correctly when the active organization is switched
The highlight does not interfere with the search filter — missing rows remain highlighted when visible in filtered results
Design token usage is verified: no hardcoded color values in the widget code
Accessibility: warning badge has a Semantics label readable by VoiceOver (e.g., 'Using default value')

Technical Requirements

frameworks
Flutter
Riverpod
apis
Derived from existing LabelKeyListViewModel — no new API calls required
data models
ResolvedLabelRow (isMissingOverride: bool)
LabelKeyListSummary (missingCount, totalCount)
performance requirements
Missing count computation must be O(n) and performed in the derived provider, not in build()
Summary banner must not trigger full list rebuild when only the banner data changes
security requirements
No sensitive org configuration data must be exposed in the banner text beyond counts
ui components
SummaryBannerWidget (missing count + total, success/warning state)
MissingOverrideBadge chip widget
Design token color references (warning, success, surface-warning)

Execution Context

Execution Tier
Tier 2

Tier 2 - 518 tasks

Can start after Tier 1 completes

Implementation Notes

Extend the existing ResolvedLabelRow view model with a boolean isMissingOverride field computed during the provider projection (resolvedValue == null || resolvedValue == fallbackValue, depending on how the repository signals 'no override'). Add a LabelKeyListSummary derived provider (or computed getter) that counts missing rows — this avoids iterating the list in build(). The summary banner should be a separate stateless widget above the ListView, fed by the summary provider. Use Container with a left BorderSide accent (design token: colorWarningBorder) rather than a full background color for the row highlight — this is more accessible and less visually aggressive.

The badge chip should use a small outlined Chip widget with a warning color token and a Semantics label.

Testing Requirements

Write flutter_test widget tests for: (1) rows with missing overrides render with the warning badge, (2) rows with overrides do not render the warning badge, (3) summary banner shows correct missing/total counts, (4) banner renders success state when missingCount is 0, (5) banner renders warning state when missingCount > 0. Write a unit test for the isMissingOverride derivation logic. Verify no hardcoded color values by asserting design token property references in widget tree (use tester.widget and check decoration). Target 95% branch coverage on banner state logic.

Epic Risks (3)
high impact medium prob integration

WcagSemanticsLabelResolver's Semantics wrappers may conflict with Semantics nodes already defined by existing accessible widgets (e.g., accessible-bottom-navigation, activity-wizard-semantics), causing duplicate or contradictory screen reader announcements that fail WCAG 2.2 AA criteria.

Mitigation & Contingency

Mitigation: Audit all existing Semantics-annotated widgets in the accessibility feature before implementing WcagSemanticsLabelResolver. Define a clear hierarchy rule: WcagSemanticsLabelResolver always merges with, never replaces, existing Semantics nodes. Use Flutter's debugSemantics output in CI to detect conflicts automatically.

Contingency: If conflicts are discovered in testing, introduce a resolverMode parameter to WcagSemanticsLabelResolver allowing it to operate in 'override' or 'merge' mode per call site; coordinate with the Screen Reader Support feature team to align Semantics strategies.

medium impact medium prob technical

If TerminologyAwareTextWidget subscribes to the full terminology map provider rather than the per-key labelProvider family, a single label update will trigger a full widget-tree rebuild across all screens simultaneously, causing jank on devices used by older peer mentors.

Mitigation & Contingency

Mitigation: Implement TerminologyAwareTextWidget using ref.watch(labelProvider(key)) on the per-key family provider from TerminologyRiverpodProviders so that only widgets bound to the changed key rebuild. Verify with Flutter DevTools 'rebuild tracking' in widget tests.

Contingency: If full-map subscriptions slip through code review, add a Riverpod lint rule that flags direct organizationLabelsNotifierProvider subscriptions inside widget build methods and enforces the per-key family pattern.

medium impact low prob security

The TerminologyAdminPreviewScreen requires coordinator-level access, but if role checks rely solely on client-side guard logic without matching Supabase RLS policies, a peer mentor could potentially access the admin preview by manipulating navigation state.

Mitigation & Contingency

Mitigation: Protect the admin preview route with a server-validated role guard that re-fetches the user's role from Supabase on screen initialization, not just from local state. Add a Supabase RLS policy that restricts label map read access for the admin preview endpoint to coordinator and admin roles only.

Contingency: If unauthorized access is discovered in testing, immediately add a middleware role assertion that redirects non-coordinators to the no-access screen and logs the unauthorized navigation attempt for audit.