From 9c15e43e918ab2897acbb21ebbd2007746dab53c Mon Sep 17 00:00:00 2001 From: Paulo Castellano Date: Wed, 10 Jun 2026 14:22:16 -0300 Subject: [PATCH 1/2] Add Copilot code review instructions --- .github/copilot-instructions.md | 39 +++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 .github/copilot-instructions.md diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md new file mode 100644 index 00000000..0b5fe34b --- /dev/null +++ b/.github/copilot-instructions.md @@ -0,0 +1,39 @@ +# TryPost — Code Review Instructions + +Laravel 13 + Inertia 3 (Vue 3 + TypeScript) + Tailwind 4 app. Flag violations of these project conventions. Prioritize correctness, security, and these rules over style nits the linters (Pint/ESLint) already catch. Cite `file:line`. + +## Backend (PHP / Laravel) + +- Validation MUST live in a `FormRequest` subclass under `app/Http/Requests/App//` (or `Api/`), type-hinted in the controller action. Flag any inline `$request->validate([...])` in controllers. +- JSON API responses MUST use an Eloquent API Resource (`JsonResource`). Flag `response()->json([...])` that maps models inline. +- In Action/service classes, use `data_get($data, 'key', $default)` — flag direct array access like `$data['key']`. +- Use `Symfony\Component\HttpFoundation\Response` constants (e.g. `Response::HTTP_CREATED`), never magic numbers like `201`. +- Imports at the top via `use`; flag inline refs like `\DB::`, `\Str::`. +- Prefer double-quoted interpolation with curly braces: `"workspace.{$id}"`, not `'workspace.'.$id`. +- Schema changes go in NEW migrations — the app is in production. Flag edits to existing migration files. +- Never pass a disk name to `Storage::` or `->store()` — use the framework default. +- Third-party API hosts / OAuth URLs come from `config/trypost.php` (`platforms.`). Flag hardcoded hosts like `https://api.x.com`. +- PHP 8: constructor property promotion, explicit return types + param type hints, `declare(strict_types=1)`, curly braces on all control structures. +- AI agent prompts live in Blade under `resources/views/prompts/`. Flag heredocs/long string prompts inside `instructions()`. + +## Frontend (Vue / TypeScript) + +- Arrow functions only — flag `function` declarations. +- Icons from `@tabler/icons-vue` (Icon-prefixed). Flag `lucide-vue-next`. +- Dates: use `@/dayjs` and `@/date` helpers — flag raw `new Date()`. +- Routes: use Wayfinder helpers (from `@/routes` / `@/actions`) — flag hardcoded URL strings like `href="/register"`. +- No HTML5 validation attributes (`required`, `minlength`, `pattern`, ...) — rely on backend validation. +- Vue components must have a single root element. + +## Pagination + +- Use `->paginate()` (never `cursorPaginate()`). Lists use Inertia scroll (`Inertia::scroll()` + ``) — flag 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 via `@dusk` selectors, not CSS classes or text. + +## Git + +- No `Co-Authored-By` lines or AI attribution in commit messages or PR descriptions. From bcefe66da227cff9037c6c2fa9f25520226cd62e Mon Sep 17 00:00:00 2001 From: Paulo Castellano Date: Wed, 10 Jun 2026 14:26:54 -0300 Subject: [PATCH 2/2] Enrich Copilot review instructions with examples and missing conventions --- .github/copilot-instructions.md | 60 ++++++++++++++++++--------------- 1 file changed, 33 insertions(+), 27 deletions(-) diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md index 0b5fe34b..b27105bc 100644 --- a/.github/copilot-instructions.md +++ b/.github/copilot-instructions.md @@ -1,39 +1,45 @@ # TryPost — Code Review Instructions -Laravel 13 + Inertia 3 (Vue 3 + TypeScript) + Tailwind 4 app. Flag violations of these project conventions. Prioritize correctness, security, and these rules over style nits the linters (Pint/ESLint) already catch. Cite `file:line`. - -## Backend (PHP / Laravel) - -- Validation MUST live in a `FormRequest` subclass under `app/Http/Requests/App//` (or `Api/`), type-hinted in the controller action. Flag any inline `$request->validate([...])` in controllers. -- JSON API responses MUST use an Eloquent API Resource (`JsonResource`). Flag `response()->json([...])` that maps models inline. -- In Action/service classes, use `data_get($data, 'key', $default)` — flag direct array access like `$data['key']`. -- Use `Symfony\Component\HttpFoundation\Response` constants (e.g. `Response::HTTP_CREATED`), never magic numbers like `201`. -- Imports at the top via `use`; flag inline refs like `\DB::`, `\Str::`. -- Prefer double-quoted interpolation with curly braces: `"workspace.{$id}"`, not `'workspace.'.$id`. -- Schema changes go in NEW migrations — the app is in production. Flag edits to existing migration files. -- Never pass a disk name to `Storage::` or `->store()` — use the framework default. -- Third-party API hosts / OAuth URLs come from `config/trypost.php` (`platforms.`). Flag hardcoded hosts like `https://api.x.com`. -- PHP 8: constructor property promotion, explicit return types + param type hints, `declare(strict_types=1)`, curly braces on all control structures. -- AI agent prompts live in Blade under `resources/views/prompts/`. Flag heredocs/long string prompts inside `instructions()`. +Laravel 13 + Inertia 3 (Vue 3 + TypeScript) + Tailwind 4, PHP 8.4, Pest 4. Flag violations of these project conventions; cite `file:line`. Skip nits the linters (Pint/ESLint) already catch. -## Frontend (Vue / TypeScript) +## Backend validation +- Validation MUST live in a `FormRequest` subclass under `app/Http/Requests/App//` (or `Api/`), type-hinted in the controller action. Name `Request` (e.g. `StorePostRequest`). Flag any inline `$request->validate([...])` in a controller. + +## Eloquent & responses +- API JSON MUST go through an Eloquent API Resource (`JsonResource`). Flag `response()->json([...])` that maps models inline. +- Explicit status codes use `Symfony\Component\HttpFoundation\Response` constants — `Response::HTTP_CREATED`, never `201`. + +## 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.`), never hardcoded (e.g. `https://api.x.com`). Tests must `Http::fake` the same `config(...)` 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 under `resources/views/prompts/`; return `view('prompts....', [...])->render()` passing only needed vars. + +## Frontend (Vue / TypeScript) - Arrow functions only — flag `function` declarations. -- Icons from `@tabler/icons-vue` (Icon-prefixed). Flag `lucide-vue-next`. -- Dates: use `@/dayjs` and `@/date` helpers — flag raw `new Date()`. -- Routes: use Wayfinder helpers (from `@/routes` / `@/actions`) — flag hardcoded URL strings like `href="/register"`. -- No HTML5 validation attributes (`required`, `minlength`, `pattern`, ...) — rely on backend validation. -- Vue components must have a single root element. +- Icons from `@tabler/icons-vue` (Icon-prefixed, e.g. `IconCheck`). Flag `lucide-vue-next`. +- Dates: `@/dayjs` for calculation, `@/date` for display formatting — flag raw `new Date()`. +- Routes: Wayfinder helpers from `@/routes` / `@/actions` — flag hardcoded URLs like `href="/register"`. After route/controller changes, `wayfinder:generate` must 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. +- ``: primary action button FIRST in the markup, then cancel/secondary. ## Pagination - -- Use `->paginate()` (never `cursorPaginate()`). Lists use Inertia scroll (`Inertia::scroll()` + ``) — flag page-number/link pagination. +- Use `->paginate()` only (never `cursorPaginate()`). Paginated lists use Inertia scroll (`Inertia::scroll()` + ``) — 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 via `@dusk` selectors, not CSS classes or text. +- 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 `@dusk` selectors, never CSS classes, tags, or text. ## Git - - No `Co-Authored-By` lines or AI attribution in commit messages or PR descriptions.