docs(form-builder): WS-5c sign-off — SCHEMA v2.5 + ARCH v1.7 §8 + addendum Q3
SCHEMA v2.5: - form_fields: conditional_logic row removed; cross-reference note added pointing at the two new tables and the addendum Q3 WS-5c Uitvoering (no library mirror). - New sections: form_field_conditional_logic_groups (tree nodes, adjacency-list via parent_group_id) and form_field_conditional_logic_conditions (leaves; value JSON nullable for empty/not_empty). Both tables use the Q2 declarative FK-chain resolver via tenantScopeStrategy() — group chain 3 hops, condition chain 4 hops (fits the WS-5c-raised cap of 5). ARCH v1.7 §8 restructured into sub-sections mirroring the §17.4 / §17.5 pattern: - 8.1 Tree structure (read-side contract) - 8.2 Relational tables (column specs, cascade, scope) - 8.3 Service boundary (logicFor/replaceLogic/toJsonShape/ assertSpecsValid/assertNoCycles) - 8.4 Operator catalogues (group + comparison) - 8.5 Cycle detection (contract preserved, implementation moved) - 8.6 Activity log (dual-events: field.updated + field.conditional_logic_replaced; FormField subject only) - 8.7 Legacy JSON migration (strict dispatch, rollback reversible) Addendum Q3 extended with "Uitvoering — WS-5c (2026-04-26)": - No-library-mirror decision reaffirmed (simple FK, no morph) - Two-table tree-structure rationale (groups + conditions semantic purity over single-table mixed-nullables) - OrganisationScope cap raise 3 → 5, rationale: legitimate 4-hop conditions chain + headroom for future deeper trees without denormalising form_field_id onto conditions - Cycle detection migrated to service, contract unchanged - Snapshot + resource JSON contract byte-identical via toJsonShape - Strict validator on save at FormRequest boundary - Scope-sibling discipline: WS-5c adds two FK-chain models (not morph); base-class extraction still parked for WS-5d Sign-off table: WS-5c afronding 2026-04-26 added. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -186,6 +186,30 @@ WS-5b splitst `form_fields.validation_rules` en `form_field_library.validation_r
|
||||
|
||||
**Afronding WS-5b.** 5 commits, baseline tests 1047 → volledig groen na commit 5. WS-5b is hiermee compleet; scope-sibling extractie en WS-5c (`conditional_logic`) / WS-5d (`options`) zijn separate work packages.
|
||||
|
||||
### Uitvoering — WS-5c (2026-04-26)
|
||||
|
||||
WS-5c splitst `form_fields.conditional_logic` JSON naar een relationele boom over twee tabellen: `form_field_conditional_logic_groups` (AND/OR nodes met `parent_group_id` voor nesting) + `form_field_conditional_logic_conditions` (leaves met `field_slug` / `comparison_operator` / `value` JSON). Tree-structuur met interleaved mixed children (groups en conditions als siblings onder één ouder), sort-order per positie binnen parent.
|
||||
|
||||
**Geen library-mirror — Q3 expliciet.** `form_field_library` draagt geen conditional_logic en komt niet in scope. Eenvoudige FK `form_field_id` op de groups-tabel; geen polymorphic morph, geen `owner_type`/`owner_id` kolommen. `FormFieldService::insertFromLibrary` propageert geen conditional_logic — library-entries dragen die state niet.
|
||||
|
||||
**Twee-tabel tree-structuur.** Alternatief (single table met nullable `value`/`operator` per rij-rol) zou semantische vervuiling hetzelfde type rot oproepen dat WS-5b's configs-split weg haalde. Groepen en condities zijn semantisch anders — één tabel per concept, interleaving via sort_order bij read-time in `toJsonShape`. Geen `sort_order` drift tussen siblings.
|
||||
|
||||
**OrganisationScope cap verhoging van 3 naar 5.** De conditions-scope-chain (`condition → group → field → schema → organisation_id`) is 4 hops; de group-chain is 3. De oude cap van 3 zou bij conditions throwen via `TenantScopeResolutionException`. Raising naar 5 dekt de ketens en geeft headroom voor toekomstige diepere trees zonder `form_field_id` op conditions te denormaliseren (drift-risico). Infrastructurele wijziging — niet beperkt tot WS-5c; volgende WS's mogen diepere chains declareren als dat architectuur-winst oplevert.
|
||||
|
||||
**Cycle detection behoud contract.** `FormFieldService::assertNoConditionalCycle` werd vervangen door `FormFieldConditionalLogicService::assertNoCycles`. Zelfde algoritme (DFS over sibling-adjacency), andere implementatie-site: leest de relationele tree, niet meer JSON. Tree-interne cycles zijn structureel onmogelijk via `parent_group_id` adjacency-list.
|
||||
|
||||
**Activity log dual-events.** `field.updated` (met gereconstrueerde `old.conditional_logic` / `new.conditional_logic` via `toJsonShape`) + `field.conditional_logic_replaced` (semantisch). FormField subject-only, conform §6.7 WS-5a en §17.4.2 WS-5b. Library-niveau is silent — er IS geen library conditional_logic om te loggen.
|
||||
|
||||
**Snapshot + API resource shape ongewijzigd.** Externe JSON-contract blijft byte-gelijk aan pre-WS-5c via `toJsonShape`. Geen frontend breaking change — de portal's `evaluateConditionalLogic` composable blijft dezelfde `{show_when: {...}}` struct consumeren.
|
||||
|
||||
**Strict validator op save (commit 3).** `StoreFormFieldRequest` / `UpdateFormFieldRequest` accepteren `conditional_logic` nu als array-shape, niet JSON string. `after()` hook roept `FormFieldConditionalLogicService::assertSpecsValid` aan en rejects unknown operators, root conditions, empty groups, en malformed children als 422 vóór enige write.
|
||||
|
||||
**Drie scope-siblings + twee FK-chain strategy users.** `FormFieldBindingScope` + `FormFieldValidationRuleScope` + `FormFieldConfigScope` zijn nog steeds de drie morph-based UNION-scope near-duplicaten (base-class extractie blijft uitgesteld tot WS-5d). WS-5c voegt twee FK-chain declaratieve strategy models toe (`FormFieldConditionalLogicGroup`, `FormFieldConditionalLogicCondition`) — die tellen niet voor de morph-sibling extractie-discipline. WS-5d's `form_field_options` wordt het vierde polymorphic-morph sibling en beslist het "abstract of niet".
|
||||
|
||||
**JSON-kolom gedropt.** `form_fields.conditional_logic` gedropt in `2026_04_26_100003`. Geen library-equivalent om te droppen. Rollback-path: "roll back WS-5c commits 1–3 samen" — de backfill `down()` reconstrueert JSON terug naar de (via commit 3 rollback teruggekomen) kolom.
|
||||
|
||||
**Afronding WS-5c.** 4 commits, baseline tests 1104 → 1148 volledig groen na commit 3 (drop-column). Breaking change acceptance: geen bridging compatibility layer — de portal blijft onaangeraakt omdat het externe JSON-contract identiek is. WS-5d (`options`) is het laatste WS-5-werkpakket.
|
||||
|
||||
---
|
||||
|
||||
## Q4 — Sanctum `personal_access_tokens`
|
||||
@@ -300,5 +324,6 @@ WS-1 rapport Categorie D bevindingen die geen architect-beslissing vereisten en
|
||||
- **Product owner:** akkoord per Bert Hausmans 2026-04-24.
|
||||
- **WS-5a afronding:** 2026-04-24 — relationele `form_field_bindings` tabel, polymorphic owner, snapshot-parity, JSON-kolommen gedropt.
|
||||
- **WS-5b afronding:** 2026-04-25 — relationele `form_field_validation_rules` + parallel `form_field_configs` tabel; `validation_rules` JSON-kolommen gedropt; frontend-contract migratie naar canonieke key-namen landed in commit 5.
|
||||
- **WS-5c afronding:** 2026-04-26 — relationele `form_field_conditional_logic_groups` + `form_field_conditional_logic_conditions` tree-tabellen; simple FK op FormField (geen library-mirror per Q3); `conditional_logic` JSON-kolom gedropt; `OrganisationScope` FK-chain cap verhoogd van 3 naar 5 hops; snapshot + API resource JSON-contract byte-identiek via `toJsonShape`.
|
||||
|
||||
Volgende stap: prompt opstellen voor WS-2 (Purpose registry) met Q6-consolidatie als integraal onderdeel van de werkstroom.
|
||||
|
||||
Reference in New Issue
Block a user