Show full chat transcript on leads, fix Chat Agent settings losing place on Drive connect
Seth+1: Claude Sonnet 5
41f3768
Chat-agent leads only showed their latest message in the lead detail
panel ("Their reply"), truncating the actual conversation. Added a
chat-agent-thread endpoint (reads the transcript already stored on
raw_webhook.messages) and load it automatically for these leads instead
of requiring a click that previously hit the Smartlead-specific thread
route and failed.
The Chat Agent settings page kicked back to the main Settings list after
connecting Google Drive. The OAuth callback always redirects to the bare
/settings URL, but which settings sub-panel was open only lived in local
component state, not the URL — so landing back on /settings forgot Chat
Agent was open. Settings.jsx now checks for the Drive-callback query
params on load and reopens straight into the Chat Agent panel.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Add dashboard activity/lead/deal stat boxes and backfill Contacts/Companies ownership scoping
Seth+1: Claude Sonnet 5
de29580
- Add Calls, Visits, New leads, Deals, and Closings stat boxes to the
Sales Dashboard, respecting the existing team/date-range filters.
- Add a tenant-wide GET /api/activities endpoint (previously only
available per-contact) and bump /api/leads' page-size cap to match
Deals, so the new dashboard counts aren't silently truncated.
- Give Contact and Company an owner_user_id column and apply the same
team-manager visibility scoping already used by Leads/Deals to their
list, detail, and patch routes — these had no ownership concept at
all before, so every tenant member could see everyone's contacts and
companies regardless of team.
- Add an Owner avatar + reassignment dropdown to Contacts.jsx and
Companies.jsx (factored into a shared OwnerCell component), matching
the admin-can-assign-anyone / member-can-only-self-claim rules the
backend now enforces.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Add "Add a contact" form to Leads and Deals detail panels
Seth+1: Claude Sonnet 5
1d7a01a
Mirrors the Companies page's existing "Add a contact" box via a new shared
AddContactForm component, using the generic POST /api/contacts route (rather
than the Companies-specific one) so it works even before a Lead/Deal's
company has synced into a Company row. Refreshes the associated-contacts
list automatically after a save.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Add sales teams: manager role, team assignment, and team-scoped data visibility
Seth+1: Claude Sonnet 5
67330bb
Managers head a team (Team.manager_user_id, TenantMembership.team_id) and see
their own plus their team's leads, deals, and Call/Visit activity; other
members see only their own. A shared _visible_owner_user_ids() helper gates
list_leads, list_deals, quarterly_recurring_metrics (which the Dashboard
reads from), and both activity-timeline endpoints. Leads gains an
owner_user_id column plus assignment UI (mirroring Deals, which already had
per-user ownership) since team-scoping needs something to scope by. Admins
manage teams and member-team assignment from a new Teams card in Settings.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Add Call/Visit activity logging and timeline for contacts and companies
Seth+1: Claude Sonnet 5
41c19e3
New ContactActivity table tracks calls/visits with notes and author,
surfaced via Call/Visit icon buttons (with an inline note textarea)
everywhere a contact appears — Contacts table rows, associated-contacts
lists on Companies/Leads/Deals, and the contact identity header in each
detail panel. Adds a per-contact activity timeline and a company-level
rollup that aggregates activity across every contact sharing that company.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Add Type field (Existing/New) to Contacts/Companies/Leads/Deals, synced like Category
Seth+1: Claude Sonnet 5
fe7e466
Company gets a new type column, wired through the existing generic
COMPANY_DETAIL_PATCH_FIELDS propagation so it syncs bidirectionally across
Company/Contact/Lead/Deal exactly like Category. Companies page also gets a
Type filter, table column, and inline-add-row selector matching Category's
existing footprint there.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Add contact number field to Contacts/Companies, show associated contacts on Leads/Deals
Seth+1: Claude Sonnet 5
c40de6e
Adds a personal phone column on Contact/CrmLead and a synced company-level
phone on Company (using the existing company_phone/company_name_for_emails
style patch-body disambiguation), surfaced in the shared identity/company
editors everywhere they're used. Leads and Deals detail panels now also show
an "Associated contacts" list for the linked company, matching the Companies
page, via a new shared AssociatedContactsList component and a
GET /api/contacts/by-company endpoint.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Fix Category revert bug on Contacts page, generalize sync to all company fields
Seth+1: Claude Sonnet 5
4b1d42b
- Contacts.jsx built its own local companyDetails object for the
editor instead of passing raw_data straight through — that object
was missing a Category key entirely, so the field always read as
empty and every autosave round-trip re-synced the form from that
same Category-less object, snapping the dropdown back to "-".
- Generalized the previous Category-only propagation into full-field
propagation: editing industry, employees, revenue, website, city,
state, country, or category anywhere (Contact/Lead/Company/Deal)
now pushes to the Company row and every Contact/Lead sharing that
company name, not just Category.
- _sync_companies_from_contacts now also tops up any blank field on
an already-existing Company row from the richest matching contact,
fixing Company rows that got stuck sparse after an early sync —
never overwrites a field that already has a value, synced or
manually edited.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Sync Category across Company/Contact/Lead, link contacts, add company-level lead conversion
Seth+1: Claude Sonnet 5
6a71a79
- Category is now a true company-level attribute: editing it from the
Company page, a Contact, a Lead, or a Deal linked to a contact
propagates to the Company row and every Contact/Lead sharing that
company name (case-insensitive), so it never drifts between the
four places it's editable.
- Fixed a gap where converting a contact to a lead didn't carry its
Category into the lead's company snapshot.
- Associated contacts in the Company detail panel are now clickable —
navigates to Contacts and opens that exact contact's detail panel
(via a short-lived ?contact= deep link, cleaned from the URL after
use).
- New "Convert to Leads" action on the Company detail panel, mirroring
the existing per-contact "Copy to Leads," but scoped to every
contact associated with that company in one action.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Add Companies page with Category field and contact sync
Seth+1: Claude Sonnet 5
c253255
- New Company entity (name, category A/B/C, industry, employees,
annual revenue, website, city/state/country) with routes to list,
create, patch, bulk-delete, and re-sync.
- Companies are associated with Contacts by case-insensitive name
match rather than a foreign key, so this is fully additive and
never touches the existing Contact/CrmLead/CrmDeal schema or
behavior. A Company row is auto-created for any distinct
Contact.company value that doesn't already have one, seeded from
the richest matching contact; manual edits are never overwritten
by later syncs.
- New Companies page (sidebar, between Contacts and Leads) built
from the same AppShell/MainTableWorkspace/SlideOverPanel
components as Leads, with a detail panel listing every associated
contact plus an inline "add a contact" form scoped to that company.
- Category dropdown (A/B/C) added to the shared CompanyDetailsEditor
used by Contacts, Leads, and Deals, so it's consistently available
wherever company …
Add Chat Agent module: RAG website widget with Drive/site knowledge base and CRM lead capture
Seth+1: Claude Sonnet 5
991c079
Adds an embeddable WordPress chat widget backed by a Google Drive folder and a
site crawl, with admin-editable skills/guardrails, streaming replies, and
automatic CrmLead creation (with live transcript) for every chat that shares
a name/email.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>