You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
refactor: remove the contact-import and ghost-user creation paths
Contacts are established solely by accepting an opportunity, which already
writes the mutual `contact` memberships in both users' personal networks
(OpportunityService → upsertContactMembership, on accept and start-chat).
Every other way of creating a contact — and the ghost users it minted — is
removed. Read/search/remove of existing contacts is unchanged.
This is the code half. Deleting the 14 ghost users still in production, and
dropping `users.is_ghost` plus the remaining `isGhost` plumbing, follow as
separate changes; nothing here can create a new ghost.
- protocol: the whole `integrations` capability (`src/integrations/`), its
five public types and the `import_gmail_contacts` tool.
- protocol: `import_contacts` and `add_contact`; `ContactServiceAdapter`
narrows to list/remove/search.
- protocol: `generateInviteMessage` — it required `recipient.isGhost`, so it
can never fire once ghosts are gone. Its endpoint
(`GET /opportunities/:id/invite-message`) and web caller go with it; the
other three invite-message call sites use local templates and are untouched.
- protocol: `contactsEnabled`, `integration` and `integrationImporter` from
`ToolDeps`; `createGhostUser` from the database interface.
- api: `POST /users/contacts`, `POST /integrations/:toolkit/import`,
`ContactService.addContact/resolveUsers/importContacts`, both
`createGhostUser*` adapters, the Gmail/Slack contact fetchers,
`contacts-feature.ts`, `contacts.guard.ts`, `lib/dedup/`,
`types/integrations.types.ts`.
- The `CONTACTS_ENABLED` and `CONTACT_DEDUP_STRATEGY` flags: with the write
paths gone they gated nothing. Remove from `startup.env.ts` and
`.env.example` (both still set in Railway — delete there after deploy).
- cli: `index contact add` and `index contact import --gmail`, plus the now
unused `--name` and `--gmail` flags.
- web: the add-contact path in AccessTab (add-by-email now only offered for
invitable networks), `usersService.addContact`, the Gmail/Slack import in
IntegrationsTab, and the ghost branch in `useOpportunityActions`.
- `contactService.removeContact` and `DELETE /users/contacts/:contactId` stay.
The hard delete doubles as the reverse opt-out that OpportunityService
honours via `restore: false`; routing personal-network removal through
`networkService.removeMember` would drop that and silently re-add people.
- Retired tool names are kept in the MCP forbidden-name lists as regression
guards.
- protocol: build clean, `architecture:check` clean, `test:isolated`
2202 pass / 0 fail, full suite at parity with the pre-change baseline
(96 pre-existing failures, all database-gated; no new failures).
- api: typecheck and lint clean; CI's hermetic gates green (83 pinning +
33 CLI guard specs). The database-backed suite is unchanged and still gated.
- cli: 351 pass / 0 fail, build and lint clean.
- web: build and lint clean.
- `check:lockfile-versions` clean.
0 commit comments