critical priority low complexity frontend pending frontend specialist Tier 1

Acceptance Criteria

TerminologyAwareTextWidget accepts a required `labelKey` string parameter and an optional `fallback` string parameter
Widget uses `ref.watch` on the active organization label map provider so it subscribes to state changes
LabelKeyResolver.resolve(labelKey, labelMap) is called on every build with the currently active map
The resolved string is passed directly to Flutter's built-in Text widget with no intermediate caching that would prevent reactivity
When the active organization changes (e.g., coordinator switches org), the widget rebuilds and renders the new org's resolved label within one frame
When the terminology sync updates the label map, the widget rebuilds automatically without hot reload or manual invalidation
Widget passes through all standard Text widget styling parameters (style, textAlign, overflow, maxLines, etc.) unmodified
No unnecessary provider reads occur — only `ref.watch` is used (not `ref.read`) to ensure subscription
Widget compiles without warnings under `dart analyze --fatal-infos`
Integration with the existing design token system: default text style inherits from the active theme

Technical Requirements

frameworks
Flutter
Riverpod
data models
OrganizationLabelMap
LabelKey
performance requirements
Widget rebuild must complete within one frame (16ms budget) — resolver call must be O(1) map lookup
No futures or async operations inside build method — label map must be synchronously available from provider
Widget should not cause parent rebuilds — use ConsumerWidget or Consumer, not setState
security requirements
Label keys must never be logged at info level or above in production builds — only debug-level output is acceptable
No raw label map values should be exposed through widget keys or debugging identifiers that could leak org-specific configuration
ui components
TerminologyAwareTextWidget (ConsumerWidget)
Flutter Text widget (internal delegate)
OrganizationLabelsNotifier (Riverpod provider, read via ref.watch)

Execution Context

Execution Tier
Tier 1

Tier 1 - 540 tasks

Can start after Tier 0 completes

Implementation Notes

Extend ConsumerWidget (not StatelessWidget) to get access to `ref` in the build method. The pattern is: `final labelMap = ref.watch(organizationLabelMapProvider); final resolved = LabelKeyResolver.resolve(labelKey, labelMap) ?? fallback ?? _humanize(labelKey); return Text(resolved, style: widget.style, ...);`.

Use `ref.watch` — never `ref.read` inside build, as `read` does not subscribe. Keep the widget thin: do not add caching, memoization, or local state. The LabelKeyResolver should handle all caching internally if needed. Pass `style`, `textAlign`, `overflow`, `maxLines`, `softWrap`, and `semanticsLabel` through to the inner Text widget so callers retain full control.

Add a `const` constructor and mark `labelKey` and `fallback` as `final` fields. Avoid importing the resolver directly in the widget — inject it through the provider graph to keep the widget testable.

Testing Requirements

Unit tests using flutter_test: (1) Wrap TerminologyAwareTextWidget in a ProviderScope with a mocked OrganizationLabelsNotifier, assert the rendered Text displays the resolved string for a known labelKey. (2) Override the provider with an updated label map and pump the widget — assert the displayed text updates without hot reload. (3) Test with an empty label map — widget must not throw. (4) Test with a null/missing key in the map — widget must fall back gracefully (see task-003).

Target: 100% branch coverage for the build method. All tests must pass with `flutter test` in CI.

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.