mirror of
https://github.com/warmbly/warmbly.git
synced 2026-09-05 16:02:48 +00:00
feat: give models.AddContact an optional Subscribed pointer and honour it in the pg_contact upsert (passed twice with explicit boolean casts because one placeholder cannot serve both the INSERT value and the DO UPDATE set without tripping Postgres parameter inference), where nil now means leave the flag alone, and stop the same upsert erasing a populated first_name, last_name, company or phone when the incoming row's cell is blank so re-importing a partial export enriches contacts instead of wiping them
This commit is contained in:
@@ -321,6 +321,12 @@ type AddContact struct {
|
||||
Categories []string `json:"categories"`
|
||||
|
||||
CustomFields map[string]string `json:"custom_fields"`
|
||||
|
||||
// Subscribed is the marketing-consent flag to store. nil means "don't
|
||||
// decide": a new contact defaults to subscribed, an existing one keeps
|
||||
// whatever it already had. Set explicitly by the importer when the file
|
||||
// carries a subscribed column.
|
||||
Subscribed *bool `json:"subscribed,omitempty"`
|
||||
}
|
||||
|
||||
type SearchContactsFilterType string
|
||||
|
||||
@@ -232,21 +232,29 @@ func (r *contactRepository) Add(ctx context.Context, userID string, orgID uuid.U
|
||||
insertBatch := pgx.Batch{}
|
||||
for _, lead := range normalized {
|
||||
insertBatch.Queue(
|
||||
// $9 and $10 are the same value: a parameter used both as an
|
||||
// INSERT value and inside the DO UPDATE set gives Postgres two
|
||||
// inference sites for one placeholder, so it is passed twice with
|
||||
// explicit casts. NULL means "leave the flag alone".
|
||||
`INSERT INTO contacts (
|
||||
id, user_id, organization_id, first_name, last_name, email, company, phone, custom_fields
|
||||
id, user_id, organization_id, first_name, last_name, email, company, phone, custom_fields, subscribed
|
||||
) VALUES (
|
||||
gen_random_uuid(), $1, $2, $3, $4, LOWER($5), $6, $7, $8
|
||||
gen_random_uuid(), $1, $2, $3, $4, LOWER($5), $6, $7, $8, COALESCE($9::boolean, TRUE)
|
||||
)
|
||||
ON CONFLICT (user_id, (LOWER(email))) DO UPDATE SET
|
||||
organization_id = COALESCE(contacts.organization_id, EXCLUDED.organization_id),
|
||||
first_name = EXCLUDED.first_name,
|
||||
last_name = EXCLUDED.last_name,
|
||||
company = EXCLUDED.company,
|
||||
phone = EXCLUDED.phone,
|
||||
-- Enrich, never erase: a blank cell in a re-imported file must
|
||||
-- not wipe a name we already have.
|
||||
first_name = COALESCE(NULLIF(EXCLUDED.first_name, ''), contacts.first_name),
|
||||
last_name = COALESCE(NULLIF(EXCLUDED.last_name, ''), contacts.last_name),
|
||||
company = COALESCE(NULLIF(EXCLUDED.company, ''), contacts.company),
|
||||
phone = COALESCE(NULLIF(EXCLUDED.phone, ''), contacts.phone),
|
||||
custom_fields = contacts.custom_fields || EXCLUDED.custom_fields,
|
||||
subscribed = COALESCE($10::boolean, contacts.subscribed),
|
||||
updated_at = NOW()
|
||||
RETURNING id, first_name, last_name, email, company, phone, custom_fields, subscribed, updated_at, created_at`,
|
||||
userID, orgID, lead.FirstName, lead.LastName, lead.Email, lead.Company, lead.Phone, lead.CustomFields,
|
||||
lead.Subscribed, lead.Subscribed,
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user