-
-
欢迎来到 Dash
-
一个收集、分享和交流的地方
-
+
+
+
+
+
+
+
+
+
💡
+
还没有想法
+
成为第一个分享的人吧
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 加载更多
+
+
+
+
+
+
+
+
+
+
+ {{ selectedIdea.author || '匿名' }}
+ {{ selectedIdea.platform }}
+ {{ new Date(selectedIdea.createdAt).toLocaleDateString('zh-CN', { year: 'numeric', month: 'long', day: 'numeric' }) }}
+
+
{{ selectedIdea.content }}
+
+
+
+
+
+
diff --git a/db.sqlite b/db.sqlite
deleted file mode 100644
index e69de29..0000000
diff --git a/packages/drizzle-pkg/db.sqlite b/packages/drizzle-pkg/db.sqlite
index 9a940da..5106788 100644
Binary files a/packages/drizzle-pkg/db.sqlite and b/packages/drizzle-pkg/db.sqlite differ
diff --git a/packages/drizzle-pkg/lib/schema/content.ts b/packages/drizzle-pkg/lib/schema/content.ts
index d8cd850..e71cd88 100644
--- a/packages/drizzle-pkg/lib/schema/content.ts
+++ b/packages/drizzle-pkg/lib/schema/content.ts
@@ -194,6 +194,24 @@ export const articleCards = sqliteTable(
],
);
+// ============ Idea(点子/想法)============
+export const ideas = sqliteTable(
+ "ideas",
+ {
+ id: integer("id").primaryKey({ autoIncrement: true }),
+ author: text("author", { length: 30 }).notNull(),
+ content: text("content").notNull(),
+ platform: text("platform", { length: 30 }),
+ color: text("color", { length: 30 }),
+ createdAt: integer("created_at", { mode: "timestamp_ms" })
+ .defaultNow()
+ .notNull(),
+ },
+ (table) => [
+ index("idx_idea_created").on(table.createdAt),
+ ],
+);
+
// ============ ChatMessage(聊天室消息)============
export const chatMessages = sqliteTable(
"chat_messages",
diff --git a/packages/drizzle-pkg/migrations/0007_add_card_content.sql b/packages/drizzle-pkg/migrations/0007_add_card_content.sql
deleted file mode 100644
index a961f45..0000000
--- a/packages/drizzle-pkg/migrations/0007_add_card_content.sql
+++ /dev/null
@@ -1 +0,0 @@
-ALTER TABLE `cards` ADD `content` text;
diff --git a/packages/drizzle-pkg/migrations/0008_chat_messages.sql b/packages/drizzle-pkg/migrations/0008_magical_black_knight.sql
similarity index 61%
rename from packages/drizzle-pkg/migrations/0008_chat_messages.sql
rename to packages/drizzle-pkg/migrations/0008_magical_black_knight.sql
index 8d34684..0d58410 100644
--- a/packages/drizzle-pkg/migrations/0008_chat_messages.sql
+++ b/packages/drizzle-pkg/migrations/0008_magical_black_knight.sql
@@ -2,7 +2,9 @@ CREATE TABLE `chat_messages` (
`id` integer PRIMARY KEY AUTOINCREMENT NOT NULL,
`nickname` text(20) NOT NULL,
`content` text NOT NULL,
- `created_at` integer NOT NULL
+ `created_at` integer DEFAULT (cast((julianday('now') - 2440587.5)*86400000 as integer)) NOT NULL,
+ `client_id` text,
+ `user_id` integer
);
--> statement-breakpoint
-CREATE INDEX `idx_chat_msg_created` ON `chat_messages` (`created_at`);
+CREATE INDEX `idx_chat_msg_created` ON `chat_messages` (`created_at`);
\ No newline at end of file
diff --git a/packages/drizzle-pkg/migrations/0009_ideas.sql b/packages/drizzle-pkg/migrations/0009_ideas.sql
new file mode 100644
index 0000000..5adbf63
--- /dev/null
+++ b/packages/drizzle-pkg/migrations/0009_ideas.sql
@@ -0,0 +1,9 @@
+CREATE TABLE `ideas` (
+ `id` integer PRIMARY KEY AUTOINCREMENT NOT NULL,
+ `author` text(30) NOT NULL,
+ `content` text NOT NULL,
+ `color` text(30),
+ `created_at` integer DEFAULT (cast((julianday('now') - 2440587.5)*86400000 as integer)) NOT NULL
+);
+--> statement-breakpoint
+CREATE INDEX `idx_idea_created` ON `ideas` (`created_at`);
diff --git a/packages/drizzle-pkg/migrations/0010_broken_machine_man.sql b/packages/drizzle-pkg/migrations/0010_broken_machine_man.sql
new file mode 100644
index 0000000..7a6646c
--- /dev/null
+++ b/packages/drizzle-pkg/migrations/0010_broken_machine_man.sql
@@ -0,0 +1 @@
+ALTER TABLE ideas ADD platform text(30);
\ No newline at end of file
diff --git a/packages/drizzle-pkg/migrations/meta/0008_snapshot.json b/packages/drizzle-pkg/migrations/meta/0008_snapshot.json
new file mode 100644
index 0000000..e3a5df5
--- /dev/null
+++ b/packages/drizzle-pkg/migrations/meta/0008_snapshot.json
@@ -0,0 +1,1303 @@
+{
+ "version": "6",
+ "dialect": "sqlite",
+ "id": "ede766ab-94ae-4696-b9a9-e1b4309154c0",
+ "prevId": "a09272fe-1725-4698-b4da-af8b6f7fa98c",
+ "tables": {
+ "oauth_accounts": {
+ "name": "oauth_accounts",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "integer",
+ "primaryKey": true,
+ "notNull": true,
+ "autoincrement": true
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "provider": {
+ "name": "provider",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "provider_user_id": {
+ "name": "provider_user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "username": {
+ "name": "username",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "email": {
+ "name": "email",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "avatar": {
+ "name": "avatar",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false,
+ "default": "(cast((julianday('now') - 2440587.5)*86400000 as integer))"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false,
+ "default": "(cast((julianday('now') - 2440587.5)*86400000 as integer))"
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {},
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "checkConstraints": {}
+ },
+ "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'"
+ },
+ "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
+ }
+ },
+ "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": {}
+ },
+ "article_cards": {
+ "name": "article_cards",
+ "columns": {
+ "article_id": {
+ "name": "article_id",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "card_id": {
+ "name": "card_id",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "sort_order": {
+ "name": "sort_order",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false,
+ "default": 0
+ }
+ },
+ "indexes": {
+ "idx_article_card_article": {
+ "name": "idx_article_card_article",
+ "columns": [
+ "article_id"
+ ],
+ "isUnique": false
+ },
+ "idx_article_card_card": {
+ "name": "idx_article_card_card",
+ "columns": [
+ "card_id"
+ ],
+ "isUnique": false
+ }
+ },
+ "foreignKeys": {
+ "article_cards_article_id_articles_id_fk": {
+ "name": "article_cards_article_id_articles_id_fk",
+ "tableFrom": "article_cards",
+ "tableTo": "articles",
+ "columnsFrom": [
+ "article_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "article_cards_card_id_cards_id_fk": {
+ "name": "article_cards_card_id_cards_id_fk",
+ "tableFrom": "article_cards",
+ "tableTo": "cards",
+ "columnsFrom": [
+ "card_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {
+ "article_card_pk": {
+ "columns": [
+ "article_id",
+ "card_id"
+ ],
+ "name": "article_card_pk"
+ }
+ },
+ "uniqueConstraints": {},
+ "checkConstraints": {}
+ },
+ "articles": {
+ "name": "articles",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "integer",
+ "primaryKey": true,
+ "notNull": true,
+ "autoincrement": true
+ },
+ "title": {
+ "name": "title",
+ "type": "text(255)",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "content": {
+ "name": "content",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "summary": {
+ "name": "summary",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "cover": {
+ "name": "cover",
+ "type": "text(500)",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "status": {
+ "name": "status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false,
+ "default": "'draft'"
+ },
+ "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": {
+ "idx_article_status": {
+ "name": "idx_article_status",
+ "columns": [
+ "status"
+ ],
+ "isUnique": false
+ },
+ "idx_article_created": {
+ "name": "idx_article_created",
+ "columns": [
+ "created_at"
+ ],
+ "isUnique": false
+ }
+ },
+ "foreignKeys": {},
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "checkConstraints": {}
+ },
+ "card_images": {
+ "name": "card_images",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "integer",
+ "primaryKey": true,
+ "notNull": true,
+ "autoincrement": true
+ },
+ "card_id": {
+ "name": "card_id",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "url": {
+ "name": "url",
+ "type": "text(500)",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "sort_order": {
+ "name": "sort_order",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false,
+ "default": 0
+ }
+ },
+ "indexes": {
+ "idx_card_image_card": {
+ "name": "idx_card_image_card",
+ "columns": [
+ "card_id"
+ ],
+ "isUnique": false
+ }
+ },
+ "foreignKeys": {
+ "card_images_card_id_cards_id_fk": {
+ "name": "card_images_card_id_cards_id_fk",
+ "tableFrom": "card_images",
+ "tableTo": "cards",
+ "columnsFrom": [
+ "card_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "no action",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "checkConstraints": {}
+ },
+ "card_tags": {
+ "name": "card_tags",
+ "columns": {
+ "card_id": {
+ "name": "card_id",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "tag_id": {
+ "name": "tag_id",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ }
+ },
+ "indexes": {
+ "idx_card_tag_card": {
+ "name": "idx_card_tag_card",
+ "columns": [
+ "card_id"
+ ],
+ "isUnique": false
+ },
+ "idx_card_tag_tag": {
+ "name": "idx_card_tag_tag",
+ "columns": [
+ "tag_id"
+ ],
+ "isUnique": false
+ }
+ },
+ "foreignKeys": {
+ "card_tags_card_id_cards_id_fk": {
+ "name": "card_tags_card_id_cards_id_fk",
+ "tableFrom": "card_tags",
+ "tableTo": "cards",
+ "columnsFrom": [
+ "card_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "no action",
+ "onUpdate": "no action"
+ },
+ "card_tags_tag_id_tags_id_fk": {
+ "name": "card_tags_tag_id_tags_id_fk",
+ "tableFrom": "card_tags",
+ "tableTo": "tags",
+ "columnsFrom": [
+ "tag_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "no action",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {
+ "card_tag_pk": {
+ "columns": [
+ "card_id",
+ "tag_id"
+ ],
+ "name": "card_tag_pk"
+ }
+ },
+ "uniqueConstraints": {},
+ "checkConstraints": {}
+ },
+ "cards": {
+ "name": "cards",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "integer",
+ "primaryKey": true,
+ "notNull": true,
+ "autoincrement": true
+ },
+ "type": {
+ "name": "type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "title": {
+ "name": "title",
+ "type": "text(255)",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "description": {
+ "name": "description",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "content": {
+ "name": "content",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "aspect_ratio": {
+ "name": "aspect_ratio",
+ "type": "real",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "category_id": {
+ "name": "category_id",
+ "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": {
+ "idx_card_category": {
+ "name": "idx_card_category",
+ "columns": [
+ "category_id"
+ ],
+ "isUnique": false
+ },
+ "idx_card_type": {
+ "name": "idx_card_type",
+ "columns": [
+ "type"
+ ],
+ "isUnique": false
+ },
+ "idx_card_created": {
+ "name": "idx_card_created",
+ "columns": [
+ "created_at"
+ ],
+ "isUnique": false
+ }
+ },
+ "foreignKeys": {
+ "cards_category_id_categories_id_fk": {
+ "name": "cards_category_id_categories_id_fk",
+ "tableFrom": "cards",
+ "tableTo": "categories",
+ "columnsFrom": [
+ "category_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "no action",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "checkConstraints": {}
+ },
+ "categories": {
+ "name": "categories",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "name": {
+ "name": "name",
+ "type": "text(100)",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "slug": {
+ "name": "slug",
+ "type": "text(100)",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "image": {
+ "name": "image",
+ "type": "text(500)",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "parent_id": {
+ "name": "parent_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "sort_order": {
+ "name": "sort_order",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false,
+ "default": 0
+ },
+ "count": {
+ "name": "count",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false,
+ "default": 0
+ },
+ "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": {
+ "idx_category_slug": {
+ "name": "idx_category_slug",
+ "columns": [
+ "slug"
+ ],
+ "isUnique": true
+ },
+ "idx_category_parent": {
+ "name": "idx_category_parent",
+ "columns": [
+ "parent_id"
+ ],
+ "isUnique": false
+ }
+ },
+ "foreignKeys": {},
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "checkConstraints": {}
+ },
+ "chat_messages": {
+ "name": "chat_messages",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "integer",
+ "primaryKey": true,
+ "notNull": true,
+ "autoincrement": true
+ },
+ "nickname": {
+ "name": "nickname",
+ "type": "text(20)",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "content": {
+ "name": "content",
+ "type": "text",
+ "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))"
+ },
+ "client_id": {
+ "name": "client_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ }
+ },
+ "indexes": {
+ "idx_chat_msg_created": {
+ "name": "idx_chat_msg_created",
+ "columns": [
+ "created_at"
+ ],
+ "isUnique": false
+ }
+ },
+ "foreignKeys": {},
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "checkConstraints": {}
+ },
+ "favorites": {
+ "name": "favorites",
+ "columns": {
+ "user_id": {
+ "name": "user_id",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "card_id": {
+ "name": "card_id",
+ "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": {
+ "idx_favorite_user": {
+ "name": "idx_favorite_user",
+ "columns": [
+ "user_id"
+ ],
+ "isUnique": false
+ },
+ "idx_favorite_card": {
+ "name": "idx_favorite_card",
+ "columns": [
+ "card_id"
+ ],
+ "isUnique": false
+ }
+ },
+ "foreignKeys": {
+ "favorites_user_id_users_id_fk": {
+ "name": "favorites_user_id_users_id_fk",
+ "tableFrom": "favorites",
+ "tableTo": "users",
+ "columnsFrom": [
+ "user_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "favorites_card_id_cards_id_fk": {
+ "name": "favorites_card_id_cards_id_fk",
+ "tableFrom": "favorites",
+ "tableTo": "cards",
+ "columnsFrom": [
+ "card_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {
+ "favorite_pk": {
+ "columns": [
+ "user_id",
+ "card_id"
+ ],
+ "name": "favorite_pk"
+ }
+ },
+ "uniqueConstraints": {},
+ "checkConstraints": {}
+ },
+ "tags": {
+ "name": "tags",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "integer",
+ "primaryKey": true,
+ "notNull": true,
+ "autoincrement": true
+ },
+ "name": {
+ "name": "name",
+ "type": "text(50)",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "slug": {
+ "name": "slug",
+ "type": "text(50)",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ }
+ },
+ "indexes": {
+ "idx_tag_slug": {
+ "name": "idx_tag_slug",
+ "columns": [
+ "slug"
+ ],
+ "isUnique": true
+ }
+ },
+ "foreignKeys": {},
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "checkConstraints": {}
+ },
+ "tools": {
+ "name": "tools",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "name": {
+ "name": "name",
+ "type": "text(50)",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "slug": {
+ "name": "slug",
+ "type": "text(50)",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "icon": {
+ "name": "icon",
+ "type": "text(100)",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "sort_order": {
+ "name": "sort_order",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false,
+ "default": 0
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {},
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "checkConstraints": {}
+ },
+ "scheduled_tasks": {
+ "name": "scheduled_tasks",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "name": {
+ "name": "name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "cron_expression": {
+ "name": "cron_expression",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "type": {
+ "name": "type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "function_name": {
+ "name": "function_name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "function_payload": {
+ "name": "function_payload",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "http_method": {
+ "name": "http_method",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "http_url": {
+ "name": "http_url",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "http_headers": {
+ "name": "http_headers",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "http_body": {
+ "name": "http_body",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "catch_up": {
+ "name": "catch_up",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false,
+ "default": 0
+ },
+ "enabled": {
+ "name": "enabled",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false,
+ "default": 1
+ },
+ "max_retries": {
+ "name": "max_retries",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false,
+ "default": 0
+ },
+ "retry_delay_seconds": {
+ "name": "retry_delay_seconds",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false,
+ "default": 60
+ },
+ "timeout_seconds": {
+ "name": "timeout_seconds",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false,
+ "default": 300
+ },
+ "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": {},
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "checkConstraints": {}
+ },
+ "task_execution_logs": {
+ "name": "task_execution_logs",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "task_id": {
+ "name": "task_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "status": {
+ "name": "status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "started_at": {
+ "name": "started_at",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false,
+ "default": "(cast((julianday('now') - 2440587.5)*86400000 as integer))"
+ },
+ "finished_at": {
+ "name": "finished_at",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "error_message": {
+ "name": "error_message",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "result_summary": {
+ "name": "result_summary",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "task_execution_logs_task_id_scheduled_tasks_id_fk": {
+ "name": "task_execution_logs_task_id_scheduled_tasks_id_fk",
+ "tableFrom": "task_execution_logs",
+ "tableTo": "scheduled_tasks",
+ "columnsFrom": [
+ "task_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "no action",
+ "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/0010_snapshot.json b/packages/drizzle-pkg/migrations/meta/0010_snapshot.json
new file mode 100644
index 0000000..312f76e
--- /dev/null
+++ b/packages/drizzle-pkg/migrations/meta/0010_snapshot.json
@@ -0,0 +1,1364 @@
+{
+ "version": "6",
+ "dialect": "sqlite",
+ "id": "288774a8-3083-4620-b814-839fa954acfa",
+ "prevId": "ede766ab-94ae-4696-b9a9-e1b4309154c0",
+ "tables": {
+ "oauth_accounts": {
+ "name": "oauth_accounts",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "integer",
+ "primaryKey": true,
+ "notNull": true,
+ "autoincrement": true
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "provider": {
+ "name": "provider",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "provider_user_id": {
+ "name": "provider_user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "username": {
+ "name": "username",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "email": {
+ "name": "email",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "avatar": {
+ "name": "avatar",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false,
+ "default": "(cast((julianday('now') - 2440587.5)*86400000 as integer))"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false,
+ "default": "(cast((julianday('now') - 2440587.5)*86400000 as integer))"
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {},
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "checkConstraints": {}
+ },
+ "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'"
+ },
+ "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
+ }
+ },
+ "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": {}
+ },
+ "article_cards": {
+ "name": "article_cards",
+ "columns": {
+ "article_id": {
+ "name": "article_id",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "card_id": {
+ "name": "card_id",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "sort_order": {
+ "name": "sort_order",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false,
+ "default": 0
+ }
+ },
+ "indexes": {
+ "idx_article_card_article": {
+ "name": "idx_article_card_article",
+ "columns": [
+ "article_id"
+ ],
+ "isUnique": false
+ },
+ "idx_article_card_card": {
+ "name": "idx_article_card_card",
+ "columns": [
+ "card_id"
+ ],
+ "isUnique": false
+ }
+ },
+ "foreignKeys": {
+ "article_cards_article_id_articles_id_fk": {
+ "name": "article_cards_article_id_articles_id_fk",
+ "tableFrom": "article_cards",
+ "tableTo": "articles",
+ "columnsFrom": [
+ "article_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "article_cards_card_id_cards_id_fk": {
+ "name": "article_cards_card_id_cards_id_fk",
+ "tableFrom": "article_cards",
+ "tableTo": "cards",
+ "columnsFrom": [
+ "card_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {
+ "article_card_pk": {
+ "columns": [
+ "article_id",
+ "card_id"
+ ],
+ "name": "article_card_pk"
+ }
+ },
+ "uniqueConstraints": {},
+ "checkConstraints": {}
+ },
+ "articles": {
+ "name": "articles",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "integer",
+ "primaryKey": true,
+ "notNull": true,
+ "autoincrement": true
+ },
+ "title": {
+ "name": "title",
+ "type": "text(255)",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "content": {
+ "name": "content",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "summary": {
+ "name": "summary",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "cover": {
+ "name": "cover",
+ "type": "text(500)",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "status": {
+ "name": "status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false,
+ "default": "'draft'"
+ },
+ "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": {
+ "idx_article_status": {
+ "name": "idx_article_status",
+ "columns": [
+ "status"
+ ],
+ "isUnique": false
+ },
+ "idx_article_created": {
+ "name": "idx_article_created",
+ "columns": [
+ "created_at"
+ ],
+ "isUnique": false
+ }
+ },
+ "foreignKeys": {},
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "checkConstraints": {}
+ },
+ "card_images": {
+ "name": "card_images",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "integer",
+ "primaryKey": true,
+ "notNull": true,
+ "autoincrement": true
+ },
+ "card_id": {
+ "name": "card_id",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "url": {
+ "name": "url",
+ "type": "text(500)",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "sort_order": {
+ "name": "sort_order",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false,
+ "default": 0
+ }
+ },
+ "indexes": {
+ "idx_card_image_card": {
+ "name": "idx_card_image_card",
+ "columns": [
+ "card_id"
+ ],
+ "isUnique": false
+ }
+ },
+ "foreignKeys": {
+ "card_images_card_id_cards_id_fk": {
+ "name": "card_images_card_id_cards_id_fk",
+ "tableFrom": "card_images",
+ "tableTo": "cards",
+ "columnsFrom": [
+ "card_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "no action",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "checkConstraints": {}
+ },
+ "card_tags": {
+ "name": "card_tags",
+ "columns": {
+ "card_id": {
+ "name": "card_id",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "tag_id": {
+ "name": "tag_id",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ }
+ },
+ "indexes": {
+ "idx_card_tag_card": {
+ "name": "idx_card_tag_card",
+ "columns": [
+ "card_id"
+ ],
+ "isUnique": false
+ },
+ "idx_card_tag_tag": {
+ "name": "idx_card_tag_tag",
+ "columns": [
+ "tag_id"
+ ],
+ "isUnique": false
+ }
+ },
+ "foreignKeys": {
+ "card_tags_card_id_cards_id_fk": {
+ "name": "card_tags_card_id_cards_id_fk",
+ "tableFrom": "card_tags",
+ "tableTo": "cards",
+ "columnsFrom": [
+ "card_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "no action",
+ "onUpdate": "no action"
+ },
+ "card_tags_tag_id_tags_id_fk": {
+ "name": "card_tags_tag_id_tags_id_fk",
+ "tableFrom": "card_tags",
+ "tableTo": "tags",
+ "columnsFrom": [
+ "tag_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "no action",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {
+ "card_tag_pk": {
+ "columns": [
+ "card_id",
+ "tag_id"
+ ],
+ "name": "card_tag_pk"
+ }
+ },
+ "uniqueConstraints": {},
+ "checkConstraints": {}
+ },
+ "cards": {
+ "name": "cards",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "integer",
+ "primaryKey": true,
+ "notNull": true,
+ "autoincrement": true
+ },
+ "type": {
+ "name": "type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "title": {
+ "name": "title",
+ "type": "text(255)",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "description": {
+ "name": "description",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "content": {
+ "name": "content",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "aspect_ratio": {
+ "name": "aspect_ratio",
+ "type": "real",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "category_id": {
+ "name": "category_id",
+ "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": {
+ "idx_card_category": {
+ "name": "idx_card_category",
+ "columns": [
+ "category_id"
+ ],
+ "isUnique": false
+ },
+ "idx_card_type": {
+ "name": "idx_card_type",
+ "columns": [
+ "type"
+ ],
+ "isUnique": false
+ },
+ "idx_card_created": {
+ "name": "idx_card_created",
+ "columns": [
+ "created_at"
+ ],
+ "isUnique": false
+ }
+ },
+ "foreignKeys": {
+ "cards_category_id_categories_id_fk": {
+ "name": "cards_category_id_categories_id_fk",
+ "tableFrom": "cards",
+ "tableTo": "categories",
+ "columnsFrom": [
+ "category_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "no action",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "checkConstraints": {}
+ },
+ "categories": {
+ "name": "categories",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "name": {
+ "name": "name",
+ "type": "text(100)",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "slug": {
+ "name": "slug",
+ "type": "text(100)",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "image": {
+ "name": "image",
+ "type": "text(500)",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "parent_id": {
+ "name": "parent_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "sort_order": {
+ "name": "sort_order",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false,
+ "default": 0
+ },
+ "count": {
+ "name": "count",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false,
+ "default": 0
+ },
+ "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": {
+ "idx_category_slug": {
+ "name": "idx_category_slug",
+ "columns": [
+ "slug"
+ ],
+ "isUnique": true
+ },
+ "idx_category_parent": {
+ "name": "idx_category_parent",
+ "columns": [
+ "parent_id"
+ ],
+ "isUnique": false
+ }
+ },
+ "foreignKeys": {},
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "checkConstraints": {}
+ },
+ "chat_messages": {
+ "name": "chat_messages",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "integer",
+ "primaryKey": true,
+ "notNull": true,
+ "autoincrement": true
+ },
+ "nickname": {
+ "name": "nickname",
+ "type": "text(20)",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "content": {
+ "name": "content",
+ "type": "text",
+ "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))"
+ },
+ "client_id": {
+ "name": "client_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ }
+ },
+ "indexes": {
+ "idx_chat_msg_created": {
+ "name": "idx_chat_msg_created",
+ "columns": [
+ "created_at"
+ ],
+ "isUnique": false
+ }
+ },
+ "foreignKeys": {},
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "checkConstraints": {}
+ },
+ "favorites": {
+ "name": "favorites",
+ "columns": {
+ "user_id": {
+ "name": "user_id",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "card_id": {
+ "name": "card_id",
+ "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": {
+ "idx_favorite_user": {
+ "name": "idx_favorite_user",
+ "columns": [
+ "user_id"
+ ],
+ "isUnique": false
+ },
+ "idx_favorite_card": {
+ "name": "idx_favorite_card",
+ "columns": [
+ "card_id"
+ ],
+ "isUnique": false
+ }
+ },
+ "foreignKeys": {
+ "favorites_user_id_users_id_fk": {
+ "name": "favorites_user_id_users_id_fk",
+ "tableFrom": "favorites",
+ "tableTo": "users",
+ "columnsFrom": [
+ "user_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "favorites_card_id_cards_id_fk": {
+ "name": "favorites_card_id_cards_id_fk",
+ "tableFrom": "favorites",
+ "tableTo": "cards",
+ "columnsFrom": [
+ "card_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {
+ "favorite_pk": {
+ "columns": [
+ "user_id",
+ "card_id"
+ ],
+ "name": "favorite_pk"
+ }
+ },
+ "uniqueConstraints": {},
+ "checkConstraints": {}
+ },
+ "ideas": {
+ "name": "ideas",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "integer",
+ "primaryKey": true,
+ "notNull": true,
+ "autoincrement": true
+ },
+ "author": {
+ "name": "author",
+ "type": "text(30)",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "content": {
+ "name": "content",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "platform": {
+ "name": "platform",
+ "type": "text(30)",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "color": {
+ "name": "color",
+ "type": "text(30)",
+ "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": {
+ "idx_idea_created": {
+ "name": "idx_idea_created",
+ "columns": [
+ "created_at"
+ ],
+ "isUnique": false
+ }
+ },
+ "foreignKeys": {},
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "checkConstraints": {}
+ },
+ "tags": {
+ "name": "tags",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "integer",
+ "primaryKey": true,
+ "notNull": true,
+ "autoincrement": true
+ },
+ "name": {
+ "name": "name",
+ "type": "text(50)",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "slug": {
+ "name": "slug",
+ "type": "text(50)",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ }
+ },
+ "indexes": {
+ "idx_tag_slug": {
+ "name": "idx_tag_slug",
+ "columns": [
+ "slug"
+ ],
+ "isUnique": true
+ }
+ },
+ "foreignKeys": {},
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "checkConstraints": {}
+ },
+ "tools": {
+ "name": "tools",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "name": {
+ "name": "name",
+ "type": "text(50)",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "slug": {
+ "name": "slug",
+ "type": "text(50)",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "icon": {
+ "name": "icon",
+ "type": "text(100)",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "sort_order": {
+ "name": "sort_order",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false,
+ "default": 0
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {},
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "checkConstraints": {}
+ },
+ "scheduled_tasks": {
+ "name": "scheduled_tasks",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "name": {
+ "name": "name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "cron_expression": {
+ "name": "cron_expression",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "type": {
+ "name": "type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "function_name": {
+ "name": "function_name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "function_payload": {
+ "name": "function_payload",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "http_method": {
+ "name": "http_method",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "http_url": {
+ "name": "http_url",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "http_headers": {
+ "name": "http_headers",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "http_body": {
+ "name": "http_body",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "catch_up": {
+ "name": "catch_up",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false,
+ "default": 0
+ },
+ "enabled": {
+ "name": "enabled",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false,
+ "default": 1
+ },
+ "max_retries": {
+ "name": "max_retries",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false,
+ "default": 0
+ },
+ "retry_delay_seconds": {
+ "name": "retry_delay_seconds",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false,
+ "default": 60
+ },
+ "timeout_seconds": {
+ "name": "timeout_seconds",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false,
+ "default": 300
+ },
+ "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": {},
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "checkConstraints": {}
+ },
+ "task_execution_logs": {
+ "name": "task_execution_logs",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "task_id": {
+ "name": "task_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "status": {
+ "name": "status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "started_at": {
+ "name": "started_at",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false,
+ "default": "(cast((julianday('now') - 2440587.5)*86400000 as integer))"
+ },
+ "finished_at": {
+ "name": "finished_at",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "error_message": {
+ "name": "error_message",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "result_summary": {
+ "name": "result_summary",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "task_execution_logs_task_id_scheduled_tasks_id_fk": {
+ "name": "task_execution_logs_task_id_scheduled_tasks_id_fk",
+ "tableFrom": "task_execution_logs",
+ "tableTo": "scheduled_tasks",
+ "columnsFrom": [
+ "task_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "no action",
+ "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 4e3700e..074c8cc 100644
--- a/packages/drizzle-pkg/migrations/meta/_journal.json
+++ b/packages/drizzle-pkg/migrations/meta/_journal.json
@@ -60,9 +60,23 @@
},
{
"idx": 8,
- "version": "7",
- "when": 1780800000000,
- "tag": "0008_chat_messages",
+ "version": "6",
+ "when": 1782497421774,
+ "tag": "0008_magical_black_knight",
+ "breakpoints": true
+ },
+ {
+ "idx": 9,
+ "version": "6",
+ "when": 1782500000000,
+ "tag": "0009_ideas",
+ "breakpoints": true
+ },
+ {
+ "idx": 10,
+ "version": "6",
+ "when": 1782501620751,
+ "tag": "0010_broken_machine_man",
"breakpoints": true
}
]
diff --git a/server/api/ideas/index.get.ts b/server/api/ideas/index.get.ts
new file mode 100644
index 0000000..40ce722
--- /dev/null
+++ b/server/api/ideas/index.get.ts
@@ -0,0 +1,10 @@
+import { listIdeas } from "../../service/ideas";
+
+export default defineWrappedResponseHandler(async (event) => {
+ const query = getQuery(event);
+ const page = Math.max(1, parseInt(String(query.page || "1")));
+ const pageSize = Math.min(50, Math.max(1, parseInt(String(query.pageSize || "30"))));
+
+ const result = await listIdeas({ page, pageSize });
+ return R.success(result);
+});
diff --git a/server/api/ideas/index.post.ts b/server/api/ideas/index.post.ts
new file mode 100644
index 0000000..5678d4f
--- /dev/null
+++ b/server/api/ideas/index.post.ts
@@ -0,0 +1,18 @@
+import { z } from "zod";
+import { validate } from "#server/utils/validation";
+import { createIdea } from "../../service/ideas";
+
+const createSchema = z.object({
+ author: z.string().max(30, "昵称不能超过 30 字").nullable().optional(),
+ content: z.string().min(1, "想法不能为空").max(500, "想法不能超过 500 字"),
+ platform: z.string().max(30).nullable().optional(),
+ color: z.string().max(30).nullable().optional(),
+});
+
+export default defineWrappedResponseHandler(async (event) => {
+ const body = await readBody(event);
+ const data = validate(createSchema, body);
+
+ const idea = await createIdea(data);
+ return R.success(idea);
+});
diff --git a/server/service/ideas/index.ts b/server/service/ideas/index.ts
new file mode 100644
index 0000000..ca9c5bb
--- /dev/null
+++ b/server/service/ideas/index.ts
@@ -0,0 +1,106 @@
+import { dbGlobal } from "drizzle-pkg/lib/db";
+import { ideas } from "drizzle-pkg/lib/schema/content";
+import { desc, sql } from "drizzle-orm";
+
+// ============ Types ============
+export interface IdeaItem {
+ id: number;
+ author: string | null;
+ content: string;
+ platform: string | null;
+ color: string | null;
+ createdAt: Date;
+}
+
+export interface CreateIdeaInput {
+ author: string | null;
+ content: string;
+ platform?: string | null;
+ color?: string | null;
+}
+
+// ============ Color palette for random assignment ============
+const IDEA_COLORS = [
+ "#cc785c", // primary coral
+ "#5db8a6", // accent teal
+ "#e8a55a", // accent amber
+ "#8b7ec8", // soft purple
+ "#6fa8dc", // soft blue
+ "#e07b7b", // soft red
+ "#7eb77f", // soft green
+ "#c9a0dc", // lavender
+];
+
+export function randomIdeaColor(): string {
+ return IDEA_COLORS[Math.floor(Math.random() * IDEA_COLORS.length)];
+}
+
+// ============ CRUD ============
+
+export async function listIdeas(opts: {
+ page?: number;
+ pageSize?: number;
+}): Promise<{ items: IdeaItem[]; total: number; page: number; pageSize: number; hasMore: boolean }> {
+ const page = opts.page ?? 1;
+ const pageSize = opts.pageSize ?? 30;
+
+ const [rows, countResult] = await Promise.all([
+ dbGlobal
+ .select()
+ .from(ideas)
+ .orderBy(desc(ideas.createdAt))
+ .limit(pageSize)
+ .offset((page - 1) * pageSize),
+ dbGlobal
+ .select({ count: sql
`count(*)` })
+ .from(ideas),
+ ]);
+
+ // $count returns differently — use sql count as fallback
+ let total = 0;
+ if (countResult && countResult.length > 0) {
+ total = (countResult[0] as any).count ?? 0;
+ }
+
+ const items: IdeaItem[] = rows.map((row) => ({
+ id: row.id,
+ author: row.author,
+ content: row.content,
+ platform: row.platform,
+ color: row.color,
+ createdAt: row.createdAt,
+ }));
+
+ return {
+ items,
+ total,
+ page,
+ pageSize,
+ hasMore: page * pageSize < total,
+ };
+}
+
+export async function createIdea(input: CreateIdeaInput): Promise {
+ const color = input.color || randomIdeaColor();
+
+ const [inserted] = await dbGlobal
+ .insert(ideas)
+ .values({
+ author: input.author || '',
+ content: input.content,
+ platform: input.platform || null,
+ color,
+ })
+ .returning({ id: ideas.id });
+
+ if (!inserted) throw new Error("Failed to create idea");
+
+ return {
+ id: inserted.id,
+ author: input.author,
+ content: input.content,
+ platform: input.platform || null,
+ color,
+ createdAt: new Date(),
+ };
+}