|
@@ -161,6 +176,11 @@ function onExecuteClose() {
{{ t.needsApproval ? '需审批' : '直接执行' }}
|
+
+
+ {{ t.adminOnly ? '仅管理员' : '所有人' }}
+
+ |
{{ t.sortOrder }} |
@@ -171,6 +191,9 @@ function onExecuteClose() {
+
@@ -390,6 +413,16 @@ function onExecuteClose() {
color: #666;
}
+.badge-admin-only {
+ background: #fef0f0;
+ color: #e53e3e;
+}
+
+.badge-all-users {
+ background: #f0f0f0;
+ color: #666;
+}
+
.sort-cell {
color: var(--color-muted);
font-size: 13px;
diff --git a/app/pages/ideas/index copy.vue b/app/pages/ideas/index copy.vue
new file mode 100644
index 0000000..3970b77
--- /dev/null
+++ b/app/pages/ideas/index copy.vue
@@ -0,0 +1,1125 @@
+
+
+
+
+
+
+
+
+ ![]()
+
+
+
+
+ 私人收藏 · 随记
+ {{ displayTitle }}|
+ {{ hero.sub }}
+
+
+
+
+
+
+
+
+
+
+
+ 
+
+
+
+
+
+ 
+
+
+
+
+ 
+
+
+
+
+
+
+
+
+ "
+ 每件东西都有自己的气味,闻到就穿越了
+ — 手记 #1
+
+
+
+
+ 
+
+
+
+
+ 
+
+
+
+
+ 
+
+
+
+
+
+
+
+
+
+ 
+
+
+
+
+
+
+
+
+
+ "
+ 收集的过程比结果更重要
+ — 手记 #2
+
+
+
+
+
+
+
+ 
+
+
+
+
+ 
+
+
+
+
+ 
+
+
+
+
+
+
+
+ "
+ 有些东西扔不掉,不是因为值钱,是因为记得
+ — 手记 #3
+
+
+
+
+
+
+
+
+ 03 · 精选
+
+
+ 不是作品集, 是私人日记
+ 没有策划,没有主题,就是随手拍、随便留。三年下来,发现这些碎片其实比"正经作品"更像自己。
+
+ 进入全部收藏
+ →
+
+
+
+
+ 
+
+ 2022 · 午后
+
+
+
+
+
+
+
+
+
+
+
+
+ ![]()
+
+ {{ c.title }}
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/pages/ideas/index.vue b/app/pages/ideas/index.vue
new file mode 100644
index 0000000..1ea5f3d
--- /dev/null
+++ b/app/pages/ideas/index.vue
@@ -0,0 +1,541 @@
+
+
+
+
+
+
+
+
+
+
+
+ 💡
+ 还没有想法
+ 成为第一个分享的人吧
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 加载更多
+
+
+
+
+
+
+
+
+
+
+
+ {{ selectedIdea.author || '匿名' }}
+ {{ selectedIdea.platform }}
+ {{ new Date(selectedIdea.createdAt).toLocaleDateString('zh-CN', { year: 'numeric', month: 'long', day: 'numeric' }) }}
+
+ {{ selectedIdea.content }}
+
+
+
+
+
+
+
+
+
diff --git a/app/pages/index.vue b/app/pages/index.vue
new file mode 100644
index 0000000..afd352a
--- /dev/null
+++ b/app/pages/index.vue
@@ -0,0 +1,41 @@
+
+
+
+
+
+
+
diff --git a/app/pages/index/index copy.vue b/app/pages/index/index copy.vue
deleted file mode 100644
index 3970b77..0000000
--- a/app/pages/index/index copy.vue
+++ /dev/null
@@ -1,1125 +0,0 @@
-
-
-
-
-
-
-
-
- ![]()
-
-
-
-
- 私人收藏 · 随记
- {{ displayTitle }}|
- {{ hero.sub }}
-
-
-
-
-
-
-
-
-
-
-
- 
-
-
-
-
-
- 
-
-
-
-
- 
-
-
-
-
-
-
-
-
- "
- 每件东西都有自己的气味,闻到就穿越了
- — 手记 #1
-
-
-
-
- 
-
-
-
-
- 
-
-
-
-
- 
-
-
-
-
-
-
-
-
-
- 
-
-
-
-
-
-
-
-
-
- "
- 收集的过程比结果更重要
- — 手记 #2
-
-
-
-
-
-
-
- 
-
-
-
-
- 
-
-
-
-
- 
-
-
-
-
-
-
-
- "
- 有些东西扔不掉,不是因为值钱,是因为记得
- — 手记 #3
-
-
-
-
-
-
-
-
- 03 · 精选
-
-
- 不是作品集, 是私人日记
- 没有策划,没有主题,就是随手拍、随便留。三年下来,发现这些碎片其实比"正经作品"更像自己。
-
- 进入全部收藏
- →
-
-
-
-
- 
-
- 2022 · 午后
-
-
-
-
-
-
-
-
-
-
-
-
- ![]()
-
- {{ c.title }}
-
-
-
-
-
-
-
-
-
-
-
diff --git a/app/pages/index/index.vue b/app/pages/index/index.vue
deleted file mode 100644
index 1ea5f3d..0000000
--- a/app/pages/index/index.vue
+++ /dev/null
@@ -1,541 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
- 💡
- 还没有想法
- 成为第一个分享的人吧
-
-
-
-
-
-
-
-
-
-
-
-
-
- 加载更多
-
-
-
-
-
-
-
-
-
-
-
- {{ selectedIdea.author || '匿名' }}
- {{ selectedIdea.platform }}
- {{ new Date(selectedIdea.createdAt).toLocaleDateString('zh-CN', { year: 'numeric', month: 'long', day: 'numeric' }) }}
-
- {{ selectedIdea.content }}
-
-
-
-
-
-
-
-
-
diff --git a/packages/drizzle-pkg/db.sqlite b/packages/drizzle-pkg/db.sqlite
index d18dfae3a1260be0fd77af25dfbf5da3a03f0ba2..bb7b2e39d1746ada8f5a939ae97b89fa3bbe09f3 100644
GIT binary patch
delta 1462
zcma)4eQXnD9Dd*XSns3PcNLm$c5`dl;=m2=x_%7>_Qz19EGrIh46y6nu5;40-P(p~?F5?4nmhI&nj!%-XU;5ZP411~&J~y{nzityc^Bkdo{kP;sbt^Z9%CjJ9eoN1_x!`%nt~
zl{GbvAgE+sYYDOpX@Lci@P1%H2i%Zd_+C2)8U3ek>9UOY=@d1S%JJDPALSt|&8#|S
zF>7m!Oj1R~iV96(8JcEUeQS`lWrofjp=M5e^H$dWiO&qvd)qJP+AqWD*&_ZbKVdA+
z+8g7%K5>!g^_J2bAx*nvw<3na-a6H*D0Qx|uc0pF5tTZxSMfEtRmCm(+yXpy^Mmoz
zcng!}Q@J%$#MdMzR3Mk|nQ5i)dai7mFbIqPk5Oq2xe@9uQ$$rRevQZyLK=;rU(pqG
z5q*xvakkAUGku5B$F37bLMYYWxK4DHtOKl&2dEaMOt;Ws(P{rpzGPp&D#v0GH54uUg|S1qOScK%4MzZ&
zdQA*J&fB?O=cMQYyck~A83mBl%R5^JPAI=)cy}0RdgLTm&IGo7sy+KwJLTzP7
zsI#X#8jM9FJN2QhL|N{{pXAoZ$TV4^8${|zF?o<2WSiJJ<_aTH0aDaYiPTDpJWrm`
ze;27GMPvuLhAhGMf4~weDG{M$uqV+a4@P&ygK=ehe^do&J>a6O(t&wCkImB`)hn?K
z?!Wtx_WjH9)Jp@2U^w2hW7keFGEaY4pRK2?x$E_m#Ym>vshpvaLa>;t)xwr*QD&Ob1WW1Rm(grH_L2eVlsfCO9yMn@)qV`*?Tq2pGMOUpO2A`{(em73`bC
z+s=ZKIox&u48L5vmcm8jD#B&J#pG(&vRCN`d1e%#b*AGcAaojM`B!-x*TrVpMrIU8
zi!w+PHDm-*1vG0Z8({P;LH12^A!%GQ@j$Y}6|FYF>KCns@@D>dhdLPVQxl2qSk$rH
zQ6oL#T)d>-v3s6=tpjuWBT2{dhTVyNMZrQm1-x^-sGtXe?Bs%(RMTnvX8do2;u$=M
zq{iQk;0M+gePWt^2=e+n<3(j~nLhmkUGu<7?1pEwr(NT)-VXgQ>Xp}MJ7!70(B-)m
zhl&KaP%e;$t-TtHy~^Q}*bD0Rn89|>tZ9M2K-hLxE72J2QV#u^MgMUrTUe}MqkkzI
PnhlWxsqMn?XISDN6B5FK
delta 759
zcma)&NoW&c6vyZL=9^AtrZZoHHZDP8OY1Tq?N6NK&=bMzPJ(#<8(UOe(bp
z)1p!<6qP|oT&M>Ty;(;XaYs?mmM)@FaYJ$v4{a%Wt2!RM`*^>1dGGys|JV7%(fP!2
z#%Ady2;#iKzoAB@VW
z%6Pi6tz~^8nv#5}P(J1l)k%TYj+#I;+wKdtc&ZL>TAAqxw^VJb%lg{dgB=~o^+_oW
zPHcYrWrNbS?idSkfxxG50T(o(x(9=lav{{f5Zv}?e!tw*b~`+y5!7lkZ$((Zs9)bv
z^Az#%AbNdtdQ#hSzX-rwW!=LvORj5c3GXg1UsK){XG|2usF!y$Hl_3774-T;ETGvR
z`7NOPSY%j_41TLeG4H8syL6)3^tJ!=rcrKR0fx$I8fWr1p-(Qpj1=OXDy(`w+qKMFKl}=8KW3dAP5{3t_z00DgOFC2L1unwe8FR
diff --git a/packages/drizzle-pkg/lib/schema/agent-tool.ts b/packages/drizzle-pkg/lib/schema/agent-tool.ts
index fa7a583..a5d3932 100644
--- a/packages/drizzle-pkg/lib/schema/agent-tool.ts
+++ b/packages/drizzle-pkg/lib/schema/agent-tool.ts
@@ -28,6 +28,7 @@ export const agentTools = sqliteTable(
config: text("config").notNull(),
enabled: integer("enabled").default(1).notNull(),
needsApproval: integer("needs_approval").default(0).notNull(),
+ adminOnly: integer("admin_only").default(0).notNull(),
sortOrder: integer("sort_order").default(0).notNull(),
createdAt: integer("created_at", { mode: "timestamp_ms" })
.defaultNow()
diff --git a/packages/drizzle-pkg/migrations/0016_broken_patch.sql b/packages/drizzle-pkg/migrations/0016_broken_patch.sql
new file mode 100644
index 0000000..4b0c579
--- /dev/null
+++ b/packages/drizzle-pkg/migrations/0016_broken_patch.sql
@@ -0,0 +1 @@
+ALTER TABLE `agent_tools` ADD `admin_only` integer DEFAULT 0 NOT NULL;
\ No newline at end of file
diff --git a/packages/drizzle-pkg/migrations/meta/0016_snapshot.json b/packages/drizzle-pkg/migrations/meta/0016_snapshot.json
new file mode 100644
index 0000000..b4ab383
--- /dev/null
+++ b/packages/drizzle-pkg/migrations/meta/0016_snapshot.json
@@ -0,0 +1,1885 @@
+{
+ "version": "6",
+ "dialect": "sqlite",
+ "id": "03361513-d968-427d-9462-56a5b55bd1e9",
+ "prevId": "84cd1430-dea1-45b0-b4cf-6bd7c02331dd",
+ "tables": {
+ "agent_tool_logs": {
+ "name": "agent_tool_logs",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "integer",
+ "primaryKey": true,
+ "notNull": true,
+ "autoincrement": true
+ },
+ "tool_id": {
+ "name": "tool_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "tool_slug": {
+ "name": "tool_slug",
+ "type": "text(50)",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "input": {
+ "name": "input",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "output": {
+ "name": "output",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "status": {
+ "name": "status",
+ "type": "text(20)",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "error_message": {
+ "name": "error_message",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "duration_ms": {
+ "name": "duration_ms",
+ "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": {
+ "agent_tool_logs_tool_id_idx": {
+ "name": "agent_tool_logs_tool_id_idx",
+ "columns": [
+ "tool_id"
+ ],
+ "isUnique": false
+ },
+ "agent_tool_logs_created_at_idx": {
+ "name": "agent_tool_logs_created_at_idx",
+ "columns": [
+ "created_at"
+ ],
+ "isUnique": false
+ }
+ },
+ "foreignKeys": {},
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "checkConstraints": {}
+ },
+ "agent_tools": {
+ "name": "agent_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
+ },
+ "description": {
+ "name": "description",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "type": {
+ "name": "type",
+ "type": "text(30)",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "config": {
+ "name": "config",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "enabled": {
+ "name": "enabled",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false,
+ "default": 1
+ },
+ "needs_approval": {
+ "name": "needs_approval",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false,
+ "default": 0
+ },
+ "admin_only": {
+ "name": "admin_only",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false,
+ "default": 0
+ },
+ "sort_order": {
+ "name": "sort_order",
+ "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": {
+ "agent_tools_slug_idx": {
+ "name": "agent_tools_slug_idx",
+ "columns": [
+ "slug"
+ ],
+ "isUnique": true
+ },
+ "agent_tools_enabled_idx": {
+ "name": "agent_tools_enabled_idx",
+ "columns": [
+ "enabled"
+ ],
+ "isUnique": false
+ }
+ },
+ "foreignKeys": {},
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "checkConstraints": {}
+ },
+ "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": {}
+ },
+ "projects": {
+ "name": "projects",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "integer",
+ "primaryKey": true,
+ "notNull": true,
+ "autoincrement": true
+ },
+ "name": {
+ "name": "name",
+ "type": "text(100)",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "tags": {
+ "name": "tags",
+ "type": "text(500)",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "description": {
+ "name": "description",
+ "type": "text(1000)",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "path": {
+ "name": "path",
+ "type": "text(500)",
+ "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_project_created": {
+ "name": "idx_project_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": {}
+ },
+ "llm_models": {
+ "name": "llm_models",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "integer",
+ "primaryKey": true,
+ "notNull": true,
+ "autoincrement": true
+ },
+ "provider_id": {
+ "name": "provider_id",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "name": {
+ "name": "name",
+ "type": "text(200)",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "model_id": {
+ "name": "model_id",
+ "type": "text(200)",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "type": {
+ "name": "type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false,
+ "default": "'text'"
+ },
+ "enabled": {
+ "name": "enabled",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false,
+ "default": 1
+ },
+ "description": {
+ "name": "description",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "max_tokens": {
+ "name": "max_tokens",
+ "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": {
+ "idx_llm_model_provider": {
+ "name": "idx_llm_model_provider",
+ "columns": [
+ "provider_id"
+ ],
+ "isUnique": false
+ },
+ "idx_llm_model_type": {
+ "name": "idx_llm_model_type",
+ "columns": [
+ "type"
+ ],
+ "isUnique": false
+ }
+ },
+ "foreignKeys": {
+ "llm_models_provider_id_llm_providers_id_fk": {
+ "name": "llm_models_provider_id_llm_providers_id_fk",
+ "tableFrom": "llm_models",
+ "tableTo": "llm_providers",
+ "columnsFrom": [
+ "provider_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "checkConstraints": {}
+ },
+ "llm_providers": {
+ "name": "llm_providers",
+ "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
+ },
+ "name": {
+ "name": "name",
+ "type": "text(100)",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "slug": {
+ "name": "slug",
+ "type": "text(100)",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "base_url": {
+ "name": "base_url",
+ "type": "text(500)",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "parse_mode": {
+ "name": "parse_mode",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false,
+ "default": "'openai'"
+ },
+ "api_key": {
+ "name": "api_key",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "status": {
+ "name": "status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false,
+ "default": "'active'"
+ },
+ "description": {
+ "name": "description",
+ "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_llm_provider_user_slug": {
+ "name": "idx_llm_provider_user_slug",
+ "columns": [
+ "user_id",
+ "slug"
+ ],
+ "isUnique": true
+ },
+ "idx_llm_provider_user": {
+ "name": "idx_llm_provider_user",
+ "columns": [
+ "user_id"
+ ],
+ "isUnique": false
+ },
+ "idx_llm_provider_status": {
+ "name": "idx_llm_provider_status",
+ "columns": [
+ "status"
+ ],
+ "isUnique": false
+ }
+ },
+ "foreignKeys": {
+ "llm_providers_user_id_users_id_fk": {
+ "name": "llm_providers_user_id_users_id_fk",
+ "tableFrom": "llm_providers",
+ "tableTo": "users",
+ "columnsFrom": [
+ "user_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "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 6965254..a25e9ec 100644
--- a/packages/drizzle-pkg/migrations/meta/_journal.json
+++ b/packages/drizzle-pkg/migrations/meta/_journal.json
@@ -113,6 +113,13 @@
"when": 1785942019319,
"tag": "0015_high_red_shift",
"breakpoints": true
+ },
+ {
+ "idx": 16,
+ "version": "6",
+ "when": 1785978733580,
+ "tag": "0016_broken_patch",
+ "breakpoints": true
}
]
}
\ No newline at end of file
diff --git a/server/api/agent-tools/[id].put.ts b/server/api/agent-tools/[id].put.ts
index f8a5014..01dc0c0 100644
--- a/server/api/agent-tools/[id].put.ts
+++ b/server/api/agent-tools/[id].put.ts
@@ -10,7 +10,7 @@ export default defineWrappedResponseHandler(async (event) => {
}
const body = await readBody(event);
- const { name, slug, description, type, config, enabled, needsApproval, sortOrder } = body;
+ const { name, slug, description, type, config, enabled, needsApproval, adminOnly, sortOrder } = body;
try {
const result = await updateAgentTool(id, {
@@ -21,6 +21,7 @@ export default defineWrappedResponseHandler(async (event) => {
config,
enabled,
needsApproval,
+ adminOnly,
sortOrder,
});
if (!result) {
diff --git a/server/api/agent-tools/index.post.ts b/server/api/agent-tools/index.post.ts
index b111271..7eff14e 100644
--- a/server/api/agent-tools/index.post.ts
+++ b/server/api/agent-tools/index.post.ts
@@ -5,7 +5,7 @@ export default defineWrappedResponseHandler(async (event) => {
await requireAdmin(event);
const body = await readBody(event);
- const { name, slug, description, type, config, enabled, needsApproval, sortOrder } = body;
+ const { name, slug, description, type, config, enabled, needsApproval, adminOnly, sortOrder } = body;
if (!name || !slug || !type) {
return R.throwError(422, "name、slug、type 不能为空", null);
@@ -20,6 +20,7 @@ export default defineWrappedResponseHandler(async (event) => {
config: config ?? {},
enabled,
needsApproval,
+ adminOnly,
sortOrder,
});
return R.success(result);
diff --git a/server/api/llm/chat/index.post.ts b/server/api/llm/chat/index.post.ts
index 8cba742..ab6849b 100644
--- a/server/api/llm/chat/index.post.ts
+++ b/server/api/llm/chat/index.post.ts
@@ -84,7 +84,7 @@ export default defineEventHandler(async (event) => {
const languageModel = resolveModel(provider, model.modelId);
- const { tools, approvalConfig } = enableTools ? await getEnabledToolsForLlm(user.id) : { tools: undefined, approvalConfig: {} };
+ const { tools, approvalConfig } = enableTools ? await getEnabledToolsForLlm(user.id, user.role) : { tools: undefined, approvalConfig: {} };
const modelMessages = await convertToModelMessages(messages);
diff --git a/server/api/llm/chat/tools.get.ts b/server/api/llm/chat/tools.get.ts
index 88f8a66..0241436 100644
--- a/server/api/llm/chat/tools.get.ts
+++ b/server/api/llm/chat/tools.get.ts
@@ -1,6 +1,8 @@
+import { getCurrentUser } from "#server/utils/context";
import { getEnabledToolInfos } from "#server/service/agent-tool";
-export default defineWrappedResponseHandler(async () => {
- const result = await getEnabledToolInfos();
+export default defineWrappedResponseHandler(async (event) => {
+ const user = await getCurrentUser(event);
+ const result = await getEnabledToolInfos(user?.role ?? null);
return R.success(result);
});
diff --git a/server/service/agent-tool/index.ts b/server/service/agent-tool/index.ts
index 2f37886..98dc5a3 100644
--- a/server/service/agent-tool/index.ts
+++ b/server/service/agent-tool/index.ts
@@ -1,5 +1,6 @@
import { dbGlobal } from "drizzle-pkg/lib/db";
import { agentTools } from "drizzle-pkg/lib/schema/agent-tool";
+import type { UserRole } from "drizzle-pkg/lib/schema/auth";
import { eq, asc } from "drizzle-orm";
import { tool, jsonSchema } from "ai";
import { z } from "zod";
@@ -98,6 +99,7 @@ export interface CreateAgentToolInput {
config: Record;
enabled?: boolean;
needsApproval?: boolean;
+ adminOnly?: boolean;
sortOrder?: number;
}
@@ -109,6 +111,7 @@ export interface UpdateAgentToolInput {
config?: Record;
enabled?: boolean;
needsApproval?: boolean;
+ adminOnly?: boolean;
sortOrder?: number;
}
@@ -186,6 +189,7 @@ export async function createAgentTool(input: CreateAgentToolInput): Promise {
+export async function getEnabledToolInfos(userRole: UserRole | null = null): Promise {
const tools = await dbGlobal
.select()
.from(agentTools)
.where(eq(agentTools.enabled, 1))
.orderBy(asc(agentTools.sortOrder));
+ const isAdmin = userRole === "admin";
+
const result: EnabledToolInfo[] = [];
for (const agentTool of tools) {
+ if (!isAdmin && agentTool.adminOnly) continue;
const executor = getExecutor(agentTool.type);
if (!executor) continue;
let config: unknown;
@@ -323,7 +331,10 @@ export async function getEnabledToolInfos(): Promise {
return result;
}
-export async function getEnabledToolsForLlm(userId: number | null = null): Promise<{
+export async function getEnabledToolsForLlm(
+ userId: number | null = null,
+ userRole: UserRole | null = null,
+): Promise<{
tools: Record>;
approvalConfig: Record;
}> {
@@ -333,9 +344,12 @@ export async function getEnabledToolsForLlm(userId: number | null = null): Promi
.where(eq(agentTools.enabled, 1))
.orderBy(asc(agentTools.sortOrder));
+ const isAdmin = userRole === "admin";
+
const result: Record = {};
const approvalConfig: Record = {};
for (const agentTool of tools) {
+ if (!isAdmin && agentTool.adminOnly) continue;
const executor = getExecutor(agentTool.type);
if (!executor) continue;
let config: unknown;
|