Změna stavu tiše přepíše vlastníka záznamu na jednajícího uživatele
import { Aside } from ‘@astrojs/starlight/components’;
Symptom
Sekce “Symptom”Obchodník hlásí, že mu „zmizel klient” — není v seznamu ani ve vyhledávání. Klient přitom v DB existuje. Postupně se na jediný účet (kancelář / info@) nahrnuly stovky klientů, které měli v práci jiní lidé.
Root cause
Sekce “Root cause”Při změně stavu leadu (kvalifikace/scoring NEW → CONTACTED) běžela „konverzní” větev, která přepisovala vlastníka klienta:
// ŠPATNĚ — fallback na jednajícího uživateleconst newOwnerId = lead.assignedTo?.id || auth.user.id;if (newOwnerId && newOwnerId !== client.ownerId) { clientUpdate.ownerId = newOwnerId;}Leady z webových formulářů často nemají přiřazeného obchodníka (assignedTo = null). Když stav takového leadu měnila kancelář (sdílený info@ účet), newOwnerId spadl na auth.user.id → vlastník klienta se přepsal na kancelář. Protože obchodníci mají RBAC scope "own" (vidí jen své klienty), klient jim ze seznamu zmizel. Efekt se kumuloval: jeden účet vlastnil 711 klientů, z toho 31 mělo lead přiřazený jinému obchodníkovi (= prokazatelně ukradeno).
Fix
Sekce “Fix”Vlastnictví převést jen na reálně přiřazeného obchodníka, nikdy na jednajícího uživatele:
// SPRÁVNĚ — žádný fallback na currentUserconst newOwnerId = lead.assignedTo?.id;if (newOwnerId && newOwnerId !== client.ownerId) { clientUpdate.ownerId = newOwnerId;}Náprava dat: klienty vlastněné kanceláří, kteří mají lead přiřazený právě jednomu obchodníkovi, vrátit tomuto obchodníkovi (jednoznačné případy automaticky, nejednoznačné ručně).
Jak se tomu vyvarovat v jiných systémech
Sekce “Jak se tomu vyvarovat v jiných systémech”- Detection: grepuj přiřazení vlastnictví (
ownerId =,assigneeId =) a hledej fallback|| currentUser/|| session.user.idna write cestě, která není „explicitní přiřazení”. - Anti-pattern: vedlejší efekt (změna stavu) tiše mění vlastnictví; „enrich/overwrite” vlastníka bez akce uživatele.
- Lepší přístup: (1) vlastnictví měň jen explicitní akcí „přiřadit”; (2) auditlog na každou změnu
ownerId; (3) test: uživatel A změní stav cizího záznamu → vlastník se NESMÍ změnit na A.
Sister bugs / související
Sekce “Sister bugs / související”- Webhook přilepí lead na cizí kontakt podle křestního jména — jiný tichý únik dat na lead-capture cestě.