fix(timetable): config-flag observer + cleaner idempotency_key

OrganisationObserver was gated on app()->runningUnitTests() — replaced
with config('artist_advance.bootstrap_on_org_create') (default true,
phpunit.xml overrides to false). Behaviour identical, but the seam is
explicit and removable. Tracked for full convergence by new BACKLOG
entry TECH-OBSERVER-TEST-CONVERGENCE — productiegedrag = testgedrag,
geen branching, na test-cleanup.

idempotency_key for the engagement-scoped draft simplified from
'aa-' + sha1(engagement_id)[0:27] to 'aa:' + engagement_id (29 chars,
fits varchar(30)). Same uniqueness guarantee, recognisable shape.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-08 23:18:15 +02:00
parent 96eb7e91e7
commit 889441cb39
4 changed files with 35 additions and 9 deletions

View File

@@ -257,16 +257,13 @@ final class EngagementPortalController extends Controller
// Pass event_id via the context bag — the schema is org-owned (not
// event-owned) and this route has no {event} parameter for the
// FormSubmissionObserver fallback. ARCH-FORM-BUILDER §17.3 footnote.
// idempotency_key column is varchar(30); a SHA-1 hex digest fits in
// 28 chars and uniquely keys "one draft per (schema, engagement)".
$key = 'aa-'.substr(hash('sha1', (string) $resolved->engagement->id), 0, 27);
// idempotency_key column is varchar(30); 'aa:' + 26-char ULID fits.
return $this->submissionService->createDraft(
schema: $schema,
subject: $resolved->subject,
submitter: null,
context: [
'idempotency_key' => $key,
'idempotency_key' => 'aa:'.$resolved->engagement->id,
'event_id' => $resolved->eventId,
],
);

View File

@@ -18,15 +18,18 @@ use App\Models\Organisation;
* The default seeder is idempotent if the org already owns an
* artist_advance schema, the call is a no-op. Safe to re-run.
*
* Skipped during automated tests so existing FormSchema-counting
* tests aren't perturbed; tests that need the auto-seed call
* `ArtistAdvanceDefault::seedFor()` explicitly.
* Gated by `config('artist_advance.bootstrap_on_org_create')`. The
* config defaults to true (production behaviour); phpunit.xml flips
* it to false so existing FormSchema-counting tests aren't perturbed.
* Tests that need the auto-seed call `ArtistAdvanceDefault::seedFor()`
* explicitly. Tracked for removal by BACKLOG entry
* `TECH-OBSERVER-TEST-CONVERGENCE`.
*/
final class OrganisationObserver
{
public function created(Organisation $organisation): void
{
if (app()->runningUnitTests()) {
if (! (bool) config('artist_advance.bootstrap_on_org_create', true)) {
return;
}