# Multi-Tenant Custom Fields

This feature allows each tenant to define additional fields for any model.
Two tables store the definitions and values:

- `custom_fields` – field metadata scoped to a tenant.
- `custom_field_values` – values for a particular record.

Both tables include `tenant_id` and optional `branch_id` so data remains
isolated between counsels.

```
CREATE TABLE `custom_fields` (
  `id` int AUTO_INCREMENT PRIMARY KEY,
  `tenant_id` int NOT NULL,
  `branch_id` int DEFAULT NULL,
  `model` varchar(100) NOT NULL,
  `field_name` varchar(100) NOT NULL,
  `field_type` varchar(50) NOT NULL,
  `is_required` tinyint NOT NULL DEFAULT 0,
  `options` json DEFAULT NULL,
  `isDeleted` tinyint NOT NULL DEFAULT 0,
  `updatedAt` timestamp NOT NULL DEFAULT current_timestamp
);
```

```
CREATE TABLE `custom_field_values` (
  `id` int AUTO_INCREMENT PRIMARY KEY,
  `field_id` int NOT NULL,
  `record_id` int NOT NULL,
  `field_value` text,
  `tenant_id` int NOT NULL,
  `branch_id` int DEFAULT NULL,
  `isDeleted` tinyint NOT NULL DEFAULT 0,
  `updatedAt` timestamp NOT NULL DEFAULT current_timestamp
);
```

`ModelHandler` now merges these tenant fields with the default model
configuration at runtime. When constructing a handler it loads any
custom field definitions for the current tenant and adds them to the
`fields` array. Controllers can then read and persist custom values
using `custom_field_values`.

To override the connection for a specific tenant, add an entry to
`config/storage.php` under the `tenants` key with a DSN or schema name.

Run `./test_setup.sh` followed by `phpunit` and `npm test` to verify
schema and runtime changes.
