Files
upstream-atomic-crm/.claude/skills/delete-initial-resource/contacts.md
upstream-mirror 93ecc1a6f8
Some checks failed
✅ Check / 🔬 ESLint (push) Failing after 21s
✅ Check / 🏷️ Typecheck (push) Failing after 11s
✅ Check / 🔎 Test (push) Failing after 11s
✅ Check / e2e-test (push) Failing after 11s
✅ Check / 🔨 Build (push) Failing after 11s
🚀 Deploy / 🚀 Deploy (doc) (push) Failing after 12s
🚀 Deploy / 🚀 Deploy (demo) (push) Failing after 12s
🚀 Deploy / 🚀 Deploy (supabase) (push) Failing after 18s
snapshot of https://github.com/marmelab/atomic-crm.git (main, 2026-09-18; blobs > 131072B omitted)
2026-09-18 01:48:50 +05:00

6.0 KiB

Deleting contacts

The spine of the CRM and the widest deletion of the five. Notes attach to contacts | deals, tasks belong only to contacts, tags is a field on Contact, companies aggregate nb_contacts, deals link contact_ids, and the activity-log + JSON-import + merge subsystems all revolve around it. Removing it orphans notes/tasks/tags.

Confirm cascade scope first

Ask the user how far to cascade — the answer changes the whole job:

  • contacts only — leave notes/tasks/tags as compiling shells (narrowing the notes union to "deals" keeps notes valid as long as deals exists; tasks/tags become orphaned shells), or
  • also delete the now-orphaned subsystems.
  • And whether to touch the backend.

Frontend specifics

  • Shared subsystems — narrow the notes union to "deals" and the activity-log union to drop "contact". Delete ActivityLogContactCreated.tsx + ActivityLogContactNoteCreated.tsx outright; drop getNewContactsAndNotes in providers/commons/activity.ts.
  • Typing landmine: DealNote.status is typed undefined (a deliberate ContactNote-compat marker in types.ts), so retyping NoteInputs's useFormContext<ContactNote | DealNote> down to <DealNote> collapses status to never and tsc rejects the status-hydration setValue("status", …). Widen it back with useFormContext<Omit<DealNote, "status"> & { status?: string }>().
  • Contact-only mobile note components (dead once contacts is gone) — delete outright: NoteCreateSheet.tsx, NoteEditSheet.tsx, NoteShowPage.tsx, NotesIteratorMobile.tsx, NoteInputsMobile.tsx (+ their stories/tests). Drop the NotesIteratorMobile re-export from notes/index.ts and clean importers (MobileNavigation.tsx, the mobile <Resource name="contacts"> note route in CRM.tsx).
  • Links to contacts: deals.contact_ids (a selector in DealInputs.tsx, a per-deal <ContactList/> in DealShow.tsx + the standalone deals/ContactList.tsx to delete, the "create a contact first" gate in DealEmpty.tsx) and tasks.contact_id (the whole task contact-linking UI: AddTask, Task, TaskCreateSheet, TaskEditSheet, TaskFormContent's selectContact, the showContact/filterByContact threading in TasksIterator/TasksListFilter/TasksListByDueDate). Decide per-link: orphaned shell (contact_ids: Identifier[], default []) vs drop.
  • Custom method: mergeContacts(sourceId, targetId) in both providers (FakeRest → providers/commons/mergeContacts.ts, delete it; supabase → the merge_contacts edge function). Also processContactAvatar/getContactAvatar (delete providers/commons/getContactAvatar.ts + test), the contacts/contact_notes + tasks nb_tasks callbacks, and the supabase contacts -> contacts_summary routing + contact_note -> contactNote remap.
  • Wrapper components outside the folder, delete outright: dashboard/HotContacts.tsx (contacts widget), dashboard/DashboardStepper.tsx (contact-onboarding wizard). Dashboard.tsx/MobileDashboard.tsx gate the whole render on contact/contactNote counts via the stepper — drop that gating. LatestNotes.tsx mixes contact_notes + a <Contact> renderer; dashboard/TasksList.tsx has an <AddTask selectContact/>.
  • JSON importer is heavily contact-coupled (importContact/importNote for contact_notes, contactGender, stats/idsMaps); also import-sample.json (drop the contacts + notes sections). ContactOption.tsx is a shared option renderer — delete it.
  • FakeRest generators: delete contacts.ts, contactNotes.ts, finalize.ts outright; clean index.ts/types.ts; deals.ts (contact_ids), tasks.ts (contact_id + nb_tasks), companies.ts (nb_contacts seed).
  • Layout/login: Header.tsx, MobileNavigation.tsx, SignupPage.tsx (redirectTo: "/contacts"), StoryWrapper.tsx (buildContact + the contacts/contact_notes db keys).

Backend

  • Drop the contacts + contact_notes tables, the tasks.contact_id column (FK + index), the contacts_summary view, and the functions merge_contacts, handle_contact_saved, handle_contact_note_created_or_updated outright — plus their triggers/policies/grants and the contacts_id_seq / "contactNotes_id_seq" grants.
  • Orphaned helpers: get_avatar_for_email (only called by handle_contact_saved) and lowercase_email_jsonb (only wired to the contact email trigger) — remove them + grants.
  • activity_log view carries the contact pattern (a contact + contact_note column on every branch and two dedicated branches contact.created/contactNote.created) — same shape as deals.
  • Edge functions (deepest of the five): delete the whole merge_contacts/ function (+ its [functions.merge_contacts] block in config.toml) and the whole postmark/ inbound-email function (+ its [functions.postmark] block) — this leaves the inbound-email settings UI in ProfilePage/SettingsPageMobile and the POSTMARK_*/VITE_INBOUND_EMAIL env vars hollow; flag that to the user. In _shared/db.ts drop ContactsTable/ContactNotesTable, the tasks.contact_id field, and their Database registrations. In mcp/: contacts (not tasks) drives CRM_BASE_URL — the display_task_list contact_name/contact_id schema fields and taskListUi.ts's contact-link rendering exist only to deep-link task→contact, so removing them makes CRM_BASE_URL (in mcp/index.ts, the __CRM_BASE_URL__ HTML placeholder, and supabase/functions/.env) dead — drop it. Rewrite the contacts/contacts_summary mentions in the get_schema/query/mutate prompt examples and swap the table name in mcp/validateSql.test.ts fixtures for a surviving table.

grep — benign matches to leave (intentional)

  • resources.companies.field_categories.contact (a company "Company info" section label in CompanyInputs.tsx/CompanyAside.tsx, not the contacts resource), the resource="contacts" JSDoc examples in misc/CreateSheet.tsx/EditSheet.tsx, and the now-unused resources.contacts.* i18n keys (optional/large — flag, don't force). supabase/migrations/ keeps historical references — never edit them.