feat(user.prefered_locale): save user's locale + invited have same locale as inviters
- OIDC JIT define the locale only at user creation, user can so change his preference later
- invited users will inherit inviter's locale
- email will use prefered_locale
- login to a new browser will use prefered_locale
This commit is contained in:
@@ -0,0 +1,47 @@
|
||||
-- ════════════════════════════════════════════════════════════════════════════
|
||||
-- Per-user preferred locale (PR C of the i18n / magic-link templating work)
|
||||
-- ════════════════════════════════════════════════════════════════════════════
|
||||
-- Carries the user's preference for server-rendered surfaces — chiefly
|
||||
-- transactional emails (invitation, login-via-email magic-link) and
|
||||
-- future server-rendered HTML for authenticated users. The frontend
|
||||
-- language switcher writes here via PATCH /api/auth/me/profile so the
|
||||
-- choice survives across sessions and devices; the OIDC callback writes
|
||||
-- here once at JIT provisioning if the IdP's `locale` claim resolves
|
||||
-- against the LocaleRegistry; the magic-link invitation flow copies the
|
||||
-- inviter's value into the new external user's row.
|
||||
--
|
||||
-- Value semantics:
|
||||
-- NULL — no explicit preference. The application resolves to
|
||||
-- OXICLOUD_DEFAULT_LOCALE (default "en"). NULL is also the
|
||||
-- post-rollback shape; nothing reads this column in a way
|
||||
-- that requires it to be set.
|
||||
-- "xx" — IETF BCP-47 primary tag, e.g. "en", "fr", "ja".
|
||||
-- "xx-YY" — primary + region subtag, e.g. "zh-TW".
|
||||
--
|
||||
-- The CHECK below enforces a permissive but bounded shape that matches
|
||||
-- what the LocaleRegistry's case-insensitive comparison will canonicalise
|
||||
-- successfully. We do NOT enforce membership in the registry's
|
||||
-- discovered codes at the DB level — that list is build-time runtime
|
||||
-- state, not schema. The application layer is the gatekeeper:
|
||||
-- `update_profile_with_perms` rejects unknown codes with 400, and the
|
||||
-- email-render path silently falls back to the server default when a
|
||||
-- stored value no longer resolves (e.g. after dropping a locale file).
|
||||
--
|
||||
-- No backfill: every existing row stays NULL → inherits the server
|
||||
-- default, which is the same behaviour every row had before this
|
||||
-- migration. Pre-PR-C users see no change.
|
||||
|
||||
ALTER TABLE auth.users
|
||||
ADD COLUMN preferred_locale TEXT NULL
|
||||
CHECK (preferred_locale IS NULL
|
||||
OR preferred_locale ~ '^[a-zA-Z]{2,3}(-[a-zA-Z0-9]{2,8})*$');
|
||||
|
||||
COMMENT ON COLUMN auth.users.preferred_locale IS
|
||||
'User-preferred locale for server-rendered surfaces (emails, future
|
||||
auth pages). IETF BCP-47 shape: primary tag + optional subtags.
|
||||
NULL = no preference; resolves to OXICLOUD_DEFAULT_LOCALE.
|
||||
Set by: UI language switcher (PATCH /api/auth/me/profile),
|
||||
OIDC JIT provisioning (one-shot, never re-applied on subsequent
|
||||
logins — UI choice is canonical), inheritance from inviter at
|
||||
external-user creation. Application enforces registry membership;
|
||||
schema only constrains the textual shape.';
|
||||
Reference in New Issue
Block a user