AI-ready development
AI Task Patterns
AI Task Patterns
Practical prompt templates for common Laravolt v7 tasks. Each pattern includes the prompt, expected output, verification steps, and common pitfalls.
How to use these patterns
- Copy the prompt template
- Replace
{placeholders}with your values - Include
/llms.txtcontext reference - Specify expected deliverables
- Verify the output with provided commands
Pattern 1: Generate CRUD for table
Prompt template
Plain Text
Read /llms.txt for Laravolt v7 conventions.Task: Generate CRUD module for {table_name}Steps:1. Create migration for {table_name} with fields: - {field_1}: {type}, {constraints} - {field_2}: {type}, {constraints} - ...2. Run migration: php artisan migrate3. Generate module: php artisan laravolt:clap --table={table_name} --module={ModuleName}4. Register ServiceProvider in config/app.php5. Verify routes: php artisan route:list --name={route_prefix}6. Run tests: php artisan test --filter={ModuleName}TestDeliverables:- Migration file- Generated module structure- Route list output- Test resultsExample: Product CRUD
Plain Text
Read /llms.txt for Laravolt v7 conventions.Task: Generate CRUD module for productsSteps:1. Create migration for products with fields: - name: string, required, max 255 - sku: string, required, unique, max 50 - description: text, nullable - price: decimal(10,2), required - is_active: boolean, default true2. Run migration: php artisan migrate3. Generate module: php artisan laravolt:clap --table=products --module=Product4. Register ServiceProvider in config/app.php5. Verify routes: php artisan route:list --name=product6. Run tests: php artisan test --filter=ProductTestDeliverables:- Migration file- Generated module structure- Route list output- Test resultsExpected output
Plain Text
✓ Migration created: database/migrations/2024_01_15_create_products_table.php✓ Migration run successfully✓ Module generated: modules/Product/✓ ServiceProvider registered✓ Routes verified (7 routes)✓ Tests passed (4 tests)Files created:- modules/Product/Controllers/ProductController.php- modules/Product/Models/Product.php- modules/Product/Requests/StoreProductRequest.php- modules/Product/Requests/UpdateProductRequest.php- modules/Product/resources/views/index.blade.php- modules/Product/resources/views/create.blade.php- modules/Product/resources/views/edit.blade.php- modules/Product/resources/views/show.blade.php- modules/Product/resources/views/form.blade.php- modules/Product/TableView.php- modules/Product/routes/web.php- modules/Product/config/config.php- modules/Product/ServiceProvider.php- modules/Product/Tests/Feature/ProductTest.phpVerification
Bash
php artisan route:list --name=productphp artisan test --filter=ProductTestphp artisan serve# Visit: http://localhost:8000/productCommon pitfalls
- ❌ Forgetting to register ServiceProvider → routes not found
- ❌ Not running migration before
laravolt:clap→ table not found error - ❌ Using wrong table name (plural vs singular) → model mismatch
- ✅ Always verify routes after generation
- ✅ Run tests before customizing
Pattern 2: Add approval workflow
Prompt template
Plain Text
Read /llms.txt for Laravolt v7 conventions.Task: Add approval workflow to {ModuleName}Requirements:1. Add status field to {table_name}: enum('draft', 'submitted', 'approved', 'rejected')2. Add submitted_at, approved_at, rejected_at timestamps3. Add approver_id foreign key (references users)4. Add approval actions to controller: - submit() - change status to 'submitted' - approve() - change status to 'approved', set approved_at and approver_id - reject() - change status to 'rejected', set rejected_at and approver_id5. Add routes for approval actions6. Add action buttons to show page (conditional on status)7. Add permissions: {resource}.submit, {resource}.approve, {resource}.reject8. Add policy checks for each action9. Add feature tests for approval workflowFiles to modify:- New migration: add_approval_fields_to_{table_name}- {ModuleName}Controller.php- routes/web.php- resources/views/show.blade.php- {ModuleName}Policy.php (create if not exists)- Tests/Feature/{ModuleName}ApprovalTest.php (new)Deliverables:- Migration file- Updated controller with approval methods- Updated routes- Updated show view with action buttons- Policy with approval rules- Test resultsExample: Purchase Order approval
Plain Text
Read /llms.txt for Laravolt v7 conventions.Task: Add approval workflow to PurchaseOrderRequirements:1. Add status field to purchase_orders: enum('draft', 'submitted', 'approved', 'rejected')2. Add submitted_at, approved_at, rejected_at timestamps3. Add approver_id foreign key (references users)4. Add approval actions to controller: - submit() - change status to 'submitted' - approve() - change status to 'approved', set approved_at and approver_id - reject() - change status to 'rejected', set rejected_at and approver_id5. Add routes for approval actions6. Add action buttons to show page (conditional on status)7. Add permissions: purchase-order.submit, purchase-order.approve, purchase-order.reject8. Add policy checks for each action9. Add feature tests for approval workflowFiles to modify:- New migration: add_approval_fields_to_purchase_orders- PurchaseOrderController.php- routes/web.php- resources/views/show.blade.php- PurchaseOrderPolicy.php (create if not exists)- Tests/Feature/PurchaseOrderApprovalTest.php (new)Deliverables:- Migration file- Updated controller with approval methods- Updated routes- Updated show view with action buttons- Policy with approval rules- Test resultsExpected output
Plain Text
✓ Migration created and run✓ Controller updated with submit/approve/reject methods✓ Routes added: purchase-order.submit, purchase-order.approve, purchase-order.reject✓ Show view updated with conditional action buttons✓ Policy created with approval rules✓ Tests created and passingNew routes:POST purchase-order/{purchase_order}/submit ... purchase-order.submitPOST purchase-order/{purchase_order}/approve ... purchase-order.approvePOST purchase-order/{purchase_order}/reject ... purchase-order.rejectVerification
Bash
php artisan migratephp artisan route:list --name=purchase-orderphp artisan test --filter=PurchaseOrderApprovalTest# Manual test:# 1. Create purchase order (status: draft)# 2. Click "Submit" (status: submitted)# 3. Login as approver# 4. Click "Approve" (status: approved, approved_at set)Common pitfalls
- ❌ Not adding policy checks → unauthorized users can approve
- ❌ Not validating status transitions → can approve already approved orders
- ❌ Forgetting to set timestamps → approved_at remains null
- ❌ Not testing negative cases → missing "cannot approve draft" test
- ✅ Always check current status before transition
- ✅ Use policy gates, not just UI hiding
- ✅ Test both allowed and denied paths
Pattern 3: Customize form with validation
Prompt template
Plain Text
Read /llms.txt for Laravolt v7 conventions.Task: Customize {ModuleName} form with validationRequirements:1. Update form fields in form.blade.php: - {field_1}: {field_type}, {attributes} - {field_2}: {field_type}, {attributes} - ...2. Update validation in StoreRequest and UpdateRequest: - {field_1}: {rules} - {field_2}: {rules} - ...3. Add custom validation messages if needed4. Add input masks for formatted fields (phone, currency, etc.)Files to modify:- resources/views/form.blade.php- Requests/Store{ModuleName}Request.php- Requests/Update{ModuleName}Request.phpUse PrelineForm API for fields.Use Laravel validation rules.Deliverables:- Updated form view- Updated validation rules- Test command to verify validationExample: Product form customization
Plain Text
Read /llms.txt for Laravolt v7 conventions.Task: Customize Product form with validationRequirements:1. Update form fields in form.blade.php: - name: text input, required, max 255, help text "Product display name" - sku: text input, required, max 50, uppercase, help text "Format: PROD-XXXX" - description: textarea, 5 rows, max 1000, optional - price: number input, required, min 0.01, currency mask (IDR) - category_id: select dropdown, required, load from categories table - is_active: checkbox, default checked2. Update validation in StoreRequest and UpdateRequest: - name: required, string, max 255, unique - sku: required, string, max 50, unique, uppercase, regex:/^PROD-[A-Z0-9]+$/ - description: nullable, string, max 1000 - price: required, numeric, min 0.01 - category_id: required, exists:categories,id - is_active: boolean3. Add custom validation messages for SKU format4. Add currency input mask for price fieldFiles to modify:- resources/views/form.blade.php- Requests/StoreProductRequest.php- Requests/UpdateProductRequest.phpUse PrelineForm API for fields.Use Laravel validation rules.Deliverables:- Updated form view- Updated validation rules- Test command to verify validationExpected output
Form view with PrelineForm:
Blade
{!! PrelineForm::text('name') ->label('Product Name') ->required() ->maxlength(255) ->help('Product display name') !!}{!! PrelineForm::text('sku') ->label('SKU') ->required() ->maxlength(50) ->help('Format: PROD-XXXX') ->attributes(['style' => 'text-transform: uppercase']) !!}{!! PrelineForm::textarea('description') ->label('Description') ->rows(5) ->maxlength(1000) !!}{!! PrelineForm::number('price') ->label('Price (IDR)') ->required() ->min(0.01) ->step(0.01) ->inputmask(['alias' => 'currency', 'prefix' => 'Rp ', 'digits' => 0]) !!}{!! PrelineForm::select('category_id', $categories) ->label('Category') ->required() ->placeholder('-- Select Category --') !!}{!! PrelineForm::checkbox('is_active', 1) ->label('Active') ->checked(old('is_active', $product->is_active ?? true)) !!}Validation rules:
PHP
// StoreProductRequest.phppublic function rules(): array{ return [ 'name' => ['required', 'string', 'max:255', 'unique:products,name'], 'sku' => ['required', 'string', 'max:50', 'unique:products,sku', 'uppercase', 'regex:/^PROD-[A-Z0-9]+$/'], 'description' => ['nullable', 'string', 'max:1000'], 'price' => ['required', 'numeric', 'min:0.01'], 'category_id' => ['required', 'exists:categories,id'], 'is_active' => ['boolean'], ];}public function messages(): array{ return [ 'sku.regex' => 'SKU must start with PROD- followed by uppercase letters and numbers.', ];}Verification
Bash
# Test validationphp artisan test --filter=ProductTest# Manual test:# 1. Try invalid SKU format (e.g., "prod-123") → expect error# 2. Try duplicate SKU → expect error# 3. Try negative price → expect error# 4. Try valid data → expect successCommon pitfalls
- ❌ Not syncing validation rules between Store and Update requests
- ❌ Forgetting
uniquerule exception for Update request - ❌ Not testing validation errors in browser
- ❌ Using wrong PrelineForm method names
- ✅ Always test both positive and negative validation cases
- ✅ Use
help()for user guidance - ✅ Use
inputmask()for formatted inputs
Pattern 4: Add search and filter to listing
Prompt template
Plain Text
Read /llms.txt for Laravolt v7 conventions.Task: Add search and filter to {ModuleName} listingRequirements:1. Add search on fields: {field_1}, {field_2}, ...2. Add filters: - {filter_1}: {type} (e.g., select, checkbox, date range) - {filter_2}: {type} - ...3. Update TableView query to apply search and filters4. Add filter UI to index pageFiles to modify:- {ModuleName}TableView.php- resources/views/index.blade.php (if custom filters needed)Use Suitable searchable() and query() methods.Deliverables:- Updated TableView with search and filters- Verification commandExample: Product listing with search and filters
Plain Text
Read /llms.txt for Laravolt v7 conventions.Task: Add search and filter to Product listingRequirements:1. Add search on fields: name, sku, description2. Add filters: - category_id: select dropdown (all categories) - is_active: select (all/active/inactive) - price_range: min/max inputs3. Update ProductTableView query to apply search and filters4. Suitable will handle filter UI automaticallyFiles to modify:- ProductTableView.phpUse Suitable searchable() and query() methods.Deliverables:- Updated TableView with search and filters- Verification commandExpected output
PHP
// ProductTableView.phpuse Laravolt\Suitable\Columns\Text;use Laravolt\Suitable\Columns\Boolean;use Laravolt\Suitable\Columns\Number;use App\Models\Category;public function columns(): array{ return [ Text::make('name', 'Product Name')->sortable(), Text::make('sku', 'SKU')->sortable(), Text::make('category.name', 'Category'), Number::make('price', 'Price')->sortable()->prefix('Rp ')->decimal(0), Boolean::make('is_active', 'Active'), ];}public function searchable(): array{ return ['name', 'sku', 'description'];}public function query(){ $query = Product::with('category'); // Filter by category if (request('category_id')) { $query->where('category_id', request('category_id')); } // Filter by active status if (request('is_active') !== null && request('is_active') !== '') { $query->where('is_active', request('is_active')); } // Filter by price range if (request('price_min')) { $query->where('price', '>=', request('price_min')); } if (request('price_max')) { $query->where('price', '<=', request('price_max')); } return $query;}public function filters(): array{ return [ 'category_id' => [ 'label' => 'Category', 'type' => 'select', 'options' => Category::pluck('name', 'id')->prepend('All Categories', ''), ], 'is_active' => [ 'label' => 'Status', 'type' => 'select', 'options' => [ '' => 'All', '1' => 'Active', '0' => 'Inactive', ], ], 'price_min' => [ 'label' => 'Min Price', 'type' => 'number', ], 'price_max' => [ 'label' => 'Max Price', 'type' => 'number', ], ];}Verification
Bash
php artisan serve# Visit: http://localhost:8000/product# Test:# 1. Type in search box → results filter by name/sku/description# 2. Select category → results filter by category# 3. Select "Active" status → only active products shown# 4. Enter price range → results within range# 5. Combine filters → all filters apply togetherCommon pitfalls
- ❌ Not handling empty filter values → query breaks
- ❌ Forgetting to eager load relationships → N+1 query problem
- ❌ Not testing filter combinations → filters conflict
- ❌ Using
=for text search instead ofLIKE - ✅ Always check
request('filter') !== null && request('filter') !== '' - ✅ Use
with()for relationships shown in columns - ✅ Test each filter individually and in combination
Pattern 5: Add row actions with policy checks
Prompt template
Plain Text
Read /llms.txt for Laravolt v7 conventions.Task: Add row actions to {ModuleName} listingRequirements:1. Add row actions: - View: route to show page - Edit: route to edit page (if user can update) - Delete: delete action (if user can delete) - {Custom action}: route/action (if user can {permission})2. Add policy checks for each action3. Update TableView with action columnFiles to modify:- {ModuleName}TableView.php- {ModuleName}Policy.php (if not exists, create it)Use Suitable action columns.Use Laravel policy gates.Deliverables:- Updated TableView with actions- Policy with action rules- Verification commandExample: Product listing with actions
Plain Text
Read /llms.txt for Laravolt v7 conventions.Task: Add row actions to Product listingRequirements:1. Add row actions: - View: route to show page - Edit: route to edit page (if user can update) - Delete: delete action (if user can delete) - Duplicate: custom action to duplicate product (if user can create)2. Add policy checks for each action3. Update ProductTableView with action columnFiles to modify:- ProductTableView.php- ProductPolicy.php (create if not exists)Use Suitable action columns.Use Laravel policy gates.Deliverables:- Updated TableView with actions- Policy with action rules- Verification commandExpected output
Policy:
PHP
// app/Policies/ProductPolicy.phpnamespace App\Policies;use App\Models\Product;use App\Models\User;class ProductPolicy{ public function viewAny(User $user): bool { return $user->can('product.read'); } public function view(User $user, Product $product): bool { return $user->can('product.read'); } public function create(User $user): bool { return $user->can('product.create'); } public function update(User $user, Product $product): bool { return $user->can('product.update'); } public function delete(User $user, Product $product): bool { return $user->can('product.delete'); } public function duplicate(User $user, Product $product): bool { return $user->can('product.create'); }}TableView with actions:
PHP
// ProductTableView.phpuse Laravolt\Suitable\Columns\Action;use Laravolt\Suitable\Columns\DropdownAction;public function columns(): array{ return [ Text::make('name', 'Product Name')->sortable(), Text::make('sku', 'SKU')->sortable(), Number::make('price', 'Price')->sortable()->prefix('Rp ')->decimal(0), Boolean::make('is_active', 'Active'), DropdownAction::make('Actions') ->actions(function ($row) { $actions = []; if (auth()->user()->can('view', $row)) { $actions[] = [ 'label' => 'View', 'url' => route('product.show', $row), ]; } if (auth()->user()->can('update', $row)) { $actions[] = [ 'label' => 'Edit', 'url' => route('product.edit', $row), ]; } if (auth()->user()->can('duplicate', $row)) { $actions[] = [ 'label' => 'Duplicate', 'url' => route('product.duplicate', $row), 'method' => 'POST', ]; } if (auth()->user()->can('delete', $row)) { $actions[] = [ 'label' => 'Delete', 'url' => route('product.destroy', $row), 'method' => 'DELETE', 'confirm' => 'Are you sure you want to delete this product?', ]; } return $actions; }), ];}Verification
Bash
# Register policy in AuthServiceProvider# app/Providers/AuthServiceProvider.phpprotected $policies = [ Product::class => ProductPolicy::class,];php artisan serve# Visit: http://localhost:8000/product# Test as different users:# 1. User with product.read only → see View action only# 2. User with product.update → see View, Edit actions# 3. User with product.delete → see View, Edit, Delete actions# 4. User with product.create → see View, Edit, Duplicate actionsCommon pitfalls
- ❌ Not registering policy in AuthServiceProvider → policy not applied
- ❌ Using UI hiding instead of policy checks → security hole
- ❌ Not testing with different user roles → unauthorized access
- ❌ Forgetting CSRF token for POST/DELETE actions
- ✅ Always use
auth()->user()->can()for action visibility - ✅ Add
confirmfor destructive actions - ✅ Test with users having different permissions
Summary
These patterns cover the most common Laravolt v7 tasks:
- Generate CRUD - Bootstrap from table to working module
- Add approval workflow - Status transitions with permissions
- Customize form - Validation, input masks, field types
- Add search/filter - Query customization for listings
- Add row actions - Policy-protected actions in tables
For each task:
- ✅ Use concrete prompts with exact file paths
- ✅ Specify verification commands
- ✅ Include expected output
- ✅ List common pitfalls
- ✅ Reference
/llms.txtfor context
What to read next
- AI Coding Quickstart - Bootstrap workflow
- Thunderclap Recipes - Post-generation customization
- AI-ready development guide - Review checklist
- Thunderclap - Generation command reference