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>
Phase 4 of S2b. Nine resources that shape the universal form builder
responses. FieldAccessService::filterVisibleFields gates every field
array — the primary defence tested by FormResourceSecurityTest (§22.9).
- FormSchemaResource: includes fields_count, submissions_count,
has_submissions, is_locked (derived from edit_lock_*), public_form_url
when public_token is set, and filtered fields collection.
- FormSchemaSummaryResource: lean list-endpoint variant.
- FormFieldResource: effective_label / help_text / options resolved via
FormLocaleResolver + translations JSON, plus TAG_PICKER available_tags
filtered by validation_rules.tag_categories.
- FormSubmissionResource: values keyed by field slug with FieldAccessService
filtering, section_statuses, active delegations, review_info,
submitted_in_locale, submission_duration_seconds.
- FormSubmissionSummaryResource: lean list variant.
- FormTemplateResource, FormFieldLibraryResource.
- PublicFormSchemaResource: strictly limited per §10 — only
is_portal_visible=true AND is_admin_only=false fields, no PII hints,
no role_restrictions, no submissions_count.
- FormSchemaWebhookResource: url/secret never returned; only url_host +
has_secret boolean.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>