fix(clients): use EffectiveFlow in BulkAttach (#6454)

* fix(clients): use EffectiveFlow in BulkAttach

Mirror Attach (#4834): seed wire clients from EffectiveFlowsByEmails so a zeroed clients.flow column does not drop Vision on bulk attach (#6432).

* test(clients): cover BulkAttach Vision flow when clients.flow is zeroed

Regression for #6432 — same scenario as TestAttach_PreservesVisionFlowWhenCanonicalColumnZeroed.

* fix(clients): only apply EffectiveFlow when present in BulkAttach

Avoid overwriting a non-empty clients.flow when EffectiveFlowsByEmails
has no entry for the email. Also drop the extra blank line that broke gofumpt.

---------

Co-authored-by: mrchatam <287639636+mrchatam@users.noreply.github.com>
This commit is contained in:
mrchatam
2026-09-12 12:43:19 +03:30
committed by GitHub
parent 3a93235783
commit 0a838563bb
2 changed files with 90 additions and 0 deletions
+14
View File
@@ -60,6 +60,17 @@ func (s *ClientService) BulkAttach(inboundSvc *InboundService, emails []string,
records = append(records, rec)
}
// Same rule as Attach (#4834): clients.flow is unreliable when a non-flow
// inbound synced last, so seed from EffectiveFlow before clientWithInboundFlow.
emailsForFlow := make([]string, 0, len(records))
for _, rec := range records {
emailsForFlow = append(emailsForFlow, rec.Email)
}
flowsByEmail, err := s.EffectiveFlowsByEmails(nil, emailsForFlow)
if err != nil {
return result, false, err
}
needRestart := false
// Prepared in order first, as in Create: fillProtocolDefaults mints the
// shared credentials, so only the node pushes below may overlap.
@@ -100,6 +111,9 @@ func (s *ClientService) BulkAttach(inboundSvc *InboundService, emails []string,
continue
}
client := *rec.ToClient()
if flow, ok := flowsByEmail[rec.Email]; ok && flow != "" {
client.Flow = flow
}
client.UpdatedAt = time.Now().UnixMilli()
if err := s.fillProtocolDefaults(&client, inbound); err != nil {
recordErr("%s -> inbound %d: %v", rec.Email, ibId, err)