docs: update CLAUDE.md with first-time setup instructions and enhance response helpers documentation
This commit is contained in:
@@ -16,6 +16,15 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co
|
||||
|
||||
All commands run inside ddev: prefix with `ddev exec` unless noted.
|
||||
|
||||
### First-time setup
|
||||
```bash
|
||||
ddev exec composer install
|
||||
ddev exec php bin/console lexik:jwt:generate-keypair # generate JWT keys
|
||||
ddev exec php bin/console doctrine:migrations:migrate --no-interaction
|
||||
ddev exec yarn install && ddev exec yarn dev
|
||||
ddev exec php bin/console app:create-admin # create first admin user
|
||||
```
|
||||
|
||||
### Backend (PHP/Symfony)
|
||||
```bash
|
||||
ddev exec php bin/console cache:clear
|
||||
@@ -28,7 +37,7 @@ ddev exec php bin/console messenger:consume async # start q
|
||||
ddev exec php bin/phpunit
|
||||
ddev exec php bin/phpunit tests/SomeTest.php # single test file
|
||||
|
||||
# Static analysis
|
||||
# Static analysis (level 5, with Symfony + Doctrine extensions)
|
||||
ddev exec php vendor/bin/phpstan analyse
|
||||
```
|
||||
|
||||
@@ -63,13 +72,16 @@ src/
|
||||
Shared/Constant/ErrorCodes.php
|
||||
```
|
||||
|
||||
**Every controller extends `BaseController`** which provides three response helpers:
|
||||
**Every controller extends `BaseController`** which provides four response helpers:
|
||||
|
||||
| Method | Shape | When to use |
|
||||
|--------|-------|-------------|
|
||||
| `$this->success($data)` | `{ success, data: $data }` | Single resource / action |
|
||||
| `$this->paginated($items, $total, $page, $limit)` | `{ success, data: $items[], meta: { totalRecords, totalPages, currentPage } }` | Admin list endpoints |
|
||||
| `$this->error($code, $message, $status)` | `{ success:false, errors:[{code,message}] }` | All error responses |
|
||||
| `$this->validationError($violations)` | `{ success:false, errors:[{code,field,message}] }` HTTP 422 | Input validation failures |
|
||||
|
||||
**Domain exceptions:** throw `AppException(ErrorCodes::ERR_XXX, null, $httpStatus)` anywhere in the domain — `ExceptionSubscriber` catches it and calls `$this->error()` automatically. All error codes and their Persian messages live in `src/Shared/Constant/ErrorCodes.php`.
|
||||
|
||||
**Critical pitfall — double-nested responses:**
|
||||
`$this->success(['data' => $rep->toArray()])` produces `{ data: { data: {...} } }`, so the frontend must extract with `data?.data?.data`. The `paginated()` helper does NOT nest — it returns `data` as a flat array.
|
||||
@@ -82,11 +94,17 @@ Single-page app mounted at `/admin/*`:
|
||||
assets/admin/
|
||||
App.tsx # React Router routes
|
||||
pages/ # one file per page
|
||||
components/ui/ # DataTable, Modal, ConfirmDialog, PageHeader, StatusBadge, Pagination
|
||||
components/
|
||||
ui/ # DataTable, Modal, ConfirmDialog, PageHeader, StatusBadge, Pagination,
|
||||
# SearchableSelect, PersianDateInput, PersianCalendar, AppointmentStatusDropdown
|
||||
layout/ # AdminLayout, Sidebar, Topbar
|
||||
hooks/ # custom React hooks
|
||||
lib/api.ts # fetch wrapper (reads JWT from localStorage key: clinicpro-auth)
|
||||
lib/utils.ts # formatRial, formatNumber, formatDate, formatDateTime
|
||||
types/index.ts # all TypeScript interfaces
|
||||
stores/authStore.ts # Zustand auth store (persisted to localStorage)
|
||||
stores/
|
||||
authStore.ts # Zustand auth store (persisted to localStorage)
|
||||
uiStore.ts # sidebar open/close state
|
||||
```
|
||||
|
||||
**Data fetching pattern:** TanStack Query v5 (`useQuery` / `useMutation`). Query keys use `['resource-name', page, filters]`.
|
||||
|
||||
Reference in New Issue
Block a user