From a7cae5c4ed4e0352d85fcc9539c0a7837e200dc3 Mon Sep 17 00:00:00 2001 From: Roy Dumblauskas Date: Fri, 26 Dec 2025 21:30:38 -0600 Subject: [PATCH] db schema overhaul --- backend/src/db/schema.ts | 80 ++++++++++++++++++++++++++++++++++++++-- 1 file changed, 77 insertions(+), 3 deletions(-) diff --git a/backend/src/db/schema.ts b/backend/src/db/schema.ts index acab481..8d317d2 100644 --- a/backend/src/db/schema.ts +++ b/backend/src/db/schema.ts @@ -1,9 +1,83 @@ -import { integer, uuid, pgTable, varchar, date } from "drizzle-orm/pg-core"; +import { + timestamp, + uuid, + pgTable, + pgEnum, + jsonb, + varchar, + integer, + bigint, + uniqueIndex, + index +} from "drizzle-orm/pg-core"; +import { relations } from "drizzle-orm"; + +export const blockTypeEnum = pgEnum("post_block_type", [ + "title", + "paragraph", + "heading", + "image", + "code", + "quote", + "ordered_list", + "unordered_list" +]); + +export const articleStatusEnum = pgEnum("post_status", [ + "draft", + "published" +]); export const articles = pgTable("articles", { id: uuid().notNull().primaryKey().defaultRandom(), + name: varchar({ length: 255 }).notNull(), - date: date({ mode: "date" }).notNull(), - text: varchar({ length: 9999 }).notNull() + article_status: articleStatusEnum().default("draft"), + author_id: uuid().notNull(), + slug: varchar({ length: 255 }).unique().notNull(), + summary: varchar({ length: 255 }).notNull(), + + date_created: timestamp({ mode: "date", withTimezone: true }).defaultNow().notNull(), + last_edit: timestamp({ mode: "date", withTimezone: true }).defaultNow().notNull(), + date_published: timestamp({ mode: "date", withTimezone: true }), }); +export const articleBlocks = pgTable("article_blocks", { + id: uuid().notNull().primaryKey().defaultRandom(), + article_id: uuid().notNull().references(() => articles.id, { onDelete: "cascade" }), + + position: integer().notNull(), + type: blockTypeEnum().notNull(), + content: jsonb().$type>().notNull(), + +}, + (table) => [{ + postPositionIdx: uniqueIndex("article_blocks_article_position_idx") + .on(table.article_id, table.position), + + postIdx: index("article_blocks_article_id_idx") + .on(table.article_id), + }]); + +export const images = pgTable("images", { + id: uuid().notNull().primaryKey().defaultRandom(), + bucket: varchar({ length: 63 }).notNull(), + key: varchar({ length: 255 }).notNull(), + mime_type: varchar({ length: 63 }).notNull(), + height: integer().notNull(), + width: integer().notNull(), + bytes: bigint({ mode: "number" }).notNull(), + +}); + + +export const articlesRelations = relations(articles, ({ many }) => ({ + blocks: many(articleBlocks), +})); + +export const articleBlocksRelations = relations(articleBlocks, ({ one }) => ({ + article: one(articles, { + fields: [articleBlocks.article_id], + references: [articles.id], + }), +}));