feat(timetable): observers — engagement denorm/guard + performance version bump

ArtistEngagementObserver:
- creating: auto-fills organisation_id from parent Artist (RFC v0.2 D10
  denormalisation), asserts artist.organisation_id == event.organisation_id;
  cross-tenant linkage throws CrossTenantEngagementException (extends
  DomainException, included in this commit).
- saving: no-op marker reserved for Session 2 state-machine validation.
- deleted: cascades soft-delete to Performance children, hard-deletes
  AdvanceSection children. AdvanceSubmission rows are immutable per
  RFC §5.4 and remain attached.

PerformanceObserver:
- saving: increments version by 1 on UPDATE only (D14 optimistic lock).
  MoveTimetablePerformanceRequest in Session 2 uses this for concurrent-
  edit detection.

Both observers registered in AppServiceProvider::boot.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-08 18:01:42 +02:00
parent 9ccf1eaceb
commit 85ad45c7e9
4 changed files with 120 additions and 0 deletions

View File

@@ -163,6 +163,11 @@ class AppServiceProvider extends ServiceProvider
FormField::observe(FormFieldChildTablesCascadeObserver::class);
FormFieldLibrary::observe(FormFieldChildTablesCascadeObserver::class);
// RFC-TIMETABLE v0.2 — engagement denorm + cross-tenant guard,
// performance optimistic-lock bump.
\App\Models\ArtistEngagement::observe(\App\Observers\ArtistEngagementObserver::class);
\App\Models\Performance::observe(\App\Observers\PerformanceObserver::class);
// RFC-WS-6 v1.3 §Q1 — FormSubmissionSubmitted listener layout.
//
// SYNC chain (single listener):