// Schema for the {{projectName}} CMS backend. // // The content TABLES aren't hand-declared — they're COMPILED from the content // types. `contentTypeToEntities(blogPost)` returns a `{ draft, published }` pair // (`blogPost_drafts` + `blogPost_published`), each already tenant-scoped // (`tenant()`, which pulls `audit()` transitively) and carrying the lifecycle // `status` column. Registering them in `databaseHandle` is what makes the // framework's auto-migrate create them across every dialect. There is no // discovery of `*.contentType.ts`; THIS import is the wiring. import { databaseHandle, id, table, text, timestamp, type ColumnDefinition, type InferRow, type Table, type TableLike, } from '@voltro/database' import { contentTypeToEntities } from '@voltro/cms' import { blogPost, page } from '../content' // ---------- Core tables (required by the audit / tenant mixins) ---------- export const actors = table('actors', { id: id(), kind: text().oneOf(['user', 'serviceAccount', 'apiKey', 'system']), displayName: text().nullable(), createdAt: timestamp().default('now'), }) export const tenants = table('tenants', { id: id(), name: text(), createdAt: timestamp().default('now'), }) // ---------- Derived content tables ---------- // Compile each content type to its draft/published table pair. Exported so the // tests can build a schema registry over the SAME tables the app registers. export const blogEntities = contentTypeToEntities(blogPost) export const pageEntities = contentTypeToEntities(page) export type BlogPostDraft = InferRow export type PageDraft = InferRow // `contentTypeToEntities` returns the structural `TableLike` type (it hides the // concrete generic), but each value IS a real `table(...).with(tenant())` at // runtime — exactly what `databaseHandle` registers. This boundary cast bridges // the two: no `any`, no behavioural change, just the concrete table type the // handle's inference expects. const asTable = (t: TableLike): Table>, boolean, string> => t as unknown as Table>, boolean, string> export const database = databaseHandle({ actors, tenants, blogPostDrafts: asTable(blogEntities.draft), blogPostPublished: asTable(blogEntities.published), pageDrafts: asTable(pageEntities.draft), pagePublished: asTable(pageEntities.published), })