25 KiB
title, description, status, owner, created, supersedes-sections-of
| title | description | status | owner | created | supersedes-sections-of |
|---|---|---|---|---|---|
| ARCH Consolidation — Architect Decisions Addendum (2026-04-24) | Beslissingen op de 6 architect-vragen uit het WS-1 rapport | binding | architect | 2026-04-24 | /dev-docs/ARCH-CONSOLIDATION-2026-04.md §5 (scope inschattingen) |
ARCH Consolidation — Architect Decisions Addendum (2026-04-24)
Context
Op 2026-04-24 leverde WS-1 (opsporings-pas) een rapport met 45 bevindingen en 6 architect-vragen. Dit addendum legt de beantwoording van die vragen vast én corrigeert waar nodig de werkstroom-scope. Dit document is bindend voor WS-2 t/m WS-8.
Bronnen:
/dev-docs/ARCH-CONSOLIDATION-2026-04.md— sprint charter (§1 principes, §3 vastgelegde besluiten, §5 werkstromen)/dev-docs/ARCH-CONSOLIDATION-WS1-REPORT.md— opsporings-rapport (45 bevindingen)
Het charter blijft ongewijzigd. §5 inschattingen worden in dit addendum herzien. §3 vastgestelde besluiten worden bevestigd (niet gewijzigd) — de architect-precisering op besluit 5 die tijdens review was overwogen is verworpen: besluit 5 blijft exact zoals geformuleerd.
Samenvatting beslissingen
| Q | Onderwerp | Besluit |
|---|---|---|
| Q1 | ULID voor 11 non-ULID tabellen | Alle 11 migreren naar ULID. Charter §3 besluit 5 blijft exact zoals geformuleerd; geen exceptions. |
| Q2 | OrganisationScope strategie | FK-chain scope extension. Denormalisatie alleen op tabellen die rapportage-hot zijn. Charter §3 besluit 3 bevestigd als enige uitzondering op basis van meetbaar rapportage-gebruik. |
| Q3 | WS-5 scope | Vier committed splits op form_fields + drie library-mirror splits. role_restrictions blijft JSON. |
| Q4 | Sanctum personal_access_tokens morph |
Ongewijzigd laten. Framework-polymorfie valt buiten de domain morph-map. Documenteren in WS-8. |
| Q5 | SCHEMA.md rewrite-shape | Aparte /dev-docs/ARCH-PLANNED-MODULES.md voor tabellen zonder migratie. SCHEMA.md wordt strict "waarheid van wat bestaat in de database". |
| Q6 | subject_type allow-list |
Consolideren onder WS-2 purpose registry. Compile-time test dwingt morph-map-alignment met purpose-registry af. |
Q1 — ULID voor 11 non-ULID tabellen
Besluit: Alle 11 tabellen uit Categorie A van het WS-1 rapport worden naar ULID gemigreerd. Charter §3 besluit 5 ("ULID consistent overal, ook pivots, ook logging-tabellen") blijft ongewijzigd. Geen exceptions.
Tabellen:
| ID | Tabel | Categorie |
|---|---|---|
| A-01 | organisation_user |
Pure pivot, geen model |
| A-02 | event_user_roles |
Pure pivot, geen model |
| A-03 | crowd_list_persons |
Pure pivot, geen model |
| A-04 | event_person_activations |
Pure pivot, geen model |
| A-05 | user_organisation_tags |
Pivot met model |
| A-06 | person_section_preferences |
Pivot met model |
| A-07 | mfa_backup_codes |
Ephemeral data |
| A-08 | mfa_email_codes |
Ephemeral data |
| A-09 | form_submission_section_statuses |
Pivot met model |
| A-10 | form_values |
EAV hot path |
| A-11 | form_value_options |
EAV hot path |
Motivatie:
- Pre-launch window: geen data-migratie, geen downtime, geen backfill-pijn. Dit is het enige moment waarop consistentie gratis is. Een half jaar later met productie-data kost hetzelfde werk weekenden met downtime.
- Performance-argumenten zijn theoretisch op Crewli's schaal: EAV join-performance tussen int en ULID keys is verwaarloosbaar bij de volumes waar Crewli zich op richt (enkele miljoenen
form_valuesper festival-jaar, ruim binnen MySQL + goede indexen op ULID). - Consistentie-winst is concreet en blijvend: elke uitzondering introduceert cognitieve belasting ("waarom is deze tabel anders?") die besluit 5 juist wil voorkomen.
- Valstrik 2 (gold-plating) niet van toepassing: dit is geen elegantie-verbetering, dit is uitvoering van een reeds genomen besluit.
Scope-impact: WS-4 migreert 11 PK's in plaats van 0 of 2.
Migratie-notes voor WS-4:
- Voor tabellen met een model (
UserOrganisationTag,PersonSectionPreference,MfaBackupCode,MfaEmailCode,FormSubmissionSectionStatus,FormValue,FormValueOption):HasUlidstrait toevoegen. - Voor pure pivots zonder model (
organisation_user,event_user_roles,crowd_list_persons,event_person_activations):$table->ulid('id')->primary()in de migratie, geen model nodig. - Inline migratie-commentaar "int AI for join performance" wordt vervangen door de ULID-migratie zelf; geen extra rationale-documentatie in de migratie.
Q2 — OrganisationScope strategie
Besluit: OrganisationScope wordt uitgebreid met een declaratieve FK-chain strategy. Denormalisatie van organisation_id blijft beperkt tot tabellen die meetbaar rapportage-hot zijn.
Concreet:
form_submissionsbehoudt denormalizedorganisation_id(per charter §3 besluit 3 — bevestigd als bewuste exception voor rapportage-queries: dashboards, CSV-exports, aggregerende counts over duizenden rijen).- Andere form-builder child tables krijgen geen eigen
organisation_idkolom; zij gebruiken FK-chain via hun parent:form_schema_sections→ viaform_schemas.organisation_idform_fields→ viaform_schemas.organisation_idform_values→ viaform_submissions.organisation_id(denormalized parent)form_value_options→ viaform_submissions.organisation_idform_submission_section_statuses→ viaform_submissions.organisation_idform_submission_delegations→ viaform_submissions.organisation_idform_schema_webhooks→ viaform_schemas.organisation_idform_webhook_deliveries→ viaform_submissions.organisation_id
Shape van de scope-extensie (concept — implementatie-details in WS-4):
class FormField extends Model
{
use HasUlids;
protected static function tenantScopeStrategy(): array
{
return ['via' => FormSchema::class, 'fk' => 'form_schema_id'];
}
}
OrganisationScope leest de strategy en bouwt de JOIN automatisch op.
Motivatie:
- Normalisatie-zuiverheid:
organisation_idheeft één bron van waarheid (form_schemas,events, enz.). Denormalisatie introduceert synchronisatie-risico en dubbele boekhouding. - Single responsibility:
OrganisationScopeblijft de multi-tenant guard. Geen gedeelde verantwoordelijkheid tussen observer + scope over 8 tabellen. - Toekomstbestendig: hetzelfde patroon werkt straks automatisch voor accreditation, briefings en andere modules met sub-tabellen. Eén scope-klasse uitbreiding, geen migraties per module.
- Denormalisatie-uitzondering gerechtvaardigd:
form_submissionsis rapportage-hot. De denormalisatie is een meetbare performance-optimalisatie voor aggregerende queries, geen "veilig-voor-het-geval-dat" patroon.
Rapportage-hotness criterium: een tabel krijgt alleen denormalized organisation_id als er regelmatig aggregerende queries rechtstreeks op draaien (counts, group-by, exports over duizenden rijen). Alle andere tabellen gebruiken FK-chain via hun parent.
Scope-impact: WS-4 krijgt één scope-klasse uitbreiding + scope-registratie op 9 form-builder child models + 5 event-data models (uit WS-1 rapport D-04: ShiftAssignment, ShiftWaitlist, VolunteerAvailability, PersonSectionPreference, PersonIdentityMatch). Geen 8 extra kolom-migraties.
Q3 — WS-5 scope
Besluit: WS-5 splitst de vier committed kolommen op form_fields (per charter §3 besluit 6) én de drie library-mirrors op form_field_library. role_restrictions blijft JSON.
Te splitsen:
| Bron kolom | Doel tabel | Sub-WS |
|---|---|---|
form_fields.binding |
form_field_bindings |
WS-5a |
form_fields.validation_rules |
form_field_validation_rules |
WS-5b |
form_fields.conditional_logic |
form_field_conditional_logic |
WS-5c |
form_fields.options |
form_field_options |
WS-5d |
form_field_library.default_binding |
form_field_bindings (met owner discriminator) |
WS-5a |
form_field_library.validation_rules |
form_field_validation_rules (met owner discriminator) |
WS-5b |
form_field_library.options |
form_field_options (met owner discriminator) |
WS-5d |
Blijft JSON:
form_fields.role_restrictions— kleine set Spatie rol-strings. Geen FK-partner mogelijk (rollen zijn strings in Spatie-permission, geen aparte tabel-PK's). Niet queryable in practice. Relationele splitsing levert geen architectuur-winst.form_fields.translations,form_field_library.translations— flat key-value bags per locale, nooit queried. Splitsen is speculatief.
Motivatie:
- Consistent relationeel form-builder domein: library en fields delen dezelfde onderliggende tabellen voor options, bindings en validation rules. Twee stijlen in hetzelfde domein is inconsistent.
- Library-entries krijgen een discriminator (exacte shape in WS-5a — ofwel
owner_typeenum (field|library), ofwel een paar nullable FK's (form_field_idORform_field_library_id)). Discriminator-keuze wordt in WS-5a besloten op basis van query-patterns. FormFieldService::insertFromLibrarykopieert rijen tussen library-entries en field-entries in plaats van JSON te hydrateren. Natuurlijk werk binnen WS-5; geen aparte PR.
Scope-impact: WS-5 wordt ~7-8 dagen in plaats van 4-6. Drie extra sub-werkstromen voor de library-mirrors passen binnen de bestaande WS-5a/b/d PR-structuur (library valt onder dezelfde PR als de corresponderende field-split).
Uitvoering — WS-5a (2026-04-24)
Discriminator-keuze: polymorphe morph (owner_type enum met waarden form_field en form_field_library, owner_id ULID). Het alternatief (twee nullable FK-kolommen form_field_id / form_field_library_id) is verworpen:
- MySQL 8 heeft geen partial-unique-support waarmee je per FK-kolom exclusief uniek kunt zijn; dat maakt de paired-FK-vorm in deze engine fundamenteel onhandig.
- Consistentie over WS-5b/c/d:
form_field_validation_rules,form_field_conditional_logicenform_field_optionsgebruiken dezelfde owner-discriminator shape per Q3. Eén idiomatisch patroon over de hele familie wint van per-tabel workarounds. - Morph-map aliassen
form_fieldenform_field_librarystonden al geregistreerd inAppServiceProvider::registerMorphMap()voor activity-log doeleinden; WS-5a heeft ze zonder extra werk hergebruikt.
Scope-enforcement: OrganisationScope (Q2 FK-chain resolver) kan geen morph-parent walken. WS-5a levert FormFieldBindingScope als sibling-scope die een UNION bouwt over beide owner-ketens (form_field → form_schema → organisation_id ∪ form_field_library → organisation_id). Zie ARCH-FORM-BUILDER §6.7.
Service-grens: FormFieldBindingService is de enige schrijver. FormFieldService::insertFromLibrary kopieert rijen via copyBindings, niet JSON (Q3 row-copy mandaat). Snapshot-writer en API-resources lezen via toJsonShape zodat het externe JSON-contract ongewijzigd blijft.
Git-log kanttekening commit 3. De 1Password signer gaf herhaalde "failed to fill whole buffer" errors op de lange HEREDOC body van de bedoelde commit-message; de uiteindelijke commit landde met alleen de titel (refactor(form-builder): pre-publish check reads form_field_bindings; drop binding JSON columns, SHA 61719bf). De volledige rationale — pre-publish check switch van JSON naar relationele query, kolom-drops op form_fields.binding en form_field_library.default_binding, factory/resource/form-request cleanup, fixture-rewrites — staat in de WS-5a completion notitie, niet in git show 61719bf. Amenden is niet geprobeerd: CLAUDE.md verbiedt signed-commit amenden.
Uitvoering — WS-5b (2026-04-25)
WS-5b splitst form_fields.validation_rules en form_field_library.validation_rules naar een relationele tabel form_field_validation_rules. Rij-shape: owner_type / owner_id (polymorphic morph, hergebruik van de WS-5a aliassen) + rule_type string(40, app-enforced enum FormFieldValidationRuleType) + parameters JSON per rule-type. Rationale: rule_type is de queryable dimensie ("welke velden hanteren regex?"), waarden zijn heterogeen (int voor min_length, string voor regex, array voor mime_types) waardoor JSON per rij passend is, niet voor de hele bag.
Seed-scan resultaat (Phase A). Zes distinct top-level keys geobserveerd in seeders/factories/tests/resource-code-paden: min, max, regex, unique, max_priorities, tag_categories. required bestond niet in de wild (kolom is_required was al de bron van waarheid). Enum-catalogus uitbreiding beperkt tot de vijftien validatie-cases; non-validatie-keys verplaatsen naar een parallelle tabel.
Strict-enterprise scope-uitbreiding. Tijdens de decision gate is WS-5b uitgebreid met een parallelle tabel form_field_configs (zie ARCH §17.5, landed in WS-5b commit 5). Rationale: tag_categories en storage_disk zijn renderings-/upload-configuratie, geen validatie-regels. Ze opnemen in form_field_validation_rules zou de tabel-naam semantisch vervuilen — precies het type drift dat deze sprint opruimt. Eén extra tabel, één extra enum, één extra service, één extra scope; géén scope-creep verder dan dat paar.
Key-translaties bij backfill.
required,unique: WARN-log + skip. Kolom-duplicaten vanis_required/is_unique. In WS-5b commit 3 is deFormValueService::$rules['unique']fallback verwijderd —is_uniqueis nu de enige bron.max_priorities→rule_type = max_selected: semantisch gelijk (cap op entries in list-valued veld); twee enum-cases voor één semantiek = rot. Seeder (FormBuilderDevSeeder) en test-assertie (PublicFormSeederTest:190) aangepast om de canonieke naam te gebruiken. Geen bridging intoJsonShape; historische snapshots blijven onaangeraakt.- Ambigu
min/max: field-type dispatch — NUMBER →min_value/max_value; TEXT/TEXTAREA/EMAIL/PHONE/URL →min_length/max_length; DATE/DATETIME →date_min/date_max; anders FAIL migratie. Type-inappropriate gebruik vanmin/maxis seed-data-bug; force correction, absorbeer niet stilletjes. tag_categories,storage_disk: skipped door de validation-rules backfill met INFO log; commit 5's configs-backfill pickt ze op inform_field_configs.
Activity log-conventie. Per §6.7 WS-5a: field.validation_rules_replaced wordt alleen geëmit op FormField-subject, niet op FormFieldLibrary. Library-niveau audits leven elders; bewuste convergentie met de binding-pattern.
Scope-sibling. FormFieldValidationRuleScope is een near-duplicaat van FormFieldBindingScope (zelfde UNION-over-two-owner-chains shape). Base-class extractie is uitgesteld tot WS-5d (waar het derde sibling form_field_options een gedeelde vorm moet onthullen); premature abstractie uit twee is nog steeds premature. Cascade-observer FormFieldBindingsCascadeObserver is hernoemd naar FormFieldChildTablesCascadeObserver en ruimt nu drie child-tabellen op (bindings, validation-rules, en — vanaf commit 5 — configs).
Strict validator op save (commit 3). De vier FormRequests (StoreFormFieldRequest, UpdateFormFieldRequest, StoreFormFieldLibraryRequest, UpdateFormFieldLibraryRequest) accepteren validation_rules nu als array-of-spec-objects ([{rule_type, parameters, error_message_key?}, ...]). Semantische validatie (enum-case + parameter-shape + callback-registry) loopt via FormFieldValidationRuleService::assertSpecsValid() in een after() hook, zodat bad specs 422 geven vóór enige write. Controllers schrijven niet langer validation_rules naar de JSON-kolom; writes gaan uitsluitend via replaceRules().
Configs-tabel landing (commit 5). form_field_configs is de parallelle tabel voor non-validation configuratie — tag_categories (TAG_PICKER-opties filter) en storage_disk (upload disk selector). Zelfde polymorphic-morph shape, eigen FormFieldConfigType enum, eigen FormFieldConfigService, eigen FormFieldConfigScope. De backfill-migratie pickt deze twee keys uit de pre-WS-5b JSON bag (die commit 2 welbewust skipte) en plaatst ze in form_field_configs vóór de JSON-kolomdrop in 2026_04_25_120002. De hernoemde FormFieldChildTablesCascadeObserver dekt nu drie child-tabellen (bindings, validation_rules, configs) op owner delete.
Drie scope-siblings. FormFieldBindingScope + FormFieldValidationRuleScope + FormFieldConfigScope — dezelfde UNION-over-two-owner-chains shape, drie near-duplicaten. Base-class extractie blijft uitgesteld tot WS-5d waar form_field_options als vierde sibling landt en het echte "wat varieert" zichtbaar zou moeten worden. Abstractie uit drie kopieën is nog steeds premature wanneer de vierde concrete implementatie aanstaande is.
Breaking change frontend-contract (commit 5). De JSON-contract wijziging landde atomair in commit 5 — geen bridging compatibility layer per de "Breaking change acceptance" clause in ARCH-FORM-BUILDER §0. Vier portal Vue-componenten gemigreerd naar de canonieke key-namen (min_value/max_value/max_length/max_selected). De tag_categories / storage_disk reads in resources bleven binnen de backend — de portal SPA had deze keys niet direct in gebruik, dus de hypothetische field.configs.tag_categories.categories frontend-migratie bleef beperkt tot documentatie (ARCH §17.5.5) tot een frontend consumer het aanroept.
JSON-kolommen gedropt. form_fields.validation_rules en form_field_library.validation_rules dropten in 2026_04_25_120002. SCHEMA.md v2.4 verwerkte de drop plus de nieuwe form_field_configs-sectie; ARCH-FORM-BUILDER bumped naar v1.6 met een volledig nieuwe §17.5. De rollback-path "roll back WS-5b commits 1–5 together" reconstrueert beide JSON-bag bestemmingen mergen validatie-rules en configs terug naar één bag per rij — niet te verwarren met de per-migratie partial rollback die niet ondersteund is.
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.
Q4 — Sanctum personal_access_tokens
Besluit: De Sanctum-default voor tokenable_type / tokenable_id (FQCN in DB, geen morph-map entry) blijft ongewijzigd.
Motivatie:
- Framework-polymorfie valt buiten de domain morph-map conventie. Een alias toevoegen introduceert onderhoudsschuld bij elke Sanctum-upgrade.
- Domain polymorfie (
form_schemas.owner_type,form_submissions.subject_type) blijft strict in morph-map geregistreerd; dit besluit raakt daar niet aan.
Documentatie-actie (WS-8): in de ARCH-documentatie wordt een expliciete regel opgenomen:
De
enforceMorphMap-conventie geldt voor domain polymorfe relaties. Framework-relaties (Sanctumtokenable_type, Spatieactivitylog.subject_type, Spatieactivitylog.causer_type) volgen hun framework-defaults en zijn expliciet uitgezonderd van de morph-map conventie.
Q5 — SCHEMA.md rewrite-shape
Besluit: WS-8 extraheert alle tabellen-zonder-migratie uit SCHEMA.md naar een apart document /dev-docs/ARCH-PLANNED-MODULES.md. SCHEMA.md wordt strict "waarheid van wat bestaat in de database".
Te verplaatsen tabellen (uit WS-1 rapport bevinding D-01):
- §3.5.4 Volunteer Profile & History:
volunteer_festival_history,post_festival_evaluations,festival_retrospectives - §3.5.6 Accreditation Engine:
accreditation_categories,accreditation_items,event_accreditation_items,accreditation_assignments,access_zones,access_zone_days,person_access_zones - §3.5.7 Artists & Advancing:
performances,stages,stage_days,advance_submissions,artist_contacts,artist_riders,itinerary_items - §3.5.8 Communication & Briefings:
briefing_templates,briefings,briefing_sends,communication_campaigns,messages,message_replies,broadcast_messages,broadcast_message_targets - §3.5.9 Check-In & Operational:
check_ins,show_day_absence_alerts,scanners,inventory_items,event_info_blocks,event_info_block_crowd_types,production_requests,material_requests
Onderhoud-pattern:
- Bij elke PR die een planned-module tabel aanmaakt verhuist de betreffende sectie van
ARCH-PLANNED-MODULES.mdnaarSCHEMA.md. Dit wordt onderdeel van de PR-template checklist. ARCH-PLANNED-MODULES.mdbehoudt de index/soft-delete/FK-intent zoals vastgelegd in de originele SCHEMA.md rijen, zodat de planning-informatie niet verloren gaat.- SCHEMA.md Rule 4 (required indexes) verwijst alleen nog naar bestaande tabellen na de rewrite.
Motivatie:
- Enterprise documentatie-discipline: onboarding developers zien direct wat er in de DB staat, zonder ruis van planning.
- SCHEMA.md Rule 4 consistent: required indexes kunnen niet meer verwijzen naar fantoom-tabellen.
- Planned-modules eigen evolutie: kan sneller bijgewerkt worden zonder SCHEMA-ruis.
Scope-impact: WS-8 wordt ~4-5 dagen in plaats van 2-3.
Q6 — subject_type allow-list
Besluit: De allow-list uit config/form_subjects.php wordt opgeheven en geconsolideerd onder de purpose-registry in WS-2. PurposeDefinition heeft per charter §3 besluit 4 al een subject_type veld; dat wordt de enige bron van waarheid.
Concreet (uitvoering in WS-2):
config/form_subjects.phpverdwijnt na WS-2.StoreFormSubmissionRequestleidt toegestanesubject_typewaarden af uitPurposeRegistry::allSubjectTypes().AppServiceProvider::bootbouwt de morph-map deels vanuit de purpose-registry (per purpose een subject-type entry) + framework-entries (activity-log subjects/causers, Sanctum uitgezonderd).- Compile-time guard: een unit-test faalt als een
subject_typeinPurposeRegistryniet in de morph-map staat, of vice versa. Dit vervangt de huidige "developer discipline" afspraak.
Motivatie:
- Eén bron van waarheid voor subject-semantiek. Geen twee-bestanden-sync met impliciete koppeling.
- Verstevigt charter §3 besluit 4:
PurposeDefinitionwordt écht de volledige purpose-specificatie.
Scope-impact: WS-2 krijgt ~halve dag extra werk. De migratie zelf is klein; het compile-time consistency testje is het echte werk.
Herziene werkstroom-scope en inschatting
Charter §5 inschattingen zijn op basis van dit addendum herzien:
| WS | Onderwerp | Charter inschatting | Herzien |
|---|---|---|---|
| WS-1 | Opsporings-pas | 1 dag | 1 dag (afgerond 2026-04-24) |
| WS-2 | Purpose registry | 2-3 dagen | 2-3 dagen + Q6 consolidatie (~halve dag) |
| WS-3 | Één SPA consolidatie | 3-5 dagen | 3-5 dagen (ongewijzigd) |
| WS-4 | ULID + denormalized submission columns + scope | 2-3 dagen | 5-6 dagen (Q1 elf ULID migraties + Q2 scope extension + scope-registratie op 14 models + D-05 Person SoftDeletes verify) |
| WS-5 | JSON-kolom-opsplitsing | 4-6 dagen | 7-8 dagen (Q3 library-mirrors toegevoegd aan WS-5a/b/d) |
| WS-6 | FormBindingApplicator | 4-5 dagen | 4-5 dagen (ongewijzigd) |
| WS-7 | Observability foundation | 2-3 dagen | 2-3 dagen + D-06 activity_log indexes |
| WS-8 | Documentatie-consolidatie | 2-3 dagen | 4-5 dagen (Q4 framework-exception + Q5 planned-modules extractie + PK-decisions doc) |
Totale herziene inschatting: 28-38 dagen werk (charter had 22-32 dagen). Toename van ~6 dagen, volledig verklaard door de strict-enterprise invulling van Q1, Q2 en Q3.
Werkstroom-volgorde ongewijzigd: WS-1 → WS-2 → WS-3 (parallel mogelijk met WS-4/5) → WS-4 → WS-5 → WS-6 → WS-7 → WS-8.
Openstaande bevindingen zonder architect-beslissing
WS-1 rapport Categorie D bevindingen die geen architect-beslissing vereisten en in de relevante werkstromen worden meegenomen:
| ID | Bevinding | Werkstroom |
|---|---|---|
| D-03 | Form-builder child models registreren OrganisationScope niet | WS-4 (als onderdeel van Q2 uitvoering) |
| D-04 (event-data subset) | ShiftAssignment / ShiftWaitlist / VolunteerAvailability / PersonSectionPreference / PersonIdentityMatch zonder scope | WS-4 |
| D-04 (user/admin subset) | MFA / TrustedDevice / UserProfile / EmailLog / OrganisationEmailSettings etc. | backlog, per-model ticket |
| D-05 | Person SoftDeletes verificatie | WS-4 |
| D-06 | activity_log (subject_type, subject_id) en (causer_type, causer_id) indexes |
WS-7 |
| D-07 | Morph map forward-looking entries documentatie-link | WS-8 |
Verwijzingen
/dev-docs/ARCH-CONSOLIDATION-2026-04.md— sprint charter (§1 principes, §3 vastgestelde besluiten blijven ongewijzigd; §5 inschattingen herzien in dit addendum)./dev-docs/ARCH-CONSOLIDATION-WS1-REPORT.md— bron van alle 45 bevindingen waarnaar dit addendum verwijst.
Sign-off
- Architect review: akkoord per Claude Chat sessie 2026-04-24, iteratief verscherpt over drie rondes (initial → strict-enterprise op Q1/Q3 → FK-chain correctie op Q2).
- Product owner: akkoord per Bert Hausmans 2026-04-24.
- WS-5a afronding: 2026-04-24 — relationele
form_field_bindingstabel, polymorphic owner, snapshot-parity, JSON-kolommen gedropt. - WS-5b afronding: 2026-04-25 — relationele
form_field_validation_rules+ parallelform_field_configstabel;validation_rulesJSON-kolommen gedropt; frontend-contract migratie naar canonieke key-namen landed in commit 5.
Volgende stap: prompt opstellen voor WS-2 (Purpose registry) met Q6-consolidatie als integraal onderdeel van de werkstroom.