Skip to content

fix(contacts): distinguish WhatsApp group contacts from real customer contacts (EVO-1018)#47

Merged
dpaes merged 2 commits into
developfrom
fix/EVO-1018
May 13, 2026
Merged

fix(contacts): distinguish WhatsApp group contacts from real customer contacts (EVO-1018)#47
dpaes merged 2 commits into
developfrom
fix/EVO-1018

Conversation

@marcelogorutuba
Copy link
Copy Markdown
Member

@marcelogorutuba marcelogorutuba commented May 7, 2026

Summary

  • Add 'group' to Contact type union in TypeScript types
  • Add include_groups param to ContactsListParams and ContactsSearchParams
  • Update ContactTypeBadge to render 'Group' badge with Users icon for group type
  • Normalize group type to person in ContactForm (groups are not editable via form)
  • Add type.group translation key to all 6 locales (en, pt, pt-BR, es, fr, it)

Validation

  • pnpm exec tsc -b --noEmit — ✅ no errors
  • Tested locally: Contacts page no longer shows WhatsApp group rows

Related PRs

Linked Issue

  • EVO-1018

Summary by Sourcery

Distinguish WhatsApp group contacts from regular person/company contacts in the contacts UI and type system.

New Features:

  • Add support for a new 'group' contact type across contact TypeScript models and query parameters.
  • Render a dedicated Group badge with an appropriate icon for contacts of type 'group'.

Enhancements:

  • Normalize group contacts to person type in the contact form to prevent editing groups via the standard form.
  • Add i18n translation key for the group contact type across all supported locales.

@sourcery-ai
Copy link
Copy Markdown

sourcery-ai Bot commented May 7, 2026

Reviewer's guide (collapsed on small PRs)

Reviewer's Guide

Adds explicit support for WhatsApp group contacts by extending the Contact types and list/search params, rendering a dedicated Group badge, normalizing groups to person in the editable form, and wiring up translations for the new type across all locales.

Class diagram for updated contact types and components

classDiagram
  class Contact {
    +string id
    +string name
    +string type  // person | company | group
    +string email
    +string phone_number
    +string thumbnail
    +ContactPipelineInfo pipeline
    +string created_at
    +string updated_at
  }

  class ContactsListParams {
    +string search
    +string sort
    +string order  // asc | desc
    +string[] labels
    +string q
    +string type  // person | company | group
    +boolean include_groups
    +string company_id
    +boolean include_contact_inboxes
    +string created_after
    +string created_before
  }

  class ContactsSearchParams {
    +number page
    +number per_page
    +string sort
    +string type  // person | company | group
    +string[] labels
    +boolean include_contact_inboxes
  }

  class ContactTypeBadge {
    +string type  // person | company | group
    +string className
    +renderBadge()
  }

  class ContactForm {
    +Contact contact
    +setFormData()
    +normalizeType()
  }

  Contact "1" --> "*" ContactPipelineInfo : pipelineInfo
  ContactForm --> Contact : uses
  ContactForm --> ContactTypeBadge : renders
  ContactTypeBadge --> ContactsTranslations : uses
  ContactsListParams --> Contact : queries
  ContactsSearchParams --> Contact : searches

  class ContactsTranslations {
    +string type_person
    +string type_company
    +string type_group
  }
Loading

File-Level Changes

Change Details Files
Extend contact domain types and query params to include a new 'group' contact type and control inclusion of groups in listings/searches.
  • Add 'group' to the Contact.type union so contacts can be typed as groups
  • Extend ContactsListParams.type and ContactsSearchParams.type unions to accept 'group'
  • Introduce include_groups?: boolean to ContactsListParams to let callers choose whether groups are returned
src/types/contacts/contact.ts
Render a dedicated visual treatment for group contacts in the UI while preserving existing badges for person/company.
  • Import the Users icon for group contacts
  • Update ContactTypeBadge props to accept 'group' and short-circuit render to a Group badge with Users icon and translated label when type === 'group'
  • Keep existing logic intact for distinguishing person vs company when not a group
src/components/contacts/ContactTypeBadge.tsx
Prevent editing group contacts via the standard contact form by normalizing their type to person in the form state.
  • When initializing ContactForm state from an existing contact, coerce contact.type === 'group' to 'person' before setting formData.type
src/components/contacts/ContactForm.tsx
Localize the new group contact type label across all supported languages.
  • Add type.group key under contacts namespace in English locale JSON
  • Add corresponding type.group entries to Spanish, French, Italian, Portuguese, and Brazilian Portuguese locale JSON files
src/i18n/locales/en/contacts.json
src/i18n/locales/es/contacts.json
src/i18n/locales/fr/contacts.json
src/i18n/locales/it/contacts.json
src/i18n/locales/pt/contacts.json
src/i18n/locales/pt-BR/contacts.json

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

Copy link
Copy Markdown

@sourcery-ai sourcery-ai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've left some high level feedback:

  • In ContactForm, the inline normalization (contact.type === 'group' ? 'person' : contact.type) || 'person' is a bit dense; consider extracting this into a small helper (e.g. normalizeEditableContactType(contact.type)) to make the intent clearer and easier to extend if other non-editable types appear later.
  • The new include_groups?: boolean flag in ContactsListParams/ContactsSearchParams overlaps conceptually with type?: 'person' | 'company' | 'group'; it may be worth clarifying or constraining how these interact (e.g. avoiding ambiguous combinations like type: 'group', include_groups: false) by using a discriminated union or runtime validation.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- In `ContactForm`, the inline normalization `(contact.type === 'group' ? 'person' : contact.type) || 'person'` is a bit dense; consider extracting this into a small helper (e.g. `normalizeEditableContactType(contact.type)`) to make the intent clearer and easier to extend if other non-editable types appear later.
- The new `include_groups?: boolean` flag in `ContactsListParams`/`ContactsSearchParams` overlaps conceptually with `type?: 'person' | 'company' | 'group'`; it may be worth clarifying or constraining how these interact (e.g. avoiding ambiguous combinations like `type: 'group', include_groups: false`) by using a discriminated union or runtime validation.

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

marcelogorutuba and others added 2 commits May 13, 2026 12:05
… contacts (EVO-1018)

- Add 'group' to Contact type union in TypeScript types
- Add include_groups param to ContactsListParams and ContactsSearchParams
- Update ContactTypeBadge to render 'Group' badge with Users icon for group type
- Normalize group type to person in ContactForm (groups are not editable via form)
- Add type.group translation key to all 6 locales (en, pt, pt-BR, es, fr, it)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…tering

- Preserve original contact.type in form state so PATCH never resets
  a group contact's type to 'person' (H1)
- Display group icon and label in edit-mode type display section (H1)
- Add 'group' to ContactCreateData.type union; introduce taxIdType
  helper to keep tax ID utilities operating on person|company only
- Refactor ContactTypeBadge to config-driven table, removing early
  returns and making future types trivial to add (L2)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Copy link
Copy Markdown

@dpaes dpaes left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Round 2 aprovado. H1 (form group preservation) confirmado: type: contact.type || 'person' preserva grupos no edit. ContactTypeBadge config-driven, type.group traduzido nos 6 locales. Detalhes completos no card Linear EVO-1018. Mergeando.

@dpaes dpaes merged commit b5dd3d3 into develop May 13, 2026
1 check passed
@dpaes dpaes deleted the fix/EVO-1018 branch May 13, 2026 20:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants