Skip to content

Added ICP management#143

Merged
anujeet98 merged 10 commits into
mainfrom
feature/icp
May 29, 2026
Merged

Added ICP management#143
anujeet98 merged 10 commits into
mainfrom
feature/icp

Conversation

@Rishavraaj
Copy link
Copy Markdown
Contributor

Summary

This PR introduces the ICP (Ideal Customer Profile) feature, which lets users define customer criteria and discover matching companies and
contacts via the Apollo.io OAuth integration.

Features

  • ICP Profile Management — Create, edit, and delete ICP profiles with filters: industries, employee ranges, revenue range, and locations
  • Company Search — Fetches matching companies from Apollo (/organizations/search) using the profile's filters, displayed in an
    infinite-scroll table with logo avatars and fallback initials
  • Contact Search — Fetches CRM contacts from Apollo (/contacts/search), displayed in an infinite-scroll table with photo avatars and
    fallback initials
  • Rich Notes Editor — EditorJS-powered notes panel on each profile with autosave
  • Profile Sidebar — Shows filter summary (industries, employee ranges, revenue range, locations, created date) with inline edit via sheet
  • Tab persistence — Active tab (details / companies / contacts) is persisted in the URL via nuqs (?tab=companies)
  • Infinite scroll — Both the profile list and Apollo result tables use infinite scroll instead of pagination

Apollo OAuth Integration

  • ApolloService now uses ApolloIntegrationService.getAccessToken(organizationId) instead of a static APOLLO_API_KEY, with automatic token
    refresh
  • Corrected OAuth scopes to match the Apollo developer portal registration:
    • Removed invalid app_scopes, mixed_people_api_search, mixed_companies_search
    • Added contacts_search, organizations_search
  • IcpModule imports IntegrationsModule to consume ApolloIntegrationService

Database

  • New IcpProfile model in sales schema with filters (JSON), description (JSON), and notes (JSON) fields
  • 3 migrations: initial profile table, notes column, description type change

Test plan

  • Create an ICP profile with industries, employee ranges, and locations set
  • Verify Companies tab loads and infinite-scrolls through Apollo results
  • Verify Contacts tab loads Apollo CRM contacts
  • Edit a profile via the sidebar pencil icon — verify changes persist
  • Add notes in the Details tab — verify autosave triggers
  • Navigate away and back — verify ?tab= URL param restores the active tab
  • Disconnect and reconnect Apollo from Settings — verify token refresh works
  • Delete an ICP profile from the list — verify confirm dialog and removal

🤖 Generated with Claude Code

Rishavraaj and others added 9 commits May 28, 2026 15:57
- ICP profile CRUD (NestJS controller/service/repository)
- Apollo.io integration via mixed_companies/search and contacts/search
- ICP list and detail pages with infinite-scroll company/contact tabs
- MultiSelect component for filter fields (industries, locations, employee ranges)
- EditorJS dark-mode CSS fixes
- Prisma IcpProfile model and migrations

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Add page/perPage params to GET /icps with Number() coercion fix
- Repository returns paginated response with total/totalPages
- Switch frontend from useQuery to useInfiniteQuery with getIcpProfilesInfinite
- Nav label updated to ICPs

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Switch contacts search to use q_keywords (industries + locations) per Apollo /contacts/search spec
- Remove unsupported filter params (q_organization_keyword_tags, organization_num_employees_ranges)
- Update response mapping to use present_raw_address and richer organization fields
- Replace useState tab with nuqs useQueryState (?tab=) for refresh-safe tab selection

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Remove restrictive q_keywords filter from Apollo contacts search so all contacts are returned (was returning 0 results)
- Replace raw <img> tags with Avatar component in ICP company and contact table name cells, with initials fallback

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Replace static APOLLO_API_KEY with OAuth access tokens from ApolloIntegrationService.
- ApolloService now injects ApolloIntegrationService and fetches Bearer tokens per org
- searchCompanies/searchContacts accept organizationId and use Authorization header
- IcpModule imports IntegrationsModule to get ApolloIntegrationService
- Remove deprecated APOLLO_API_KEY from .env.example

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Replace invalid app_scopes with correct scope names from Apollo's supported list
- Use contacts_search (CRM contacts) and organizations_search (company search)
- Remove mixed_people_api_search and mixed_companies_search which are not registered in the OAuth app
- Log active scopes in authorization URL for easier debugging

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Merged duplicate @zuko/ui-kit imports in IcpForm.tsx and replaced
`any` types with `unknown`/`typeof fetch` in chat.test.tsx.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- BasePage.updateTableCell: blur for number/date inputs instead of
  Enter (number inputs don't save on Enter)
- BasePage.showHistory: increase post-click wait from 500ms to 5s
- apollo-integration.spec: decode URL before asserting oauth/authorize
  (Apollo redirects through login, encoding the auth URL in a param)
- companies.spec: increase navigation timeout to 20s with waitUntil
  commit to avoid waiting for slow full-page load
- DealDetailPage.goto: wait for deal title instead of h2 Activity
  heading; the title renders much earlier and is always present

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Comment thread apps/backend/src/app/icp/apollo.service.ts Outdated
Comment thread apps/backend/src/app/icp/apollo.service.ts Outdated
- Updated variable name from `pag` to `pagination` in ApolloService to enhance code readability.
- Adjusted references to the new variable name in the pagination response structure.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@anujeet98 anujeet98 merged commit ddebefd into main May 29, 2026
2 checks passed
@anujeet98 anujeet98 deleted the feature/icp branch May 29, 2026 06:28
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