ArtistEngagement::class, 'fk' => 'engagement_id']; } protected $fillable = [ 'engagement_id', 'event_id', 'stage_id', 'lane', 'start_at', 'end_at', 'version', 'notes', ]; protected function casts(): array { return [ 'lane' => 'integer', 'start_at' => 'datetime', 'end_at' => 'datetime', 'version' => 'integer', ]; } public function getActivitylogOptions(): LogOptions { return LogOptions::defaults() ->logOnly(['start_at', 'end_at', 'stage_id', 'lane', 'notes']) ->logOnlyDirty() // Performance.version is bumped by PerformanceObserver on every // dirty save. Skip the auto-log when *only* updated_at + version // moved — those rows correspond to bookkeeping touches, not // user-meaningful changes (D14). ->dontLogIfAttributesChangedOnly(['updated_at', 'version']) ->useLogName('performance'); } public function tapActivity(Activity $activity, string $eventName): void { $properties = $activity->properties?->toArray() ?? []; $properties['event_id'] = $this->event_id; $properties['organisation_id'] = $this->engagement?->organisation_id; $activity->properties = collect($properties); } public function engagement(): BelongsTo { return $this->belongsTo(ArtistEngagement::class, 'engagement_id'); } public function event(): BelongsTo { return $this->belongsTo(Event::class); } public function stage(): BelongsTo { return $this->belongsTo(Stage::class); } public function isParked(): bool { return $this->stage_id === null; } }