PhoenixKitCRM

CRM module for PhoenixKit — implements the PhoenixKit.Module behaviour for auto-discovery by a parent Phoenix application.

An interaction-tracking CRM: contacts (people) and companies (legal entities), the interactions logged between them, each with its own media, comments, and activity feed. Roles opt in to CRM access, and every admin gets per-user column configuration.

Features

Files/Images tabs require core Storage to be enabled; the Comments tab requires the phoenix_kit_comments module.

Installation

Add to the parent PhoenixKit app's mix.exs:

# Local development
{:phoenix_kit_crm, path: "../phoenix_kit_crm"}

# or, once published / pinned to a tag
{:phoenix_kit_crm, "~> 0.6"}

Then mix deps.get. The module appears in Admin > Modules and the sidebar automatically; toggle it on to expose /admin/crm.

Routes

Path LiveView
/admin/crm PhoenixKitCRM.Web.CRMLive
/admin/crm/contacts PhoenixKitCRM.Web.ContactsLive
/admin/crm/contacts/new · /:uuid/edit PhoenixKitCRM.Web.ContactFormLive
/admin/crm/contacts/:uuid PhoenixKitCRM.Web.ContactShowLive
/admin/crm/companies PhoenixKitCRM.Web.CompaniesLive
/admin/crm/companies/new · /:uuid/edit PhoenixKitCRM.Web.CompanyFormLive
/admin/crm/companies/:uuid PhoenixKitCRM.Web.CompanyShowLive
/admin/crm/lists (+ /new, /:uuid/edit, /:uuid/members, /:uuid/import) PhoenixKitCRM.Web.ListsLive + form/members/import views
/admin/crm/comparison PhoenixKitCRM.Web.ComparisonLive
/admin/crm/organizations PhoenixKitCRM.Web.OrganizationsView
/admin/crm/role/:role_uuid PhoenixKitCRM.Web.RoleView
/admin/settings/crm PhoenixKitCRM.Web.SettingsLive

The CRM section appears only after the module is toggled on under Admin > Settings > CRM; per-role subtabs appear for each opted-in role.

Database

The module owns its schema through its own versioned migration chain (PhoenixKitCRM.Migrations, via the PhoenixKit.Module.migration_module/0 callback). V01 adopts the tables core historically created; later versions are this repo's — V05 added the company interaction anchor. The applied version is a crm_schema:<N> comment marker on phoenix_kit_crm_contacts.

The parent app applies both chains via mix phoenix_kit.install / mix phoenix_kit.update (mix phoenix_kit.status reports them).

Settings keys

Development

mix deps.get
mix compile
mix test            # unit tests; integration tests excluded if no DB
mix precommit       # compile + format + credo --strict + dialyzer

For integration tests, create the test database once:

createdb phoenix_kit_crm_test

The CRM's tables migration ships in phoenix_kit core. Until that core release is published, run the suite against a local core checkout so the test DB migrates to the version that has the CRM tables:

PHOENIX_KIT_PATH=../phoenix_kit mix test

With PHOENIX_KIT_PATH unset, the published Hex pin is used (publish/CI-safe).

See AGENTS.md for the development conventions, file layout, and testing setup.

License

MIT — see LICENSE.

Managed organization mirrors

On a core version with managed-organization switching and manager administration, an administrator in their own account can choose Create managed organization on a saved company's edit page. Search for and select the first active manager explicitly. The company's email becomes a contact address; it may be shared with another account and never grants management by matching that account. Managers enter the organization from core's account menu and manage invitations in its account settings. Older supported core versions retain the independent mirror flow and hide this option.

Programmatic callers use Companies.create_mirror_user(company, managed: true, manager_actor: actor, first_manager_uuid: person_uuid), with actor constructed at browser mount by ManagedMirror.actor_from_session(session) from the trusted signed session, never event parameters. Creation locks and re-reads the company; concurrent requests cannot create a second orphaned account.

For a managed mirror, comparisons, resolution and reverse creation/adoption use contact_email. Claimed mirror account details remain read-only from CRM; edit those details through core's organization settings. Linking a CRM company never adds manager grants. The CRM package can be released after the core feature; no higher core floor is required because this path checks API availability.