Mirrors the frontend catch-up in 570f17e: a substantial amount of
finished-but-never-committed backend work had accumulated locally.
- New CustomField module: admin-managed field definitions per client,
reorderable, typed values stored per client (backing the frontend's
ClientCustomFieldCard + settings/fields page)
- History entries switch from a hardcoded type enum to a dynamic,
admin-managed HistoryType module (reorderable, backing
settings/history-types)
- New Import module: CSV client import (backing settings/import)
- Clients table gains soft deletes (deleted_at)
- Supporting factories, seeders, policies, and feature tests for all
of the above
All 63 backend tests pass locally before this commit.
34 lines
1.4 KiB
Markdown
34 lines
1.4 KiB
Markdown
# Backend — Laravel 10
|
|
|
|
## Module pattern
|
|
Every feature lives in `app/Modules/<Name>/`:
|
|
- `Controllers/<Name>Controller.php` — thin: authorize → DTO → action → resource
|
|
- `Actions/Create<Name>Action.php` — handle(DTO): Model
|
|
- `Actions/Update<Name>Action.php` — handle(Model, DTO): Model
|
|
- `Models/<Name>.php` — Eloquent model
|
|
- `Resources/<Name>Resource.php` — explicit field list, no `$this->resource`
|
|
- `DTOs/<Name>Data.php` — readonly constructor + static `fromRequest()`
|
|
- `Requests/Create<Name>Request.php` / `Update<Name>Request.php`
|
|
- `Policies/<Name>Policy.php`
|
|
|
|
## Commands
|
|
```
|
|
composer test # Pest, SQLite in-memory
|
|
composer static-analysis # pint --test + phpstan + phpmd (user do the static code analysis manually)
|
|
php artisan migrate # run migrations (against Docker MySQL)
|
|
```
|
|
|
|
## DB schema
|
|
- `users`: id, name, email, password, role(enum:admin|staff), timestamps
|
|
- `clients`: id, client_number(unique), name, notes(JSON), timestamps
|
|
- `history_entries`: id, client_id(FK), type(enum), body(text), author_id(FK), updated_by(FK nullable), deleted_at, timestamps
|
|
|
|
## Auth
|
|
- Sanctum SPA cookie sessions — `EnsureFrontendRequestsAreStateful` on `api` middleware group
|
|
- Filament: `web` guard, `/admin/login`
|
|
- No Passport, no tokens
|
|
|
|
## API conventions
|
|
- Resources always wrap in `data` key (JsonResource default)
|
|
- Paginated lists: `data[]` + `meta.total` etc.
|
|
- 201 on create, 200 on update, 204 on delete
|