Define LocalStorage type-safe key constants
epic-organization-selection-infrastructure-task-001 — Create a typed constants file defining all SharedPreferences keys used by the Organization Selection feature. Establish a namespaced key convention (e.g., 'org_selection.selected_org_id') to prevent collision with other feature keys. Include Dart type annotations for all key-value pairs.
Acceptance Criteria
Technical Requirements
Implementation Notes
Use an abstract final class (Dart 3+) or a class with a private constructor to hold the constants — this prevents accidental instantiation. Example pattern: `abstract final class OrgSelectionStorageKeys { static const String selectedOrgId = 'org_selection.selected_org_id'; }`. Align the namespace prefix with whatever convention is already used elsewhere in the codebase — check existing SharedPreferences usage before deciding on 'org_selection' as the prefix. If the codebase uses a different separator (underscore vs dot), match it.
Keep this file minimal: its only job is key definitions. Do not put serialization logic, default values, or adapter code here — those belong in the LocalStorageAdapter (task-002). The file-level doc comment should list all keys in a table for quick reference.
Testing Requirements
Write a single unit test file that: (1) collects all static const String values from the constants class using reflection or a manually maintained list; (2) asserts that every value starts with 'org_selection.'; (3) asserts that no two constants share the same string value (uniqueness check). This test acts as a regression guard — if a developer adds a key that violates the naming convention or duplicates an existing key, CI fails immediately.
SharedPreferences behaves differently on iOS (NSUserDefaults) vs Android (SharedPreferences) for edge cases such as first-launch cold reads, storage quota exceeded, or process kill mid-write. If the adapter does not account for these differences, the persistence layer can silently return null on one platform while returning a stale value on the other, causing incorrect routing decisions downstream.
Mitigation & Contingency
Mitigation: Write platform-specific integration tests using flutter_test device runners for both iOS and Android. Document known platform delta in the adapter's inline comments and encode defensive fallback for null returns at the repository boundary.
Contingency: If platform delta causes persistent issues, replace SharedPreferences with flutter_secure_storage for this key — the LocalStorageAdapter abstraction makes this a single-file swap with no impact on the repository or service layer.
The shared_preferences Flutter plugin may have a version conflict with other plugins already in the project pubspec.yaml. A conflict discovered late in the epic blocks all downstream epics.
Mitigation & Contingency
Mitigation: Resolve and pin the shared_preferences version in pubspec.yaml as the very first task of this epic before writing any implementation code. Run flutter pub get and resolve any version conflicts immediately.
Contingency: If version pinning is impossible due to transitive conflicts, implement LocalStorageAdapter using path_provider + dart:io for JSON file storage as an alternative — the interface contract remains unchanged.