Creating tables
The add-table builder is reached at /admin/tables/new. It is a single form
that stages a draft table — profile, name, and an ordered list of columns —
and creates it in one call. The server stays the single owner of the draft’s
rules, the same ones the TUI client applies between keystrokes.
The routes
Section titled “The routes”| Method | Route | Purpose |
|---|---|---|
GET |
/admin/tables/new |
renders the builder |
POST |
/admin/tables/builder |
stages every button press and field change |
POST |
/admin/tables |
creates the table |
The builder can be entered with ?profile=<name>&global=true so the picker
opens on the profile (or global scope) the admin panel handed over.
Profile and name
Section titled “Profile and name”The profile selector lists existing profiles plus a special New profile
choice (__new__). Choosing it reveals a text input for the new profile’s
name; creating the table then creates the profile too. A new profile also asks
for an accounting currency, because provisioning its accounting system tables
requires one. Books are currently EUR-only, so a non-EUR currency is refused by
the backend.
The global toggle puts the table in the Global scope (__global), shared by
every profile. The table name must be an identifier, must not duplicate an
existing table in the profile, and reserved names such as pg_catalog are
refused.
Staging columns
Section titled “Staging columns”The column panel is the same vocabulary described in How table definitions work. For each pending column you set:
- name;
- type (with the follow-ups for
temporal,gtin,decimal(p,s), andlink(table)); - indexed toggle;
- quantity ledger toggle (only for the types that allow it);
- currency and rounding (
exactorhalf-up) for money and accounting types; - row display toggle, which decides whether the column identifies a row.
Columns can be added, removed, reordered, and index-toggled before creation.
The declared order is the order the table gets its columns in, and the preview
shows what will really exist — including the system columns id, deleted,
and created_at, and any columns a compound type expands into.
Accounting columns
Section titled “Accounting columns”Choosing the accounting type (a compound, creation-only type) generates the
managed columns name, tax_point_date, debit, credit, and account.
The definition row must be named accounting and carry a currency equal to
the profile’s book currency; the generated debit and credit columns inherit
that currency and rounding.
Generated-column aliases
Section titled “Generated-column aliases”Generated columns can be renamed from the builder. The alias fields have no
change trigger of their own — type the names, then press the button that
applies them, so the preview matches what the table will really be called.
An alias must be a valid column name and must not collide with a declared
column, another generated column, or a system column.
Creating
Section titled “Creating”The draft is validated locally with the same checks the client runs, then the
server re-validates authoritatively. A refused create answers 422 with the
reason rendered into the builder. On success the browser redirects to the
admin panel with the new table selected:
/admin?profile=<name>&table=<name>From there the new table’s initial grants, columns, and other actions are one click away.