feat(companies): add kvk_number column for B2B identity binding (WS-6)

WS-6 binding-target registry references company.kvk_number as a B2B
identity-key candidate. The column needed to exist on the model
before the registry could legitimately reference it. Nullable
because not every Company has a registered KvK (foreign companies,
partners, agencies); identity-key publish guards enforce presence
where required, not at schema level.

Changes:
- New migration `2026_04_28_140000_add_kvk_number_to_companies_table`
  adds nullable string column + index after `type`.
- Company::$fillable expanded.
- CompanyFactory generates an 8-digit KvK by default.
- CompanyKvkNumberTest covers attribute persistence, nullability,
  and information_schema-verified index existence.
- SCHEMA.md → v2.8 with the new column row + indexes line.
- Schema dump regenerated (CI fast-path).

Migration step counts in 5 backfill tests bumped +1 (the new
migration sits at the top of the migration stack):
  - FormFieldBindingMigrationTest:           18→19, 16→17
  - ConditionalLogicBackfillTest:             7→8
  - FormFieldConfigBackfillAndDropTest:      13→14
  - FormFieldOptionsBackfillTest:             3→4
  - FormFieldValidationRuleBackfillTest:     16→17

Refs: WS-6 sessie 3a binding-target drift audit

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-04-28 20:17:56 +02:00
parent 7bf14790d8
commit 3733554e5d
11 changed files with 116 additions and 29 deletions

View File

@@ -1,10 +1,17 @@
# Crewli — Core Database Schema
> Source: Design Document v1.3 — Section 3.5
> **Version: 2.7** — Updated April 2026
> **Version: 2.8** — Updated April 2026
>
> **Changelog:**
>
> - v2.8: WS-6 session 3a.5 — `companies.kvk_number` column added
> (nullable, indexed). Aligns with the binding-target registry's
> B2B identity-key candidate. Registry entries renamed/removed in
> the same session to match real model columns; consistency test
> extended with model-existence + column-existence assertions.
> RFC-WS-6.md v1.2 §3 Q9 addendum.
>
> - v2.7: WS-6 session 2.5 — `form_schemas.default_crowd_type_id` column
> added (nullable; required at publish time for event_registration via
> RequiresDefaultCrowdType guard). Replaces the silent `oldest()`
@@ -909,13 +916,14 @@ $effectiveDate = $shift->end_date ?? $shift->timeSlot->date;
| `organisation_id` | ULID FK | → organisations |
| `name` | string | |
| `type` | enum | `supplier\|partner\|agency\|venue\|other` |
| `kvk_number` | string nullable | KvK registration number (Dutch Chamber of Commerce). Indexed. **v2.8 — WS-6 sessie 3a.5** |
| `contact_first_name` | string nullable | |
| `contact_last_name` | string nullable | |
| `contact_email` | string nullable | |
| `contact_phone` | string nullable | |
| `deleted_at` | timestamp nullable | Soft delete |
**Indexes:** `(organisation_id)`
**Indexes:** `(organisation_id)`, `(kvk_number)`
**Soft delete:** yes
---