refactor(form-builder): drop custom purpose escape from schemas
Reduces the FormPurpose vocabulary from 22 variants + a `custom` escape to the seven v1.0 purposes registered in the new PurposeRegistry. - Purge migration deletes any form_schemas row whose `purpose` is not in the v1.0 set (cascades through form_fields, form_submissions, form_values, form_value_options, form_schema_sections, form_submission_section_statuses, form_submission_delegations, form_schema_webhooks, form_webhook_deliveries via existing FK). - Drop migration removes the `custom_purpose_slug` column + its index. - Both migrations declare their `down()` as a hard failure — we do not support reversing a purge (pre-launch, no production data). - `FormPurpose` enum slims to the seven cases; the legacy helpers (defaultSubmissionMode / defaultSubjectType / allowsPublicAccess) now delegate to PurposeRegistry so callers keep working. - FormSchema fillable / FormSchemaResource / StoreFormSchemaRequest / UpdateFormSchemaRequest / FormSchemaFactory drop every reference to `custom_purpose_slug` and the `custom` purpose. - VerifyFormsDataIntegrity drops the custom-slug mismatch check and sources the subject-type allow-list from PurposeRegistry. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,95 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
||||
/**
|
||||
* WS-2 — Purge form_schemas rows whose `purpose` is no longer in the
|
||||
* v1.0 PurposeRegistry (7-slug vocabulary) OR whose `purpose = 'custom'`.
|
||||
*
|
||||
* Child tables cascade via their existing FK constraints (cascadeOnDelete)
|
||||
* on form_schemas/form_submissions.
|
||||
*
|
||||
* `down()` is intentionally a hard failure — we do not support reversing
|
||||
* a purge migration (pre-launch, no production data).
|
||||
*/
|
||||
return new class extends Migration
|
||||
{
|
||||
/** @var list<string> */
|
||||
private const VALID_PURPOSES = [
|
||||
'event_registration',
|
||||
'artist_advance',
|
||||
'supplier_intake',
|
||||
'post_event_evaluation',
|
||||
'incident_report',
|
||||
'signature_contract',
|
||||
'user_profile',
|
||||
];
|
||||
|
||||
public function up(): void
|
||||
{
|
||||
$invalidPurposes = DB::table('form_schemas')
|
||||
->whereNotIn('purpose', self::VALID_PURPOSES)
|
||||
->pluck('purpose')
|
||||
->unique()
|
||||
->values()
|
||||
->all();
|
||||
|
||||
if ($invalidPurposes === []) {
|
||||
echo "[purge_invalid_form_purposes] no schemas with invalid purposes — nothing to delete.\n";
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$schemaIds = DB::table('form_schemas')
|
||||
->whereNotIn('purpose', self::VALID_PURPOSES)
|
||||
->pluck('id')
|
||||
->all();
|
||||
|
||||
$submissionIds = DB::table('form_submissions')
|
||||
->whereIn('form_schema_id', $schemaIds)
|
||||
->pluck('id')
|
||||
->all();
|
||||
|
||||
$counts = [
|
||||
'form_schemas' => count($schemaIds),
|
||||
'form_submissions' => count($submissionIds),
|
||||
'form_fields' => DB::table('form_fields')->whereIn('form_schema_id', $schemaIds)->count(),
|
||||
'form_schema_sections' => DB::table('form_schema_sections')->whereIn('form_schema_id', $schemaIds)->count(),
|
||||
'form_values' => $submissionIds === [] ? 0
|
||||
: DB::table('form_values')->whereIn('form_submission_id', $submissionIds)->count(),
|
||||
'form_value_options' => $submissionIds === [] ? 0
|
||||
: DB::table('form_value_options')
|
||||
->whereIn('form_value_id', DB::table('form_values')->whereIn('form_submission_id', $submissionIds)->select('id'))
|
||||
->count(),
|
||||
'form_submission_section_statuses' => $submissionIds === [] ? 0
|
||||
: DB::table('form_submission_section_statuses')->whereIn('form_submission_id', $submissionIds)->count(),
|
||||
'form_submission_delegations' => $submissionIds === [] ? 0
|
||||
: DB::table('form_submission_delegations')->whereIn('form_submission_id', $submissionIds)->count(),
|
||||
'form_schema_webhooks' => DB::table('form_schema_webhooks')->whereIn('form_schema_id', $schemaIds)->count(),
|
||||
'form_webhook_deliveries' => $submissionIds === [] ? 0
|
||||
: DB::table('form_webhook_deliveries')->whereIn('form_submission_id', $submissionIds)->count(),
|
||||
];
|
||||
|
||||
echo sprintf(
|
||||
"[purge_invalid_form_purposes] purging schemas with invalid purposes: %s\n",
|
||||
implode(', ', $invalidPurposes),
|
||||
);
|
||||
foreach ($counts as $table => $n) {
|
||||
echo " {$table}: {$n}\n";
|
||||
}
|
||||
|
||||
// FK cascade does the rest — delete only the parent rows.
|
||||
DB::table('form_schemas')->whereIn('id', $schemaIds)->delete();
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
throw new \RuntimeException(
|
||||
'purge_invalid_form_purposes cannot be reversed — this migration '
|
||||
.'deletes rows permanently. Restore from backup or run migrate:fresh.'
|
||||
);
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,38 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
/**
|
||||
* WS-2 — Drop the `custom_purpose_slug` escape from `form_schemas`.
|
||||
*
|
||||
* v1.0 Purpose registry replaces the `custom` purpose + per-organisation
|
||||
* slug construct with a fixed set of seven purposes. See
|
||||
* ARCH-CONSOLIDATION-2026-04.md §3 besluit 4 and ARCH-FORM-BUILDER.md
|
||||
* §17.3 (Purpose registry).
|
||||
*
|
||||
* `down()` is intentionally a hard failure — we do not support reversing
|
||||
* this migration (pre-launch, no production data).
|
||||
*/
|
||||
return new class extends Migration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
Schema::table('form_schemas', function (Blueprint $table): void {
|
||||
$table->dropIndex('fs_custom_purpose_slug_idx');
|
||||
$table->dropColumn('custom_purpose_slug');
|
||||
});
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
throw new \RuntimeException(
|
||||
'drop_custom_purpose_slug_from_form_schemas cannot be reversed — '
|
||||
.'the custom purpose escape is retired in v1.0. Restore from '
|
||||
.'backup or run migrate:fresh.'
|
||||
);
|
||||
}
|
||||
};
|
||||
Reference in New Issue
Block a user