agentleFS
michaelalbermichaelalber/ai-toolkit/skills/php-feature-slice/SKILL.md

php-feature-slice

Skill3 starsChanged 3 months agoMITView on GitHub

Scaffolds feature-based PHP / Laravel architecture using feature folders, thin controllers, Form Requests, a service/action layer, and API Resources. PHP analog of dotnet-vertical-slice and python-feature-slice — no mediator library; uses the Laravel service container for dependency injection and structural CQRS conventions. Use when creating feature-based PHP projects, adding Laravel features, scaffolding service layers, or organizing PHP code by feature rather than by technical layer.

The file

We split this skill into the rules it gives an agent

1 rule. About 0 are common, 0 are distinctive, and 1 is very specific to this project.

  • ≈0

    Common · estimate

    Many files like this have a rule of this kind.

  • ≈0

    Distinctive · estimate

    This author's own choices. Worth a look.

  • 1

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Very specific:

    Create the feature namespace.

    line 68

≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

PHP Feature Slice Architecture

"The best code is code that never has to be written." -- Jeff Atwood

"Organize around business capabilities, not technical layers." -- Sam Newman, Building Microservices

Core Philosophy

Feature slice architecture organizes code by business capability, not by technical layer. Laravel's default skeleton is layer-based — app/Http/Controllers, app/Models, app/Services spread one feature across many directories. This skill replaces that with self-contained vertical slices: app/Features/Orders/, app/Features/Users/, each owning its full stack — controller, Form Request, service, API Resource, and tests.

In PHP with Laravel, the mediator pattern (FreeMediator in .NET) is replaced by Laravel's service container. Service classes are constructor-injected into controllers; the container resolves them automatically. CQRS separation is a structural and naming convention — OrderReadService vs OrderWriteService — not a library contract.

Non-Negotiable Constraints:

  1. declare(strict_types=1) at the top of every PHP file
  2. Feature isolation — no cross-feature imports; features communicate through shared domain code only
  3. Service layer owns business logic — controllers are thin; no business logic in controllers
  4. Form Requests for all input — never trust raw $request->input(); validation lives in FormRequest::rules()
  5. API Resources for all output — never return Eloquent models directly from controllers
  6. Eloquent or bound parameters only — never string-concatenated SQL

What this skill is NOT:

  • It is NOT a microservices guide — feature slices live within a single Laravel application
  • It is NOT prescriptive about feature count — start with the features you have
  • It is NOT a replacement for DDD — it is compatible with DDD but does not require it

The 10 domain principles (Feature Isolation, Service Autonomy, Minimal Abstractions, DI via the Container, Read/Write Separation, Validation at the Boundary, Explicit Output Shaping, Controller Thinness, Strict Typing, Test Proximity) and the grounding search_knowledge query map live in references/domain-principles.md. CQRS naming conventions live in references/laravel-cqrs-conventions.md.

Workflow

Phase 1: DETECT

Objective: Understand the existing structure before scaffolding.

# PHP and Laravel version
php -v | head -1
grep -E '"(php|laravel/framework)"' composer.json

# Existing structure — layered, modular, or already feature-based
find app -type d -not -path '*/vendor/*' | head -30

# Existing route registration and service bindings
grep -rn "Route::" routes/ | head -20
grep -rn "->bind\|->singleton" app/Providers/ | head -20

Record: PHP version, Laravel version (5.5 / 6.x / 8+ / 12.x), current layout, route file (routes/api.php vs web.php), auth pattern.

Phase 2: SCAFFOLD

Create the feature namespace. See references/feature-folder-template.md for file-by-file content.

app/Features/<Name>/
  Controllers/<Name>Controller.php   # thin; resolve → call service → resource
  Requests/Store<Name>Request.php     # FormRequest: rules() + toDto()
  Requests/Update<Name>Request.php
  Services/<Name>ReadService.php       # queries
  Services/<Name>WriteService.php      # commands
  Resources/<Name>Resource.php         # JsonResource output shaping
  Dtos/Create<Name>Dto.php             # validated, readonly transfer object
routes/features/<name>.php             # route group for the slice
tests/Feature/<Name>/Create<Name>Test.php
tests/Unit/<Name>/<Name>WriteServiceTest.php

Phase 3: REGISTER

Wire the slice into routing and (only if an interface exists) the container.

// routes/api.php
require __DIR__ . '/features/orders.php';

// app/Providers/AppServiceProvider.php — only when an interface is introduced
$this->app->bind(OrderWriteContract::class, OrderWriteService::class);

Phase 4: VERIFY

php artisan route:list --path=api/v1/<name>     # routes registered
vendor/bin/pest tests/Feature/<Name> tests/Unit/<Name>   # or phpunit
vendor/bin/pint --dirty                          # Laravel's default style fixer (wraps php-cs-fixer)
# Cross-feature import check — should print nothing
grep -rn "use App\\\\Features\\\\" app/Features/<Name> | grep -v "App\\\\Features\\\\<Name>"

State Block

<php-feature-slice-state>
  phase: DETECT | SCAFFOLD | REGISTER | VERIFY | COMPLETE
  feature_name: [name]
  laravel_version: [detected]
  existing_structure: layered | modular | feature-based | unknown
  routes_registered: true | false
  read_service_created: true | false
  write_service_created: true | false
  tests_scaffolded: true | false
  last_action: [description]
  next_action: [description]
</php-feature-slice-state>

Output Template

Feature Slice Scaffold: [Feature Name]

## Feature Slice Scaffold: [Feature Name]

### Files Created
- [ ] `app/Features/<Name>/Controllers/<Name>Controller.php`
- [ ] `app/Features/<Name>/Requests/Store<Name>Request.php`
- [ ] `app/Features/<Name>/Requests/Update<Name>Request.php`
- [ ] `app/Features/<Name>/Services/<Name>ReadService.php`
- [ ] `app/Features/<Name>/Services/<Name>WriteService.php`
- [ ] `app/Features/<Name>/Resources/<Name>Resource.php`
- [ ] `app/Features/<Name>/Dtos/Create<Name>Dto.php`
- [ ] `routes/features/<name>.php`
- [ ] `tests/Feature/<Name>/Create<Name>Test.php`
- [ ] `tests/Unit/<Name>/<Name>WriteServiceTest.php`

### Registration
- [ ] Route group required into `routes/api.php`
- [ ] Prefix set: `/api/v1/<name>`; middleware: `['api', 'auth:sanctum']`

### Verification
- [ ] `php artisan route:list` shows the new routes
- [ ] `pest` / `phpunit` green for the slice
- [ ] `pint --dirty` clean
- [ ] No cross-feature imports detected

The feature folder diagram is in references/domain-principles.md. The AI discipline rules (no-logic-in-controllers, Form Request + DTO boundary, no cross-feature imports), the 10-row anti-patterns table, and the error-recovery procedures (cross-feature import, oversized service, oversized controller) live in references/discipline-and-recovery.md.

Integration with Other Skills

SkillRelationship
php-api-scaffolderEndpoint-level quality (Sanctum auth, throttle, versioning, OpenAPI). Use together when a new slice needs production-grade endpoints.
php-migration-managerWhen a slice needs schema changes, manage the Laravel migration lifecycle and rollback safety.
php-security-reviewAfter scaffolding, audit the slice's validation, authorization, and query safety against OWASP.
php-architecture-checklistArchitecture quality gate. Run after several slices to verify isolation and coupling.
tdd-loopDrive each service method test-first (RED → GREEN → REFACTOR) rather than scaffolding code ahead of tests.

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.