Install
$ agentstack add skill-edulazaro-laraclaude-generate-crud ✓ scanned · ✓ verified — works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
About
Subcommands
| Subcommand | Description | |---|---| | ` | Generate full CRUD scaffolding for the given model (e.g., Invoice, Task, Document`) |
Overview
This is a generator skill. It creates a complete CRUD setup following the project's conventions: migration, model, controller, routes, Volt table component (index), create/edit modal, and delete confirmation modal. Every generated file follows the project's established patterns.
Instructions
Step 1: Gather information
Ask the user for the following (or infer from context):
- Model name (required - from argument)
- Fields - What columns does the table need? (name, type, nullable, default)
- Relationships - Does it belong to User, Organization, Office, etc.?
- Multi-tenant - Does it need
organization_idandoffice_id? (default: yes for most models) - Soft deletes - Should records be soft-deleted? (default: yes)
- Which fields are displayed in the table - Usually 4-7 columns
- Which fields are editable in the modal - Usually all non-system fields
If the user provides enough context, infer sensible defaults and proceed.
Step 2: Study existing patterns
Before generating ANY files, read existing implementations to match conventions exactly:
- Read an existing model for patterns:
`` app/Models/Property.php or app/Models/Client.php `` Note: fillable, casts, relationships, traits, soft deletes, slug usage
- Read an existing migration for conventions:
`` database/migrations/ (find a recent one) `` Note: foreign key patterns, index names, column ordering
- Read the base TableComponent:
Search for class TableComponent to understand the exact interface
- Read an existing table Volt component:
`` resources/views/livewire/ (find one extending TableComponent) ``
- Read an existing modal Volt component:
`` resources/views/livewire/modals/ (any existing modal) ``
- Read routes/app.php for route registration patterns
- Read an existing controller for the standard pattern
Step 3: Generate the migration
Create migration file using artisan via Docker:
docker exec abodara_app php artisan make:migration create_model_names_table
Then edit the generated file to add the schema.
Migration conventions:
id();
$table->string('slug')->unique();
$table->foreignId('organization_id')->constrained()->onDelete('cascade');
$table->foreignId('office_id')->nullable()->constrained()->onDelete('set null');
$table->foreignId('user_id')->nullable()->constrained()->onDelete('set null');
// ... model-specific fields
$table->string('name');
$table->text('description')->nullable();
$table->enum('status', ['draft', 'active', 'archived'])->default('draft');
$table->boolean('active')->default(true);
$table->timestamps();
$table->softDeletes();
});
}
public function down(): void
{
Schema::dropIfExists('model_names');
}
};
Key migration rules:
- Always include
slugwith unique index for URL-friendly identifiers - Use
foreignId()->constrained()for relationships - Organization/office foreign keys: organization cascades, office sets null
- Put
timestamps()andsoftDeletes()last - Use
enumfor finite status sets - Use
decimal(12, 2)for monetary values - Use
textfor long content,stringfor short content
Step 4: Generate the model
Create file at app/Models/ModelName.php.
Model conventions:
'boolean',
];
public function organization(): BelongsTo
{
return $this->belongsTo(Organization::class);
}
public function office(): BelongsTo
{
return $this->belongsTo(Office::class);
}
public function user(): BelongsTo
{
return $this->belongsTo(User::class);
}
}
Key model rules:
- Always import related models with
usestatements - Use return type hints on relationships (
: BelongsTo,: HasMany) - Include
SoftDeletestrait when migration hassoftDeletes() - Cast booleans, dates, and enums appropriately
- No comments unless explicitly requested
- Fillable array includes all user-editable fields
- Do NOT include
id,created_at,updated_at,deleted_atin fillable
Step 5: Generate the controller
Create file at app/Http/Controllers/ModelNameController.php.
Controller conventions:
Step 7: Generate the table Volt component
Create resources/views/livewire/model-names/index.blade.php.
Follow the EXACT same pattern as the lc:generate-table skill. Key points:
- Extend
TableComponent - Include search filter with debounce
- Include status filter if model has status field
- Sortable columns
wire:keyon every rowx-tables.dropdownfor row actions (NOT in columns array)- Infinite scroll with
x-intersect @text()for all visible strings- Dark mode support
- Empty state
Include the modals at the bottom of the component:
{{-- Filters and table content --}}
{{-- Modals --}}
Step 8: Generate the create/edit modal
Create resources/views/livewire/modals/create-model-name.blade.php and resources/views/livewire/modals/edit-model-name.blade.php.
Follow the EXACT same pattern as the lc:generate-modal skill. Key points:
- Volt single-file component
- `` with proper id and title
x-fields.*components for inputs (already include @error - NO duplicate error display)- Footer slot with cancel and submit buttons
- Validation rules
- Event dispatching for parent refresh
- Reset form after successful action
For the create modal:
- Generate a slug using
Str::uuid()orStr::slug() - Set
organization_idandoffice_idfrom the authenticated user's context - Dispatch
model-name-createdevent after creation
For the edit modal:
- Load data via
#[On('open-edit-model-name')]event - Populate form fields from model
- Dispatch
model-name-updatedevent after update
Step 9: Generate the delete confirmation modal
Create resources/views/livewire/modals/confirm-delete-model-name.blade.php.
Use the confirmation modal variant from lc:generate-modal. Dispatch model-name-deleted event.
Step 10: Register routes
Edit routes/app.php to add the new routes.
Read the file first to find the right location, then add:
Route::get('/model-names', [ModelNameController::class, 'index'])->name('model-names.index');
Route::get('/model-names/{modelName}', [ModelNameController::class, 'show'])->name('model-names.show');
Add the use import for the controller at the top of the routes file.
Step 11: Run migration
docker exec abodara_app php artisan migrate
Step 12: Summary output
After generating all files, display a complete summary:
## CRUD Generated: ModelName
### Files created:
1. database/migrations/YYYY_MM_DD_HHMMSS_create_model_names_table.php
2. app/Models/ModelName.php
3. app/Http/Controllers/ModelNameController.php
4. resources/views/model-names/index.blade.php
5. resources/views/livewire/model-names/index.blade.php
6. resources/views/livewire/modals/create-model-name.blade.php
7. resources/views/livewire/modals/edit-model-name.blade.php
8. resources/views/livewire/modals/confirm-delete-model-name.blade.php
### Routes added to routes/app.php:
- GET /model-names -> model-names.index
- GET /model-names/{modelName} -> model-names.show
### Migration status:
Migration executed successfully.
### Next steps:
- Add navigation link to sidebar/menu
- Add authorization policies if needed
- Customize table columns and filters
- Add any additional business logic to actions
Key conventions across ALL generated files
- Volt single-file components - NEVER create separate Livewire PHP class files
@text()for all user-visible text - Defaults in English, no hardcoded strings- Model imports with
use- Never inline\App\Models\ - No comments - Unless explicitly requested
- Pink color scheme for primary buttons (
bg-pink-600 hover:bg-pink-700) - Dark mode on every visual element
wire:navigateon internal links- Soft deletes by default
- Slug field for URL-friendly identifiers
- Multi-tenant with
organization_idby default
Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: edulazaro
- Source: edulazaro/laraclaude
- License: MIT
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet — be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.