WS-6 v1.3-delta D2 — Listener refactor + integration #11

Merged
bert.hausmans merged 8 commits from feat/ws-6-v1.3-delta-d2 into main 2026-05-08 08:25:52 +02:00
Showing only changes of commit fa06c0f9f3 - Show all commits

View File

@@ -4,6 +4,7 @@ declare(strict_types=1);
namespace App\Listeners\FormBuilder;
use App\Enums\FormBuilder\ApplyStatus;
use App\Enums\FormBuilder\FormFieldType;
use App\Enums\FormBuilder\FormPurpose;
use App\Events\FormBuilder\FormSubmissionSubmitted;
@@ -24,6 +25,11 @@ use Illuminate\Support\Facades\Log;
* person's linked user. No-ops when person.user_id is null (deferred
* sync runs on PersonIdentityService::confirmMatch).
*
* Gating-invariant first statement per ARCH-BINDINGS §5.6: skip unless
* apply_status is COMPLETED. PARTIAL and FAILED both fall through
* rebuilding tags against a Person whose tag-binding may have been the
* binding that failed would propagate partial state into derived data.
*
* Failure mode: log at error level; never throw. Event propagation must
* reach sibling listeners (§31.1 identity, §31.3 shifts, §31.8 crowd lists).
*/
@@ -43,11 +49,25 @@ final class SyncTagPickerSelectionsOnSubmit implements ShouldQueue
public function handle(FormSubmissionSubmitted $event): void
{
try {
// Gating-invariant first statement per ARCH-BINDINGS §5.6.
// The fresh() reload is required because the inner-txn commit
// happens between dispatch and worker pickup; the in-memory
// event submission may carry pre-commit state.
$submission = $event->submission->fresh(['schema']);
if ($submission === null) {
return;
}
if ($submission->apply_status !== ApplyStatus::COMPLETED) {
Log::info('form-builder.queued-listener.skipped_apply_failed', [
'listener' => self::class,
'submission_id' => (string) $submission->id,
'apply_status' => $submission->apply_status?->value,
]);
return;
}
$schema = $submission->schema;
if ($schema === null) {
return;