7db27af7a6
- 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
48 lines
2.9 KiB
SQL
48 lines
2.9 KiB
SQL
-- ════════════════════════════════════════════════════════════════════════════
|
|
-- 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.';
|