Skip to content

Latest commit

 

History

History
292 lines (207 loc) · 19.1 KB

File metadata and controls

292 lines (207 loc) · 19.1 KB
=== .ai/php-laravel rules ===

General code instructions

  • Don't generate code comments above the methods or code blocks if they are obvious. Don't add docblock comments when defining variables, unless instructed to, like /** @var \App\Models\User $currentUser */. Generate comments only for something that needs extra explanation for the reasons why that code was written.
  • For new features, you MUST generate Pest automated tests.
  • To run tests, ALWAYS delegate to the test-runner subagent via Task tool. Do not run vendor/bin/sail artisan test directly — it pollutes your context with long output.
  • For library documentation, if some library is not available in Laravel Boost 'search-docs', always use context7. Automatically use the Context7 MCP tools to resolve library id and get library docs without me having to explicitly ask.
  • If you made changes to CSS/Javascript files or added new Tailwind classes in Blade, run npm run build after all front-end changes are finished.

Memory instructions (mem0)

This project uses the mem0 skill for persistent memory across sessions. ACTIVELY use mem0 — do not wait to be asked. The skill handles the API mechanics;


PHP instructions

  • In PHP, use match operator over switch whenever possible
  • Generate Enums always in the folder app/Enums, not in the main app/ folder, unless instructed differently.
  • Always use Enum value as the default in the migration if column values are from the enum. Always casts this column to the enum type in the Model.
  • Don't create temporary variables like $currentUser = auth()->user() if that variable is used only one time.
  • Always use Enum where possible instead of hardcoded string values, if Enum class exists. For example, in Blade files, and in the tests when creating data if field is casted to Enum then use that Enum instead of hardcoding the value.

Laravel instructions

  • Always run Laravel-related CLI commands using Sail: prefix commands with ./vendor/bin/sail.
    • Use ./vendor/bin/sail artisan migrate instead of php artisan migrate
    • Use ./vendor/bin/sail artisan test instead of php artisan test
    • Use ./vendor/bin/sail artisan make:model User instead of php artisan make:model User
    • Use ./vendor/bin/sail composer install instead of composer install
    • Use ./vendor/bin/sail npm run build instead of npm run build
  • Never assume global PHP, Composer, or Node execution. Always run commands inside the Sail container.
  • Eloquent Observers should be registered in Eloquent Models with PHP Attributes, and not in AppServiceProvider. Example: #[ObservedBy([UserObserver::class])] with use Illuminate\Database\Eloquent\Attributes\ObservedBy; on top
  • Aim for "slim" Controllers/Components and put larger logic pieces in Service classes
  • Use Laravel helpers instead of use section classes. Examples: use auth()->id() instead of Auth::id() and adding Auth in the use section. Other examples: use redirect()->route() instead of Redirect::route(), or str()->slug() instead of Str::slug().
  • Don't use whereKey() or whereKeyNot(), use specific fields like id. Example: instead of ->whereKeyNot($currentUser->getKey()), use ->where('id', '!=', $currentUser->id).
  • Don't add ::query() when running Eloquent create() statements. Example: instead of User::query()->create(), use User::create().
  • When adding columns in a migration, update the model's $fillable array to include those new attributes.
  • Never chain multiple migration-creating commands (e.g., make:model -m, make:migration) with && or ; — they may get identical timestamps. Run each command separately and wait for completion before running the next.
  • Enums: If a PHP Enum exists for a domain concept, always use its cases (or their ->value) instead of raw strings everywhere — routes, middleware, migrations, seeds, configs, and UI defaults.
  • Don't create Controllers with just one method which just returns view(). Instead, use Route::view() with Blade file directly.
  • Always use Laravel's @session() directive instead of @if(session()) for displaying flash messages in Blade templates.
  • In Blade files always use @selected() and @checked() directives instead of selected and checked HTML attributes. Good example: @selected(old('status') === App\Enums\ProjectStatus::Pending->value). Bad example: {{ old('status') === App\Enums\ProjectStatus::Pending->value ? 'selected' : '' }}.

Service classes

  • Use Service classes to encapsulate reusable business logic, keeping Controllers and Livewire Components slim.
  • Service classes MUST be created in the app/Services/ folder.
  • If a Service is used in only ONE method of a Controller or Component, inject it directly into that method via type-hinting. If it is used in MULTIPLE methods, initialize it in the Constructor (or mount()/boot() for Livewire Components).
  • The same injection rule applies to both traditional Controllers and Livewire Components — use mount() or boot() to inject Services in Components when needed across multiple methods, or inject directly into the action method.
  • Services MUST NOT contain presentation logic (views, redirects, flash messages). Return data or throw exceptions, and let the Controller/Component decide how to present the result.
  • Services MUST be independently testable — avoid coupling with request(), session(), or auth() directly. Receive those values as parameters instead.

AI / LLM integration (Laravel AI SDK)

Regra de ouro: Laravel AI SDK (laravel/ai) já é a camada de abstração. Não envelope o SDK atrás de interfaces/DTOs custom em nome de "testabilidade" — a testabilidade vem do container.

Sempre que for tocar em código de LLM/Agent, ative a skill ai-sdk-development (.claude/skills/ai-sdk-development/SKILL.md).

  • Localização: Agents moram em app/Ai/Agents/. Nunca em app/Services/. A pasta app/Services/Ai/ não deve existir.
  • Contratos obrigatórios: toda Agent class MUST implements Laravel\Ai\Contracts\Agent. Se retorna JSON estruturado, também implements Laravel\Ai\Contracts\HasStructuredOutput. Sempre use Laravel\Ai\Promptable.
  • System prompt: uma public const SYSTEM_PROMPT retornada por instructions(): string. Não embutir o prompt inline em $this->prompt(...).
  • Schema: definido em schema(\Illuminate\Contracts\JsonSchema\JsonSchema $schema): array usando o builder tipado$schema->object(fn ($s) => [...]), $schema->string()->enum([...])->nullable()->required(), $schema->array()->max(N)->items(...). Proibido retornar arrays JSON-Schema crus (['type' => 'object', 'properties' => ...]).
  • Métodos públicos por fluxo: ex. analyzeText(string $query): StructuredAgentResponse, analyzeImage(string $imagePath): StructuredAgentResponse. Chamam $this->prompt(prompt: ..., attachments: ..., model: (string) config('worthly.llm.model')) diretamente. Não crie classes PromptBuilder / ProductAnalysisPrompt separadas.
  • Anexos: sempre via objetos do SDK — \Laravel\Ai\Files\Image::fromStorage($path, disk: ...), Files\Pdf::fromStorage(...), etc. Nunca passar paths como string solta dentro de arrays.
  • Proibido criar:
    • Interface LlmClient (ou similar) envolvendo o SDK.
    • DTO LlmResponse (ou similar) reembrulhando StructuredAgentResponse. Use o retorno do SDK direto ($response->toArray(), $response->object).
    • Qualquer wrapper que chame agent(...)->prompt(...) por baixo de uma fachada custom.
  • Service ↔ Agent: Services em app/Services/ orquestram (transação, persistência, quota, mapeamento de exceção). A chamada LLM mora dentro do Agent, não no Service. O Service injeta o Agent pelo construtor.
  • Erros do provider: capture Throwable da chamada do Agent no Service e re-lance como exceção de domínio (ex.: LlmProviderException). Não vaze tipos do SDK para fora do Service.
  • Testabilidade — esta é a única forma correta:
    $fake = new class extends ProductReviewer {
        public function analyzeText(string $query): StructuredAgentResponse { /* canned */ }
    };
    $this->app->instance(ProductReviewer::class, $fake);
    Não existe LlmClient para mockar. Não use Mockery no SDK. Se sentir necessidade de "abstrair para testar", pare e releia este bloco.
  • Configuração de modelo: sempre (string) config('worthly.llm.model') (ou config equivalente do projeto) dentro do Agent. Não hardcode string de modelo.

Model construction rules

  • Models MUST define the $fillable property correctly for all mass-assignable attributes.
  • When adding new columns via migration, you MUST update the corresponding Model $fillable array.
  • Relationships MUST follow Laravel naming conventions (user(), orders(), profile(), etc.).
  • Relationship methods MUST use correct return types (HasMany, BelongsTo, HasOne, etc.).
  • All relationships MUST have their inverse defined when applicable.
    • If User hasMany Order, then Order MUST define belongsTo(User::class).
    • If User hasOne Profile, then Profile MUST define belongsTo(User::class).
  • Do not assume foreign key naming. Explicitly define foreign keys if they don't follow Laravel conventions.
  • If a column represents a domain concept backed by an Enum, the Model MUST cast it using $casts.

Testing instructions

Before Writing Tests

  1. Check database schema - Use database-schema tool to understand:

    • Which columns have defaults
    • Which columns are nullable
    • Foreign key relationship names
  2. Verify relationship names - Read the model file to confirm:

    • Exact relationship method names (not assumed from column names)
    • Return types and related models
  3. Test realistic states - Don't assume:

    • Empty model = all nulls (check for defaults)
    • user_id foreign key = user() relationship (could be author(), employer(), etc.)
    • When testing form submissions that redirect back with errors, assert that old input is preserved using assertSessionHasOldInput().

=== foundation rules ===

Laravel Boost Guidelines

The Laravel Boost guidelines are specifically curated by Laravel maintainers for this application. These guidelines should be followed closely to ensure the best experience when building Laravel applications.

Foundational Context

This application is a Laravel application and its main Laravel ecosystems package & versions are below. You are an expert with them all. Ensure you abide by these specific packages & versions.

  • php - 8.5
  • laravel/ai (AI) - v0
  • laravel/framework (LARAVEL) - v13
  • laravel/prompts (PROMPTS) - v0
  • laravel/sail (SAIL) - v1
  • laravel/sanctum (SANCTUM) - v4
  • laravel/boost (BOOST) - v2
  • laravel/mcp (MCP) - v0
  • laravel/pail (PAIL) - v1
  • laravel/pint (PINT) - v1
  • pestphp/pest (PEST) - v4
  • phpunit/phpunit (PHPUNIT) - v12

Skills Activation

This project has domain-specific skills available in **/skills/**. You MUST activate the relevant skill whenever you work in that domain—don't wait until you're stuck.

Conventions

  • You must follow all existing code conventions used in this application. When creating or editing a file, check sibling files for the correct structure, approach, and naming.
  • Use descriptive names for variables and methods. For example, isRegisteredForDiscounts, not discount().
  • Check for existing components to reuse before writing a new one.

Verification Scripts

  • Do not create verification scripts or tinker when tests cover that functionality and prove they work. Unit and feature tests are more important.

Application Structure & Architecture

  • Stick to existing directory structure; don't create new base folders without approval.
  • Do not change the application's dependencies without approval.

Frontend Bundling

  • If the user doesn't see a frontend change reflected in the UI, it could mean they need to run vendor/bin/sail npm run build, vendor/bin/sail npm run dev, or vendor/bin/sail composer run dev. Ask them.

Documentation Files

  • You must only create documentation files if explicitly requested by the user.

Replies

  • Be concise in your explanations - focus on what's important rather than explaining obvious details.

=== boost rules ===

Laravel Boost

Tools

  • Laravel Boost is an MCP server with tools designed specifically for this application. Prefer Boost tools over manual alternatives like shell commands or file reads.
  • Use database-query to run read-only queries against the database instead of writing raw SQL in tinker.
  • Use database-schema to inspect table structure before writing migrations or models.
  • Use get-absolute-url to resolve the correct scheme, domain, and port for project URLs. Always use this before sharing a URL with the user.
  • Use browser-logs to read browser logs, errors, and exceptions. Only recent logs are useful, ignore old entries.

Searching Documentation (IMPORTANT)

  • Always use search-docs before making code changes. Do not skip this step. It returns version-specific docs based on installed packages automatically.
  • Pass a packages array to scope results when you know which packages are relevant.
  • Use multiple broad, topic-based queries: ['rate limiting', 'routing rate limiting', 'routing']. Expect the most relevant results first.
  • Do not add package names to queries because package info is already shared. Use test resource table, not filament 4 test resource table.

Search Syntax

  1. Use words for auto-stemmed AND logic: rate limit matches both "rate" AND "limit".
  2. Use "quoted phrases" for exact position matching: "infinite scroll" requires adjacent words in order.
  3. Combine words and phrases for mixed queries: middleware "rate limit".
  4. Use multiple queries for OR logic: queries=["authentication", "middleware"].

Artisan

  • Run Artisan commands directly via the command line (e.g., vendor/bin/sail artisan route:list). Use vendor/bin/sail artisan list to discover available commands and vendor/bin/sail artisan [command] --help to check parameters.
  • Inspect routes with vendor/bin/sail artisan route:list. Filter with: --method=GET, --name=users, --path=api, --except-vendor, --only-vendor.
  • Read configuration values using dot notation: vendor/bin/sail artisan config:show app.name, vendor/bin/sail artisan config:show database.default. Or read config files directly from the config/ directory.
  • To check environment variables, read the .env file directly.

Tinker

  • Execute PHP in app context for debugging and testing code. Do not create models without user approval, prefer tests with factories instead. Prefer existing Artisan commands over custom tinker code.
  • Always use single quotes to prevent shell expansion: vendor/bin/sail artisan tinker --execute 'Your::code();'
    • Double quotes for PHP strings inside: vendor/bin/sail artisan tinker --execute 'User::where("active", true)->count();'

=== php rules ===

PHP

  • Always use curly braces for control structures, even for single-line bodies.
  • Use PHP 8 constructor property promotion: public function __construct(public GitHub $github) { }. Do not leave empty zero-parameter __construct() methods unless the constructor is private.
  • Use explicit return type declarations and type hints for all method parameters: function isAccessible(User $user, ?string $path = null): bool
  • Use TitleCase for Enum keys: FavoritePerson, BestLake, Monthly.
  • Prefer PHPDoc blocks over inline comments. Only add inline comments for exceptionally complex logic.
  • Use array shape type definitions in PHPDoc blocks.

=== deployments rules ===

Deployment

  • Laravel can be deployed using Laravel Cloud, which is the fastest way to deploy and scale production Laravel applications.

=== sail rules ===

Laravel Sail

  • This project runs inside Laravel Sail's Docker containers. You MUST execute all commands through Sail.
  • Start services using vendor/bin/sail up -d and stop them with vendor/bin/sail stop.
  • Open the application in the browser by running vendor/bin/sail open.
  • Always prefix PHP, Artisan, Composer, and Node commands with vendor/bin/sail. Examples:
    • Run Artisan Commands: vendor/bin/sail artisan migrate
    • Install Composer packages: vendor/bin/sail composer install
    • Execute Node commands: vendor/bin/sail npm run dev
    • Execute PHP scripts: vendor/bin/sail php [script]
  • View all available Sail commands by running vendor/bin/sail without arguments.

=== laravel/core rules ===

Do Things the Laravel Way

  • Use vendor/bin/sail artisan make: commands to create new files (i.e. migrations, controllers, models, etc.). You can list available Artisan commands using vendor/bin/sail artisan list and check their parameters with vendor/bin/sail artisan [command] --help.
  • If you're creating a generic PHP class, use vendor/bin/sail artisan make:class.
  • Pass --no-interaction to all Artisan commands to ensure they work without user input. You should also pass the correct --options to ensure correct behavior.

Model Creation

  • When creating new models, create useful factories and seeders for them too. Ask the user if they need any other things, using vendor/bin/sail artisan make:model --help to check the available options.

APIs & Eloquent Resources

  • For APIs, default to using Eloquent API Resources and API versioning unless existing API routes do not, then you should follow existing application convention.

URL Generation

  • When generating links to other pages, prefer named routes and the route() function.

Testing

  • When creating models for tests, use the factories for the models. Check if the factory has custom states that can be used before manually setting up the model.
  • Faker: Use methods such as $this->faker->word() or fake()->randomDigit(). Follow existing conventions whether to use $this->faker or fake().
  • When creating tests, make use of vendor/bin/sail artisan make:test [options] {name} to create a feature test, and pass --unit to create a unit test. Most tests should be feature tests.

Vite Error

  • If you receive an "Illuminate\Foundation\ViteException: Unable to locate file in Vite manifest" error, you can run vendor/bin/sail npm run build or ask the user to run vendor/bin/sail npm run dev or vendor/bin/sail composer run dev.

=== pint/core rules ===

Laravel Pint Code Formatter

  • If you have modified any PHP files, you must run vendor/bin/sail bin pint --dirty --format agent before finalizing changes to ensure your code matches the project's expected style.
  • Do not run vendor/bin/sail bin pint --test --format agent, simply run vendor/bin/sail bin pint --format agent to fix any formatting issues.

=== pest/core rules ===

Pest

  • This project uses Pest for testing. Create tests: vendor/bin/sail artisan make:test --pest {name}.
  • The {name} argument should not include the test suite directory. Use vendor/bin/sail artisan make:test --pest SomeFeatureTest instead of vendor/bin/sail artisan make:test --pest Feature/SomeFeatureTest.
  • Run tests: vendor/bin/sail artisan test --compact or filter: vendor/bin/sail artisan test --compact --filter=testName.
  • Do NOT delete tests without approval.