# Table Builder Workflow

The Table Builder module lets tenant administrators create new database tables without deploying code. Definitions are stored in the `tenant_tables` table as JSON describing each column.

`TableBuilderController` exposes a `create` endpoint that stores the definition and immediately builds the table. The controller verifies the record belongs to the current tenant before running any SQL. Super Admins can still call `POST /api/table_builder/build/{id}` to manually rebuild a table and `POST /api/table_builder/alter/{id}` to apply column changes using `ALTER TABLE` statements generated from the stored definition.

## Dynamic IndexedDB Schema

Client side storage uses IndexedDB via `LocalSyncManager`. The list of object stores is produced by `api/schema.php`. This script loads the static base stores from `schema.js` and merges any table names found in `tenant_tables`. It outputs JavaScript defining `DB_VERSION` and `DB_STORES` so modules can import it directly.

`DB_VERSION` is calculated as `100 + MAX(id)` from `tenant_tables`. Whenever a new table is created the version increases automatically which forces browsers to recreate their IndexedDB databases.

## Typical Workflow

1. Open **Table Builder** from the dashboard and create a new record specifying the table name and columns. **Super Admins (user ID 1) may omit `tenant_id` to create a global table without the tenant prefix.**
2. Saving the record immediately executes the `CREATE TABLE` statement.
   A model file named after the table is also generated under `models/` so
   controllers can access the new table using `ModelHandler`.
3. Call `POST /api/table_builder/alter/{id}` to apply column changes or `POST /api/table_builder/build/{id}` to manually rebuild the table if needed.
4. Apply the migration `20250901_allow_null_tenant_tables.sql` and then run `./test_setup.sh`, `phpunit` and `npm test` to verify the update. The setup script recreates the database and `schema.php` will now export the new table in `DB_STORES`.

No manual edits to `schema.js` are required. Simply creating the table and rebuilding the test environment ensures offline modules know about the new store.
