docs: close base scope-class extraction follow-up (post-WS-5)

Reflects the FormFieldChildTableMorphScope extraction landed in the
previous commit:

  - ARCH-FORM-BUILDER.md v1.9 — five locations updated:
      §6.7 (Relational binding table) — added forward reference
        sentence after the FormFieldBindingScope escape-hatch line
        (WS-5a was the first scope; previously had no deferral note
        because nothing existed yet to defer)
      §17.4.2 (Relational table form_field_validation_rules) —
        "deferred to WS-5d per addendum Q3" replaced with marker-
        subclass forward reference
      §17.5.3 (Service, scope, cascade — config) — same replacement
      §17.6.1 (Field options rationale) — "unblocks the deliberate
        follow-up" replaced with completion-confirmation
      §17.6.3 (Service / scope / cascade — option) — "deferred to a
        follow-up work package" replaced with marker-subclass forward
        reference + Phase A diff verification result
    Version metadata + changelog updated; v1.8 prose preserved in the
    Previous-versions block.

  - ARCH-CONSOLIDATION-ADDENDUM-2026-04-24.md — new
    "Uitvoering — base scope-class extractie (2026-04-25)" section
    inserted after the WS-5d Uitvoering, documenting the Phase A
    diff-verification, marker-subclass approach, private→protected
    YAGNI policy, the inline-FQN → use-statements stylistic refinement,
    static-analysis impact (Larastan baseline clean, Rector
    357 → 355), and net-diff figures.

  - BACKLOG.md — FORM-BUILDER-MORPH-SCOPE-BASE-CLASS item closed
    via strikethrough header + "Status: closed 2026-04-25" annotation
    (matches the TECH-TS-PORTAL-TSC closure convention from earlier
    this week).

  - SCHEMA.md — three stale "deferred" claims updated to reflect the
    completed extraction:
      header v2.6 changelog mention rewritten to point at the now-
        landed FormFieldChildTableMorphScope
      form_field_validation_rules table-section global-scope note
        replaced with marker-subclass forward reference
      form_field_options table-section global-scope note same
        replacement
    Schema version NOT bumped — no actual schema change.
    The two other scope mentions (form_field_bindings,
    form_field_configs) made no deferral claims and remain accurate.

Note: the work package's prose listed "§6.7 / §17.4.3 / §17.5.3 /
§17.6.3" as deferral-note locations. The actual locations were
§17.4.2 (not §17.4.3), §17.5.3, §17.6.1 (not just §17.6.3), and
§17.6.3 — §6.7 had no deferral note (WS-5a was the first scope,
nothing to defer yet). All five spots updated in line with the work
package's intent.

WS-5 family fully complete: no open follow-up items remain under the
"delete > adapt" discipline of the WS-5 refactor.

Tests: 1208 passed (3260 assertions). No code changes in this commit.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-04-25 04:52:01 +02:00
parent 9fa8231cf7
commit f7ddc1b3ce
4 changed files with 130 additions and 37 deletions

View File

@@ -1,4 +1,4 @@
# ARCH — Universal Form Builder (v1.8)
# ARCH — Universal Form Builder (v1.9)
> **Source of truth** for Crewli's universal Form Builder architecture.
> Any discrepancy with SCHEMA.md is resolved in favour of this document
@@ -14,11 +14,19 @@
> pre-WS-5d `options` JSON columns dropped on both `form_fields` and
> `form_field_library`; per-option translations live on the option row
> itself). **WS-5 family complete.**
> **Version:** 1.8 (new §17.6 "Field options (relational)" for the WS-5d
> split; §17.4 / §17.5 sibling-catalogue prose extended to mention the
> fourth concrete morph-scope; existing Webhooks section renumbered
> from §17.6 to §17.7).
> **Version:** 1.9 (FormFieldChildTableMorphScope abstract base class
> extracted across the four WS-5 siblings; concrete scope classes are
> now marker subclasses preserving identity for existing
> `withoutGlobalScope(SubclassName::class)` call sites; deferral notes
> in §6.7 / §17.4.2 / §17.5.3 / §17.6.1 / §17.6.3 replaced with forward
> references to the base; rationale in
> ARCH-CONSOLIDATION-ADDENDUM-2026-04-24.md §"Uitvoering — base
> scope-class extractie").
> **Previous:**
> 1.8 (new §17.6 "Field options (relational)" for the WS-5d
> split; §17.4 / §17.5 sibling-catalogue prose extended to mention the
> fourth concrete morph-scope; existing Webhooks section renumbered
> from §17.6 to §17.7),
> 1.7 (§8 restructured into tree-structure, relational-tables,
> service-boundary, operator-catalogue, cycle-detection, activity-log
> and legacy-migration sub-sections; contract unchanged),
@@ -1284,6 +1292,15 @@ explicit override via constructor, then route parameter `organisation`
the scope. Escape hatch:
`FormFieldBinding::withoutGlobalScope(FormFieldBindingScope::class)`.
Post-WS-5d, `FormFieldBindingScope` is a marker subclass of
`FormFieldChildTableMorphScope`; the shared UNION-over-two-owner-chains
logic lives in the abstract base. See
`app/Models/Scopes/FormFieldChildTableMorphScope.php`. Identity-
preserving extraction landed after the four sibling scopes existed
(rationale + Phase A diff verification in
ARCH-CONSOLIDATION-ADDENDUM-2026-04-24.md §"Uitvoering — base
scope-class extractie").
**Service boundary (`FormFieldBindingService`):** all writes go through
the service — no controller fills bindings directly on the model. The
service owns:
@@ -2465,11 +2482,12 @@ Organisation context resolution mirrors `OrganisationScope`; the escape
hatch is
`FormFieldValidationRule::withoutGlobalScope(FormFieldValidationRuleScope::class)`.
Base-class extraction between the two scope classes is deliberately
deferred to WS-5d per addendum Q3 — premature abstraction from two
siblings is still premature, and WS-5d's `form_field_options` /
WS-5c's `form_field_conditional_logic` may surface a different shared
shape.
`FormFieldValidationRuleScope` is a marker subclass of
`FormFieldChildTableMorphScope`; the shared logic lives in the
abstract base. See `app/Models/Scopes/FormFieldChildTableMorphScope.php`.
Identity-preserving extraction landed after WS-5d — rationale and
Phase A diff verification in ARCH-CONSOLIDATION-ADDENDUM-2026-04-24.md
§"Uitvoering — base scope-class extractie".
**Service boundary (`FormFieldValidationRuleService`).** All writes go
through the service — no controller writes rules directly on the
@@ -2628,11 +2646,13 @@ Mirrors §17.4's validation-rules stack one-for-one:
- **Service boundary** (`FormFieldConfigService`) — `configsFor`,
`replaceConfigs`, `copyConfigs`, `toJsonShape`, `assertSpecsValid`.
Single writer; all controller paths go through it.
- **Multi-tenancy** (`FormFieldConfigScope`) — third near-duplicate of
`FormFieldBindingScope`. The three siblings' base-class extraction is
deferred to WS-5d per addendum Q3 (abstracting from three is still
premature when the fourth sibling is about to land and may clarify
what truly varies).
- **Multi-tenancy** (`FormFieldConfigScope`) — marker subclass of
`FormFieldChildTableMorphScope`; the shared UNION-over-two-owner-
chains logic lives in the abstract base. See
`app/Models/Scopes/FormFieldChildTableMorphScope.php`. Identity-
preserving extraction landed after WS-5d (rationale in
ARCH-CONSOLIDATION-ADDENDUM-2026-04-24.md §"Uitvoering — base
scope-class extractie").
- **Cascade** — shared `FormFieldChildTablesCascadeObserver` (renamed
from `FormFieldBindingsCascadeObserver` in WS-5b commit 1) covers
all three relational tables on owner delete.
@@ -2691,8 +2711,9 @@ per-locale translations JSON map.
WS-5d follows the WS-5a / WS-5b discipline one-for-one: dedicated
service as single writer, UNION-over-two-owner-chains scope, shared
cascade observer. Fourth and final WS-5 sibling — landing it
materialises the four concrete morph-scope implementations and
unblocks the deliberate follow-up of base-class extraction.
materialised the four concrete morph-scope implementations. The
follow-up base-class extraction landed in a separate work package
post-WS-5d (`FormFieldChildTableMorphScope`).
#### 17.6.2 Table + catalogue
@@ -2739,12 +2760,14 @@ it.
FormRequests in their `after()` hook to reject malformed specs at the
HTTP boundary before any write.
`FormFieldOptionScope` is the fourth concrete UNION-over-two-owner-
chains sibling, near-duplicate of the binding / validation-rules /
configs scopes. Base-class extraction across the four siblings is
deliberately deferred to a follow-up work package now that the four
implementations exist and the "what actually varies" question can be
answered empirically.
`FormFieldOptionScope` is a marker subclass of
`FormFieldChildTableMorphScope`; the shared UNION-over-two-owner-
chains logic lives in the abstract base. See
`app/Models/Scopes/FormFieldChildTableMorphScope.php`. The "what
actually varies" question across the four siblings was answered
empirically (Phase A diff verification clean: nothing varies). See
ARCH-CONSOLIDATION-ADDENDUM-2026-04-24.md §"Uitvoering — base
scope-class extractie".
`FormFieldChildTablesCascadeObserver` extended to physically delete
option rows on owner soft-delete OR force-delete; options are