Bump pestphp/pest, pest-plugin-laravel, and pest-plugin-browser to ^5.0. pest-plugin-laravel v5 requires Laravel ^13.23, so the framework lock is updated accordingly. Refresh agent docs/skills for the Pest 5 / PHPUnit 13 baseline. Co-authored-by: Paulo Castellano <hello@paulocastellano.com>
3.4 KiB
3.4 KiB
TryPost — Code Review Instructions
Laravel 13 + Inertia 3 (Vue 3 + TypeScript) + Tailwind 4, PHP 8.4, Pest 5. Flag violations of these project conventions; cite file:line. Skip nits the linters (Pint/ESLint) already catch.
Backend validation
- Validation MUST live in a
FormRequestsubclass underapp/Http/Requests/App/<Group>/(orApi/), type-hinted in the controller action. Name<Verb><Resource>Request(e.g.StorePostRequest). Flag any inline$request->validate([...])in a controller.
Eloquent & responses
- API JSON MUST go through an Eloquent API Resource (
JsonResource). Flagresponse()->json([...])that maps models inline. - Explicit status codes use
Symfony\Component\HttpFoundation\Responseconstants —Response::HTTP_CREATED, never201.
PHP idioms
- In Action/service classes use
data_get($data, 'key', $default)— flag direct$data['key']or$data['k'] ?? $x. - Imports at the top via
use; flag inline refs like\DB::,\Str::uuid(). - Double-quoted interpolation with curly braces:
"workspace.{$id}", not'workspace.'.$id. - Constructor property promotion; explicit return types + param type hints;
declare(strict_types=1); curly braces on every control structure (even one-liners); TitleCase enum keys; prefer PHPDoc (with array-shape types) over inline comments.
Migrations (app is in production)
- Schema changes go in NEW migrations. Flag any edit to an existing migration file.
Storage & external URLs
- Never pass a disk name to
Storage::or->store()— use the default disk. - Third-party API hosts / OAuth endpoints come from
config/trypost.php(platforms.<name>), never hardcoded (e.g.https://api.x.com). Tests mustHttp::fakethe sameconfig(...)value, not a literal URL. Only the host is config; protocol path segments (/oauth2/token) stay inline.
AI agents (app/Ai/Agents)
- Never embed prompts in PHP (heredocs / long string literals in
instructions()). Instruction text lives in Blade underresources/views/prompts/; returnview('prompts....', [...])->render()passing only needed vars.
Frontend (Vue / TypeScript)
- Arrow functions only — flag
functiondeclarations. - Icons from
@tabler/icons-vue(Icon-prefixed, e.g.IconCheck). Flaglucide-vue-next. - Dates:
@/dayjsfor calculation,@/datefor display formatting — flag rawnew Date(). - Routes: Wayfinder helpers from
@/routes/@/actions— flag hardcoded URLs likehref="/register". After route/controller changes,wayfinder:generatemust be run. - No HTML5 validation attributes (
required,minlength,pattern, …) — rely solely on backend validation. - Vue components have a single root element. Reuse existing components/composables before adding new ones.
<DialogFooter>: primary action button FIRST in the markup, then cancel/secondary.
Pagination
- Use
->paginate()only (nevercursorPaginate()). Paginated lists use Inertia scroll (Inertia::scroll()+<InfiniteScroll>) — flag traditional page-number/link pagination.
Tests (required)
- Every behavioral change needs a test, new or updated. Flag logic changes shipped without tests.
- Feature & Dusk tests MUST use named routes via
route('...')— flag hardcoded URL strings. Dusk interacts/asserts via@duskselectors, never CSS classes, tags, or text.
Git
- No
Co-Authored-Bylines or AI attribution in commit messages or PR descriptions.