From c33787912c0234772c23a5c810df399c7e47fca3 Mon Sep 17 00:00:00 2001 From: johndoe6345789 Date: Thu, 19 Mar 2026 09:20:28 +0000 Subject: [PATCH] fix(dbal): add tenantId auto-add to loadFromDirectory, fix ComponentNode schema loadFromDirectory() was missing the tenantId field auto-add logic that loadFromFile() already had, causing "Unknown field: tenantId" on all entities using the shorthand `"tenantId": true` convention. Also corrected ComponentNode schema to match the C++ struct fields (pageId, parentId, childIds, order) instead of the wrong Redux shape. Co-Authored-By: Claude Opus 4.6 (1M context) --- .../production/src/adapters/schema_loader.hpp | 16 ++++++ .../entities/codeforge/componentNode.json | 57 ++++++++++++------- 2 files changed, 51 insertions(+), 22 deletions(-) diff --git a/dbal/production/src/adapters/schema_loader.hpp b/dbal/production/src/adapters/schema_loader.hpp index 87957e46c..723ba2b02 100644 --- a/dbal/production/src/adapters/schema_loader.hpp +++ b/dbal/production/src/adapters/schema_loader.hpp @@ -259,6 +259,22 @@ public: entity.fields.push_back(field); } } + // Auto-add tenantId field if top-level tenantId: true is set + if (json.contains("tenantId") && json["tenantId"].is_boolean()) { + if (json["tenantId"].get()) { + bool has_tenant = false; + for (const auto& f : entity.fields) + if (f.name == "tenantId") { has_tenant = true; break; } + if (!has_tenant) { + FieldDefinition tenant_field; + tenant_field.name = "tenantId"; + tenant_field.type = "string"; + tenant_field.required = false; + tenant_field.nullable = true; + entity.fields.push_back(tenant_field); + } + } + } if (json.contains("indexes")) { for (const auto& idx : json["indexes"]) { IndexDefinition index; diff --git a/dbal/shared/api/schema/entities/codeforge/componentNode.json b/dbal/shared/api/schema/entities/codeforge/componentNode.json index 1b4195f5a..daa694b06 100644 --- a/dbal/shared/api/schema/entities/codeforge/componentNode.json +++ b/dbal/shared/api/schema/entities/codeforge/componentNode.json @@ -1,7 +1,7 @@ { "entity": "ComponentNode", "version": "1.0", - "description": "Visual component definition with props and child hierarchy", + "description": "Visual component node in a page tree with parent-child hierarchy and ordering", "tenantId": true, "fields": { "id": { @@ -10,34 +10,34 @@ "generated": true, "description": "Unique component node identifier" }, - "name": { + "pageId": { "type": "string", "required": true, - "max_length": 255, - "description": "Component display name" + "description": "Page this component belongs to" + }, + "parentId": { + "type": "string", + "optional": true, + "nullable": true, + "description": "Parent component ID (null for root components)" }, "type": { - "type": "enum", + "type": "string", "required": true, - "values": ["atom", "molecule", "organism"], - "description": "Component classification tier" + "min_length": 1, + "max_length": 100, + "description": "Component type name" }, - "code": { - "type": "text", + "childIds": { + "type": "string", "required": true, - "description": "Component source code" + "description": "Serialized list of child component IDs" }, - "props": { - "type": "json", - "description": "Array of prop definitions [{name, type, required, defaultValue, description}]" - }, - "metadata": { - "type": "json", - "description": "Additional component metadata" - }, - "updatedAt": { - "type": "bigint", - "generated": true + "order": { + "type": "integer", + "required": true, + "default": 0, + "description": "Display order within parent scope (non-negative)" } }, "indexes": [ @@ -45,9 +45,22 @@ "fields": ["tenantId"] }, { - "fields": ["type"] + "fields": ["pageId"] + }, + { + "fields": ["parentId"] + }, + { + "fields": ["pageId", "parentId", "order"] } ], + "relations": { + "page": { + "type": "belongs-to", + "entity": "UiPage", + "foreign_key": "pageId" + } + }, "acl": { "create": { "user": true }, "read": { "self": true, "admin": true },