From 9870f5d102bcac710d4c33deda0da8cb073528a3 Mon Sep 17 00:00:00 2001 From: Ahmed Darrazi Date: Tue, 20 Jan 2026 23:36:08 +0100 Subject: [PATCH] chore: install Laravel Boost + MCP config --- .ai/guidelines/filament-v5-blueprint.md | 173 ++++++ .ai/guidelines/filament-v5-checklist.md | 79 +++ .gemini/settings.json | 15 +- .github/copilot-instructions.md | 683 ++++++++++++++++++++++++ Agents.md | 344 ++++++++++-- GEMINI.md | 343 ++++++++++-- boost.json | 11 +- docs/research/filament-v5-notes.md | 114 ++++ opencode.json | 14 + 9 files changed, 1667 insertions(+), 109 deletions(-) create mode 100644 .ai/guidelines/filament-v5-blueprint.md create mode 100644 .ai/guidelines/filament-v5-checklist.md create mode 100644 .github/copilot-instructions.md create mode 100644 docs/research/filament-v5-notes.md create mode 100644 opencode.json diff --git a/.ai/guidelines/filament-v5-blueprint.md b/.ai/guidelines/filament-v5-blueprint.md new file mode 100644 index 0000000..a3a558a --- /dev/null +++ b/.ai/guidelines/filament-v5-blueprint.md @@ -0,0 +1,173 @@ +## Source of Truth +If any Filament behavior is uncertain, lookup the exact section in: +- docs/research/filament-v5-notes.md +and prefer that over guesses. + +# SECTION B — FILAMENT V5 BLUEPRINT (EXECUTABLE RULES) + +# Filament Blueprint (v5) + +## 1) Non-negotiables +- Filament v5 requires Livewire v4.0+. +- Laravel 11+: register panel providers in `bootstrap/providers.php` (never `bootstrap/app.php`). +- Global search hard rule: If a Resource should appear in Global Search, it must have an Edit or View page; otherwise it will return no results. +- Destructive actions must execute via `Action::make(...)->action(...)` and include `->requiresConfirmation()` (no exceptions). +- Prefer render hooks + CSS hook classes over publishing Filament internal views. + +Sources: +- https://filamentphp.com/docs/5.x/upgrade-guide +- https://filamentphp.com/docs/5.x/panel-configuration +- https://filamentphp.com/docs/5.x/resources/global-search +- https://filamentphp.com/docs/5.x/actions/modals +- https://filamentphp.com/docs/5.x/advanced/render-hooks +- https://filamentphp.com/docs/5.x/styling/css-hooks + +## 2) Directory & naming conventions +- Default to Filament discovery conventions for Resources/Pages/Widgets unless you adopt modular architecture. +- Clusters: directory layout is recommended, not mandatory; functional behavior depends on `$cluster`. + +Sources: +- https://filamentphp.com/docs/5.x/navigation/clusters +- https://filamentphp.com/docs/5.x/advanced/modular-architecture + +## 3) Panel setup defaults +- Default to a single `/admin` panel unless multiple audiences/configs demand multiple panels. +- Verify provider registration (Laravel 11+: `bootstrap/providers.php`) when adding a panel. +- Use `path()` carefully; treat `path('')` as a high-risk change requiring route conflict review. +- Assets policy: + - Panel-only assets: register via panel config. + - Shared/plugin assets: register via `FilamentAsset::register()`. + - Deployment must include `php artisan filament:assets`. + +Sources: +- https://filamentphp.com/docs/5.x/panel-configuration +- https://filamentphp.com/docs/5.x/advanced/assets + +## 4) Navigation & information architecture +- Use nav groups + sort order intentionally; apply conditional visibility for clarity, but enforce authorization separately. +- Use clusters to introduce hierarchy and sub-navigation when sidebar complexity grows. +- Treat cluster code structure as a recommendation (organizational benefit), not a required rule. +- User menu: + - Configure via `userMenuItems()` with Action objects. + - Never put destructive actions there without confirmation + authorization. + +Sources: +- https://filamentphp.com/docs/5.x/navigation/overview +- https://filamentphp.com/docs/5.x/navigation/clusters +- https://filamentphp.com/docs/5.x/navigation/user-menu + +## 5) Resource patterns +- Default to Resources for CRUD; use custom pages for non-CRUD tools/workflows. +- Global search: + - If a resource is intended for global search: ensure Edit/View page exists. + - Otherwise disable global search for that resource (don’t “expect it to work”). + - If global search renders relationship-backed details: eager-load via global search query override. + - For very large datasets: consider disabling term splitting (only when needed). + +Sources: +- https://filamentphp.com/docs/5.x/resources/overview +- https://filamentphp.com/docs/5.x/resources/global-search + +## 6) Page lifecycle & query rules +- Treat relationship-backed rendering in aggregate contexts (global search details, list summaries) as requiring eager loading. +- Prefer render hooks for layout injection; avoid publishing internal views. + +Sources: +- https://filamentphp.com/docs/5.x/resources/global-search +- https://filamentphp.com/docs/5.x/advanced/render-hooks + +## 7) Infolists vs RelationManagers (decision tree) +- Interactive CRUD / attach / detach under owner record → RelationManager. +- Pick existing related record(s) inside owner form → Select / CheckboxList relationship fields. +- Inline CRUD inside owner form → Repeater. +- Default performance stance: RelationManagers stay lazy-loaded unless explicit UX justification exists. + +Sources: +- https://filamentphp.com/docs/5.x/resources/managing-relationships +- https://filamentphp.com/docs/5.x/infolists/overview + +## 8) Form patterns (validation, reactivity, state) +- Default: minimize server-driven reactivity; only use it when schema/visibility/requirements must change server-side. +- Prefer “on blur” semantics for chatty inputs when using reactive behavior (per docs patterns). +- Custom field views must obey state binding modifiers. + +Sources: +- https://filamentphp.com/docs/5.x/forms/overview +- https://filamentphp.com/docs/5.x/forms/custom-fields + +## 9) Table & action patterns +- Tables: always define a meaningful empty state (and empty-state actions where appropriate). +- Actions: + - Execution actions use `->action(...)`. + - Destructive actions add `->requiresConfirmation()`. + - Navigation-only actions should use `->url(...)`. + - UNVERIFIED: do not assert modal/confirmation behavior for URL-only actions unless verified. + +Sources: +- https://filamentphp.com/docs/5.x/tables/empty-state +- https://filamentphp.com/docs/5.x/actions/modals + +## 10) Authorization & security +- Enforce panel access in non-local environments as documented. +- UI visibility is not security; enforce policies/access checks in addition to hiding UI. +- Bulk operations: explicitly decide between “Any” policy methods vs per-record authorization. + +Sources: +- https://filamentphp.com/docs/5.x/users/overview +- https://filamentphp.com/docs/5.x/resources/deleting-records + +## 11) Notifications & UX feedback +- Default to explicit success/error notifications for user-triggered mutations that aren’t instantly obvious. +- Treat polling as a cost; set intervals intentionally where polling is used. + +Sources: +- https://filamentphp.com/docs/5.x/notifications/overview +- https://filamentphp.com/docs/5.x/widgets/stats-overview + +## 12) Performance defaults +- Heavy assets: prefer on-demand loading (`loadedOnRequest()` + `x-load-css` / `x-load-js`) for heavy dependencies. +- Styling overrides use CSS hook classes; layout injection uses render hooks; avoid view publishing. + +Sources: +- https://filamentphp.com/docs/5.x/advanced/assets +- https://filamentphp.com/docs/5.x/styling/css-hooks +- https://filamentphp.com/docs/5.x/advanced/render-hooks + +## 13) Testing requirements +- Test pages/relation managers/widgets as Livewire components. +- Test actions using Filament’s action testing guidance. +- Do not mount non-Livewire classes in Livewire tests. + +Sources: +- https://filamentphp.com/docs/5.x/testing/overview +- https://filamentphp.com/docs/5.x/testing/testing-actions + +## 14) Forbidden patterns +- Mixing Filament v3/v4 APIs into v5 code. +- Any mention of Livewire v3 for Filament v5. +- Registering panel providers in `bootstrap/app.php` on Laravel 11+. +- Destructive actions without `->requiresConfirmation()`. +- Shipping heavy assets globally when on-demand loading fits. +- Publishing Filament internal views as a default customization technique. + +Sources: +- https://filamentphp.com/docs/5.x/upgrade-guide +- https://filamentphp.com/docs/5.x/panel-configuration +- https://filamentphp.com/docs/5.x/actions/modals +- https://filamentphp.com/docs/5.x/advanced/assets + +## 15) Agent output contract +For any implementation request, the agent must explicitly state: +1) Livewire v4.0+ compliance. +2) Provider registration location (Laravel 11+: `bootstrap/providers.php`). +3) For each globally searchable resource: whether it has Edit/View page (or global search is disabled). +4) Which actions are destructive and how confirmation + authorization is handled. +5) Asset strategy: global vs on-demand and where `filament:assets` runs in deploy. +6) Testing plan: which pages/widgets/relation managers/actions are covered. + +Sources: +- https://filamentphp.com/docs/5.x/upgrade-guide +- https://filamentphp.com/docs/5.x/panel-configuration +- https://filamentphp.com/docs/5.x/resources/global-search +- https://filamentphp.com/docs/5.x/advanced/assets +- https://filamentphp.com/docs/5.x/testing/testing-actions \ No newline at end of file diff --git a/.ai/guidelines/filament-v5-checklist.md b/.ai/guidelines/filament-v5-checklist.md new file mode 100644 index 0000000..a19366f --- /dev/null +++ b/.ai/guidelines/filament-v5-checklist.md @@ -0,0 +1,79 @@ +# SECTION C — AI REVIEW CHECKLIST (STRICT CHECKBOXES) + +## Version Safety +- [ ] Filament v5 explicitly targets Livewire v4.0+ (no Livewire v3 references anywhere). + - Source: https://filamentphp.com/docs/5.x/upgrade-guide — “Upgrading Livewire” +- [ ] All references are Filament `/docs/5.x/` only (no v3/v4 docs, no legacy APIs). +- [ ] Upgrade assumptions match the v5 upgrade guide requirements and steps. + - Source: https://filamentphp.com/docs/5.x/upgrade-guide — “New requirements” + +## Panel & Navigation +- [ ] Laravel 11+: panel providers are registered in `bootstrap/providers.php` (not `bootstrap/app.php`). + - Source: https://filamentphp.com/docs/5.x/panel-configuration — “Creating a new panel” +- [ ] Panel `path()` choices are intentional and do not conflict with existing routes (especially `path('')`). + - Source: https://filamentphp.com/docs/5.x/panel-configuration — “Changing the path” +- [ ] Cluster usage is correctly configured (discovery + `$cluster` assignments). + - Source: https://filamentphp.com/docs/5.x/navigation/clusters — “Creating a cluster” +- [ ] Cluster semantics (sub-navigation + grouped navigation behavior) are understood and verified against the clusters docs. + - Source: https://filamentphp.com/docs/5.x/navigation/clusters — “Introduction” +- [ ] Cluster directory structure is treated as recommended, not mandatory. + - Source: https://filamentphp.com/docs/5.x/navigation/clusters — “Code structure recommendations for panels using clusters” +- [ ] User menu items are registered via `userMenuItems()` and permission-gated where needed. + - Source: https://filamentphp.com/docs/5.x/navigation/user-menu — “Introduction” + +## Resource Structure +- [ ] `$recordTitleAttribute` is set for any resource intended for global search. + - Source: https://filamentphp.com/docs/5.x/resources/overview — “Record titles” +- [ ] Hard rule enforced: every globally searchable resource has an Edit or View page; otherwise global search is disabled for it. + - Source: https://filamentphp.com/docs/5.x/resources/global-search — “Setting global search result titles” +- [ ] Relationship-backed global search details are eager-loaded via the global search query override. + - Source: https://filamentphp.com/docs/5.x/resources/global-search — “Adding extra details to global search results” + +## Infolists & Relations +- [ ] Each relationship uses the correct tool (RelationManager vs Select/CheckboxList vs Repeater) based on required interaction. + - Source: https://filamentphp.com/docs/5.x/resources/managing-relationships — “Choosing the right tool for the job” +- [ ] RelationManagers remain lazy-loaded by default unless there’s an explicit UX justification. + - Source: https://filamentphp.com/docs/5.x/resources/managing-relationships — “Disabling lazy loading” + +## Forms +- [ ] Server-driven reactivity is minimal; chatty inputs do not trigger network requests unnecessarily. + - Source: https://filamentphp.com/docs/5.x/forms/overview — “Reactive fields on blur” +- [ ] Custom field views obey state binding modifiers (no hardcoded `wire:model` without modifiers). + - Source: https://filamentphp.com/docs/5.x/forms/custom-fields — “Obeying state binding modifiers” + +## Tables & Actions +- [ ] Tables define a meaningful empty state (and empty-state actions where appropriate). + - Source: https://filamentphp.com/docs/5.x/tables/empty-state — “Adding empty state actions” +- [ ] All destructive actions execute via `->action(...)` and include `->requiresConfirmation()`. + - Source: https://filamentphp.com/docs/5.x/actions/modals — “Confirmation modals” +- [ ] No checklist rule assumes confirmation/modals for `->url(...)` actions unless verified in docs (UNVERIFIED behavior must not be asserted as fact). + - Source: https://filamentphp.com/docs/5.x/actions/modals — “Confirmation modals” + +## Authorization & Security +- [ ] Panel access is enforced for non-local environments as documented. + - Source: https://filamentphp.com/docs/5.x/users/overview — “Authorizing access to the panel” +- [ ] UI visibility is not treated as authorization; policies/access checks still enforce boundaries. +- [ ] Bulk operations intentionally choose between “Any” policy methods vs per-record authorization where required. + - Source: https://filamentphp.com/docs/5.x/resources/deleting-records — “Authorization” + +## UX & Notifications +- [ ] User-triggered mutations provide explicit success/error notifications when outcomes aren’t instantly obvious. + - Source: https://filamentphp.com/docs/5.x/notifications/overview — “Introduction” +- [ ] Polling (widgets/notifications) is configured intentionally (interval set or disabled) to control load. + - Source: https://filamentphp.com/docs/5.x/widgets/stats-overview — “Live updating stats (polling)” + +## Performance +- [ ] Heavy frontend assets are loaded on-demand using `loadedOnRequest()` + `x-load-css` / `x-load-js` where appropriate. + - Source: https://filamentphp.com/docs/5.x/advanced/assets — “Lazy loading CSS” / “Lazy loading JavaScript” +- [ ] Styling overrides use CSS hook classes discovered via DevTools (no brittle selectors by default). + - Source: https://filamentphp.com/docs/5.x/styling/css-hooks — “Discovering hook classes” + +## Testing +- [ ] Livewire tests mount Filament pages/relation managers/widgets (Livewire components), not static resource classes. + - Source: https://filamentphp.com/docs/5.x/testing/overview — “What is a Livewire component when using Filament?” +- [ ] Actions that mutate data are covered using Filament’s action testing guidance. + - Source: https://filamentphp.com/docs/5.x/testing/testing-actions — “Testing actions” + +## Deployment / Ops +- [ ] `php artisan filament:assets` is included in the deployment process when using registered assets. + - Source: https://filamentphp.com/docs/5.x/advanced/assets — “The FilamentAsset facade” \ No newline at end of file diff --git a/.gemini/settings.json b/.gemini/settings.json index 7f50738..dfcb3db 100644 --- a/.gemini/settings.json +++ b/.gemini/settings.json @@ -1,5 +1,14 @@ { - "general": { - "previewFeatures": false - } + "general": { + "previewFeatures": false + }, + "mcpServers": { + "laravel-boost": { + "command": "vendor/bin/sail", + "args": [ + "artisan", + "boost:mcp" + ] + } + } } \ No newline at end of file diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md new file mode 100644 index 0000000..b0091a0 --- /dev/null +++ b/.github/copilot-instructions.md @@ -0,0 +1,683 @@ + +=== .ai/filament-v5-blueprint rules === + +## Source of Truth +If any Filament behavior is uncertain, lookup the exact section in: +- docs/research/filament-v5-notes.md +and prefer that over guesses. + +# SECTION B — FILAMENT V5 BLUEPRINT (EXECUTABLE RULES) + +# Filament Blueprint (v5) + +## 1) Non-negotiables +- Filament v5 requires Livewire v4.0+. +- Laravel 11+: register panel providers in `bootstrap/providers.php` (never `bootstrap/app.php`). +- Global search hard rule: If a Resource should appear in Global Search, it must have an Edit or View page; otherwise it will return no results. +- Destructive actions must execute via `Action::make(...)->action(...)` and include `->requiresConfirmation()` (no exceptions). +- Prefer render hooks + CSS hook classes over publishing Filament internal views. + +Sources: +- https://filamentphp.com/docs/5.x/upgrade-guide +- https://filamentphp.com/docs/5.x/panel-configuration +- https://filamentphp.com/docs/5.x/resources/global-search +- https://filamentphp.com/docs/5.x/actions/modals +- https://filamentphp.com/docs/5.x/advanced/render-hooks +- https://filamentphp.com/docs/5.x/styling/css-hooks + +## 2) Directory & naming conventions +- Default to Filament discovery conventions for Resources/Pages/Widgets unless you adopt modular architecture. +- Clusters: directory layout is recommended, not mandatory; functional behavior depends on `$cluster`. + +Sources: +- https://filamentphp.com/docs/5.x/navigation/clusters +- https://filamentphp.com/docs/5.x/advanced/modular-architecture + +## 3) Panel setup defaults +- Default to a single `/admin` panel unless multiple audiences/configs demand multiple panels. +- Verify provider registration (Laravel 11+: `bootstrap/providers.php`) when adding a panel. +- Use `path()` carefully; treat `path('')` as a high-risk change requiring route conflict review. +- Assets policy: + - Panel-only assets: register via panel config. + - Shared/plugin assets: register via `FilamentAsset::register()`. + - Deployment must include `php artisan filament:assets`. + +Sources: +- https://filamentphp.com/docs/5.x/panel-configuration +- https://filamentphp.com/docs/5.x/advanced/assets + +## 4) Navigation & information architecture +- Use nav groups + sort order intentionally; apply conditional visibility for clarity, but enforce authorization separately. +- Use clusters to introduce hierarchy and sub-navigation when sidebar complexity grows. +- Treat cluster code structure as a recommendation (organizational benefit), not a required rule. +- User menu: + - Configure via `userMenuItems()` with Action objects. + - Never put destructive actions there without confirmation + authorization. + +Sources: +- https://filamentphp.com/docs/5.x/navigation/overview +- https://filamentphp.com/docs/5.x/navigation/clusters +- https://filamentphp.com/docs/5.x/navigation/user-menu + +## 5) Resource patterns +- Default to Resources for CRUD; use custom pages for non-CRUD tools/workflows. +- Global search: + - If a resource is intended for global search: ensure Edit/View page exists. + - Otherwise disable global search for that resource (don’t “expect it to work”). + - If global search renders relationship-backed details: eager-load via global search query override. + - For very large datasets: consider disabling term splitting (only when needed). + +Sources: +- https://filamentphp.com/docs/5.x/resources/overview +- https://filamentphp.com/docs/5.x/resources/global-search + +## 6) Page lifecycle & query rules +- Treat relationship-backed rendering in aggregate contexts (global search details, list summaries) as requiring eager loading. +- Prefer render hooks for layout injection; avoid publishing internal views. + +Sources: +- https://filamentphp.com/docs/5.x/resources/global-search +- https://filamentphp.com/docs/5.x/advanced/render-hooks + +## 7) Infolists vs RelationManagers (decision tree) +- Interactive CRUD / attach / detach under owner record → RelationManager. +- Pick existing related record(s) inside owner form → Select / CheckboxList relationship fields. +- Inline CRUD inside owner form → Repeater. +- Default performance stance: RelationManagers stay lazy-loaded unless explicit UX justification exists. + +Sources: +- https://filamentphp.com/docs/5.x/resources/managing-relationships +- https://filamentphp.com/docs/5.x/infolists/overview + +## 8) Form patterns (validation, reactivity, state) +- Default: minimize server-driven reactivity; only use it when schema/visibility/requirements must change server-side. +- Prefer “on blur” semantics for chatty inputs when using reactive behavior (per docs patterns). +- Custom field views must obey state binding modifiers. + +Sources: +- https://filamentphp.com/docs/5.x/forms/overview +- https://filamentphp.com/docs/5.x/forms/custom-fields + +## 9) Table & action patterns +- Tables: always define a meaningful empty state (and empty-state actions where appropriate). +- Actions: + - Execution actions use `->action(...)`. + - Destructive actions add `->requiresConfirmation()`. + - Navigation-only actions should use `->url(...)`. + - UNVERIFIED: do not assert modal/confirmation behavior for URL-only actions unless verified. + +Sources: +- https://filamentphp.com/docs/5.x/tables/empty-state +- https://filamentphp.com/docs/5.x/actions/modals + +## 10) Authorization & security +- Enforce panel access in non-local environments as documented. +- UI visibility is not security; enforce policies/access checks in addition to hiding UI. +- Bulk operations: explicitly decide between “Any” policy methods vs per-record authorization. + +Sources: +- https://filamentphp.com/docs/5.x/users/overview +- https://filamentphp.com/docs/5.x/resources/deleting-records + +## 11) Notifications & UX feedback +- Default to explicit success/error notifications for user-triggered mutations that aren’t instantly obvious. +- Treat polling as a cost; set intervals intentionally where polling is used. + +Sources: +- https://filamentphp.com/docs/5.x/notifications/overview +- https://filamentphp.com/docs/5.x/widgets/stats-overview + +## 12) Performance defaults +- Heavy assets: prefer on-demand loading (`loadedOnRequest()` + `x-load-css` / `x-load-js`) for heavy dependencies. +- Styling overrides use CSS hook classes; layout injection uses render hooks; avoid view publishing. + +Sources: +- https://filamentphp.com/docs/5.x/advanced/assets +- https://filamentphp.com/docs/5.x/styling/css-hooks +- https://filamentphp.com/docs/5.x/advanced/render-hooks + +## 13) Testing requirements +- Test pages/relation managers/widgets as Livewire components. +- Test actions using Filament’s action testing guidance. +- Do not mount non-Livewire classes in Livewire tests. + +Sources: +- https://filamentphp.com/docs/5.x/testing/overview +- https://filamentphp.com/docs/5.x/testing/testing-actions + +## 14) Forbidden patterns +- Mixing Filament v3/v4 APIs into v5 code. +- Any mention of Livewire v3 for Filament v5. +- Registering panel providers in `bootstrap/app.php` on Laravel 11+. +- Destructive actions without `->requiresConfirmation()`. +- Shipping heavy assets globally when on-demand loading fits. +- Publishing Filament internal views as a default customization technique. + +Sources: +- https://filamentphp.com/docs/5.x/upgrade-guide +- https://filamentphp.com/docs/5.x/panel-configuration +- https://filamentphp.com/docs/5.x/actions/modals +- https://filamentphp.com/docs/5.x/advanced/assets + +## 15) Agent output contract +For any implementation request, the agent must explicitly state: +1) Livewire v4.0+ compliance. +2) Provider registration location (Laravel 11+: `bootstrap/providers.php`). +3) For each globally searchable resource: whether it has Edit/View page (or global search is disabled). +4) Which actions are destructive and how confirmation + authorization is handled. +5) Asset strategy: global vs on-demand and where `filament:assets` runs in deploy. +6) Testing plan: which pages/widgets/relation managers/actions are covered. + +Sources: +- https://filamentphp.com/docs/5.x/upgrade-guide +- https://filamentphp.com/docs/5.x/panel-configuration +- https://filamentphp.com/docs/5.x/resources/global-search +- https://filamentphp.com/docs/5.x/advanced/assets +- https://filamentphp.com/docs/5.x/testing/testing-actions + + +=== .ai/filament-v5-checklist rules === + +# SECTION C — AI REVIEW CHECKLIST (STRICT CHECKBOXES) + +## Version Safety +- [ ] Filament v5 explicitly targets Livewire v4.0+ (no Livewire v3 references anywhere). + - Source: https://filamentphp.com/docs/5.x/upgrade-guide — “Upgrading Livewire” +- [ ] All references are Filament `/docs/5.x/` only (no v3/v4 docs, no legacy APIs). +- [ ] Upgrade assumptions match the v5 upgrade guide requirements and steps. + - Source: https://filamentphp.com/docs/5.x/upgrade-guide — “New requirements” + +## Panel & Navigation +- [ ] Laravel 11+: panel providers are registered in `bootstrap/providers.php` (not `bootstrap/app.php`). + - Source: https://filamentphp.com/docs/5.x/panel-configuration — “Creating a new panel” +- [ ] Panel `path()` choices are intentional and do not conflict with existing routes (especially `path('')`). + - Source: https://filamentphp.com/docs/5.x/panel-configuration — “Changing the path” +- [ ] Cluster usage is correctly configured (discovery + `$cluster` assignments). + - Source: https://filamentphp.com/docs/5.x/navigation/clusters — “Creating a cluster” +- [ ] Cluster semantics (sub-navigation + grouped navigation behavior) are understood and verified against the clusters docs. + - Source: https://filamentphp.com/docs/5.x/navigation/clusters — “Introduction” +- [ ] Cluster directory structure is treated as recommended, not mandatory. + - Source: https://filamentphp.com/docs/5.x/navigation/clusters — “Code structure recommendations for panels using clusters” +- [ ] User menu items are registered via `userMenuItems()` and permission-gated where needed. + - Source: https://filamentphp.com/docs/5.x/navigation/user-menu — “Introduction” + +## Resource Structure +- [ ] `$recordTitleAttribute` is set for any resource intended for global search. + - Source: https://filamentphp.com/docs/5.x/resources/overview — “Record titles” +- [ ] Hard rule enforced: every globally searchable resource has an Edit or View page; otherwise global search is disabled for it. + - Source: https://filamentphp.com/docs/5.x/resources/global-search — “Setting global search result titles” +- [ ] Relationship-backed global search details are eager-loaded via the global search query override. + - Source: https://filamentphp.com/docs/5.x/resources/global-search — “Adding extra details to global search results” + +## Infolists & Relations +- [ ] Each relationship uses the correct tool (RelationManager vs Select/CheckboxList vs Repeater) based on required interaction. + - Source: https://filamentphp.com/docs/5.x/resources/managing-relationships — “Choosing the right tool for the job” +- [ ] RelationManagers remain lazy-loaded by default unless there’s an explicit UX justification. + - Source: https://filamentphp.com/docs/5.x/resources/managing-relationships — “Disabling lazy loading” + +## Forms +- [ ] Server-driven reactivity is minimal; chatty inputs do not trigger network requests unnecessarily. + - Source: https://filamentphp.com/docs/5.x/forms/overview — “Reactive fields on blur” +- [ ] Custom field views obey state binding modifiers (no hardcoded `wire:model` without modifiers). + - Source: https://filamentphp.com/docs/5.x/forms/custom-fields — “Obeying state binding modifiers” + +## Tables & Actions +- [ ] Tables define a meaningful empty state (and empty-state actions where appropriate). + - Source: https://filamentphp.com/docs/5.x/tables/empty-state — “Adding empty state actions” +- [ ] All destructive actions execute via `->action(...)` and include `->requiresConfirmation()`. + - Source: https://filamentphp.com/docs/5.x/actions/modals — “Confirmation modals” +- [ ] No checklist rule assumes confirmation/modals for `->url(...)` actions unless verified in docs (UNVERIFIED behavior must not be asserted as fact). + - Source: https://filamentphp.com/docs/5.x/actions/modals — “Confirmation modals” + +## Authorization & Security +- [ ] Panel access is enforced for non-local environments as documented. + - Source: https://filamentphp.com/docs/5.x/users/overview — “Authorizing access to the panel” +- [ ] UI visibility is not treated as authorization; policies/access checks still enforce boundaries. +- [ ] Bulk operations intentionally choose between “Any” policy methods vs per-record authorization where required. + - Source: https://filamentphp.com/docs/5.x/resources/deleting-records — “Authorization” + +## UX & Notifications +- [ ] User-triggered mutations provide explicit success/error notifications when outcomes aren’t instantly obvious. + - Source: https://filamentphp.com/docs/5.x/notifications/overview — “Introduction” +- [ ] Polling (widgets/notifications) is configured intentionally (interval set or disabled) to control load. + - Source: https://filamentphp.com/docs/5.x/widgets/stats-overview — “Live updating stats (polling)” + +## Performance +- [ ] Heavy frontend assets are loaded on-demand using `loadedOnRequest()` + `x-load-css` / `x-load-js` where appropriate. + - Source: https://filamentphp.com/docs/5.x/advanced/assets — “Lazy loading CSS” / “Lazy loading JavaScript” +- [ ] Styling overrides use CSS hook classes discovered via DevTools (no brittle selectors by default). + - Source: https://filamentphp.com/docs/5.x/styling/css-hooks — “Discovering hook classes” + +## Testing +- [ ] Livewire tests mount Filament pages/relation managers/widgets (Livewire components), not static resource classes. + - Source: https://filamentphp.com/docs/5.x/testing/overview — “What is a Livewire component when using Filament?” +- [ ] Actions that mutate data are covered using Filament’s action testing guidance. + - Source: https://filamentphp.com/docs/5.x/testing/testing-actions — “Testing actions” + +## Deployment / Ops +- [ ] `php artisan filament:assets` is included in the deployment process when using registered assets. + - Source: https://filamentphp.com/docs/5.x/advanced/assets — “The FilamentAsset facade” + + +=== 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 enhance the user's satisfaction 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.4.15 +- filament/filament (FILAMENT) - v5 +- laravel/framework (LARAVEL) - v12 +- laravel/prompts (PROMPTS) - v0 +- livewire/livewire (LIVEWIRE) - v4 +- laravel/mcp (MCP) - v0 +- laravel/pint (PINT) - v1 +- laravel/sail (SAIL) - v1 +- pestphp/pest (PEST) - v4 +- phpunit/phpunit (PHPUNIT) - v12 +- tailwindcss (TAILWINDCSS) - v4 + +## 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, 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 it works. 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. + +## Replies +- Be concise in your explanations - focus on what's important rather than explaining obvious details. + +## Documentation Files +- You must only create documentation files if explicitly requested by the user. + + +=== boost rules === + +## Laravel Boost +- Laravel Boost is an MCP server that comes with powerful tools designed specifically for this application. Use them. + +## Artisan +- Use the `list-artisan-commands` tool when you need to call an Artisan command to double check the available parameters. + +## URLs +- Whenever you share a project URL with the user you should use the `get-absolute-url` tool to ensure you're using the correct scheme, domain / IP, and port. + +## Tinker / Debugging +- You should use the `tinker` tool when you need to execute PHP to debug code or query Eloquent models directly. +- Use the `database-query` tool when you only need to read from the database. + +## Reading Browser Logs With the `browser-logs` Tool +- You can read browser logs, errors, and exceptions using the `browser-logs` tool from Boost. +- Only recent browser logs will be useful - ignore old logs. + +## Searching Documentation (Critically Important) +- Boost comes with a powerful `search-docs` tool you should use before any other approaches. This tool automatically passes a list of installed packages and their versions to the remote Boost API, so it returns only version-specific documentation specific for the user's circumstance. You should pass an array of packages to filter on if you know you need docs for particular packages. +- The 'search-docs' tool is perfect for all Laravel related packages, including Laravel, Inertia, Livewire, Filament, Tailwind, Pest, Nova, Nightwatch, etc. +- You must use this tool to search for Laravel-ecosystem documentation before falling back to other approaches. +- Search the documentation before making code changes to ensure we are taking the correct approach. +- Use multiple, broad, simple, topic based queries to start. For example: `['rate limiting', 'routing rate limiting', 'routing']`. +- Do not add package names to queries - package information is already shared. For example, use `test resource table`, not `filament 4 test resource table`. + +### Available Search Syntax +- You can and should pass multiple queries at once. The most relevant results will be returned first. + +1. Simple Word Searches with auto-stemming - query=authentication - finds 'authenticate' and 'auth' +2. Multiple Words (AND Logic) - query=rate limit - finds knowledge containing both "rate" AND "limit" +3. Quoted Phrases (Exact Position) - query="infinite scroll" - Words must be adjacent and in that order +4. Mixed Queries - query=middleware "rate limit" - "middleware" AND exact phrase "rate limit" +5. Multiple Queries - queries=["authentication", "middleware"] - ANY of these terms + + +=== php rules === + +## PHP + +- Always use curly braces for control structures, even if it has one line. + +### Constructors +- Use PHP 8 constructor property promotion in `__construct()`. + - public function __construct(public GitHub $github) { } +- Do not allow empty `__construct()` methods with zero parameters. + +### Type Declarations +- Always use explicit return type declarations for methods and functions. +- Use appropriate PHP type hints for method parameters. + + +protected function isAccessible(User $user, ?string $path = null): bool +{ + ... +} + + +## Comments +- Prefer PHPDoc blocks over comments. Never use comments within the code itself unless there is something _very_ complex going on. + +## PHPDoc Blocks +- Add useful array shape type definitions for arrays when appropriate. + +## Enums +- Typically, keys in an Enum should be TitleCase. For example: `FavoritePerson`, `BestLake`, `Monthly`. + + +=== 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. + + +=== tests rules === + +## Test Enforcement + +- Every change must be programmatically tested. Write a new test or update an existing test, then run the affected tests to make sure they pass. +- Run the minimum number of tests needed to ensure code quality and speed. Use `vendor/bin/sail artisan test` with a specific filename or filter. + + +=== 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 the `list-artisan-commands` tool. +- 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. + +### Database +- Always use proper Eloquent relationship methods with return type hints. Prefer relationship methods over raw queries or manual joins. +- Use Eloquent models and relationships before suggesting raw database queries +- Avoid `DB::`; prefer `Model::query()`. Generate code that leverages Laravel's ORM capabilities rather than bypassing them. +- Generate code that prevents N+1 query problems by using eager loading. +- Use Laravel's query builder for very complex database operations. + +### Model Creation +- When creating new models, create useful factories and seeders for them too. Ask the user if they need any other things, using `list-artisan-commands` to check the available options to `vendor/bin/sail artisan make:model`. + +### 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. + +### Controllers & Validation +- Always create Form Request classes for validation rather than inline validation in controllers. Include both validation rules and custom error messages. +- Check sibling Form Requests to see if the application uses array or string based validation rules. + +### Queues +- Use queued jobs for time-consuming operations with the `ShouldQueue` interface. + +### Authentication & Authorization +- Use Laravel's built-in authentication and authorization features (gates, policies, Sanctum, etc.). + +### URL Generation +- When generating links to other pages, prefer named routes and the `route()` function. + +### Configuration +- Use environment variables only in configuration files - never use the `env()` function directly outside of config files. Always use `config('app.name')`, not `env('APP_NAME')`. + +### 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`. + + +=== laravel/v12 rules === + +## Laravel 12 + +- Use the `search-docs` tool to get version specific documentation. +- Since Laravel 11, Laravel has a new streamlined file structure which this project uses. + +### Laravel 12 Structure +- No middleware files in `app/Http/Middleware/`. +- `bootstrap/app.php` is the file to register middleware, exceptions, and routing files. +- `bootstrap/providers.php` contains application specific service providers. +- **No app\Console\Kernel.php** - use `bootstrap/app.php` or `routes/console.php` for console configuration. +- **Commands auto-register** - files in `app/Console/Commands/` are automatically available and do not require manual registration. + +### Database +- When modifying a column, the migration must include all of the attributes that were previously defined on the column. Otherwise, they will be dropped and lost. +- Laravel 11 allows limiting eagerly loaded records natively, without external packages: `$query->latest()->limit(10);`. + +### Models +- Casts can and likely should be set in a `casts()` method on a model rather than the `$casts` property. Follow existing conventions from other models. + + +=== livewire/core rules === + +## Livewire Core +- Use the `search-docs` tool to find exact version specific documentation for how to write Livewire & Livewire tests. +- Use the `vendor/bin/sail artisan make:livewire [Posts\CreatePost]` artisan command to create new components +- State should live on the server, with the UI reflecting it. +- All Livewire requests hit the Laravel backend, they're like regular HTTP requests. Always validate form data, and run authorization checks in Livewire actions. + +## Livewire Best Practices +- Livewire components require a single root element. +- Use `wire:loading` and `wire:dirty` for delightful loading states. +- Add `wire:key` in loops: + + ```blade + @foreach ($items as $item) +
+ {{ $item->name }} +
+ @endforeach + ``` + +- Prefer lifecycle hooks like `mount()`, `updatedFoo()` for initialization and reactive side effects: + + + public function mount(User $user) { $this->user = $user; } + public function updatedSearch() { $this->resetPage(); } + + + +## Testing Livewire + + + Livewire::test(Counter::class) + ->assertSet('count', 0) + ->call('increment') + ->assertSet('count', 1) + ->assertSee(1) + ->assertStatus(200); + + + + + $this->get('/posts/create') + ->assertSeeLivewire(CreatePost::class); + + + +=== pint/core rules === + +## Laravel Pint Code Formatter + +- You must run `vendor/bin/sail bin pint --dirty` before finalizing changes to ensure your code matches the project's expected style. +- Do not run `vendor/bin/sail bin pint --test`, simply run `vendor/bin/sail bin pint` to fix any formatting issues. + + +=== pest/core rules === + +## Pest +### Testing +- If you need to verify a feature is working, write or update a Unit / Feature test. + +### Pest Tests +- All tests must be written using Pest. Use `vendor/bin/sail artisan make:test --pest {name}`. +- You must not remove any tests or test files from the tests directory without approval. These are not temporary or helper files - these are core to the application. +- Tests should test all of the happy paths, failure paths, and weird paths. +- Tests live in the `tests/Feature` and `tests/Unit` directories. +- Pest tests look and behave like this: + +it('is true', function () { + expect(true)->toBeTrue(); +}); + + +### Running Tests +- Run the minimal number of tests using an appropriate filter before finalizing code edits. +- To run all tests: `vendor/bin/sail artisan test`. +- To run all tests in a file: `vendor/bin/sail artisan test tests/Feature/ExampleTest.php`. +- To filter on a particular test name: `vendor/bin/sail artisan test --filter=testName` (recommended after making a change to a related file). +- When the tests relating to your changes are passing, ask the user if they would like to run the entire test suite to ensure everything is still passing. + +### Pest Assertions +- When asserting status codes on a response, use the specific method like `assertForbidden` and `assertNotFound` instead of using `assertStatus(403)` or similar, e.g.: + +it('returns all', function () { + $response = $this->postJson('/api/docs', []); + + $response->assertSuccessful(); +}); + + +### Mocking +- Mocking can be very helpful when appropriate. +- When mocking, you can use the `Pest\Laravel\mock` Pest function, but always import it via `use function Pest\Laravel\mock;` before using it. Alternatively, you can use `$this->mock()` if existing tests do. +- You can also create partial mocks using the same import or self method. + +### Datasets +- Use datasets in Pest to simplify tests which have a lot of duplicated data. This is often the case when testing validation rules, so consider going with this solution when writing tests for validation rules. + + +it('has emails', function (string $email) { + expect($email)->not->toBeEmpty(); +})->with([ + 'james' => 'james@laravel.com', + 'taylor' => 'taylor@laravel.com', +]); + + + +=== pest/v4 rules === + +## Pest 4 + +- Pest v4 is a huge upgrade to Pest and offers: browser testing, smoke testing, visual regression testing, test sharding, and faster type coverage. +- Browser testing is incredibly powerful and useful for this project. +- Browser tests should live in `tests/Browser/`. +- Use the `search-docs` tool for detailed guidance on utilizing these features. + +### Browser Testing +- You can use Laravel features like `Event::fake()`, `assertAuthenticated()`, and model factories within Pest v4 browser tests, as well as `RefreshDatabase` (when needed) to ensure a clean state for each test. +- Interact with the page (click, type, scroll, select, submit, drag-and-drop, touch gestures, etc.) when appropriate to complete the test. +- If requested, test on multiple browsers (Chrome, Firefox, Safari). +- If requested, test on different devices and viewports (like iPhone 14 Pro, tablets, or custom breakpoints). +- Switch color schemes (light/dark mode) when appropriate. +- Take screenshots or pause tests for debugging when appropriate. + +### Example Tests + + +it('may reset the password', function () { + Notification::fake(); + + $this->actingAs(User::factory()->create()); + + $page = visit('/sign-in'); // Visit on a real browser... + + $page->assertSee('Sign In') + ->assertNoJavascriptErrors() // or ->assertNoConsoleLogs() + ->click('Forgot Password?') + ->fill('email', 'nuno@laravel.com') + ->click('Send Reset Link') + ->assertSee('We have emailed your password reset link!') + + Notification::assertSent(ResetPassword::class); +}); + + + +$pages = visit(['/', '/about', '/contact']); + +$pages->assertNoJavascriptErrors()->assertNoConsoleLogs(); + + + +=== tailwindcss/core rules === + +## Tailwind Core + +- Use Tailwind CSS classes to style HTML, check and use existing tailwind conventions within the project before writing your own. +- Offer to extract repeated patterns into components that match the project's conventions (i.e. Blade, JSX, Vue, etc..) +- Think through class placement, order, priority, and defaults - remove redundant classes, add classes to parent or child carefully to limit repetition, group elements logically +- You can use the `search-docs` tool to get exact examples from the official documentation when needed. + +### Spacing +- When listing items, use gap utilities for spacing, don't use margins. + + +
+
Superior
+
Michigan
+
Erie
+
+
+ + +### Dark Mode +- If existing pages and components support dark mode, new pages and components must support dark mode in a similar way, typically using `dark:`. + + +=== tailwindcss/v4 rules === + +## Tailwind 4 + +- Always use Tailwind CSS v4 - do not use the deprecated utilities. +- `corePlugins` is not supported in Tailwind v4. +- In Tailwind v4, configuration is CSS-first using the `@theme` directive — no separate `tailwind.config.js` file is needed. + +@theme { + --color-brand: oklch(0.72 0.11 178); +} + + +- In Tailwind v4, you import Tailwind using a regular CSS `@import` statement, not using the `@tailwind` directives used in v3: + + + - @tailwind base; + - @tailwind components; + - @tailwind utilities; + + @import "tailwindcss"; + + + +### Replaced Utilities +- Tailwind v4 removed deprecated utilities. Do not use the deprecated option - use the replacement. +- Opacity values are still numeric. + +| Deprecated | Replacement | +|------------+--------------| +| bg-opacity-* | bg-black/* | +| text-opacity-* | text-black/* | +| border-opacity-* | border-black/* | +| divide-opacity-* | divide-black/* | +| ring-opacity-* | ring-black/* | +| placeholder-opacity-* | placeholder-black/* | +| flex-shrink-* | shrink-* | +| flex-grow-* | grow-* | +| overflow-ellipsis | text-ellipsis | +| decoration-slice | box-decoration-slice | +| decoration-clone | box-decoration-clone | +
diff --git a/Agents.md b/Agents.md index 2993b9d..2f6e883 100644 --- a/Agents.md +++ b/Agents.md @@ -386,6 +386,266 @@ ## Reference Materials === +=== .ai/filament-v5-blueprint rules === + +## Source of Truth +If any Filament behavior is uncertain, lookup the exact section in: +- docs/research/filament-v5-notes.md +and prefer that over guesses. + +# SECTION B — FILAMENT V5 BLUEPRINT (EXECUTABLE RULES) + +# Filament Blueprint (v5) + +## 1) Non-negotiables +- Filament v5 requires Livewire v4.0+. +- Laravel 11+: register panel providers in `bootstrap/providers.php` (never `bootstrap/app.php`). +- Global search hard rule: If a Resource should appear in Global Search, it must have an Edit or View page; otherwise it will return no results. +- Destructive actions must execute via `Action::make(...)->action(...)` and include `->requiresConfirmation()` (no exceptions). +- Prefer render hooks + CSS hook classes over publishing Filament internal views. + +Sources: +- https://filamentphp.com/docs/5.x/upgrade-guide +- https://filamentphp.com/docs/5.x/panel-configuration +- https://filamentphp.com/docs/5.x/resources/global-search +- https://filamentphp.com/docs/5.x/actions/modals +- https://filamentphp.com/docs/5.x/advanced/render-hooks +- https://filamentphp.com/docs/5.x/styling/css-hooks + +## 2) Directory & naming conventions +- Default to Filament discovery conventions for Resources/Pages/Widgets unless you adopt modular architecture. +- Clusters: directory layout is recommended, not mandatory; functional behavior depends on `$cluster`. + +Sources: +- https://filamentphp.com/docs/5.x/navigation/clusters +- https://filamentphp.com/docs/5.x/advanced/modular-architecture + +## 3) Panel setup defaults +- Default to a single `/admin` panel unless multiple audiences/configs demand multiple panels. +- Verify provider registration (Laravel 11+: `bootstrap/providers.php`) when adding a panel. +- Use `path()` carefully; treat `path('')` as a high-risk change requiring route conflict review. +- Assets policy: + - Panel-only assets: register via panel config. + - Shared/plugin assets: register via `FilamentAsset::register()`. + - Deployment must include `php artisan filament:assets`. + +Sources: +- https://filamentphp.com/docs/5.x/panel-configuration +- https://filamentphp.com/docs/5.x/advanced/assets + +## 4) Navigation & information architecture +- Use nav groups + sort order intentionally; apply conditional visibility for clarity, but enforce authorization separately. +- Use clusters to introduce hierarchy and sub-navigation when sidebar complexity grows. +- Treat cluster code structure as a recommendation (organizational benefit), not a required rule. +- User menu: + - Configure via `userMenuItems()` with Action objects. + - Never put destructive actions there without confirmation + authorization. + +Sources: +- https://filamentphp.com/docs/5.x/navigation/overview +- https://filamentphp.com/docs/5.x/navigation/clusters +- https://filamentphp.com/docs/5.x/navigation/user-menu + +## 5) Resource patterns +- Default to Resources for CRUD; use custom pages for non-CRUD tools/workflows. +- Global search: + - If a resource is intended for global search: ensure Edit/View page exists. + - Otherwise disable global search for that resource (don’t “expect it to work”). + - If global search renders relationship-backed details: eager-load via global search query override. + - For very large datasets: consider disabling term splitting (only when needed). + +Sources: +- https://filamentphp.com/docs/5.x/resources/overview +- https://filamentphp.com/docs/5.x/resources/global-search + +## 6) Page lifecycle & query rules +- Treat relationship-backed rendering in aggregate contexts (global search details, list summaries) as requiring eager loading. +- Prefer render hooks for layout injection; avoid publishing internal views. + +Sources: +- https://filamentphp.com/docs/5.x/resources/global-search +- https://filamentphp.com/docs/5.x/advanced/render-hooks + +## 7) Infolists vs RelationManagers (decision tree) +- Interactive CRUD / attach / detach under owner record → RelationManager. +- Pick existing related record(s) inside owner form → Select / CheckboxList relationship fields. +- Inline CRUD inside owner form → Repeater. +- Default performance stance: RelationManagers stay lazy-loaded unless explicit UX justification exists. + +Sources: +- https://filamentphp.com/docs/5.x/resources/managing-relationships +- https://filamentphp.com/docs/5.x/infolists/overview + +## 8) Form patterns (validation, reactivity, state) +- Default: minimize server-driven reactivity; only use it when schema/visibility/requirements must change server-side. +- Prefer “on blur” semantics for chatty inputs when using reactive behavior (per docs patterns). +- Custom field views must obey state binding modifiers. + +Sources: +- https://filamentphp.com/docs/5.x/forms/overview +- https://filamentphp.com/docs/5.x/forms/custom-fields + +## 9) Table & action patterns +- Tables: always define a meaningful empty state (and empty-state actions where appropriate). +- Actions: + - Execution actions use `->action(...)`. + - Destructive actions add `->requiresConfirmation()`. + - Navigation-only actions should use `->url(...)`. + - UNVERIFIED: do not assert modal/confirmation behavior for URL-only actions unless verified. + +Sources: +- https://filamentphp.com/docs/5.x/tables/empty-state +- https://filamentphp.com/docs/5.x/actions/modals + +## 10) Authorization & security +- Enforce panel access in non-local environments as documented. +- UI visibility is not security; enforce policies/access checks in addition to hiding UI. +- Bulk operations: explicitly decide between “Any” policy methods vs per-record authorization. + +Sources: +- https://filamentphp.com/docs/5.x/users/overview +- https://filamentphp.com/docs/5.x/resources/deleting-records + +## 11) Notifications & UX feedback +- Default to explicit success/error notifications for user-triggered mutations that aren’t instantly obvious. +- Treat polling as a cost; set intervals intentionally where polling is used. + +Sources: +- https://filamentphp.com/docs/5.x/notifications/overview +- https://filamentphp.com/docs/5.x/widgets/stats-overview + +## 12) Performance defaults +- Heavy assets: prefer on-demand loading (`loadedOnRequest()` + `x-load-css` / `x-load-js`) for heavy dependencies. +- Styling overrides use CSS hook classes; layout injection uses render hooks; avoid view publishing. + +Sources: +- https://filamentphp.com/docs/5.x/advanced/assets +- https://filamentphp.com/docs/5.x/styling/css-hooks +- https://filamentphp.com/docs/5.x/advanced/render-hooks + +## 13) Testing requirements +- Test pages/relation managers/widgets as Livewire components. +- Test actions using Filament’s action testing guidance. +- Do not mount non-Livewire classes in Livewire tests. + +Sources: +- https://filamentphp.com/docs/5.x/testing/overview +- https://filamentphp.com/docs/5.x/testing/testing-actions + +## 14) Forbidden patterns +- Mixing Filament v3/v4 APIs into v5 code. +- Any mention of Livewire v3 for Filament v5. +- Registering panel providers in `bootstrap/app.php` on Laravel 11+. +- Destructive actions without `->requiresConfirmation()`. +- Shipping heavy assets globally when on-demand loading fits. +- Publishing Filament internal views as a default customization technique. + +Sources: +- https://filamentphp.com/docs/5.x/upgrade-guide +- https://filamentphp.com/docs/5.x/panel-configuration +- https://filamentphp.com/docs/5.x/actions/modals +- https://filamentphp.com/docs/5.x/advanced/assets + +## 15) Agent output contract +For any implementation request, the agent must explicitly state: +1) Livewire v4.0+ compliance. +2) Provider registration location (Laravel 11+: `bootstrap/providers.php`). +3) For each globally searchable resource: whether it has Edit/View page (or global search is disabled). +4) Which actions are destructive and how confirmation + authorization is handled. +5) Asset strategy: global vs on-demand and where `filament:assets` runs in deploy. +6) Testing plan: which pages/widgets/relation managers/actions are covered. + +Sources: +- https://filamentphp.com/docs/5.x/upgrade-guide +- https://filamentphp.com/docs/5.x/panel-configuration +- https://filamentphp.com/docs/5.x/resources/global-search +- https://filamentphp.com/docs/5.x/advanced/assets +- https://filamentphp.com/docs/5.x/testing/testing-actions + + +=== .ai/filament-v5-checklist rules === + +# SECTION C — AI REVIEW CHECKLIST (STRICT CHECKBOXES) + +## Version Safety +- [ ] Filament v5 explicitly targets Livewire v4.0+ (no Livewire v3 references anywhere). + - Source: https://filamentphp.com/docs/5.x/upgrade-guide — “Upgrading Livewire” +- [ ] All references are Filament `/docs/5.x/` only (no v3/v4 docs, no legacy APIs). +- [ ] Upgrade assumptions match the v5 upgrade guide requirements and steps. + - Source: https://filamentphp.com/docs/5.x/upgrade-guide — “New requirements” + +## Panel & Navigation +- [ ] Laravel 11+: panel providers are registered in `bootstrap/providers.php` (not `bootstrap/app.php`). + - Source: https://filamentphp.com/docs/5.x/panel-configuration — “Creating a new panel” +- [ ] Panel `path()` choices are intentional and do not conflict with existing routes (especially `path('')`). + - Source: https://filamentphp.com/docs/5.x/panel-configuration — “Changing the path” +- [ ] Cluster usage is correctly configured (discovery + `$cluster` assignments). + - Source: https://filamentphp.com/docs/5.x/navigation/clusters — “Creating a cluster” +- [ ] Cluster semantics (sub-navigation + grouped navigation behavior) are understood and verified against the clusters docs. + - Source: https://filamentphp.com/docs/5.x/navigation/clusters — “Introduction” +- [ ] Cluster directory structure is treated as recommended, not mandatory. + - Source: https://filamentphp.com/docs/5.x/navigation/clusters — “Code structure recommendations for panels using clusters” +- [ ] User menu items are registered via `userMenuItems()` and permission-gated where needed. + - Source: https://filamentphp.com/docs/5.x/navigation/user-menu — “Introduction” + +## Resource Structure +- [ ] `$recordTitleAttribute` is set for any resource intended for global search. + - Source: https://filamentphp.com/docs/5.x/resources/overview — “Record titles” +- [ ] Hard rule enforced: every globally searchable resource has an Edit or View page; otherwise global search is disabled for it. + - Source: https://filamentphp.com/docs/5.x/resources/global-search — “Setting global search result titles” +- [ ] Relationship-backed global search details are eager-loaded via the global search query override. + - Source: https://filamentphp.com/docs/5.x/resources/global-search — “Adding extra details to global search results” + +## Infolists & Relations +- [ ] Each relationship uses the correct tool (RelationManager vs Select/CheckboxList vs Repeater) based on required interaction. + - Source: https://filamentphp.com/docs/5.x/resources/managing-relationships — “Choosing the right tool for the job” +- [ ] RelationManagers remain lazy-loaded by default unless there’s an explicit UX justification. + - Source: https://filamentphp.com/docs/5.x/resources/managing-relationships — “Disabling lazy loading” + +## Forms +- [ ] Server-driven reactivity is minimal; chatty inputs do not trigger network requests unnecessarily. + - Source: https://filamentphp.com/docs/5.x/forms/overview — “Reactive fields on blur” +- [ ] Custom field views obey state binding modifiers (no hardcoded `wire:model` without modifiers). + - Source: https://filamentphp.com/docs/5.x/forms/custom-fields — “Obeying state binding modifiers” + +## Tables & Actions +- [ ] Tables define a meaningful empty state (and empty-state actions where appropriate). + - Source: https://filamentphp.com/docs/5.x/tables/empty-state — “Adding empty state actions” +- [ ] All destructive actions execute via `->action(...)` and include `->requiresConfirmation()`. + - Source: https://filamentphp.com/docs/5.x/actions/modals — “Confirmation modals” +- [ ] No checklist rule assumes confirmation/modals for `->url(...)` actions unless verified in docs (UNVERIFIED behavior must not be asserted as fact). + - Source: https://filamentphp.com/docs/5.x/actions/modals — “Confirmation modals” + +## Authorization & Security +- [ ] Panel access is enforced for non-local environments as documented. + - Source: https://filamentphp.com/docs/5.x/users/overview — “Authorizing access to the panel” +- [ ] UI visibility is not treated as authorization; policies/access checks still enforce boundaries. +- [ ] Bulk operations intentionally choose between “Any” policy methods vs per-record authorization where required. + - Source: https://filamentphp.com/docs/5.x/resources/deleting-records — “Authorization” + +## UX & Notifications +- [ ] User-triggered mutations provide explicit success/error notifications when outcomes aren’t instantly obvious. + - Source: https://filamentphp.com/docs/5.x/notifications/overview — “Introduction” +- [ ] Polling (widgets/notifications) is configured intentionally (interval set or disabled) to control load. + - Source: https://filamentphp.com/docs/5.x/widgets/stats-overview — “Live updating stats (polling)” + +## Performance +- [ ] Heavy frontend assets are loaded on-demand using `loadedOnRequest()` + `x-load-css` / `x-load-js` where appropriate. + - Source: https://filamentphp.com/docs/5.x/advanced/assets — “Lazy loading CSS” / “Lazy loading JavaScript” +- [ ] Styling overrides use CSS hook classes discovered via DevTools (no brittle selectors by default). + - Source: https://filamentphp.com/docs/5.x/styling/css-hooks — “Discovering hook classes” + +## Testing +- [ ] Livewire tests mount Filament pages/relation managers/widgets (Livewire components), not static resource classes. + - Source: https://filamentphp.com/docs/5.x/testing/overview — “What is a Livewire component when using Filament?” +- [ ] Actions that mutate data are covered using Filament’s action testing guidance. + - Source: https://filamentphp.com/docs/5.x/testing/testing-actions — “Testing actions” + +## Deployment / Ops +- [ ] `php artisan filament:assets` is included in the deployment process when using registered assets. + - Source: https://filamentphp.com/docs/5.x/advanced/assets — “The FilamentAsset facade” + + === foundation rules === # Laravel Boost Guidelines @@ -396,10 +656,10 @@ ## 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.4.15 -- filament/filament (FILAMENT) - v4 +- filament/filament (FILAMENT) - v5 - laravel/framework (LARAVEL) - v12 - laravel/prompts (PROMPTS) - v0 -- livewire/livewire (LIVEWIRE) - v3 +- livewire/livewire (LIVEWIRE) - v4 - laravel/mcp (MCP) - v0 - laravel/pint (PINT) - v1 - laravel/sail (SAIL) - v1 @@ -411,7 +671,6 @@ ## 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, naming. - Use descriptive names for variables and methods. For example, `isRegisteredForDiscounts`, not `discount()`. - Check for existing components to reuse before writing a new one. -- UI consistency: Prefer Filament components (``, infolist/table entries, etc.) over custom HTML/Tailwind for admin UI; only roll custom markup when Filament cannot express the UI. ## Verification Scripts - Do not create verification scripts or tinker when tests cover that functionality and prove it works. Unit and feature tests are more important. @@ -421,7 +680,7 @@ ## Application Structure & Architecture - 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 `npm run build`, `npm run dev`, or `composer run dev`. Ask them. +- 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. ## Replies - Be concise in your explanations - focus on what's important rather than explaining obvious details. @@ -499,20 +758,35 @@ ## Enums - Typically, keys in an Enum should be TitleCase. For example: `FavoritePerson`, `BestLake`, `Monthly`. +=== 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. + + === tests rules === ## Test Enforcement - Every change must be programmatically tested. Write a new test or update an existing test, then run the affected tests to make sure they pass. -- Run the minimum number of tests needed to ensure code quality and speed. Use `php artisan test` with a specific filename or filter. +- Run the minimum number of tests needed to ensure code quality and speed. Use `vendor/bin/sail artisan test` with a specific filename or filter. === laravel/core rules === ## Do Things the Laravel Way -- Use `php artisan make:` commands to create new files (i.e. migrations, controllers, models, etc.). You can list available Artisan commands using the `list-artisan-commands` tool. -- If you're creating a generic PHP class, use `php artisan make:class`. +- Use `vendor/bin/sail artisan make:` commands to create new files (i.e. migrations, controllers, models, etc.). You can list available Artisan commands using the `list-artisan-commands` tool. +- 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. ### Database @@ -523,7 +797,7 @@ ### Database - Use Laravel's query builder for very complex database operations. ### Model Creation -- When creating new models, create useful factories and seeders for them too. Ask the user if they need any other things, using `list-artisan-commands` to check the available options to `php artisan make:model`. +- When creating new models, create useful factories and seeders for them too. Ask the user if they need any other things, using `list-artisan-commands` to check the available options to `vendor/bin/sail artisan make:model`. ### 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. @@ -547,10 +821,10 @@ ### Configuration ### 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 `php artisan make:test [options] {name}` to create a feature test, and pass `--unit` to create a unit test. Most tests should be feature tests. +- 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 `npm run build` or ask the user to run `npm run dev` or `composer run dev`. +- 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`. === laravel/v12 rules === @@ -579,7 +853,7 @@ ### Models ## Livewire Core - Use the `search-docs` tool to find exact version specific documentation for how to write Livewire & Livewire tests. -- Use the `php artisan make:livewire [Posts\CreatePost]` artisan command to create new components +- Use the `vendor/bin/sail artisan make:livewire [Posts\CreatePost]` artisan command to create new components - State should live on the server, with the UI reflecting it. - All Livewire requests hit the Laravel backend, they're like regular HTTP requests. Always validate form data, and run authorization checks in Livewire actions. @@ -622,48 +896,12 @@ ## Testing Livewire -=== livewire/v3 rules === - -## Livewire 3 - -### Key Changes From Livewire 2 -- These things changed in Livewire 2, but may not have been updated in this application. Verify this application's setup to ensure you conform with application conventions. - - Use `wire:model.live` for real-time updates, `wire:model` is now deferred by default. - - Components now use the `App\Livewire` namespace (not `App\Http\Livewire`). - - Use `$this->dispatch()` to dispatch events (not `emit` or `dispatchBrowserEvent`). - - Use the `components.layouts.app` view as the typical layout path (not `layouts.app`). - -### New Directives -- `wire:show`, `wire:transition`, `wire:cloak`, `wire:offline`, `wire:target` are available for use. Use the documentation to find usage examples. - -### Alpine -- Alpine is now included with Livewire, don't manually include Alpine.js. -- Plugins included with Alpine: persist, intersect, collapse, and focus. - -### Lifecycle Hooks -- You can listen for `livewire:init` to hook into Livewire initialization, and `fail.status === 419` for the page expiring: - - -document.addEventListener('livewire:init', function () { - Livewire.hook('request', ({ fail }) => { - if (fail && fail.status === 419) { - alert('Your session expired'); - } - }); - - Livewire.hook('message.failed', (message, component) => { - console.error(message); - }); -}); - - - === pint/core rules === ## Laravel Pint Code Formatter -- You must run `vendor/bin/pint --dirty` before finalizing changes to ensure your code matches the project's expected style. -- Do not run `vendor/bin/pint --test`, simply run `vendor/bin/pint` to fix any formatting issues. +- You must run `vendor/bin/sail bin pint --dirty` before finalizing changes to ensure your code matches the project's expected style. +- Do not run `vendor/bin/sail bin pint --test`, simply run `vendor/bin/sail bin pint` to fix any formatting issues. === pest/core rules === @@ -673,7 +911,7 @@ ### Testing - If you need to verify a feature is working, write or update a Unit / Feature test. ### Pest Tests -- All tests must be written using Pest. Use `php artisan make:test --pest {name}`. +- All tests must be written using Pest. Use `vendor/bin/sail artisan make:test --pest {name}`. - You must not remove any tests or test files from the tests directory without approval. These are not temporary or helper files - these are core to the application. - Tests should test all of the happy paths, failure paths, and weird paths. - Tests live in the `tests/Feature` and `tests/Unit` directories. @@ -686,9 +924,9 @@ ### Pest Tests ### Running Tests - Run the minimal number of tests using an appropriate filter before finalizing code edits. -- To run all tests: `php artisan test`. -- To run all tests in a file: `php artisan test tests/Feature/ExampleTest.php`. -- To filter on a particular test name: `php artisan test --filter=testName` (recommended after making a change to a related file). +- To run all tests: `vendor/bin/sail artisan test`. +- To run all tests in a file: `vendor/bin/sail artisan test tests/Feature/ExampleTest.php`. +- To filter on a particular test name: `vendor/bin/sail artisan test --filter=testName` (recommended after making a change to a related file). - When the tests relating to your changes are passing, ask the user if they would like to run the entire test suite to ensure everything is still passing. ### Pest Assertions diff --git a/GEMINI.md b/GEMINI.md index 220d86e..e1aafa1 100644 --- a/GEMINI.md +++ b/GEMINI.md @@ -226,6 +226,266 @@ ## Reference Materials === +=== .ai/filament-v5-blueprint rules === + +## Source of Truth +If any Filament behavior is uncertain, lookup the exact section in: +- docs/research/filament-v5-notes.md +and prefer that over guesses. + +# SECTION B — FILAMENT V5 BLUEPRINT (EXECUTABLE RULES) + +# Filament Blueprint (v5) + +## 1) Non-negotiables +- Filament v5 requires Livewire v4.0+. +- Laravel 11+: register panel providers in `bootstrap/providers.php` (never `bootstrap/app.php`). +- Global search hard rule: If a Resource should appear in Global Search, it must have an Edit or View page; otherwise it will return no results. +- Destructive actions must execute via `Action::make(...)->action(...)` and include `->requiresConfirmation()` (no exceptions). +- Prefer render hooks + CSS hook classes over publishing Filament internal views. + +Sources: +- https://filamentphp.com/docs/5.x/upgrade-guide +- https://filamentphp.com/docs/5.x/panel-configuration +- https://filamentphp.com/docs/5.x/resources/global-search +- https://filamentphp.com/docs/5.x/actions/modals +- https://filamentphp.com/docs/5.x/advanced/render-hooks +- https://filamentphp.com/docs/5.x/styling/css-hooks + +## 2) Directory & naming conventions +- Default to Filament discovery conventions for Resources/Pages/Widgets unless you adopt modular architecture. +- Clusters: directory layout is recommended, not mandatory; functional behavior depends on `$cluster`. + +Sources: +- https://filamentphp.com/docs/5.x/navigation/clusters +- https://filamentphp.com/docs/5.x/advanced/modular-architecture + +## 3) Panel setup defaults +- Default to a single `/admin` panel unless multiple audiences/configs demand multiple panels. +- Verify provider registration (Laravel 11+: `bootstrap/providers.php`) when adding a panel. +- Use `path()` carefully; treat `path('')` as a high-risk change requiring route conflict review. +- Assets policy: + - Panel-only assets: register via panel config. + - Shared/plugin assets: register via `FilamentAsset::register()`. + - Deployment must include `php artisan filament:assets`. + +Sources: +- https://filamentphp.com/docs/5.x/panel-configuration +- https://filamentphp.com/docs/5.x/advanced/assets + +## 4) Navigation & information architecture +- Use nav groups + sort order intentionally; apply conditional visibility for clarity, but enforce authorization separately. +- Use clusters to introduce hierarchy and sub-navigation when sidebar complexity grows. +- Treat cluster code structure as a recommendation (organizational benefit), not a required rule. +- User menu: + - Configure via `userMenuItems()` with Action objects. + - Never put destructive actions there without confirmation + authorization. + +Sources: +- https://filamentphp.com/docs/5.x/navigation/overview +- https://filamentphp.com/docs/5.x/navigation/clusters +- https://filamentphp.com/docs/5.x/navigation/user-menu + +## 5) Resource patterns +- Default to Resources for CRUD; use custom pages for non-CRUD tools/workflows. +- Global search: + - If a resource is intended for global search: ensure Edit/View page exists. + - Otherwise disable global search for that resource (don’t “expect it to work”). + - If global search renders relationship-backed details: eager-load via global search query override. + - For very large datasets: consider disabling term splitting (only when needed). + +Sources: +- https://filamentphp.com/docs/5.x/resources/overview +- https://filamentphp.com/docs/5.x/resources/global-search + +## 6) Page lifecycle & query rules +- Treat relationship-backed rendering in aggregate contexts (global search details, list summaries) as requiring eager loading. +- Prefer render hooks for layout injection; avoid publishing internal views. + +Sources: +- https://filamentphp.com/docs/5.x/resources/global-search +- https://filamentphp.com/docs/5.x/advanced/render-hooks + +## 7) Infolists vs RelationManagers (decision tree) +- Interactive CRUD / attach / detach under owner record → RelationManager. +- Pick existing related record(s) inside owner form → Select / CheckboxList relationship fields. +- Inline CRUD inside owner form → Repeater. +- Default performance stance: RelationManagers stay lazy-loaded unless explicit UX justification exists. + +Sources: +- https://filamentphp.com/docs/5.x/resources/managing-relationships +- https://filamentphp.com/docs/5.x/infolists/overview + +## 8) Form patterns (validation, reactivity, state) +- Default: minimize server-driven reactivity; only use it when schema/visibility/requirements must change server-side. +- Prefer “on blur” semantics for chatty inputs when using reactive behavior (per docs patterns). +- Custom field views must obey state binding modifiers. + +Sources: +- https://filamentphp.com/docs/5.x/forms/overview +- https://filamentphp.com/docs/5.x/forms/custom-fields + +## 9) Table & action patterns +- Tables: always define a meaningful empty state (and empty-state actions where appropriate). +- Actions: + - Execution actions use `->action(...)`. + - Destructive actions add `->requiresConfirmation()`. + - Navigation-only actions should use `->url(...)`. + - UNVERIFIED: do not assert modal/confirmation behavior for URL-only actions unless verified. + +Sources: +- https://filamentphp.com/docs/5.x/tables/empty-state +- https://filamentphp.com/docs/5.x/actions/modals + +## 10) Authorization & security +- Enforce panel access in non-local environments as documented. +- UI visibility is not security; enforce policies/access checks in addition to hiding UI. +- Bulk operations: explicitly decide between “Any” policy methods vs per-record authorization. + +Sources: +- https://filamentphp.com/docs/5.x/users/overview +- https://filamentphp.com/docs/5.x/resources/deleting-records + +## 11) Notifications & UX feedback +- Default to explicit success/error notifications for user-triggered mutations that aren’t instantly obvious. +- Treat polling as a cost; set intervals intentionally where polling is used. + +Sources: +- https://filamentphp.com/docs/5.x/notifications/overview +- https://filamentphp.com/docs/5.x/widgets/stats-overview + +## 12) Performance defaults +- Heavy assets: prefer on-demand loading (`loadedOnRequest()` + `x-load-css` / `x-load-js`) for heavy dependencies. +- Styling overrides use CSS hook classes; layout injection uses render hooks; avoid view publishing. + +Sources: +- https://filamentphp.com/docs/5.x/advanced/assets +- https://filamentphp.com/docs/5.x/styling/css-hooks +- https://filamentphp.com/docs/5.x/advanced/render-hooks + +## 13) Testing requirements +- Test pages/relation managers/widgets as Livewire components. +- Test actions using Filament’s action testing guidance. +- Do not mount non-Livewire classes in Livewire tests. + +Sources: +- https://filamentphp.com/docs/5.x/testing/overview +- https://filamentphp.com/docs/5.x/testing/testing-actions + +## 14) Forbidden patterns +- Mixing Filament v3/v4 APIs into v5 code. +- Any mention of Livewire v3 for Filament v5. +- Registering panel providers in `bootstrap/app.php` on Laravel 11+. +- Destructive actions without `->requiresConfirmation()`. +- Shipping heavy assets globally when on-demand loading fits. +- Publishing Filament internal views as a default customization technique. + +Sources: +- https://filamentphp.com/docs/5.x/upgrade-guide +- https://filamentphp.com/docs/5.x/panel-configuration +- https://filamentphp.com/docs/5.x/actions/modals +- https://filamentphp.com/docs/5.x/advanced/assets + +## 15) Agent output contract +For any implementation request, the agent must explicitly state: +1) Livewire v4.0+ compliance. +2) Provider registration location (Laravel 11+: `bootstrap/providers.php`). +3) For each globally searchable resource: whether it has Edit/View page (or global search is disabled). +4) Which actions are destructive and how confirmation + authorization is handled. +5) Asset strategy: global vs on-demand and where `filament:assets` runs in deploy. +6) Testing plan: which pages/widgets/relation managers/actions are covered. + +Sources: +- https://filamentphp.com/docs/5.x/upgrade-guide +- https://filamentphp.com/docs/5.x/panel-configuration +- https://filamentphp.com/docs/5.x/resources/global-search +- https://filamentphp.com/docs/5.x/advanced/assets +- https://filamentphp.com/docs/5.x/testing/testing-actions + + +=== .ai/filament-v5-checklist rules === + +# SECTION C — AI REVIEW CHECKLIST (STRICT CHECKBOXES) + +## Version Safety +- [ ] Filament v5 explicitly targets Livewire v4.0+ (no Livewire v3 references anywhere). + - Source: https://filamentphp.com/docs/5.x/upgrade-guide — “Upgrading Livewire” +- [ ] All references are Filament `/docs/5.x/` only (no v3/v4 docs, no legacy APIs). +- [ ] Upgrade assumptions match the v5 upgrade guide requirements and steps. + - Source: https://filamentphp.com/docs/5.x/upgrade-guide — “New requirements” + +## Panel & Navigation +- [ ] Laravel 11+: panel providers are registered in `bootstrap/providers.php` (not `bootstrap/app.php`). + - Source: https://filamentphp.com/docs/5.x/panel-configuration — “Creating a new panel” +- [ ] Panel `path()` choices are intentional and do not conflict with existing routes (especially `path('')`). + - Source: https://filamentphp.com/docs/5.x/panel-configuration — “Changing the path” +- [ ] Cluster usage is correctly configured (discovery + `$cluster` assignments). + - Source: https://filamentphp.com/docs/5.x/navigation/clusters — “Creating a cluster” +- [ ] Cluster semantics (sub-navigation + grouped navigation behavior) are understood and verified against the clusters docs. + - Source: https://filamentphp.com/docs/5.x/navigation/clusters — “Introduction” +- [ ] Cluster directory structure is treated as recommended, not mandatory. + - Source: https://filamentphp.com/docs/5.x/navigation/clusters — “Code structure recommendations for panels using clusters” +- [ ] User menu items are registered via `userMenuItems()` and permission-gated where needed. + - Source: https://filamentphp.com/docs/5.x/navigation/user-menu — “Introduction” + +## Resource Structure +- [ ] `$recordTitleAttribute` is set for any resource intended for global search. + - Source: https://filamentphp.com/docs/5.x/resources/overview — “Record titles” +- [ ] Hard rule enforced: every globally searchable resource has an Edit or View page; otherwise global search is disabled for it. + - Source: https://filamentphp.com/docs/5.x/resources/global-search — “Setting global search result titles” +- [ ] Relationship-backed global search details are eager-loaded via the global search query override. + - Source: https://filamentphp.com/docs/5.x/resources/global-search — “Adding extra details to global search results” + +## Infolists & Relations +- [ ] Each relationship uses the correct tool (RelationManager vs Select/CheckboxList vs Repeater) based on required interaction. + - Source: https://filamentphp.com/docs/5.x/resources/managing-relationships — “Choosing the right tool for the job” +- [ ] RelationManagers remain lazy-loaded by default unless there’s an explicit UX justification. + - Source: https://filamentphp.com/docs/5.x/resources/managing-relationships — “Disabling lazy loading” + +## Forms +- [ ] Server-driven reactivity is minimal; chatty inputs do not trigger network requests unnecessarily. + - Source: https://filamentphp.com/docs/5.x/forms/overview — “Reactive fields on blur” +- [ ] Custom field views obey state binding modifiers (no hardcoded `wire:model` without modifiers). + - Source: https://filamentphp.com/docs/5.x/forms/custom-fields — “Obeying state binding modifiers” + +## Tables & Actions +- [ ] Tables define a meaningful empty state (and empty-state actions where appropriate). + - Source: https://filamentphp.com/docs/5.x/tables/empty-state — “Adding empty state actions” +- [ ] All destructive actions execute via `->action(...)` and include `->requiresConfirmation()`. + - Source: https://filamentphp.com/docs/5.x/actions/modals — “Confirmation modals” +- [ ] No checklist rule assumes confirmation/modals for `->url(...)` actions unless verified in docs (UNVERIFIED behavior must not be asserted as fact). + - Source: https://filamentphp.com/docs/5.x/actions/modals — “Confirmation modals” + +## Authorization & Security +- [ ] Panel access is enforced for non-local environments as documented. + - Source: https://filamentphp.com/docs/5.x/users/overview — “Authorizing access to the panel” +- [ ] UI visibility is not treated as authorization; policies/access checks still enforce boundaries. +- [ ] Bulk operations intentionally choose between “Any” policy methods vs per-record authorization where required. + - Source: https://filamentphp.com/docs/5.x/resources/deleting-records — “Authorization” + +## UX & Notifications +- [ ] User-triggered mutations provide explicit success/error notifications when outcomes aren’t instantly obvious. + - Source: https://filamentphp.com/docs/5.x/notifications/overview — “Introduction” +- [ ] Polling (widgets/notifications) is configured intentionally (interval set or disabled) to control load. + - Source: https://filamentphp.com/docs/5.x/widgets/stats-overview — “Live updating stats (polling)” + +## Performance +- [ ] Heavy frontend assets are loaded on-demand using `loadedOnRequest()` + `x-load-css` / `x-load-js` where appropriate. + - Source: https://filamentphp.com/docs/5.x/advanced/assets — “Lazy loading CSS” / “Lazy loading JavaScript” +- [ ] Styling overrides use CSS hook classes discovered via DevTools (no brittle selectors by default). + - Source: https://filamentphp.com/docs/5.x/styling/css-hooks — “Discovering hook classes” + +## Testing +- [ ] Livewire tests mount Filament pages/relation managers/widgets (Livewire components), not static resource classes. + - Source: https://filamentphp.com/docs/5.x/testing/overview — “What is a Livewire component when using Filament?” +- [ ] Actions that mutate data are covered using Filament’s action testing guidance. + - Source: https://filamentphp.com/docs/5.x/testing/testing-actions — “Testing actions” + +## Deployment / Ops +- [ ] `php artisan filament:assets` is included in the deployment process when using registered assets. + - Source: https://filamentphp.com/docs/5.x/advanced/assets — “The FilamentAsset facade” + + === foundation rules === # Laravel Boost Guidelines @@ -236,10 +496,10 @@ ## 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.4.15 -- filament/filament (FILAMENT) - v4 +- filament/filament (FILAMENT) - v5 - laravel/framework (LARAVEL) - v12 - laravel/prompts (PROMPTS) - v0 -- livewire/livewire (LIVEWIRE) - v3 +- livewire/livewire (LIVEWIRE) - v4 - laravel/mcp (MCP) - v0 - laravel/pint (PINT) - v1 - laravel/sail (SAIL) - v1 @@ -260,7 +520,7 @@ ## Application Structure & Architecture - 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 `npm run build`, `npm run dev`, or `composer run dev`. Ask them. +- 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. ## Replies - Be concise in your explanations - focus on what's important rather than explaining obvious details. @@ -338,20 +598,35 @@ ## Enums - Typically, keys in an Enum should be TitleCase. For example: `FavoritePerson`, `BestLake`, `Monthly`. +=== 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. + + === tests rules === ## Test Enforcement - Every change must be programmatically tested. Write a new test or update an existing test, then run the affected tests to make sure they pass. -- Run the minimum number of tests needed to ensure code quality and speed. Use `php artisan test` with a specific filename or filter. +- Run the minimum number of tests needed to ensure code quality and speed. Use `vendor/bin/sail artisan test` with a specific filename or filter. === laravel/core rules === ## Do Things the Laravel Way -- Use `php artisan make:` commands to create new files (i.e. migrations, controllers, models, etc.). You can list available Artisan commands using the `list-artisan-commands` tool. -- If you're creating a generic PHP class, use `php artisan make:class`. +- Use `vendor/bin/sail artisan make:` commands to create new files (i.e. migrations, controllers, models, etc.). You can list available Artisan commands using the `list-artisan-commands` tool. +- 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. ### Database @@ -362,7 +637,7 @@ ### Database - Use Laravel's query builder for very complex database operations. ### Model Creation -- When creating new models, create useful factories and seeders for them too. Ask the user if they need any other things, using `list-artisan-commands` to check the available options to `php artisan make:model`. +- When creating new models, create useful factories and seeders for them too. Ask the user if they need any other things, using `list-artisan-commands` to check the available options to `vendor/bin/sail artisan make:model`. ### 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. @@ -386,10 +661,10 @@ ### Configuration ### 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 `php artisan make:test [options] {name}` to create a feature test, and pass `--unit` to create a unit test. Most tests should be feature tests. +- 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 `npm run build` or ask the user to run `npm run dev` or `composer run dev`. +- 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`. === laravel/v12 rules === @@ -418,7 +693,7 @@ ### Models ## Livewire Core - Use the `search-docs` tool to find exact version specific documentation for how to write Livewire & Livewire tests. -- Use the `php artisan make:livewire [Posts\CreatePost]` artisan command to create new components +- Use the `vendor/bin/sail artisan make:livewire [Posts\CreatePost]` artisan command to create new components - State should live on the server, with the UI reflecting it. - All Livewire requests hit the Laravel backend, they're like regular HTTP requests. Always validate form data, and run authorization checks in Livewire actions. @@ -461,48 +736,12 @@ ## Testing Livewire -=== livewire/v3 rules === - -## Livewire 3 - -### Key Changes From Livewire 2 -- These things changed in Livewire 2, but may not have been updated in this application. Verify this application's setup to ensure you conform with application conventions. - - Use `wire:model.live` for real-time updates, `wire:model` is now deferred by default. - - Components now use the `App\Livewire` namespace (not `App\Http\Livewire`). - - Use `$this->dispatch()` to dispatch events (not `emit` or `dispatchBrowserEvent`). - - Use the `components.layouts.app` view as the typical layout path (not `layouts.app`). - -### New Directives -- `wire:show`, `wire:transition`, `wire:cloak`, `wire:offline`, `wire:target` are available for use. Use the documentation to find usage examples. - -### Alpine -- Alpine is now included with Livewire, don't manually include Alpine.js. -- Plugins included with Alpine: persist, intersect, collapse, and focus. - -### Lifecycle Hooks -- You can listen for `livewire:init` to hook into Livewire initialization, and `fail.status === 419` for the page expiring: - - -document.addEventListener('livewire:init', function () { - Livewire.hook('request', ({ fail }) => { - if (fail && fail.status === 419) { - alert('Your session expired'); - } - }); - - Livewire.hook('message.failed', (message, component) => { - console.error(message); - }); -}); - - - === pint/core rules === ## Laravel Pint Code Formatter -- You must run `vendor/bin/pint --dirty` before finalizing changes to ensure your code matches the project's expected style. -- Do not run `vendor/bin/pint --test`, simply run `vendor/bin/pint` to fix any formatting issues. +- You must run `vendor/bin/sail bin pint --dirty` before finalizing changes to ensure your code matches the project's expected style. +- Do not run `vendor/bin/sail bin pint --test`, simply run `vendor/bin/sail bin pint` to fix any formatting issues. === pest/core rules === @@ -512,7 +751,7 @@ ### Testing - If you need to verify a feature is working, write or update a Unit / Feature test. ### Pest Tests -- All tests must be written using Pest. Use `php artisan make:test --pest {name}`. +- All tests must be written using Pest. Use `vendor/bin/sail artisan make:test --pest {name}`. - You must not remove any tests or test files from the tests directory without approval. These are not temporary or helper files - these are core to the application. - Tests should test all of the happy paths, failure paths, and weird paths. - Tests live in the `tests/Feature` and `tests/Unit` directories. @@ -525,9 +764,9 @@ ### Pest Tests ### Running Tests - Run the minimal number of tests using an appropriate filter before finalizing code edits. -- To run all tests: `php artisan test`. -- To run all tests in a file: `php artisan test tests/Feature/ExampleTest.php`. -- To filter on a particular test name: `php artisan test --filter=testName` (recommended after making a change to a related file). +- To run all tests: `vendor/bin/sail artisan test`. +- To run all tests in a file: `vendor/bin/sail artisan test tests/Feature/ExampleTest.php`. +- To filter on a particular test name: `vendor/bin/sail artisan test --filter=testName` (recommended after making a change to a related file). - When the tests relating to your changes are passing, ask the user if they would like to run the entire test suite to ensure everything is still passing. ### Pest Assertions diff --git a/boost.json b/boost.json index e337384..0a16d2e 100644 --- a/boost.json +++ b/boost.json @@ -1,7 +1,16 @@ { "agents": [ "codex", + "copilot", + "gemini", "opencode" ], - "guidelines": [] + "editors": [ + "codex", + "gemini", + "opencode", + "vscode" + ], + "guidelines": [], + "sail": true } diff --git a/docs/research/filament-v5-notes.md b/docs/research/filament-v5-notes.md new file mode 100644 index 0000000..c7dc91a --- /dev/null +++ b/docs/research/filament-v5-notes.md @@ -0,0 +1,114 @@ +# SECTION A — FILAMENT V5 NOTES (BULLETS + SOURCES) + +## Versioning & Base Requirements +- Rule: Filament v5 requires Livewire v4.0+. + When: Always when installing/upgrading Filament v5. When NOT: Never target Livewire v3 in a v5 codebase. + Source: https://filamentphp.com/docs/5.x/upgrade-guide — “Upgrading Livewire” + +## Panels — Configuration +- Rule: Panels are configured via dedicated panel providers; the default admin panel ships at `/admin`. + When: Always—centralize panel setup (resources/pages/widgets/plugins) here. When NOT: Don’t scatter core panel configuration across unrelated providers. + Source: https://filamentphp.com/docs/5.x/panel-configuration — “The default admin panel” +- Rule: New panel providers must be registered in `bootstrap/providers.php` for Laravel 11+ (or `config/app.php` for Laravel 10 and below). + When: When adding a new panel or if panel creation didn’t auto-register. When NOT: Don’t register panel providers in `bootstrap/app.php`. + Source: https://filamentphp.com/docs/5.x/panel-configuration — “Creating a new panel” +- Rule: Use `path()` to change a panel’s URL prefix; `path('')` mounts at `/` and can conflict with existing routes. + When: When `/admin` is not desired. When NOT: Don’t set `path('')` if `/` is already routed in `routes/web.php`. + Source: https://filamentphp.com/docs/5.x/panel-configuration — “Changing the path” +- Rule: Use render hooks to inject Blade content into Filament layouts without publishing internal views. + When: When inserting banners/scripts/partials into specific layout locations. When NOT: Don’t publish Filament views for small layout tweaks. + Source: https://filamentphp.com/docs/5.x/advanced/render-hooks — “Registering render hooks” + +## Navigation — Groups, Ordering, Visibility +- Rule: Navigation is built from resources/pages/clusters and can be grouped, sorted, and conditionally shown/hidden. + When: Always—use groups/sorting for predictable IA. When NOT: Don’t treat “hidden navigation” as authorization; still enforce policies/access checks. + Source: https://filamentphp.com/docs/5.x/navigation/overview — “Introduction” +- Rule: Clusters group resources/pages under a single nav item and provide sub-navigation. + When: When the sidebar becomes too large and needs hierarchy. When NOT: Don’t cluster if it reduces discoverability for your users. + Source: https://filamentphp.com/docs/5.x/navigation/clusters — “Introduction” +- Rule: Cluster code structure (moving pages/resources into a cluster directory) is recommended, not required; behavior depends on `$cluster`. + When: When you want consistent organization. When NOT: Don’t treat the directory layout as mandatory. + Source: https://filamentphp.com/docs/5.x/navigation/clusters — “Code structure recommendations for panels using clusters” +- Rule: The user menu is configured via `userMenuItems()` with Action objects and supports conditional visibility and sidebar placement. + When: When adding account-related links/actions. When NOT: Don’t put destructive actions there without confirmation + authorization. + Source: https://filamentphp.com/docs/5.x/navigation/user-menu — “Introduction” + +## Theming & Branding — CSS Hooks, Colors, Icons +- Rule: Filament exposes CSS hook classes (prefixed `fi-`) and recommends discovering them via browser DevTools. + When: When styling core UI safely. When NOT: Don’t rely on brittle selectors; request/PR missing hooks instead of hacking around them. + Source: https://filamentphp.com/docs/5.x/styling/css-hooks — “Discovering hook classes” +- Rule: Apply styling by targeting hook classes (including Tailwind `@apply`) and use `!important` sparingly. + When: When overriding default spacing/appearance in a maintainable way. When NOT: Don’t blanket `!important` your theme. + Source: https://filamentphp.com/docs/5.x/styling/css-hooks — “Applying styles to hook classes” +- Rule: Customize the default semantic color palettes via `FilamentColor::register()` (e.g., primary, danger, etc.). + When: When aligning Filament semantics to your brand palette. When NOT: Don’t hardcode per-component hex values when semantics suffice. + Source: https://filamentphp.com/docs/5.x/styling/colors — “Customizing the default colors” +- Rule: Replace default UI icons globally via `FilamentIcon::register()` (icon aliases map to your chosen icons). + When: When standardizing iconography or switching icon sets. When NOT: Don’t hardcode SVGs everywhere when aliases cover the UI. + Source: https://filamentphp.com/docs/5.x/styling/icons — “Replacing the default icons” + +## Asset System — Global + Lazy / On-Demand +- Rule: Register shared assets via `FilamentAsset::register()`; assets are published into `/public` when `php artisan filament:assets` runs. + When: For app/plugin assets loaded by Filament. When NOT: Don’t assume assets exist in production without the publish step. + Source: https://filamentphp.com/docs/5.x/advanced/assets — “The FilamentAsset facade” +- Rule: Lazy-load CSS with `x-load-css` and prevent auto-loading via `loadedOnRequest()` for page-specific styles. + When: For heavy CSS used only on certain pages/components. When NOT: Don’t lazy-load tiny styles used everywhere. + Source: https://filamentphp.com/docs/5.x/advanced/assets — “Lazy loading CSS” +- Rule: Lazy-load JavaScript with `x-load-js` and prevent auto-loading via `loadedOnRequest()` for page-specific scripts. + When: For heavy JS libraries used only on a subset of pages/widgets. When NOT: Don’t lazy-load scripts required for baseline panel behavior. + Source: https://filamentphp.com/docs/5.x/advanced/assets — “Lazy loading JavaScript” + +## Plugin System — Mechanics + Panel Scoping +- Rule: Panel plugins integrate via a Plugin object; standalone plugins integrate via a service provider (no panel binding). + When: When deciding whether a package needs panel-specific registration. When NOT: Don’t force a Plugin object for standalone-only components. + Source: https://filamentphp.com/docs/5.x/plugins/getting-started — “The Plugin object” +- Rule: Plugin assets should be registered in the plugin’s service provider so Filament can manage publishing/loading. + When: When shipping CSS/JS/Alpine components with a package. When NOT: Don’t register package assets ad-hoc only in app panel providers. + Source: https://filamentphp.com/docs/5.x/plugins/getting-started — “Registering assets” +- Rule: Panel-scoped module/plugin registration can be centralized using `Panel::configureUsing()` for modular architectures. + When: When modules should enable Filament artifacts only for specific panels. When NOT: Don’t register all modules globally if panels target different audiences. + Source: https://filamentphp.com/docs/5.x/advanced/modular-architecture — “Registering plugins conditionally for specific panels” +- Rule: Panel plugins are configurable per panel; treat “enabled in panel A” and “enabled in panel B” as independent configuration contexts. + When: When the same app has multiple panels with different modules enabled. When NOT: Don’t assume a plugin is active across all panels. + Source: https://filamentphp.com/docs/5.x/plugins/panel-plugins — “Introduction” + +## Actions — Modals, Confirmation, Execution +- Rule: Use `Action::make(...)->action(...)` to execute logic; use `requiresConfirmation()` for confirmation modals. + When: For destructive or high-impact actions. When NOT: Don’t skip confirmation for destructive operations. + Source: https://filamentphp.com/docs/5.x/actions/modals — “Confirmation modals” +- Rule: Action modals can render a schema to collect input; submitted modal data is available to the action handler. + When: When you need “form-in-action” workflows. When NOT: Don’t create bespoke modals when schema-in-modal is sufficient. + Source: https://filamentphp.com/docs/5.x/actions/modals — “Rendering a form in a modal” + +## Resources & Pages — Global Search, Queries +- Rule: Global search returns results for a resource only if it has an Edit or View page; otherwise the resource returns no results. + When: When enabling global search for a resource. When NOT: Don’t expect global search on resources without Edit/View pages. + Source: https://filamentphp.com/docs/5.x/resources/global-search — “Setting global search result titles” +- Rule: If global search result details access relationships, override the global search query to eager-load them to avoid N+1. + When: Any time you return relationship-backed details. When NOT: Don’t lazy-load relationships in global search rendering. + Source: https://filamentphp.com/docs/5.x/resources/global-search — “Adding extra details to global search results” +- Rule: You can disable search term splitting for performance on large datasets. + When: When global search becomes expensive. When NOT: Don’t disable if multi-word relevance is important. + Source: https://filamentphp.com/docs/5.x/resources/global-search — “Disabling search term splitting” + +## Tables — Empty States +- Rule: Tables support empty-state content and can add empty-state actions to guide first-time users. + When: Always—empty-state guidance improves “first run” UX. When NOT: Don’t leave empty lists without a clear next step when creation is expected. + Source: https://filamentphp.com/docs/5.x/tables/empty-state — “Adding empty state actions” + +## Testing +- Rule: Filament testing distinguishes Livewire components (pages/relation managers/widgets) from non-Livewire classes (resources/actions/schema objects). + When: When choosing what to mount with `Livewire::test()`. When NOT: Don’t try to Livewire-test non-Livewire classes directly. + Source: https://filamentphp.com/docs/5.x/testing/overview — “What is a Livewire component when using Filament?” +- Rule: Actions have dedicated testing guidance; follow it for asserting action execution and side effects. + When: When actions drive critical business workflows. When NOT: Don’t leave actions untested if they mutate data or trigger external effects. + Source: https://filamentphp.com/docs/5.x/testing/testing-actions — “Testing actions” + +## OPINIONATED — best practices not explicitly mandated by docs +- Rule: Standardize destructive actions: danger styling + requiresConfirmation() + policy authorization + success/error notification. + When: For delete/force-delete/restore/bulk destructive ops. When NOT: For trivial, reversible toggles. + +## UNVERIFIED — not explicitly stated in the cited v5 pages above +- Rule: If you need confirmation or a modal, prefer `->action(...)` + `->requiresConfirmation()`; use `->url(...)` for navigation links. + When: When deciding whether an action should execute vs navigate. When NOT: Don’t assume modal/confirmation behavior for URL-only actions without verifying in docs. + Source: https://filamentphp.com/docs/5.x/actions/modals — “Confirmation modals” \ No newline at end of file diff --git a/opencode.json b/opencode.json new file mode 100644 index 0000000..6f800ed --- /dev/null +++ b/opencode.json @@ -0,0 +1,14 @@ +{ + "$schema": "https://opencode.ai/config.json", + "mcp": { + "laravel-boost": { + "type": "local", + "enabled": true, + "command": [ + "vendor/bin/sail", + "artisan", + "boost:mcp" + ] + } + } +} \ No newline at end of file