Accessibility Preferences
Data Entity
Description
Per-user accessibility configuration storing screen reader settings, cognitive mode preferences, sensitive field audio warning toggles, and other WCAG 2.2 AA compliance settings. Drives app-wide UI adaptation for users with visual, cognitive, or motor impairments.
Data Structure
| Name | Type | Description | Constraints |
|---|---|---|---|
id |
uuid |
Primary key, auto-generated UUID for the accessibility preferences record | PKrequiredunique |
user_id |
uuid |
Foreign key referencing the users table. One-to-one relationship; each user has exactly one preferences record. | requiredunique |
screen_reader_enabled |
boolean |
Whether the user has explicitly enabled screen reader optimisations within the app (VoiceOver/JAWS semantic label enhancements beyond OS defaults). Drives SensitiveSemantics wrapper activation and live region announcements. | required |
sensitive_field_warnings_enabled |
boolean |
Whether the app should play an audio warning before a screen reader reads a sensitive field (e.g. medical summary, personal ID number). Required for NHF compliance. | required |
sensitive_field_warning_text |
text |
Custom warning message spoken before sensitive fields are read aloud. If null, a system default message is used. Allows organisations to provide domain-appropriate wording. | - |
cognitive_mode_enabled |
boolean |
Whether simplified/low-cognitive-load layout is active. When true, Simplified Navigation Screen hides secondary actions, reduces list items to 5, and enforces explicit back button on every screen. | required |
font_scale |
decimal |
User-selected text scale factor applied at MaterialApp level via textScaleFactor. Valid range 0.8–2.0 in increments of 0.1. Defaults to 1.0 (system default). | required |
contrast_theme |
enum |
Selected colour contrast theme. 'default' uses standard design tokens; 'high_contrast' applies WCAG 2.2 AA-compliant high-contrast token set. | required |
preferred_locale |
string |
BCP 47 language tag for the user's preferred locale (e.g. 'nb-NO', 'nn-NO'). Used for speech recognition locale selection and date/number formatting. Null means fall back to device locale. | - |
speech_input_enabled |
boolean |
Whether the speech-to-text microphone affordance is shown on supported text fields. Respects SpeechPreferencesRepository contract. Defaults to false until user opts in. | required |
reduce_motion_enabled |
boolean |
Whether animated transitions (e.g. Animated Stats Widget count-up, badge unlock animations) should be reduced or disabled. Supports users with vestibular disorders. | required |
tap_target_scale |
enum |
Minimum tap target size preference. 'standard' enforces 48dp (WCAG minimum); 'large' enforces 56dp for users with motor impairments. | required |
created_at |
datetime |
Timestamp when this preferences record was first created (UTC). Auto-set on insert. | required |
updated_at |
datetime |
Timestamp of the most recent update to any preference field (UTC). Must be updated on every write. | required |
Database Indexes
idx_accessibility_preferences_user_id
Columns: user_id
idx_accessibility_preferences_cognitive_mode
Columns: cognitive_mode_enabled
Validation Rules
font_scale_range
error
Validation failed
font_scale_step
error
Validation failed
contrast_theme_valid_enum
error
Validation failed
preferred_locale_bcp47
error
Validation failed
sensitive_field_warning_text_length
error
Validation failed
user_id_references_existing_user
error
Validation failed
no_duplicate_user_preferences
error
Validation failed
boolean_fields_non_null
error
Validation failed
Business Rules
one_record_per_user
Each user must have exactly one accessibility preferences record. The record is created automatically on first login with all default values. Upsert semantics must be used rather than blind inserts.
cascade_delete_on_user_removal
When a user record is deleted, the associated accessibility_preferences row must be deleted via CASCADE to prevent orphaned configuration records.
cognitive_mode_simplifies_navigation
When cognitive_mode_enabled is true, Simplified Navigation Screen must limit primary navigation items to five, hide secondary metadata, and enforce explicit back button on every non-root screen. This is a runtime behavioural contract, not only a stored flag.
sensitive_warning_default_on
sensitive_field_warnings_enabled defaults to true for all users to ensure no user is inadvertently exposed to unannounced sensitive field read-aloud. Users must explicitly opt out.
preferences_propagated_app_wide
Accessibility preferences must be loaded and cached in Riverpod providers at session start before any screen renders. No screen may render without resolved accessibility context to avoid flash of incorrect layout.
offline_first_caching
Preferences must be cached locally (Hive or shared_preferences) so the app renders correctly without a network round-trip on cold start. Local cache is authoritative until a successful remote fetch completes.
updated_at_maintained
The updated_at field must be set to the current UTC timestamp on every UPDATE operation. This is enforced via a Supabase database trigger to prevent client-side clock skew.
rls_self_read_write_only
Supabase RLS policy must ensure a user can only read and update their own accessibility_preferences row (auth.uid() = user_id). No role, including coordinator, may read or modify another user's accessibility preferences.
font_scale_applied_globally
The font_scale value must be applied to MaterialApp's textScaleFactor so that all text across the entire app scales uniformly, including third-party widgets. Per-widget overrides are forbidden.
wcag_contrast_validation_on_theme_change
When contrast_theme is updated, the resolved ThemeData must be validated against WCAG 2.2 AA contrast requirements (4.5:1 for normal text, 3:1 for large text) before being applied. Non-compliant themes must be rejected.
CRUD Operations
Storage Configuration
Entity Relationships
Each user has one accessibility preferences record configuring their WCAG 2.2 AA accessibility settings app-wide