Platform concepts
Platform concepts
Who this is for: integrators, implementers and project owners who build on the platform and want one picture of what it is made of and how the pieces fit.
What it covers: the document tree, data tables and their columns, forms, dashboards, spreadsheets, the customer portal and the rights model. It is conceptual. Click-by-click steps are in the and the ; installing ready-made setups is in .
The big picture
A project is one tree of items. "Item" is the umbrella word: folders, rich-text documents, data tables, forms, dashboards, spreadsheets, whiteboards and links all live in the same navigator and share the same rights model. You organise them in folders, and you share any of them with your team or with external portal users.
Most business data lives in data tables. Everything else either feeds a table (forms), reads a table (dashboards), references a table (links, lookups, rollups) or frames it (documents, the portal).
Form ----- writes rows -----> Data table <----- reads and totals ----- Dashboard
| ^ ^
links, lookups | | rollups | reads ranges
and rollups v | |
Data table Spreadsheet
Portal (external users) -- sees only what you share, row by row --> tables, forms, dashboards, documents
Item types
Type (menu entry) | What it is |
|---|---|
Folder | A container. Can break rights inheritance and can be shared with the portal as a whole |
Document | A rich-text page, edited by several people at once |
Data table | The core data primitive: typed rows and columns. Every business object (customer, invoice, work order) is a row in a table |
Form | A form that writes a row, or a header row plus line rows, into a target table |
Dashboard | Panels that read and chart data from tables and spreadsheets |
Spreadsheet | A collaborative Excel-compatible workbook |
Link | A shortcut in the tree to another item or to a saved view of a table |
Whiteboard | A visual board for sketching and planning together |
Site | A public shop or booking website built on a catalogue or bookings table |
Connector | A link to an outside service: payments, delivery, CRM, telephony, speech, addresses |
App connection | The binding between the project and a custom front-end application. Developer-facing |
The project also keeps shared tools that items rely on: document states, tags, working calendars, an asset library and person directories. See .
Three audiences
Your team works in the project with rights on each item.
Portal users are your customers and partners. They sign in to a separate website and see only what you publish to the portal.
Data tables: the core primitive
A data table is a set of rows described by typed columns. Unlike a spreadsheet, every column has a type that controls how its values are entered, checked, shown, filtered, sorted and exported. The server checks every write, whichever way it arrives (grid, form, import, automation, portal). The behaviour is described in .
Column types
There are 42 column types. The Add column dialog offers 40 of them. Completeness is filled in by the engine and Working calendar is allowed only on the staff directory. Each type, with its settings, is on . By purpose:
Group | Types (internal key in |
|---|---|
Text and numbers | Text ( |
Dates | Date ( |
Choices and workflow | Select ( |
People | Person ( |
Contact details | URL ( |
Files and media | Files ( |
Links and computed | Reference ( |
Engine-maintained | Sequence ( |
Scheduling and location | Geofence ( |
Product catalogues | Attribute set ( |
Computed columns recalculate automatically when their inputs change. You never type into a Formula, Rollup, Lookup, Sequence or Balance cell.
Links (references)
A Reference column links a row to one or more rows of another table, or of the same table. It is how you model relationships: an invoice line references its invoice, an order references a customer, a category references its parent. A reference can be single or multiple, can filter which rows the picker offers, and can mark a hierarchy parent (a self-link, for trees such as locations or categories).
Lookups and rollups (derived data)
Once tables are linked you can show related data without copying it.
Lookup: "show this product's price on the order line". It pulls one field from one linked row.
Rollup: "total of all lines on this invoice". It aggregates a column across many related rows. The functions are Sum, Average, Min, Max, Count, Count unique, Concatenate, Count by value (a tally per option, shown as badges) and Collect references. A tally can be added up a hierarchy with Include all sub-levels.
A rollup runs backward (rows that reference this row) or forward (rows this row references). That is why an invoice total updates when you add a line, and a customer's balance reflects their open invoices.
A Formula calculates from other cells of the same row, with 88 functions in 18 families. It can also reach other tables through functions that match rows by value. When rows are already linked, prefer a lookup or rollup. See and .
Status and workflows
A Status column turns a table into a process. Each state has a name, a colour and a meta-status (New, Draft, In Progress, Finished, Declined), and can:
restrict which states it can move to (a real state machine, if Enforce transition workflow is on);
lock the row, so a posted ledger entry or a signed note cannot be edited;
require fields before the row may enter the state;
move the row on its own, based on data (an invoice becomes Paid when its outstanding amount reaches zero) or on time (a quote Expires after a timeout);
limit by group who may move a row into the state, edit it or comment in it.
The product ships ready-made lifecycles for invoices, purchase orders, sales, work orders, bookings, memberships, reservations and more. They arrive with the modules in . Details are in .
Views
A view is a saved way of looking at one table: filters, sort, hidden and pinned columns.
View | What it shows |
|---|---|
Grid | The default rows-and-columns table |
Kanban | Cards grouped by a column (Select, Status, Priority or Person). Dragging a card changes the value and, on a status column, runs the workflow |
Calendar | Rows placed by a date column |
Timeline | Bars from planned start and end dates, with lanes |
Pivot | A read-only crosstab with up to 3 row levels and 2 column levels. Offered on every table |
Matrix | One master product's variants in a grid of two axes |
Price pivot | Products against price-list columns. Only on a price-list table |
Roster | Resources against days, with shifts. Only on a shift-schedule table, or any table with a resource column and planned dates |
Booking calendar | Resource against time slots, optionally published as a booking page. Only on booking-appointment tables |
Purposes and behaviours
Two concepts let the platform treat an ordinary table as a specific business object:
A purpose is the table's meaning, such as core_customer, core_invoice or core_work_order. Modules, cross-table links and some features use it to find "the customers table" without hard-coding an id. Set it in Table behaviour & roles, or with the datatable_set_meta tool.
Ledger: an append-only log of movements. Posted rows cannot be edited, only reversed. A Balance column on a master table sums these movements (stock on hand, store-credit wallet, account balance).
Exclusive scheduling: double-booking protection for a time-bound resource (a technician, a room, a table, a vehicle and driver). Set directly in Table behaviour & roles, or with datatable_set_behaviour.
Price list and Exchange rates: back the PRICE_FOR and FX_RATE formula functions.
Person directory and Secondary directory: the staff table (one per project, with working calendars) and a people list without calendars.
Recurring billing is not a behaviour. It is the Issue recurring invoice automation action.
You rarely set these by hand. Installing a module or a business type creates tables with the right purposes, behaviours, links, rollups and workflows already wired. See and .
Forms: getting data in
A form is a surface that writes a row into a target table. It is the intake layer: people add data without edit access to the table itself. A separate Submit right governs forms.
What a form can do:
Collect typed input. Fields are bound to table columns: text, number, date, choice, file upload, a reference picker. Computed columns are never inputs.
Validate. Required fields and length, pattern and range rules, checked on the client and on the server.
Stamp the submitter. The row records who submitted (a team member or a portal user) and when, on the server, so it cannot be faked.
Create line-item forms. One submission creates a header row plus its line rows together, or nothing at all (an order with its lines, an invoice with its lines). Lines can be added with an item picker, cards over a catalogue, a list, or a spreadsheet-style table.
Enrich from a catalogue. When a line field references a product, the form can show read-only preview columns (price, stock), freeze a value onto the line as a snapshot (price at the time of order), or keep it live through a lookup.
Capture provenance. Submission time, a source label, and optional IP, browser, referrer and UTM values.
Collect consent, with a versioned consent text.
Speak several languages. Labels, help text and messages per language.
Forms come in three flavours:
Internal: for signed-in team members.
Portal: for signed-in customers. The submitter is stamped as a portal user.
Public: anonymous and shared by link (lead capture, feedback), with an optional captcha and rate limiting.
The key idea: forms separate intake from editing. Field teams, partners or the public can submit data while your tables stay protected from direct writes. See .
Dashboards: reading the data
A dashboard is a panel-based reporting page without SQL. Each panel binds on its own to a data table, or to a spreadsheet range, and shapes the data with filters, grouping and measures.
Panel | What it shows |
|---|---|
Metric | One number (total revenue, active members), optionally with a trend line or a gauge |
Chart | Bar, stacked bar, 100% stacked bar, horizontal bar, line, area, stacked area, pie, donut or funnel, with a category, measures and an optional breakdown series |
Pivot | An interactive crosstab: up to 3 row levels by 2 column levels, with subtotals, grand totals, heatmap colouring and CSV export |
Table | Rows of a table as a grid or cards |
Spreadsheet | A read-only view of sheets from a workbook |
Text | A heading, note or caption |
How panels get their data:
Binding. Point a panel at a table (by item), or at a spreadsheet by item plus a named range or an A1 range.
Query. Filters (combined with AND), dimensions (group-by and pivot axes), measures (sum, average, min, max, counts, and a weighted average), an optional breakdown series, sorting and a Top-N limit.
Slicers. Dashboard-level filter strips that viewers click. A slicer filters every panel whose table has that column, so one choice re-scopes the whole page. Viewers' choices are not saved for others.
Panels read live data. When a source table changes while someone looks, the page offers Refresh.
On the portal, a dashboard can be published read-only. Metric, Chart, Pivot and Table panels honour each viewer's row-level access. Spreadsheet panels, and panels that read a spreadsheet, are not available on the portal or on a public page, because a spreadsheet has no per-viewer row filtering. Publishing a dashboard exposes no source table by itself: each source needs its own decision. See .
Spreadsheets
A spreadsheet is an Excel-compatible workbook that several people edit in real time. It lives in the tree like everything else, with formulas, formatting and several sheets. It is a free-form calculation surface, complementary to data tables, which hold structured, queryable records.
Spreadsheets and tables meet in dashboards: a Metric or Chart panel can read a named range or an A1 range from a spreadsheet, so you can model in a sheet and chart it next to table data. Use a spreadsheet for ad-hoc modelling and a data table for the transactional, related records that drive workflows and rollups. See .
Portals: sharing with external users
The portal is your project's window to people outside your team: customers, clients, vendors, contractors. They sign in separately and see only what you share, narrowed to only their own rows where you configure it. Their accounts are separate from team accounts.
Who they are
Portal users: individual external people, identified by email.
Portal groups: sets of portal users, for sharing in bulk.
Portal companies: records that link portal users to a company in your data, so you can share "everything for Acme Corp" at once.
What they can do: open shared items, submit forms, comment and, where you allow it, edit together in real time. They see nothing else.
How sharing works. You grant a right on an item or folder to a principal: a portal user, a company or a group. A folder marked access-restricted replaces inherited rights for its whole subtree. By default an external user sees nothing until you share (fail-closed). Sharing an item to the portal is a separate switch from granting a right. See .
Per-viewer row filtering. The same table can show each viewer a different slice. The Row filter on a table has three settings:
Only the rows they created: a customer sees the rows they submitted, such as their own requests.
Rows matching their profile: a column is matched against the viewer's company, group or other attributes, such as the orders of their company.
Everyone sees all rows: for reference data such as a price list.
A table with no row rule and no submitter column is blocked on the portal, never shown in full.
Sign-in. An emailed link or a 6-digit code, a password, a passkey (WebAuthn), and a Telegram mini-app login.
Start pages. You choose the item each external user lands on, per user, company or group. If several apply, the order is user, then company, then group. A start page the person cannot open is skipped. See .
CORS allowlist for your own front end
If a customer-built web app calls the portal API from its own website, add that website's origin to the project's allowlist (External Portals, CORS settings). Each entry is either an exact origin (https://app.example.com) or a one-level wildcard (https://*.example.com). A bare * is always rejected.
Careful: every entry is a trust grant. Any page on that origin can call the portal and public form services with the visitor's sign-in, read every answer a signed-in portal user would receive, and learn which project addresses, item numbers and row numbers exist from the difference between "not signed in" and "not found" replies. Add only origins the customer controls. Never add shared sandbox or hosting sites such as
codepen.io,jsfiddle.netor*.vercel.app, where any tenant can publish arbitrary JavaScript. Confirm any wildcard deliberately: it widens the grant to every site under it.
Rights, in one place
Access is governed by 12 rights. They are granted to a person or a group, on the whole project or on one item, and inherit down the folder tree until an access-restricted folder resets them. The same rights apply to every item type, to team members and to portal principals.
Right | What it grants |
|---|---|
Read | See the item or the table's rows. The base for everything else |
Comment | Comment on rows and items (includes Read) |
Fill fields | Fill an item's fields and comment, without editing its text (includes Read and Comment) |
Edit | Change content and rows (includes Read, Comment and Submit). Uses an editor seat |
Submit | Submit a form without edit rights on the table behind it (includes Read) |
Chat | Use the AI assistant on the item |
AI Jobs | Start long AI jobs, kept apart from Chat because they cost more |
Manage Members | Add and remove people and grant access (every right except Owner) |
Manage External Users | Invite, block and relink portal users |
Manage Working Calendar | Edit working calendars (weekends, holidays) |
Owner | Everything, including managing access. Only an owner can grant or remove it |
Billing | Marks the one person the project is billed to. Not ticked in the rights picker |
Anonymous public access is not a right: it comes from publishing the item and the project. Not every dialog offers every right, and the per-item Manage access… dialog calls the Owner right Manage. The full matrix, the invite presets and what each menu item needs are in the .
How it fits together: a worked example
A wholesale coffee seller installs the Inventory & Stock and Invoicing & Payments modules, adds an Orders table of their own, and then:
Portal order form --header + lines--> Orders ---reference---> Customers
| line items reference
v
Catalogue <--balance (on_hand)-- Stock movements (ledger)
Orders --rollup: order total
Orders --workflow--> Invoices <--rollup: amount paid-- Payments
Invoices --auto: outstanding = 0--> Paid
Invoices + Catalogue --> AR and stock dashboard
Invoices --row filter by company--> the customer's portal view
A customer submits the portal order form. It creates an order row plus its line rows in one step, and stamps the customer as submitter.
Lines reference the catalogue. A lookup copies the current price and a rollup sums the order total.
The order's status workflow leads to an invoice. Recorded payments roll up into the invoice's amount paid, and a conditional transition moves the invoice to Paid when the balance clears.
Fulfilment writes stock movements into the ledger, and the catalogue's on-hand balance updates in the same save.
A dashboard charts receivables and stock. The customer sees only their own invoices in the portal, through a Row filter.
Every arrow is a feature described on this page: references, rollups, workflows, ledgers and balances, forms, dashboards and portal scoping. The modules wire the common combinations for you.