condoedge/crm
A Laravel CRM package for managing contacts, leads, deals, pipelines, and activities in one place. It provides ready-to-use models, migrations, and resources to add customer relationship features to your PHP app quickly, with a structure that is easy to customize and extend.
The package is still pre-1.0 (0.4.0), so treat every minor bump as potentially breaking and pin an exact version in composer.json ("condoedge/crm": "0.4.0"). Start by installing it into a fresh Laravel app and running php artisan vendor:publish --tag=crm-config (check vendor/condoedge/crm/config/ if the tag differs) since CRM packages of this shape almost always ship a publishable config for tables, models, and Filament resources. Register the package service provider if it isn't auto-discovered, then run migrations in a scratch database before touching staging — the scout/inscription tables are the core domain and are the most likely to change shape between releases.
First use case: bootstrap an admin user and open the CRM panel. In 0.4.0 the highest-value thing to exercise first is the new RegisterScoutDrawer — an admin-only flow that lets a staff member register a scout directly from the admin UI without going through the normal self-service inscription path. Wire it into an existing Filament resource action or page, confirm the admin gate/authorization, and submit one test registration end-to-end. If that works, you understand the package's core write path (scout creation + inscription) and can build on it.
The release cadence here (0.3.55 → 0.4.0 with only one commit) tells you the maintainers are shipping incrementally, so structure your integration so package updates are cheap to absorb.
Wrap the package's models and services. Don't call Condoedge\Crm\Models\Scout directly from controllers or Filament resources — put a thin app-level service (App\Crm\ScoutRegistrar or similar) in front of it. When a 0.5.0 rename or signature change lands you patch one class, not forty call sites. This is the single most important pattern for a pre-1.0 dependency.
Invoke RegisterScoutDrawer the Filament way. The new feature is a Drawer — in Filament that means a page-level or resource-level action that opens a side panel with a form schema and a register/create callback. Mount it via Action::make('registerScout')->schema(RegisterScoutDrawer::schema())->action(fn ($data, $livewire) => …) rather than instantiating it as a widget. Authorization is almost certainly enforced inside the drawer (admin-only), but verify by logging in as a non-admin and confirming the action is hidden and the underlying route rejects the POST.
Keep admin inscription and self-service inscription on the same domain service. If the package has an existing public inscription flow, the new admin path likely reuses models but skips validation or payment steps. Check the commit (7330574) to see whether it introduces a new service or duplicates logic — if duplicated, wrap both in your own service so business rules (duplicate detection, email uniqueness, required custom fields) don't drift between the two entry points.
Pair it with your auth/role layer. "By admin" implies a gate check. Map the package's expectation (Filament's canRegisterScout policy method, or a Spatie permission like crm.scouts.register) onto your existing roles and test with a non-admin. Don't rely on UI hiding alone.
Seed and snapshot test after every bump. Because breaking changes aren't signalled in the changelog, keep a Pest test that (a) creates a scout via the admin drawer, (b) asserts the resulting DB row, and (c) hits any public read endpoints. Run it before merging any version bump — it's cheaper than reading diffs.
0.4.0 is a breaking signal even without a BREAKING CHANGE: footer. Semver-wise 0.3.x → 0.4.0 is a minor bump and under 0.x anything can break. The changelog shows only a feature commit, but the diff could still change model casts, resource namespaces, or migration names. Read git log v0.3.55..v0.4.0 --stat before upgrading — the notes are auto-generated by conventional-commits and only surface what was labelled.
Drawers are Filament-version-sensitive. RegisterScoutDrawer will behave differently on Filament v2 vs v3 vs v4 (schema method names, Action vs PageAction, mountedAction vs mountedActions). Confirm the Filament version in the package's composer.json matches your app's; a mismatch will surface as a blank drawer or a Method schema does not exist error at runtime, not at install time.
Admin authorization is easy to under-test. The commit message says "by admin" but the implementation may only hide the button. Write an explicit test as a user without the role, hitting the Livewire action directly (Livewire::test(...)->call('registerScout', $payload)) and assert a 403. This is the most common security gap in freshly-added admin flows.
Migrations in a 0.x package can be destructive. Never run php artisan migrate from a package upgrade on production without reviewing the generated migration files first — packages sometimes drop/recreate tables. Use --pretend and diff against your schema dump.
Config caching bites on upgrades. If the package adds a new config key (likely given the new feature — e.g. a toggle for admin registration), a stale bootstrap/cache/config.php will make it appear missing. Run php artisan config:clear and optimize:clear as standard upgrade steps and commit a note to your upgrade runbook.
Extension points to lean on: policies registered via the package's service provider (override by re-registering in AuthServiceProvider), Filament resources that can be swapped for your own subclass, and event hooks (ScoutRegistered-style events) that let you plug in notifications, audit logging, or side effects without forking. Check vendor/condoedge/crm/src/Events/ — if none exist yet, filing an issue for one is cheaper than a fork.
Pin and watch the tag. "condoedge/crm": "0.4.0" (exact), and subscribe to GitHub releases so 0.4.1 hotfixes surface. With this commit density (55 patches in 0.3.x), an unpinned ^0.4 will silently pull changes that break your admin drawer.
How can I help you explore Laravel packages today?