riyadhafraa 014f9ecb0e Fix PDF font color not reflecting system settings via per-field merge
Root cause: resolveFontPrefsForUser() used `userRow ?? globalRow` whole-row
precedence. When an admin saved font settings with scope="global", only the
global row was updated. If the admin also had a user-scope row (created by
prior saves with the default scope="user"), ALL fields from the user-scope
row overrode the global row — including fontColor — causing the PDF to show
the old color even after changing global settings.

Schema change (executive-meetings.ts):
- Made fontFamily, fontSize, fontWeight, alignment, fontColor nullable.
  User-scope rows now store NULL for fields that inherit from global,
  and only store non-null values for fields the user explicitly overrode.

Backend fix (executive-meetings.ts):
- resolveFontPrefsForUser: per-field merge —
  user non-null → global non-null → schema default.
- PATCH handler for user-scope: after upsert, compares each field with the
  current global values. Fields matching global are set to NULL (= inherit).
  The post-nullification row is returned in the API response and audit log.
- No user-scope rows are deleted; scope isolation is preserved.

Frontend fix (executive-meetings.tsx):
- effectiveFont computed via per-field merge (u?.field ?? g?.field ?? default)
- FontSettingsResponse type updated for nullable fields (FontSettingsRow)
- Scope switching in FontSettingsSection loads the selected scope's values
  (global → globalFont ?? DEFAULT_FONT; user → effective font)
- globalFont prop threaded through SettingsSection → FontSettingsSection

Data migration: existing user-scope rows normalized via SQL — fields matching
global values set to NULL so per-field inheritance applies immediately.

Verified: TypeScript clean, e2e Playwright test passes, API tests confirm
per-field merge, nullification, and PDF color propagation.
2026-05-04 12:30:00 +00:00
2026-04-21 12:16:59 +00:00
2026-04-18 02:00:09 +00:00
2026-04-18 02:00:09 +00:00
2026-04-18 02:00:09 +00:00
S
Description
No description provided
138 MiB
Languages
TypeScript 69.2%
JavaScript 29.2%
CSS 0.6%
Shell 0.6%
Dockerfile 0.2%
Other 0.2%