import { pgTable, varchar, text, integer, uuid, index, uniqueIndex } from 'drizzle-orm/pg-core'; import { companies, users } from './tenancy'; import { wikiScopeEnum, pk, fk, createdAt, updatedAt, deletedAt, slugCol } from './_shared'; // One wiki page per (company, scope, slug). scope_id is null for global pages. // Unique-with-NULLS-NOT-DISTINCT on (company_id, scope_type, scope_id, slug) // is added in the follow-up SQL migration (Drizzle can't express it). export const wikiPages = pgTable( 'wiki_pages', { id: pk(), companyId: fk('company_id') .notNull() .references(() => companies.id, { onDelete: 'cascade' }), scopeType: wikiScopeEnum('scope_type').notNull(), scopeId: uuid('scope_id'), // null for global slug: slugCol(), title: varchar('title', { length: 255 }).notNull(), // Pointer to the latest wiki_revisions row. Set after first revision is written. currentRevisionId: fk('current_revision_id'), createdBy: fk('created_by').references(() => users.id, { onDelete: 'set null' }), createdAt: createdAt(), updatedAt: updatedAt(), deletedAt: deletedAt() }, (t) => ({ byScope: index('wiki_by_scope').on(t.scopeType, t.scopeId) // (company_id, scope_type, scope_id, slug) unique with NULLS NOT DISTINCT // is created in the follow-up SQL migration. }) ); export const wikiRevisions = pgTable( 'wiki_revisions', { id: pk(), pageId: fk('page_id') .notNull() .references(() => wikiPages.id, { onDelete: 'cascade' }), revision: integer('revision').notNull(), title: varchar('title', { length: 255 }).notNull(), bodyMd: text('body_md').notNull(), // Maintained by trigger (declared as text, ALTERed to tsvector in follow-up). bodyTsv: text('body_tsv'), editedBy: fk('edited_by').references(() => users.id, { onDelete: 'set null' }), editedAt: createdAt(), comment: varchar('comment', { length: 500 }) }, (t) => ({ pageRevUq: uniqueIndex('wiki_rev_page_rev_uq').on(t.pageId, t.revision), byPage: index('wiki_rev_by_page').on(t.pageId, t.revision) }) ); export type WikiPage = typeof wikiPages.$inferSelect; export type WikiRevision = typeof wikiRevisions.$inferSelect;