Mirror the lead minimum-necessary mask on the client (§164.502(b))

Featurekamo-internal
Shipped
4 Agosti 2026, 04:17 UTC
Author
kamo
Commit
1fea0c6

SecurityService now withholds custom-form answers from a caller who is not the lead's assignee (and, in a handlesPhi tenant, even from a holder of right 161). That mask is the enforcement; this is not. Two paths still bypass it: - LeadRealtimePublisher puts a FULL, unmasked LeadDTO on security.leads.rt.{orgId} — one payload fanned out to every subscriber in the org, with no per-recipient projection possible. Until that event carries identifiers only and the client refetches, app/lib/leads/leadFieldMask.ts is the only thing between a colleague's intake answers and every open lead pane in the tenant. LeadViewClient now runs incoming realtime payloads through it before any of it reaches state. - Rendering: a withheld form and a never-filled-in one arrive looking identical, so the decision has to be recomputed, not inferred. The custom-form pane drops its Edit affordance when answers are restricted — saving a blank form would PUT {} over the real answers, which the server now 403s anyway. Organization.handlesPhi is delivered on the existing column -> DTO -> OrgContext path (the org entity already serialises it; the zod schema and Organization.fromJSON allow-list were the missing links), not a second channel. No new user-visible copy: the explanatory "restricted" label needs a key in the translation-dictionary repo and is deliberately left for that change.

All changes

Je, unaona nini kuhusu usafiri?

Kila moja ya hizi updates ardhi katika nafasi yako ya kazi moja kwa moja. Kuanza bure na kuangalia kukua wiki baada ya wiki.

Kuwa Huru MileleMtazamo wa bei