fix(clients): list contacts join + nationality backfill + col redesign
Wire primary email + primary phone into the /clients list service so the redesigned columns (Name · Email · Phone · Country · Source · Latest stage · Created) actually have data. Picks the row marked is_primary=true; falls back to most-recent created_at when the flag is unset. - 0026 schema migration: unique partial index idx_cc_one_primary_per_channel on (client_id, channel) WHERE is_primary=true. Prevents the §14.2 "multiple primaries" ambiguity. - 0027 data migration: backfill clients.nationality_iso from the primary phone's value_country. 218 -> 36 missing on dev. Idempotent. - listClients: add a fifth parallel query for client_contacts; build primaryEmailMap / primaryPhoneMap in-memory from the pre-sorted result. - client-columns: drop Yachts/Companies/Tags from the default view per §5.1; add Email/Phone/Country/Latest-stage columns; rename "Nationality" -> "Country" since phone country is a proxy (§14.2). - client-card: prefer email, fall back to phone, for the line under the name; replaces the old `contacts.find(isPrimary)` lookup. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -77,6 +77,11 @@ export const clientContacts = pgTable(
|
||||
index('idx_cc_phone')
|
||||
.on(table.channel, table.value)
|
||||
.where(sql`${table.channel} = 'phone'`),
|
||||
// At most one is_primary=true per (client_id, channel). Prevents
|
||||
// ambiguity when the /clients list pulls "the" primary phone/email.
|
||||
uniqueIndex('idx_cc_one_primary_per_channel')
|
||||
.on(table.clientId, table.channel)
|
||||
.where(sql`${table.isPrimary} = true`),
|
||||
],
|
||||
);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user