Context
Pages, forms, posts and many other authored things share drafts, versions, publishing, slugs, SEO, translation, permissions and search. One package per type would repeat all of that. A generic JSON store for every type would be the “JSONB-for-everything” that 0011 rejects. Tenants also want extra fields on both content and business records (a Student, an Order).Decision
-
CT1 —
@stackra/contentis the free content core. Page, form definition and post are built-in content types sharing drafts, versions, publishing, slugs, SEO, i18n, permissions, search and the document format of 0110. New types are declared in code with@ContentTypein any module. -
CT3 —
@ContentTypeis@Modelplus a trait bundle:HasRevisions,Publishable,Sluggable,HasSeo,Translatable,Searchable,HasCustomFieldsand routes (0096). Each type is a real, typed table generated by gen (0097); there is no generic JSON store. -
The decision rule:
-
CT4 — Built-in content types:
- page, post, form definition, gallery;
- help article, FAQ, announcement, changelog;
- legal document (acceptance feeds consent), testimonial, team member, job posting;
- reusable blocks, remote navigation menus (which feed
@stackra/navigation), redirects and short links.
-
CT2 —
HasCustomFieldsis free and bounded, on content types and on business models. Values live in a side table and are validated by the stored field schema; how many fields a tenant may add is a plan limit enforced through entitlements. - Tenant-defined new content types at runtime are Pro and later, and need their own amendment of 0011 first.
Consequences
- Every content type gets publishing, SEO and search for free, and stays a typed table that migrations and RLS understand.
- The decision rule gives reviewers a test for “should this be content”.
- Custom fields add a side-table join to reads; search and list filtering must learn about them.
Enforcement
Planned: the gen validation pass fails a@ContentType that also declares a state machine or money field without the
domain-model form, and a HasCustomFields model with no entitlement limit key. Nothing checks this today.