critical priority low complexity backend pending backend specialist Tier 1

Acceptance Criteria

SensitiveFieldConfigurationRegistry class is implemented as a pure Dart class with no Flutter dependencies
isSensitive(String fieldId) returns true for all default sensitive fields: personnummer, full_name, address, health_data, date_of_birth, phone_number
getWarningKey(String fieldId) returns a non-null localization key string for sensitive fields and null for non-sensitive fields
registerField(String fieldId, String warningKey) adds new fields at runtime without requiring app restart
unregisterField(String fieldId) removes a field registration and isSensitive returns false afterward
Registry is exposed as a Riverpod Provider<SensitiveFieldConfigurationRegistry> accessible app-wide
Default seed configuration covers all NHF-required sensitive fields (personnummer, full name, address, health data) as defined in workshop requirements
Registry is immutable from outside — only registration methods mutate state, no direct map access
All public methods have null-safe signatures and handle empty/null fieldId gracefully without throwing

Technical Requirements

frameworks
Flutter
Riverpod
data models
SensitiveFieldConfig
performance requirements
isSensitive() lookup must complete in O(1) — use a HashMap internally
Registry initialization must complete synchronously at provider creation time
security requirements
Field IDs must be treated as opaque strings — no logging of field values or field content
Registry must not expose the internal map directly to prevent external mutation

Execution Context

Execution Tier
Tier 1

Tier 1 - 540 tasks

Can start after Tier 0 completes

Implementation Notes

Keep the registry as a plain Dart class (no ChangeNotifier needed — state is mutated only through explicit methods). Use a final Map _registry internally initialized in the constructor. Seed defaults in a static const map and copy into the mutable map at construction. For the Riverpod provider, use Provider (not StateProvider) since the registry manages its own internal mutation.

Warning keys should follow a namespaced convention like 'accessibility.warning.personnummer' to align with the app's localization system. This registry will be consumed by the semantics service facade and any form widget that needs to announce sensitive field warnings.

Testing Requirements

Write unit tests using flutter_test covering: (1) default seed fields are all recognized as sensitive, (2) getWarningKey returns correct key per field, (3) runtime registration of a new field works, (4) unregistration removes sensitivity, (5) isSensitive returns false for unknown fields, (6) null/empty fieldId does not throw. Minimum 90% branch coverage on the registry class.

Component
Sensitive Field Configuration
data low
Epic Risks (2)
high impact medium prob technical

Flutter's SemanticsService behaves differently between iOS (VoiceOver) and Android (TalkBack) in edge cases — e.g., announcement queuing, focus-gain timing, and attribute support. If the facade does not correctly abstract these differences, announcements may be silent or misfired on one platform, causing regression on the other platform to go unnoticed until device testing.

Mitigation & Contingency

Mitigation: Write platform-divergence unit tests early using SemanticsServiceFacade mocks. Validate announcement delivery on a physical iPhone (VoiceOver) and Android device (TalkBack) at the end of each sprint. Document known platform differences in the facade's inline API comments.

Contingency: If a platform difference cannot be abstracted cleanly, expose a platform-specific override path in the facade and implement targeted workarounds per platform, accepting the added complexity in exchange for correct behaviour.

medium impact medium prob scope

Accessibility preferences stored in local storage may need new fields as higher-tier epics are implemented (e.g., announcement verbosity, sensitive-field guard toggle). Schema changes to an already-persisted store risk data migration failures or silent defaults on existing installs, breaking user preferences.

Mitigation & Contingency

Mitigation: Design the AccessibilitySettingsRepository with a versioned JSON schema from the start, using merge-with-defaults on read so new fields fall back gracefully. Define the full expected field list upfront based on all downstream epic requirements before writing the first record.

Contingency: If migration fails on a live install, fall back to full reset-to-defaults with a one-time in-app notification informing the user that accessibility preferences have been reset and inviting them to reconfigure.