Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Craftable Laravel Package

dejwcake/craftable

Craftable is an admin panel and CRUD generator for Laravel that scaffolds management screens, forms, and data tables with authentication and permissions built in, so you can ship back-office tools without repetitive boilerplate.

View on GitHub
Deep Wiki
Context7

Getting Started

This package sits on top of spatie/laravel-permission and is version-locked to the same line as dejwcake/admin-auth (both 2.1.0 now target spatie/laravel-permission ^8.3).

  1. Check your existing pin first. If your composer.json pins spatie/laravel-permission to ^7, this release will not install — you must upgrade that package in the same change. composer why-not spatie/laravel-permission ^8.3 will show you what's holding it back.
  2. Upgrade as a set: spatie/laravel-permission ^8.3, dejwcake/admin-auth 2.1.0, and this package 2.1.0. Do them in one branch so you only run the migration/verification pass once.
  3. Publish and migrate as usual, then seed your role matrix.
  4. Look first at: the README (baseline/cache regeneration is now documented there), then AGENTS.md / CLAUDE.md — new in this release and the fastest way to get an AI pair-programmer oriented to the conventions.
  5. First use case: assign a role in a seeder, guard a route with the role/permission middleware, and confirm $user->hasPermissionTo(...) returns true in Tinker. That single loop exercises the config, the cache, and the guard wiring.

Implementation Patterns

Role matrix in a seeder, permissions in code. Define role names and their permission sets in a seeder (idempotent via firstOrCreate/syncPermissions), and reference permissions in middleware and policies by name. This keeps authorization declarative and re-runnable on every deploy.

Use enums for role names. With the v8 upgrade, findByName() / findOrCreate() accept BackedEnum|string. Pass a UserRole::Admin enum rather than a magic string — it gives you static analysis coverage on permission checks and removes a whole class of typo bugs.

$user->assignRole(UserRole::Admin);
$user->hasPermissionTo(Permission::PostsEdit);

Guarding routes. Use the package's middleware aliases (role:, permission:, role_or_permission:) on route groups rather than scattering abort_unless calls in controllers. Reserve explicit Gate::authorize / policy checks for per-record authorization.

Custom Role / Permission models. If you implement the contracts yourself (common when you add team_id or extra columns), this is the one place the upgrade can break your code — see Gotchas.

Deployment. Add php artisan permission:cache-reset to your deploy script after migrations and seeders. The permission cache is the single most common source of "it works locally" bugs in this ecosystem.

Dist installs are now lean. .gitattributes excludes tests, CI, and QA configs from the archive. If you vendor-patch this package, use --prefer-source (or a path repository) so you retain the test suite for verification.

Gotchas and Tips

This is a transitive major bump, and it is a hard blocker. The version constraint is ^8.3, not ^7.4|^8.3. Nothing in this package's code changed — the risk is entirely in the spatie upgrade and in whatever else in your app depends on spatie v7. Treat it as a breaking change for your application and schedule it deliberately, not as a patch bump.

Custom contract implementations will fatal-error at runtime, not install time. If you implement Spatie\Permission\Contracts\Role or Permission, update the signatures to accept BackedEnum|string:

public function findByName(BackedEnum|string $name, ?string $guardName = null): RoleContract;
public function findOrCreate(BackedEnum|string $name, ?string $guardName = null): RoleContract;

Composer will happily install; you'll only find out when a role lookup runs. Grep for findByName and findOrCreate in your app/ before you merge.

Cache is per-guard and survives deploys. After changing role/permission definitions, run php artisan permission:cache-reset. In tests, clear the cache in setUp or use RefreshDatabase plus an explicit reset — stale cache across test methods causes flaky, order-dependent failures.

Seeders must be idempotent. With an ^8.3 upgrade you'll likely re-run seeders against existing data. firstOrCreate + syncPermissions (not givePermissionTo, which accumulates) keeps repeat runs safe.

Debugging checklist: php artisan permission:cache-reset → check config/permission.php guard names match your auth guards → php artisan tinker and inspect $user->getAllPermissions() → verify the role is attached to the correct guard. Guard mismatch is the second most common failure after cache.

Extension points to prefer: custom Role/Permission models via the config file, a PermissionRegistrar-aware service provider for cache invalidation on model events, and policies for row-level rules. Avoid re-implementing the role hierarchy inside controllers.

CI/QA context is for maintainers, not consumers. PHPMD 3, coverage on the pgsql job, and MariaDB 12.3 in docker-compose describe the package's own pipeline — you don't need to mirror them, but they're a reasonable signal of what the maintainers test against (Postgres and MariaDB both first-class).

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
jinas/dhivatar
store-doc/laravel-storage-driver
plus-it/laravel-translation-manager
diephp/perhaps
diephp/telegraph
osmaviation/spreadsheet
microsoft/fluentui-system-icons
mmccook/php-json-canonicalization-scheme
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console
pnscripts/filament-broadquill-lite
pnscripts/laravel-sentfold-lite
vleap/mx-sdk-laravel-internal
twidpay/utils
htetmyathlaing/scout-elasticsearch-driver
artisan-toolbox/front-awesome
ls/client-assistant
users-au/laravel-client
cgv/localized-resource