feat(form-builder): add failure_response_code column to form_submissions

Per RFC-WS-6 §Q3 v1.3 addition 2 + ARCH-BINDINGS §7.1 v1.2.

Denormalised mirror of the FormBindingApplicatorException subclass
classification, written by ApplyBindingsOnFormSubmit's outer-transaction
catch block (D2) when apply_status='failed'. Drives response-shape copy.
NULL when apply_status is not 'failed'.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
2026-05-08 01:53:13 +02:00
parent b2558791e6
commit e32de8a0f0
2 changed files with 50 additions and 0 deletions

View File

@@ -0,0 +1,47 @@
<?php
declare(strict_types=1);
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
/**
* Per RFC-WS-6 §Q3 v1.3 addition 2 + ARCH-BINDINGS §7.1 v1.2.
*
* Mirrors the FormBindingApplicatorException subclass classification onto
* a denormalised string column for response-shape rendering. Values:
* - schema_config_error (HTTP 422)
* - temporary_error (HTTP 503)
* - data_integrity_error (HTTP 422)
* - unknown_error (HTTP 500)
*
* Read by the response renderer when apply_status='failed' to surface
* contextual user-facing error copy. The exception subclass on the
* action-failures row is the canonical source; this column is the
* response-shape driver. Both reference the same submission.id ULID.
*
* NULL when apply_status is not 'failed' (per the lifecycle:
* pending/completed/partial no failure to classify).
*/
return new class extends Migration
{
public function up(): void
{
Schema::table('form_submissions', function (Blueprint $table): void {
$table->string('failure_response_code', 40)
->nullable()
->after('apply_status');
$table->index('failure_response_code', 'fs_failure_response_code_idx');
});
}
public function down(): void
{
Schema::table('form_submissions', function (Blueprint $table): void {
$table->dropIndex('fs_failure_response_code_idx');
$table->dropColumn('failure_response_code');
});
}
};

View File

@@ -761,6 +761,7 @@ CREATE TABLE `form_submissions` (
`anonymised_at` timestamp NULL DEFAULT NULL,
`identity_match_status` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`apply_status` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`failure_response_code` varchar(40) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`apply_completed_at` timestamp NULL DEFAULT NULL,
`search_index` mediumtext CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci,
`created_at` timestamp NULL DEFAULT NULL,
@@ -778,6 +779,7 @@ CREATE TABLE `form_submissions` (
KEY `fs_event_status_idx` (`event_id`,`status`),
KEY `fs_schema_apply_status_idx` (`form_schema_id`,`apply_status`),
KEY `fs_org_apply_status_idx` (`organisation_id`,`apply_status`),
KEY `fs_failure_response_code_idx` (`failure_response_code`),
FULLTEXT KEY `fs_search_index_fulltext` (`search_index`),
CONSTRAINT `form_submissions_event_id_foreign` FOREIGN KEY (`event_id`) REFERENCES `events` (`id`) ON DELETE SET NULL,
CONSTRAINT `form_submissions_form_schema_id_foreign` FOREIGN KEY (`form_schema_id`) REFERENCES `form_schemas` (`id`) ON DELETE CASCADE,
@@ -1773,3 +1775,4 @@ INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (123,'2026_04_28_10
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (124,'2026_04_28_140000_add_kvk_number_to_companies_table',2);
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (125,'2026_04_28_180000_create_form_submission_action_failure_retry_attempts_table',2);
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (126,'2026_04_28_181000_add_exception_trace_to_form_submission_action_failures',2);
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (127,'2026_05_08_000001_add_failure_response_code_to_form_submissions',3);