feat(auth): persist per-user theme preference (base mode + accent) (PMS-410) #301

Merged
vas2000-work merged 1 commit from fix/PMS-410-theme-prefs into main 2026-06-17 22:37:01 +02:00
Owner

Implements PMS-410: a per-user theme preference (theme_base_mode + theme_accent_id) that backs the MAPPS-259 theme picker's cross-device sync.

Mirrors the existing date_format_string field at every touchpoint: migration 054_user_theme_prefs.sql (nullable TEXT + CHECK), the UserRow row struct and its From mapping, the User / CurrentUser / UserResponse / UpdateUserRequest / CreateUserRequest DTOs, and the auth service SELECT / INSERT / UPDATE paths plus the at_jwt construction. Adds a validate_theme_base_mode custom validator so an invalid base mode returns a clean 422 (a bare DB CHECK violation maps to 500, so the CHECK stays as defense-in-depth).

GET /api/v1/auth/me returns both fields; PUT accepts and persists them (omitted fields unchanged); unset defaults to NULL.

Verified in the dev container: cargo check --all-targets, the tests/auth.rs round-trip integration test (persist, read-back, partial update, invalid base mode -> 422), migration 054 applies cleanly, cargo fmt --check, clippy -D warnings, and the pre-commit hook.

Merge this before the mokosh-apps MAPPS-259 account-sync relies on these fields in a deployed environment.

#PMS-410

Implements PMS-410: a per-user theme preference (theme_base_mode + theme_accent_id) that backs the MAPPS-259 theme picker's cross-device sync. Mirrors the existing date_format_string field at every touchpoint: migration 054_user_theme_prefs.sql (nullable TEXT + CHECK), the UserRow row struct and its From mapping, the User / CurrentUser / UserResponse / UpdateUserRequest / CreateUserRequest DTOs, and the auth service SELECT / INSERT / UPDATE paths plus the at_jwt construction. Adds a validate_theme_base_mode custom validator so an invalid base mode returns a clean 422 (a bare DB CHECK violation maps to 500, so the CHECK stays as defense-in-depth). GET /api/v1/auth/me returns both fields; PUT accepts and persists them (omitted fields unchanged); unset defaults to NULL. Verified in the dev container: cargo check --all-targets, the tests/auth.rs round-trip integration test (persist, read-back, partial update, invalid base mode -> 422), migration 054 applies cleanly, cargo fmt --check, clippy -D warnings, and the pre-commit hook. Merge this before the mokosh-apps MAPPS-259 account-sync relies on these fields in a deployed environment. #PMS-410
feat(auth): persist per-user theme preference (base mode + accent) (PMS-410)
All checks were successful
E2E / Playwright against staging (pull_request) Successful in 34s
Check / fmt + clippy + compile + unit/doc tests (pull_request) Successful in 1m55s
Integration / integration tests (pull_request) Successful in 3m39s
Create release / Create release from merged PR (pull_request) Has been skipped
c355277d07
Add two per-user preference fields, theme_base_mode (light|dark|system) and theme_accent_id (an opaque accent id, max 32 chars), mirroring the existing date_format_string field at every touchpoint: migration 054_user_theme_prefs.sql (nullable TEXT + CHECK constraints), the UserRow row struct and its From mapping, the User / CurrentUser / UserResponse / UpdateUserRequest / CreateUserRequest DTOs, and the auth service SELECT / INSERT / UPDATE paths plus the at_jwt construction.

Add a validate_theme_base_mode custom validator so an invalid base mode returns a clean 422; a bare DB CHECK violation maps to 500, so the CHECK constraint stays only as defense-in-depth. theme_accent_id gets a length check mirroring date_format_string.

GET /api/v1/auth/me now returns both fields; PUT accepts and persists them, leaving omitted fields unchanged; unset values default to NULL (the SPA treats NULL base mode as system and falls back to its default accent). Add a tests/auth.rs round-trip test covering persist, read-back, partial update, and the invalid-base-mode 422.

This backs the MAPPS-259 theme picker's per-user, cross-device sync.

#PMS-410
#MAPPS-259

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
psa-systems/mokosh-server!301
No description provided.