align ai workflow rules
This commit is contained in:
parent
4241f5ba29
commit
efb932903b
3 changed files with 205 additions and 220 deletions
|
|
@ -8,57 +8,76 @@ Read `ai/shared.md` first. This file covers backend-specific rules.
|
|||
|
||||
**Location:** `backend/`.
|
||||
|
||||
The application is still close to the Laravel starter structure. Do not
|
||||
introduce a domain architecture, repository layer, service layer, or other
|
||||
abstraction before the codebase and requested behavior justify it. Match
|
||||
existing Laravel conventions and inspect similar code before adding a new
|
||||
pattern.
|
||||
The backend follows a domain-oriented structure. Existing areas use entities,
|
||||
DTOs, repository interfaces, Eloquent implementations, use cases, and test
|
||||
fakes. Extend those patterns when adding behavior to an established area. Do
|
||||
not add speculative layers or interfaces that the requested behavior does not
|
||||
need.
|
||||
|
||||
## Laravel patterns
|
||||
The Vue application remains a separate project under `frontend/website/`.
|
||||
Keep frontend source, dependencies, builds, and delivery out of the backend
|
||||
unless the user explicitly asks to integrate them. The backend root route is
|
||||
intentionally unclaimed; the built-in health endpoint is `/up`.
|
||||
|
||||
- Keep controllers thin. Put reusable business behavior in an appropriately
|
||||
named application or domain class once the behavior warrants extraction.
|
||||
- Use dedicated request validation rather than validating substantial payloads
|
||||
inline in controllers.
|
||||
- Let unexpected exceptions reach Laravel's exception handler. Catch only
|
||||
exceptions that can be handled meaningfully at the current boundary.
|
||||
## Code patterns
|
||||
|
||||
- Inspect similar domain code before adding a new entity, DTO, repository,
|
||||
use case, controller action, or fake.
|
||||
- Entities own domain state and behavior and expose descriptive methods.
|
||||
- DTOs are explicit data containers for creation or transfer between seams.
|
||||
- Repository interfaces define domain-facing persistence operations. Keep
|
||||
Eloquent details in their implementations and register bindings in the
|
||||
application provider.
|
||||
- Put reusable business behavior in a use case. Give a use case a request DTO
|
||||
when it accepts a payload; call `execute()` directly when it has no input.
|
||||
- Document use-case exceptions with `@throws` when callers are expected to
|
||||
handle them.
|
||||
- Keep controllers thin. Translate HTTP input to use-case input and domain
|
||||
output to the response contract.
|
||||
- Catch only documented, expected exceptions at the controller boundary. Let
|
||||
unexpected exceptions reach Laravel's exception handler.
|
||||
- Fake repositories are in-memory implementations used by unit tests. Return
|
||||
a new entity instance from create and lookup methods rather than exposing a
|
||||
stored reference.
|
||||
- Use Eloquent relationships and query scopes consistently rather than
|
||||
duplicating query fragments.
|
||||
- Avoid speculative interfaces and abstractions with only one trivial
|
||||
implementation.
|
||||
- The Vue application is a separate project under `frontend/website/`.
|
||||
- Keep frontend source, dependencies, builds, and delivery out of the backend
|
||||
unless the user explicitly asks to integrate them.
|
||||
- The backend root route is intentionally unclaimed. The built-in health
|
||||
endpoint is `/up`.
|
||||
|
||||
## Tests
|
||||
## Unit tests
|
||||
|
||||
- Follow the existing PHPUnit organization under `tests/Unit/` and
|
||||
`tests/Feature/`.
|
||||
- Prefer `PHPUnit\Framework\TestCase` when a test only exercises plain PHP.
|
||||
- Extend `Tests\TestCase` only when the test needs Laravel's container,
|
||||
facades, database, routing, or HTTP kernel.
|
||||
- HTTP feature tests extend `Tests\TestCase`.
|
||||
- Use `RefreshDatabase` when a test reads or writes database state.
|
||||
- Assert behavior at the appropriate seam:
|
||||
- Unit tests cover isolated business behavior and edge cases.
|
||||
- Feature tests cover routing, middleware, validation, persistence, and
|
||||
response shape.
|
||||
- Do not duplicate every business branch through the HTTP layer when unit
|
||||
coverage already proves it. Feature tests should focus on wiring and the
|
||||
public contract.
|
||||
- Follow the existing organization under `tests/Unit/<Area>/`.
|
||||
- Use fake repositories and fake collaborators for the behavior under test.
|
||||
Construct unrelated dependency entities directly instead of routing them
|
||||
through additional repositories.
|
||||
- Test use-case branches at the use-case seam. Do not repeat every branch in
|
||||
controller or HTTP tests.
|
||||
- Plain entities, value objects, use cases, middleware, and controller units
|
||||
should extend `PHPUnit\Framework\TestCase` when they do not need Laravel.
|
||||
- Extend `Tests\TestCase` only when a test needs Laravel's container, facades,
|
||||
database, routing, or HTTP kernel.
|
||||
- Reserve direct Eloquent repository feature tests for persistence mapping,
|
||||
query behavior, or database constraints that cannot be proven through a
|
||||
plain unit test.
|
||||
|
||||
## Test database
|
||||
## Feature tests
|
||||
|
||||
- Feature tests exercise the HTTP seam: routing, middleware, real Eloquent
|
||||
bindings, cookies, persistence, validation, and response shape.
|
||||
- Feature tests are additive to unit tests. Prefer a happy path and the
|
||||
relevant authorization guard instead of duplicating all business branches.
|
||||
- Place endpoint tests under `tests/Feature/<Area>/`, extend
|
||||
`Tests\TestCase`, and use `RefreshDatabase` when database state is involved.
|
||||
- Development and runtime use PostgreSQL through the local Unix socket.
|
||||
- PHPUnit intentionally uses SQLite `:memory:` as configured in
|
||||
`phpunit.xml`.
|
||||
- Feature tests are self-contained and do not require the process-compose
|
||||
PostgreSQL service.
|
||||
PHPUnit uses SQLite `:memory:` as configured in `phpunit.xml`, so feature
|
||||
tests are self-contained and do not need the worktree stack.
|
||||
- Never point `RefreshDatabase` tests at the development PostgreSQL database.
|
||||
- Keep mail set to the PHPUnit `array` transport unless a test explicitly
|
||||
exercises a real mail integration.
|
||||
- Keep mail on PHPUnit's `array` transport unless a test explicitly exercises
|
||||
a real mail integration.
|
||||
- Authentication uses a custom database-session cookie, not a Laravel guard.
|
||||
`actingAs()` does not apply. Credentialed requests use
|
||||
`withCredentials()` and `withUnencryptedCookie()` because API middleware
|
||||
reads the raw cookie.
|
||||
- Read an unencrypted response cookie with
|
||||
`$response->getCookie($name, false)`.
|
||||
|
||||
## PHP rules
|
||||
|
||||
|
|
@ -80,7 +99,7 @@ pattern.
|
|||
- Do not add production repository or model APIs solely to make seeding
|
||||
convenient.
|
||||
- Use existing lookup methods for cross-seeder relationships. When a group of
|
||||
records only makes sense together, keep them in one seeder and retain local
|
||||
records only makes sense together, keep it in one seeder and retain local
|
||||
references.
|
||||
|
||||
## Migrations
|
||||
|
|
@ -99,15 +118,12 @@ pattern.
|
|||
- Once a production database exists, replace this policy with additive,
|
||||
forward-only migrations.
|
||||
|
||||
## Before completing backend work
|
||||
## Backend workflow
|
||||
|
||||
- Run the focused test during development.
|
||||
- Run the full test suite before completion:
|
||||
|
||||
```sh
|
||||
direnv exec "$(git rev-parse --show-toplevel)" php artisan test
|
||||
```
|
||||
|
||||
- Run the Composer static-analysis scripts.
|
||||
- Run the focused PHPUnit test while developing.
|
||||
- Use `just backend-types-check` for Larastan and `just backend-test` for the
|
||||
full PHPUnit suite during iteration.
|
||||
- Fix failures caused by the change. Report unrelated baseline failures
|
||||
precisely rather than hiding them or expanding scope without authorization.
|
||||
precisely rather than expanding scope silently.
|
||||
- The shared `just test-all` command is the required completion gate. Focused
|
||||
backend recipes never replace it.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue