Skip to content

MATRIZ — Canonical Terminology

One word per concept. When code, UI, or docs disagree, this file wins. Casing convention across boundaries: DB columns are snake_case, TypeScript types/fields are camelCase, and REST/JSONB wire payloads use snake_case (to match DB column names). Drizzle converts between the first two automatically.

Concept Canonical term What it is Do NOT also call it
Tree element node (API/types); UI may say “element” for UX A row in dom_nodes — a div/section/heading/component-instance in the page tree. domNode (ok as the TS type DomNode), “block”
Page page (informal) A subtree rooted at a dom_node with is_page_root = true, addressed by page_path. —
Page metadata site_page Editorial/SEO metadata row (site_pages: title, slug, seo, status). Distinct from the node tree. “the page record” (ambiguous)
Reusable definition component A template in the components table (Button, Card, …). “element definition”
A component on a page component instance A node carrying component_instance JSONB (variant + slot overrides + link status). “component node” (ok informally)
A user-created reusable subtree symbol (symbols DB table, D:symbols-v1) A per-target, user-created reusable component: a dom_nodes subtree marked as the master, whose instances are linked copies kept in sync (workers/src/routes/symbols.ts, runSymbolSync, D:symbol-lineage-pairing). Name collision, unrelated concept: “site symbol” (@current.<name>, see the Recurring-structures section below) is a completely different, unrelated feature — a dated pointer to “the current X”, nothing to do with reusable components. When either name could be ambiguous, say “symbol (reusable component)” for this one and “site symbol” for the other. bare “symbol” where a site symbol could also be meant
Content schema column field A column in a content_type.schema (CMS). “slot”
Component/text content key slot A keyed content value on a node (slot_values), e.g. text, src, href. Y.Text-backed for text. “field”, “property”
CMS row content item A row in content_items (itemId in REST params, ContentItem in TS). —
Repeating UI container repeater A node that renders its template once per item of a bound collection. “list block”
The bound data set collection A content_type with many items (data_source.type = 'content_collection'). “repeater” (that’s the UI), “list”
Node → data link data_binding JSONB on a node mapping it to a collection/item + per-slot bindings. “binding config”
Design token design token (DesignToken TS / /api/tokens REST / design_tokens DB) A named design value resolved to a CSS variable. “variable”
Make a site live publish Compile published nodes → static HTML → R2 (POST /api/publish/:siteId). “deploy”, “build”
Ship code/infra deploy wrangler deploy / CI deploy of the Worker or Pages app. “publish”
Record of a publish build A row in builds tracking one publish’s result. “deploy”
Tenant boundary project The projects table row. The Clerk organization IS the project — projects.id is the Clerk org_... text id (personal/no-org sessions use a Clerk user id instead). Holds billing, team membership, design systems. “org” (ok informally, but “org” is Clerk’s word, not the DB’s), “site” (that’s a target)
Identity provider’s team object Clerk org The organization object Clerk itself manages (membership, invites, the org:admin/org:member built-in roles). 1:1 with a project once synced via /api/webhooks/clerk. “project” when talking about Clerk’s own UI/API surface
Deployable site target A row in targets (formerly sites) — one publishable site inside a project. targets.projectId scopes it. Code still spells this siteId/site_id almost everywhere (see the Naming drift note in CLAUDE.md) — a “site” in frontend/route code is a target. “site” in new code/docs (fine as a legacy spelling in existing code)
A project’s builder-side user user (Clerk user) A human with a Clerk account who edits sites in the Worker/editor. users.id is the Clerk user_... text id. Distinct from a visitor/member below — a Clerk user never has a data-member-visible state. “member” (that’s a site’s own end-user), “visitor”
A published site’s signed-in end-user member A row identified by visitorId/memberId, authenticated by the first-party member-auth system (Visitor Auth D73/VA-3: MEMBER_SESSION_SIGNING_KEY, the __matriz_member cookie). Not a Clerk identity at all — a completely separate, parallel auth system for a target’s own audience (readers, customers, portal users). “user” (ambiguous with Clerk user), “visitor” alone once authenticated
A published site’s anonymous end-user visitor Anyone viewing a published site before/without completing member sign-in. Becomes a member once a session is minted. data-member-visible="anon|signed-out" targets this state. “member”
Project permission tier ProjectRole One of five capability bundles in packages/schema/src/rbac.ts: viewer (read only), content-editor (CMS content + publish, no structure), editor (content + structure, no publish), publisher (editor + publish + domains + members), admin (everything + backup-restore, team/roles, keys, billing, delete). Deliberately NOT a strict linear hierarchy — a content-editor can publish but not touch structure. Resolved per-request by resolveEffectiveRole (hybrid model: Clerk’s claim owns the admin bit, project_users.role owns the other four tiers). “permission level”, “access tier”

Recurring structures + live time — built (waves 0–3)

Section titled “Recurring structures + live time — built (waves 0–3)”

The rows below name vocabulary for plans/RECURRING-STRUCTURES-AND-LIVE-TIME-PLAN.md (D:recurring-structures). Waves 0–2 are built and merged (PR #682): schedules, gates, derive rules, upsert scope, symbols, /time + /symbols, temporal visibility rules and deferred pre-filters, rollups, the table element + CSV/XLSX export, submission identity + row moderation, multi-image member uploads, and collection triggers/instantiation (an item created in a container spawning forms/pages from a template) all exist in code today. Wave 3 (D:recurring-setup-ui) added the guided CMS surfaces — Recurring setup, the edit gate editor, a UI for the collapse-slots pass — named below. Everything in this section describes present behaviour, not a plan.

Concept Canonical term What it is Do NOT also call it
An occurrence collection container A collection whose items are occurrences of a recurring thing (an edition, a season, a cohort) and that may carry a schedule field; the specific noun (edition, cohort, season) is the domain’s own label for its container. “phase collection”, “occurrence type”
Ordered dated periods on an item schedule A field type holding an ordered, non-overlapping list of periods, fully edited in the CMS — no code, no per-period collection. “phases list”, “calendar field”
One dated entry in a schedule period { key, label, start, end, gates, data }; “the current period” is the one whose [start, end) contains the clock. “phase” (a 12x12 label, not a system term)
A period’s on/off switch gate A boolean on a period (submit/edit/show) that forms, member-item edits and visibility rules obey live — an admin moving a date changes the verdict on the next request. “deadline flag”, “window”
A named “current thing” pointer site symbol (@current.<name>) A dated pointer, declared in targets.settings.symbols (SymbolDef, workers/src/lib/symbols.ts), that resolves to “the current X” (an item, and its current period) wherever a request has a clock. Name collision, unrelated concept: the symbols DB table (D:symbols-v1) is a per-target user-created reusable component — a completely different feature that predates this one and keeps its own name in code and UI. When either name could be ambiguous, say “site symbol” for this concept. “variable” (reserved for design tokens), “pointer field”, bare “symbol” where the reusable-component table could also be meant
A server-side stamp rule on a form derive rule A rule (stamp_time, symbol, symbol_period, constant) that writes a field from the clock/symbol at ingest, overwriting any client-submitted value for that key. “computed field” (that’s a rollup), “hidden input”
A write’s replace-identity upsert scope (upsertScope) A declared list of fields whose values plus the visitor id form a write target’s identity, so re-submitting replaces that row atomically instead of duplicating it. “dedupe key”, “unique constraint” (the DB mechanism underneath it)
A read-only reverse reference rollup A field type computed at query time from another collection (e.g. “all works by this member”); never stored, never a form input. “computed field”, “reverse relation”, “join field”
A designable, exportable grid element data table (element type table) A page element bound to a collection or a rollup that renders a grid with configured columns, sorting/filtering, and CSV/XLSX export. “grid”, “repeater” (a repeater has one template, not columns or export)
A date-driven condition settled live temporal rule A visibility rule or pre-filter whose operand is a date, @now, or a relative token — marked at publish, settled in the visitor’s browser against a server-corrected clock. “date filter”, “live filter”
A flow step that spawns from a template instantiation A FlowStep that creates forms and/or pages from a template when an item is created in a triggering collection. “schema linker” (the rejected column-mutation approach), “auto-provision”
The per-occurrence join collection participation (join collection) A collection with one row per participant per container occurrence (visitor/member, container item, period, and their data) — the join between people and occurrences. “user folder”, “signup record”
The guided setup page for this whole pattern Recurring setup The /cms/:siteId/recurring pane (RecurringSetupPane.tsx) — a status-driven checklist covering the container collection, site symbol, participation collection, edit gate, an optional collapse pass, and sign-up form guidance, for any container/symbol/participation instance. “recurring wizard” (it’s a stepper, not a modal wizard), “editions setup” (editions is one instance, not the concept)
A collection-level self-edit lock tied to a period edit gate (content_types.schema.member_edit_gate) A { symbol, match_field } setting on a participation collection: a member’s own-row edit is refused unless the row’s match_field names an item, in symbol’s collection, whose current period has its edit gate (see the generic term above) open. Configured on the collection’s Schema designer (MemberEditGateEditor.tsx), enforced in workers/src/routes/modules/member-data.ts. bare “gate” where the period-level boolean is meant (that’s the generic term above), “lock”

The v2/v3/v4 suffixes are historical and have been removed from code (zero v3 identifiers remain). The component system is just “the component system”. Plan/schema files keep a version in their filename only as a document version, never in code identifiers.