Theme Config
Data Entity
Description
Per-user visual theme settings including font scale factor and contrast theme selection (standard or high contrast WCAG 2.2 AA). Used by the Theme Service to build the active ThemeData at MaterialApp level for consistent accessible typography and color contrast.
Data Structure
| Name | Type | Description | Constraints |
|---|---|---|---|
id |
uuid |
Primary key — unique identifier for this theme configuration record | PKrequiredunique |
user_id |
uuid |
Foreign key referencing users.id. One-to-one relationship: each user has exactly one theme config record. Cascade-deleted when the user is deleted. | requiredunique |
font_scale |
decimal |
Multiplier applied to the base Flutter textScaleFactor at MaterialApp level. A value of 1.0 represents the default system font size. Discrete steps are offered in the UI (e.g., 0.85, 1.0, 1.15, 1.3, 1.5) but the stored value is a decimal to support future continuous control. | required |
contrast_theme |
enum |
Selected colour contrast theme. 'standard' uses the default design token palette. 'high_contrast' applies a WCAG 2.2 AA-compliant high-contrast palette with minimum 4.5:1 normal-text contrast ratio and 3:1 large-text contrast ratio, validated by WcagContrastValidator. | required |
created_at |
datetime |
Timestamp when this theme config record was first created — typically at user onboarding when defaults are written. | required |
updated_at |
datetime |
Timestamp of the most recent update to font_scale or contrast_theme. Used to determine whether to prefer cached local values or re-fetch from Supabase on session restore. | required |
Database Indexes
idx_theme_configs_user_id
Columns: user_id
idx_theme_configs_contrast_theme
Columns: contrast_theme
Validation Rules
font_scale_range
error
Validation failed
font_scale_range_on_update
error
Validation failed
contrast_theme_enum_check
error
Validation failed
contrast_theme_enum_check_on_update
error
Validation failed
user_id_references_valid_user
error
Validation failed
no_duplicate_user_config
error
Validation failed
updated_at_monotonic
warning
Validation failed
Business Rules
one_config_per_user
Each user must have exactly one theme_configs record. A unique constraint on user_id enforces this at the database level. On first login, a default record (font_scale=1.0, contrast_theme='standard') is upserted if one does not already exist.
default_config_on_onboarding
When a new user is created, a theme_configs record with default values (font_scale=1.0, contrast_theme='standard') must be inserted atomically with user creation to ensure Theme Service never encounters a missing config.
wcag_contrast_compliance
The high_contrast theme selection must guarantee a minimum 4.5:1 contrast ratio for normal text and 3:1 for large text per WCAG 2.2 AA. The WcagContrastValidator is invoked at theme build time to assert all colour role pairs before the ThemeData is applied.
font_scale_applied_globally
The stored font_scale value must be applied at the MaterialApp textScaleFactor level so that all text in the app scales uniformly. Individual widgets must not override the global scale factor.
local_cache_sync_on_session_restore
On app launch, the Theme Repository must compare the locally cached theme config (Hive/SharedPreferences) against the Supabase record using updated_at. The most recently updated value wins and overwrites the other. This ensures the user's last change persists across reinstalls and devices.
cascade_delete_on_user_removal
When a user record is deleted, the associated theme_configs record must be deleted via database-level ON DELETE CASCADE to prevent orphaned configuration rows.
rls_self_read_write_only
Supabase RLS policies must restrict read and write access to theme_configs exclusively to the owning user (auth.uid() = user_id). No role — including coordinator or admin — may read or modify another user's theme preferences.
CRUD Operations
Storage Configuration
Entity Relationships
Each user has one theme configuration record controlling font scale and contrast theme selection