high priority low complexity backend pending backend specialist Tier 2

Acceptance Criteria

SpeechRecognitionService queries NativeSpeechApiBridge.getAvailableLocales() during or immediately after initialization
If nb-NO is in the returned list, it is selected as the active locale
If nb-NO is absent but no-NO is present, no-NO is selected and a warning is logged
If neither nb-NO nor no-NO is present, en-US is used as the final fallback and a warning is logged
A Stream<List<Locale>> localesAvailable is exposed so UI can react to locale availability
A getter activeLocale returns the currently selected Locale
A warning is emitted via dart:developer log (level: warning) if nb-NO is absent — message includes the list of available locales for QA diagnostics
Locale selection logic is encapsulated in a pure function (e.g., selectBestLocale(List<Locale> available, SpeechLocaleConfig config)) that can be unit-tested independently

Technical Requirements

frameworks
Flutter
Riverpod
apis
NativeSpeechApiBridge.getAvailableLocales()
data models
SpeechLocaleConfig
SpeechRecognitionEvent
performance requirements
Locale query must not block the UI thread — must be awaited asynchronously
Locale list should be cached after first query; re-querying on every startListening() call is not acceptable

Execution Context

Execution Tier
Tier 2

Tier 2 - 518 tasks

Can start after Tier 1 completes

Implementation Notes

Extract locale selection into a top-level or static pure function selectBestLocale(List available, SpeechLocaleConfig config) → Locale. This allows it to be tested without instantiating the full service. Use dart:developer's log() function for warnings (not print() or debugPrint()) with the appropriate log level. Cache the result of getAvailableLocales() in a private _availableLocales field set during initialization.

Do not re-query on each startListening() call — locale availability is device-level and does not change during an app session. Expose localesAvailable as a BehaviorSubject-equivalent (or a StateProvider in Riverpod) so it immediately emits the current value to new subscribers.

Testing Requirements

Unit tests for the pure selectBestLocale() function covering: nb-NO available (returns nb-NO), only no-NO available (returns no-NO + warning), only en-US available (returns en-US + warning), empty list (returns en-US + warning), list with nb-NO and others (still returns nb-NO). Integration test on a Norwegian device/simulator confirms nb-NO is available and selected. Use flutter_test. Logging assertions can use a custom log capture approach or verify via mock NativeSpeechApiBridge responses.

Component
Speech Recognition Service
service high
Epic Risks (2)
medium impact medium prob technical

The speech_to_text Flutter package delegates accuracy entirely to the OS-native engine. Norwegian accuracy for domain-specific vocabulary (medical terms, organisation names, accessibility terminology) may fall below the 85% acceptance threshold on older devices or in noisy environments, causing user frustration and manual correction overhead that negates the time saving.

Mitigation & Contingency

Mitigation: Configure the SpeechRecognitionService with Norwegian as the explicit locale and test against a representative corpus of peer mentoring vocabulary on target devices. Expose locale switching so users can fallback to Bokmål vs Nynorsk. Clearly set user expectations in the UI that transcription is a starting point for editing, not a finished product.

Contingency: If accuracy is consistently below threshold on specific device/OS combinations, add a device-capability check that hides the dictation button with an explanatory message rather than offering a degraded experience. Document affected device models for QA and org contacts.

medium impact low prob dependency

The speech_to_text Flutter package is a third-party dependency that may introduce breaking API changes or deprecations on major version upgrades, requiring rework of SpeechRecognitionService when Flutter or platform OS versions are updated.

Mitigation & Contingency

Mitigation: Wrap all speech_to_text API calls behind the SpeechRecognitionService interface so that package changes are isolated to one file. Pin the package version in pubspec.yaml and review changelogs before any upgrade. Write integration tests that exercise the package contract so regressions are caught immediately.

Contingency: If the package is abandoned or has unresolvable issues, NativeSpeechApiBridge already provides the platform-channel abstraction needed to implement a direct plugin replacement with minimal changes to SpeechRecognitionService.