From 901667d31782df70e66031993a170c4a0c0c799f Mon Sep 17 00:00:00 2001 From: npmrun <1549469775@qq.com> Date: Sat, 18 Apr 2026 15:53:41 +0800 Subject: [PATCH] feat(db): add post_comments table for nested comments Made-with: Cursor --- .../drizzle-pkg/database/sqlite/schema/content.ts | 37 +- packages/drizzle-pkg/db.sqlite | Bin 94208 -> 106496 bytes packages/drizzle-pkg/lib/schema/content.ts | 2 +- .../drizzle-pkg/migrations/0002_post-comments.sql | 20 + .../drizzle-pkg/migrations/meta/0002_snapshot.json | 950 +++++++++++++++++++++ packages/drizzle-pkg/migrations/meta/_journal.json | 7 + 6 files changed, 1014 insertions(+), 2 deletions(-) create mode 100644 packages/drizzle-pkg/migrations/0002_post-comments.sql create mode 100644 packages/drizzle-pkg/migrations/meta/0002_snapshot.json diff --git a/packages/drizzle-pkg/database/sqlite/schema/content.ts b/packages/drizzle-pkg/database/sqlite/schema/content.ts index de68be8..8866635 100644 --- a/packages/drizzle-pkg/database/sqlite/schema/content.ts +++ b/packages/drizzle-pkg/database/sqlite/schema/content.ts @@ -1,4 +1,11 @@ -import { integer, sqliteTable, text, uniqueIndex } from "drizzle-orm/sqlite-core"; +import { + index, + integer, + sqliteTable, + text, + uniqueIndex, + type AnySQLiteColumn, +} from "drizzle-orm/sqlite-core"; import { users } from "./auth"; @@ -44,3 +51,31 @@ export const timelineEvents = sqliteTable("timeline_events", { .$onUpdate(() => new Date()) .notNull(), }); + +export const postComments = sqliteTable( + "post_comments", + { + id: integer().primaryKey(), + postId: integer("post_id") + .notNull() + .references(() => posts.id, { onDelete: "cascade" }), + parentId: integer("parent_id").references((): AnySQLiteColumn => postComments.id), + authorUserId: integer("author_user_id").references(() => users.id, { onDelete: "set null" }), + guestDisplayName: text("guest_display_name"), + body: text().notNull(), + kind: text().notNull(), + deletedAt: integer("deleted_at", { mode: "timestamp_ms" }), + deletedByUserId: integer("deleted_by_user_id").references(() => users.id, { + onDelete: "set null", + }), + createdAt: integer("created_at", { mode: "timestamp_ms" }).defaultNow().notNull(), + updatedAt: integer("updated_at", { mode: "timestamp_ms" }) + .defaultNow() + .$onUpdate(() => new Date()) + .notNull(), + }, + (table) => [ + index("post_comments_post_id_idx").on(table.postId), + index("post_comments_parent_id_idx").on(table.parentId), + ], +); diff --git a/packages/drizzle-pkg/db.sqlite b/packages/drizzle-pkg/db.sqlite index 51e67dd4a233a99c107435e8c03a3fce1f76f3bd..2098d6012f12e0648720af998e3714ce0fa7f1a7 100644 GIT binary patch delta 957 zcmaJI_N6|? z4gm05vorklp(tes!*?FMQ=TG(+*ZJbd;m334*8mlrw2_<+9*(SQ;CR(!-^bUCnd@Jn zZD<3a-)IwUG#U0QqDUKnw&vzJ_m2|@Z~!^b8~43KYi>Uk>=|^k%*NIl)0yK$M@D$YS(Aj*}LqhW{xzO?l;WxrduK*{g1LvA^jA~I1av8co z9o;n+9il(T>T`b(;9=Ee;AiJw&)dXzjaQ0QcVb1w#-4>N+jUhL^Vk@hHqYUX zXOZOqnGQ0EgJlu}Z!XVgu6Z2SIP6)sv$C^H+AJtg#j<^p2_p~N=4hrQ) statement-breakpoint +CREATE INDEX `post_comments_post_id_idx` ON `post_comments` (`post_id`);--> statement-breakpoint +CREATE INDEX `post_comments_parent_id_idx` ON `post_comments` (`parent_id`); \ No newline at end of file diff --git a/packages/drizzle-pkg/migrations/meta/0002_snapshot.json b/packages/drizzle-pkg/migrations/meta/0002_snapshot.json new file mode 100644 index 0000000..6ce0d1d --- /dev/null +++ b/packages/drizzle-pkg/migrations/meta/0002_snapshot.json @@ -0,0 +1,950 @@ +{ + "version": "6", + "dialect": "sqlite", + "id": "ea7fcedb-76a9-4158-b247-2a5f162b1bdd", + "prevId": "66f33657-5926-4ac6-a196-2d142081b192", + "tables": { + "sessions": { + "name": "sessions", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "user_id": { + "name": "user_id", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "expires_at": { + "name": "expires_at", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "(cast((julianday('now') - 2440587.5)*86400000 as integer))" + } + }, + "indexes": { + "sessions_user_id_idx": { + "name": "sessions_user_id_idx", + "columns": [ + "user_id" + ], + "isUnique": false + } + }, + "foreignKeys": { + "sessions_user_id_users_id_fk": { + "name": "sessions_user_id_users_id_fk", + "tableFrom": "sessions", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "users": { + "name": "users", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "username": { + "name": "username", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "email": { + "name": "email", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "nickname": { + "name": "nickname", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "password": { + "name": "password", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "avatar": { + "name": "avatar", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "role": { + "name": "role", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "'user'" + }, + "status": { + "name": "status", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "'active'" + }, + "public_slug": { + "name": "public_slug", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "bio_markdown": { + "name": "bio_markdown", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "bio_visibility": { + "name": "bio_visibility", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "'private'" + }, + "social_links_json": { + "name": "social_links_json", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "'[]'" + }, + "avatar_visibility": { + "name": "avatar_visibility", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "'private'" + }, + "created_at": { + "name": "created_at", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "(cast((julianday('now') - 2440587.5)*86400000 as integer))" + }, + "updated_at": { + "name": "updated_at", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "(cast((julianday('now') - 2440587.5)*86400000 as integer))" + } + }, + "indexes": { + "users_username_unique": { + "name": "users_username_unique", + "columns": [ + "username" + ], + "isUnique": true + }, + "users_public_slug_unique": { + "name": "users_public_slug_unique", + "columns": [ + "public_slug" + ], + "isUnique": true + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "app_configs": { + "name": "app_configs", + "columns": { + "key": { + "name": "key", + "type": "text", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "value": { + "name": "value", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "value_type": { + "name": "value_type", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "updated_at": { + "name": "updated_at", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "(cast((julianday('now') - 2440587.5)*86400000 as integer))" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "user_configs": { + "name": "user_configs", + "columns": { + "user_id": { + "name": "user_id", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "key": { + "name": "key", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "value": { + "name": "value", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "value_type": { + "name": "value_type", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "updated_at": { + "name": "updated_at", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "(cast((julianday('now') - 2440587.5)*86400000 as integer))" + } + }, + "indexes": { + "user_configs_user_id_idx": { + "name": "user_configs_user_id_idx", + "columns": [ + "user_id" + ], + "isUnique": false + } + }, + "foreignKeys": { + "user_configs_user_id_users_id_fk": { + "name": "user_configs_user_id_users_id_fk", + "tableFrom": "user_configs", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "user_configs_user_id_key_pk": { + "columns": [ + "user_id", + "key" + ], + "name": "user_configs_user_id_key_pk" + } + }, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "post_comments": { + "name": "post_comments", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "post_id": { + "name": "post_id", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "parent_id": { + "name": "parent_id", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "author_user_id": { + "name": "author_user_id", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "guest_display_name": { + "name": "guest_display_name", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "body": { + "name": "body", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "kind": { + "name": "kind", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "deleted_at": { + "name": "deleted_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "deleted_by_user_id": { + "name": "deleted_by_user_id", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "(cast((julianday('now') - 2440587.5)*86400000 as integer))" + }, + "updated_at": { + "name": "updated_at", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "(cast((julianday('now') - 2440587.5)*86400000 as integer))" + } + }, + "indexes": { + "post_comments_post_id_idx": { + "name": "post_comments_post_id_idx", + "columns": [ + "post_id" + ], + "isUnique": false + }, + "post_comments_parent_id_idx": { + "name": "post_comments_parent_id_idx", + "columns": [ + "parent_id" + ], + "isUnique": false + } + }, + "foreignKeys": { + "post_comments_post_id_posts_id_fk": { + "name": "post_comments_post_id_posts_id_fk", + "tableFrom": "post_comments", + "tableTo": "posts", + "columnsFrom": [ + "post_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "post_comments_parent_id_post_comments_id_fk": { + "name": "post_comments_parent_id_post_comments_id_fk", + "tableFrom": "post_comments", + "tableTo": "post_comments", + "columnsFrom": [ + "parent_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "post_comments_author_user_id_users_id_fk": { + "name": "post_comments_author_user_id_users_id_fk", + "tableFrom": "post_comments", + "tableTo": "users", + "columnsFrom": [ + "author_user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "post_comments_deleted_by_user_id_users_id_fk": { + "name": "post_comments_deleted_by_user_id_users_id_fk", + "tableFrom": "post_comments", + "tableTo": "users", + "columnsFrom": [ + "deleted_by_user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "posts": { + "name": "posts", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "user_id": { + "name": "user_id", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "title": { + "name": "title", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "slug": { + "name": "slug", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "body_markdown": { + "name": "body_markdown", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "excerpt": { + "name": "excerpt", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "cover_url": { + "name": "cover_url", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "tags_json": { + "name": "tags_json", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "'[]'" + }, + "published_at": { + "name": "published_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "visibility": { + "name": "visibility", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "'private'" + }, + "share_token": { + "name": "share_token", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "(cast((julianday('now') - 2440587.5)*86400000 as integer))" + }, + "updated_at": { + "name": "updated_at", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "(cast((julianday('now') - 2440587.5)*86400000 as integer))" + } + }, + "indexes": { + "posts_user_id_slug_unique": { + "name": "posts_user_id_slug_unique", + "columns": [ + "user_id", + "slug" + ], + "isUnique": true + } + }, + "foreignKeys": { + "posts_user_id_users_id_fk": { + "name": "posts_user_id_users_id_fk", + "tableFrom": "posts", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "timeline_events": { + "name": "timeline_events", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "user_id": { + "name": "user_id", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "occurred_on": { + "name": "occurred_on", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "title": { + "name": "title", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "body_markdown": { + "name": "body_markdown", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "link_url": { + "name": "link_url", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "visibility": { + "name": "visibility", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "'private'" + }, + "share_token": { + "name": "share_token", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "(cast((julianday('now') - 2440587.5)*86400000 as integer))" + }, + "updated_at": { + "name": "updated_at", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "(cast((julianday('now') - 2440587.5)*86400000 as integer))" + } + }, + "indexes": {}, + "foreignKeys": { + "timeline_events_user_id_users_id_fk": { + "name": "timeline_events_user_id_users_id_fk", + "tableFrom": "timeline_events", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "rss_feeds": { + "name": "rss_feeds", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "user_id": { + "name": "user_id", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "feed_url": { + "name": "feed_url", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "title": { + "name": "title", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "site_url": { + "name": "site_url", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "last_fetched_at": { + "name": "last_fetched_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "last_error": { + "name": "last_error", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "poll_interval_minutes": { + "name": "poll_interval_minutes", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "(cast((julianday('now') - 2440587.5)*86400000 as integer))" + } + }, + "indexes": { + "rss_feeds_user_id_feed_url_unique": { + "name": "rss_feeds_user_id_feed_url_unique", + "columns": [ + "user_id", + "feed_url" + ], + "isUnique": true + } + }, + "foreignKeys": { + "rss_feeds_user_id_users_id_fk": { + "name": "rss_feeds_user_id_users_id_fk", + "tableFrom": "rss_feeds", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "rss_items": { + "name": "rss_items", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "user_id": { + "name": "user_id", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "feed_id": { + "name": "feed_id", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "guid": { + "name": "guid", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "canonical_url": { + "name": "canonical_url", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "title": { + "name": "title", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "summary": { + "name": "summary", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "content_snippet": { + "name": "content_snippet", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "author": { + "name": "author", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "published_at": { + "name": "published_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "visibility": { + "name": "visibility", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "'private'" + }, + "share_token": { + "name": "share_token", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "(cast((julianday('now') - 2440587.5)*86400000 as integer))" + } + }, + "indexes": { + "rss_items_feed_id_guid_unique": { + "name": "rss_items_feed_id_guid_unique", + "columns": [ + "feed_id", + "guid" + ], + "isUnique": true, + "where": "\"rss_items\".\"guid\" IS NOT NULL" + } + }, + "foreignKeys": { + "rss_items_user_id_users_id_fk": { + "name": "rss_items_user_id_users_id_fk", + "tableFrom": "rss_items", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "rss_items_feed_id_rss_feeds_id_fk": { + "name": "rss_items_feed_id_rss_feeds_id_fk", + "tableFrom": "rss_items", + "tableTo": "rss_feeds", + "columnsFrom": [ + "feed_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + } + }, + "views": {}, + "enums": {}, + "_meta": { + "schemas": {}, + "tables": {}, + "columns": {} + }, + "internal": { + "indexes": {} + } +} \ No newline at end of file diff --git a/packages/drizzle-pkg/migrations/meta/_journal.json b/packages/drizzle-pkg/migrations/meta/_journal.json index 4802fd2..834c554 100644 --- a/packages/drizzle-pkg/migrations/meta/_journal.json +++ b/packages/drizzle-pkg/migrations/meta/_journal.json @@ -15,6 +15,13 @@ "when": 1776457621565, "tag": "0001_add-multitenant-content-rss", "breakpoints": true + }, + { + "idx": 2, + "version": "6", + "when": 1776498812973, + "tag": "0002_post-comments", + "breakpoints": true } ] } \ No newline at end of file