refactor(form-builder): pre-publish check reads form_field_bindings; drop binding JSON columns

This commit is contained in:
2026-04-24 20:09:27 +02:00
parent 6933e6d700
commit 61719bf8bf
18 changed files with 375 additions and 97 deletions

View File

@@ -128,28 +128,24 @@ final class VerifyFormsDataIntegrity extends Command
->havingRaw('COUNT(*) > 1')
->count();
// Binding registry cross-check
$binding = (array) config('form_binding', []);
// Binding registry cross-check (WS-5a: relational form_field_bindings).
$registry = (array) config('form_binding', []);
$badBindings = 0;
$invalidBindings = DB::table('form_fields')->whereNotNull('binding')->select('binding')->get();
foreach ($invalidBindings as $row) {
$b = is_string($row->binding) ? json_decode($row->binding, true) : null;
if (! is_array($b) || ! isset($b['mode'], $b['entity'], $b['column'])) {
$bindingRows = DB::table('form_field_bindings')
->select(['mode', 'target_entity', 'target_attribute'])
->get();
foreach ($bindingRows as $row) {
if (! in_array($row->mode, ['entity_owned', 'mirrored'], true)) {
$badBindings++;
continue;
}
if (! in_array($b['mode'], ['entity_owned', 'mirrored'], true)) {
if (! isset($registry[$row->target_entity][$row->target_attribute])) {
$badBindings++;
continue;
}
if (! isset($binding[$b['entity']][$b['column']])) {
$badBindings++;
continue;
}
if (($binding[$b['entity']][$b['column']]['writable'] ?? false) !== true) {
if (($registry[$row->target_entity][$row->target_attribute]['writable'] ?? false) !== true) {
$badBindings++;
}
}