# Backend context > Read `ai/shared.md` first. This file only covers backend-specific rules. ## Project Context **Stack:** PHP 8.4, Laravel 12, PHPUnit, Composer. **Architecture:** Domain-Driven Design. Code is organized by domain entity into Entities, DTOs, Repositories, Use Cases, and Fakes (in-memory repos for tests). ## Code patterns - Look at similar entities (e.g. `AgendaSlot`, `Event`) for reference - Entities: constructor with properties, getters - DTOs: simple data containers for creation - Repositories: interfaces that define data access - Use cases: business logic with Request objects - When throwing exceptions, add `@throws` docblock - Fakes: in-memory implementations for testing - Look at `tests/Fakes/` for examples - Find/lookup methods must return a new instance of the entity, not the stored reference - Tests: follow existing patterns in `tests/Unit/[Entity]/UseCases/` - In `setUp`, only use fake repositories for entities under test - construct dependency objects directly with `new` (e.g. `new Event(id: 0, slug: 'test')`) instead of creating them through their fake repositories ## PHP rules - Imports: always put `use` statements at the top of the file, never use inline imports (e.g. `\App\Foo\Bar::class`) - Closures: never use arrow functions (`fn () =>`) - always use regular anonymous functions (`function () { return ...; }`) - Defaults: never use default values for function or constructor parameters - every argument must be passed explicitly at every call site, including nullable params (write `?Foo $bar` not `?Foo $bar = null`) ## Seeders - Split `database/seeders/` one file per domain entity (e.g. `UserSeeder`, `StartupUserProfileSeeder`), not one per scenario - `DatabaseSeeder` stays as the orchestrator - calls sub-seeders via `$this->call([...])` in dependency order - Resolve cross-entity coupling with `findByX` lookups in later seeders ## Pre-commit Run `composer cs:fix` on worked-on directories before committing.