Created under app/Http/Requests/Api/V1/Artist/, mirroring the
existing FormRequest pattern (final class, authorize() returns true,
controller-level Gate::authorize). One request per CRUD shape plus the
two domain-specific endpoints:
artists create / update
genres create / update (with org-scoped unique)
stages create / update (with event-scoped unique)
stages/order ReorderStagesRequest — permutation check
engagements create / update — per RFC §10.3, with
ContractRequiresFee + OptionExpiresInFuture
conditional rules wired
performances create / update — per §10.2; cross-FK
engagement.event_id ↔ event_id chain
enforced via withValidator closure;
update is non-placement only (placement
edits go through /timetable/move)
timetable/move per §10.4; resolves target_event_id from
target_stage_id + target_start_at via
stage_days, then reuses StageActiveOnEvent
+ WithinEventBounds for downstream rules
stages/{stage}/days §10.5 matrix replace; each event_id must
equal stage.event_id (flat) or be sub-event
(festival)
Custom error messages in Dutch where user-facing. Cross-FK rules that
span request inputs (engagement vs event-id chain, day matrix sub-event
membership) live in withValidator after-closures so the rule cache is
stable per request.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>