@minion-stack/db 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (206) hide show
  1. package/dist/index.d.ts +4 -0
  2. package/dist/index.d.ts.map +1 -0
  3. package/dist/index.js +8 -0
  4. package/dist/index.js.map +1 -0
  5. package/dist/relations.d.ts +126 -0
  6. package/dist/relations.d.ts.map +1 -0
  7. package/dist/relations.js +178 -0
  8. package/dist/relations.js.map +1 -0
  9. package/dist/schema/activity-bins.d.ts +118 -0
  10. package/dist/schema/activity-bins.d.ts.map +1 -0
  11. package/dist/schema/activity-bins.js +19 -0
  12. package/dist/schema/activity-bins.js.map +1 -0
  13. package/dist/schema/agent-groups.d.ts +180 -0
  14. package/dist/schema/agent-groups.d.ts.map +1 -0
  15. package/dist/schema/agent-groups.js +22 -0
  16. package/dist/schema/agent-groups.js.map +1 -0
  17. package/dist/schema/agents.d.ts +196 -0
  18. package/dist/schema/agents.d.ts.map +1 -0
  19. package/dist/schema/agents.js +20 -0
  20. package/dist/schema/agents.js.map +1 -0
  21. package/dist/schema/auth/index.d.ts +1713 -0
  22. package/dist/schema/auth/index.d.ts.map +1 -0
  23. package/dist/schema/auth/index.js +152 -0
  24. package/dist/schema/auth/index.js.map +1 -0
  25. package/dist/schema/backup-configs.d.ts +207 -0
  26. package/dist/schema/backup-configs.d.ts.map +1 -0
  27. package/dist/schema/backup-configs.js +18 -0
  28. package/dist/schema/backup-configs.js.map +1 -0
  29. package/dist/schema/bugs.d.ts +232 -0
  30. package/dist/schema/bugs.d.ts.map +1 -0
  31. package/dist/schema/bugs.js +26 -0
  32. package/dist/schema/bugs.js.map +1 -0
  33. package/dist/schema/builder.d.ts +1546 -0
  34. package/dist/schema/builder.d.ts.map +1 -0
  35. package/dist/schema/builder.js +143 -0
  36. package/dist/schema/builder.js.map +1 -0
  37. package/dist/schema/channel-assignments.d.ts +120 -0
  38. package/dist/schema/channel-assignments.d.ts.map +1 -0
  39. package/dist/schema/channel-assignments.js +19 -0
  40. package/dist/schema/channel-assignments.js.map +1 -0
  41. package/dist/schema/channel-identities.d.ts +141 -0
  42. package/dist/schema/channel-identities.d.ts.map +1 -0
  43. package/dist/schema/channel-identities.js +21 -0
  44. package/dist/schema/channel-identities.js.map +1 -0
  45. package/dist/schema/channels.d.ts +213 -0
  46. package/dist/schema/channels.d.ts.map +1 -0
  47. package/dist/schema/channels.js +26 -0
  48. package/dist/schema/channels.js.map +1 -0
  49. package/dist/schema/chat-messages.d.ts +192 -0
  50. package/dist/schema/chat-messages.d.ts.map +1 -0
  51. package/dist/schema/chat-messages.js +23 -0
  52. package/dist/schema/chat-messages.js.map +1 -0
  53. package/dist/schema/config-snapshots.d.ts +120 -0
  54. package/dist/schema/config-snapshots.d.ts.map +1 -0
  55. package/dist/schema/config-snapshots.js +16 -0
  56. package/dist/schema/config-snapshots.js.map +1 -0
  57. package/dist/schema/connection-events.d.ts +173 -0
  58. package/dist/schema/connection-events.d.ts.map +1 -0
  59. package/dist/schema/connection-events.js +22 -0
  60. package/dist/schema/connection-events.js.map +1 -0
  61. package/dist/schema/credential-health.d.ts +116 -0
  62. package/dist/schema/credential-health.d.ts.map +1 -0
  63. package/dist/schema/credential-health.js +19 -0
  64. package/dist/schema/credential-health.js.map +1 -0
  65. package/dist/schema/device-identities.d.ts +120 -0
  66. package/dist/schema/device-identities.d.ts.map +1 -0
  67. package/dist/schema/device-identities.js +14 -0
  68. package/dist/schema/device-identities.js.map +1 -0
  69. package/dist/schema/files.d.ts +175 -0
  70. package/dist/schema/files.d.ts.map +1 -0
  71. package/dist/schema/files.js +16 -0
  72. package/dist/schema/files.js.map +1 -0
  73. package/dist/schema/flows.d.ts +156 -0
  74. package/dist/schema/flows.d.ts.map +1 -0
  75. package/dist/schema/flows.js +12 -0
  76. package/dist/schema/flows.js.map +1 -0
  77. package/dist/schema/gateway-heartbeats.d.ts +186 -0
  78. package/dist/schema/gateway-heartbeats.d.ts.map +1 -0
  79. package/dist/schema/gateway-heartbeats.js +23 -0
  80. package/dist/schema/gateway-heartbeats.js.map +1 -0
  81. package/dist/schema/index.d.ts +37 -0
  82. package/dist/schema/index.d.ts.map +1 -0
  83. package/dist/schema/index.js +38 -0
  84. package/dist/schema/index.js.map +1 -0
  85. package/dist/schema/marketplace-agents.d.ts +397 -0
  86. package/dist/schema/marketplace-agents.d.ts.map +1 -0
  87. package/dist/schema/marketplace-agents.js +25 -0
  88. package/dist/schema/marketplace-agents.js.map +1 -0
  89. package/dist/schema/marketplace-installs.d.ts +101 -0
  90. package/dist/schema/marketplace-installs.d.ts.map +1 -0
  91. package/dist/schema/marketplace-installs.js +21 -0
  92. package/dist/schema/marketplace-installs.js.map +1 -0
  93. package/dist/schema/missions.d.ts +194 -0
  94. package/dist/schema/missions.d.ts.map +1 -0
  95. package/dist/schema/missions.js +29 -0
  96. package/dist/schema/missions.js.map +1 -0
  97. package/dist/schema/personal-agents.d.ts +302 -0
  98. package/dist/schema/personal-agents.d.ts.map +1 -0
  99. package/dist/schema/personal-agents.js +37 -0
  100. package/dist/schema/personal-agents.js.map +1 -0
  101. package/dist/schema/reliability-events.d.ts +211 -0
  102. package/dist/schema/reliability-events.d.ts.map +1 -0
  103. package/dist/schema/reliability-events.js +28 -0
  104. package/dist/schema/reliability-events.js.map +1 -0
  105. package/dist/schema/server-backups.d.ts +154 -0
  106. package/dist/schema/server-backups.d.ts.map +1 -0
  107. package/dist/schema/server-backups.js +23 -0
  108. package/dist/schema/server-backups.js.map +1 -0
  109. package/dist/schema/server-provision-configs.d.ts +410 -0
  110. package/dist/schema/server-provision-configs.d.ts.map +1 -0
  111. package/dist/schema/server-provision-configs.js +43 -0
  112. package/dist/schema/server-provision-configs.js.map +1 -0
  113. package/dist/schema/servers.d.ts +192 -0
  114. package/dist/schema/servers.d.ts.map +1 -0
  115. package/dist/schema/servers.js +22 -0
  116. package/dist/schema/servers.js.map +1 -0
  117. package/dist/schema/session-tasks.d.ts +211 -0
  118. package/dist/schema/session-tasks.d.ts.map +1 -0
  119. package/dist/schema/session-tasks.js +26 -0
  120. package/dist/schema/session-tasks.js.map +1 -0
  121. package/dist/schema/sessions.d.ts +209 -0
  122. package/dist/schema/sessions.d.ts.map +1 -0
  123. package/dist/schema/sessions.js +27 -0
  124. package/dist/schema/sessions.js.map +1 -0
  125. package/dist/schema/settings.d.ts +118 -0
  126. package/dist/schema/settings.d.ts.map +1 -0
  127. package/dist/schema/settings.js +19 -0
  128. package/dist/schema/settings.js.map +1 -0
  129. package/dist/schema/skill-execution-stats.d.ts +209 -0
  130. package/dist/schema/skill-execution-stats.d.ts.map +1 -0
  131. package/dist/schema/skill-execution-stats.js +24 -0
  132. package/dist/schema/skill-execution-stats.js.map +1 -0
  133. package/dist/schema/skills.d.ts +209 -0
  134. package/dist/schema/skills.d.ts.map +1 -0
  135. package/dist/schema/skills.js +24 -0
  136. package/dist/schema/skills.js.map +1 -0
  137. package/dist/schema/tasks.d.ts +192 -0
  138. package/dist/schema/tasks.d.ts.map +1 -0
  139. package/dist/schema/tasks.js +22 -0
  140. package/dist/schema/tasks.js.map +1 -0
  141. package/dist/schema/unified-events.d.ts +247 -0
  142. package/dist/schema/unified-events.d.ts.map +1 -0
  143. package/dist/schema/unified-events.js +29 -0
  144. package/dist/schema/unified-events.js.map +1 -0
  145. package/dist/schema/user-agents.d.ts +82 -0
  146. package/dist/schema/user-agents.d.ts.map +1 -0
  147. package/dist/schema/user-agents.js +17 -0
  148. package/dist/schema/user-agents.js.map +1 -0
  149. package/dist/schema/user-preferences.d.ts +99 -0
  150. package/dist/schema/user-preferences.d.ts.map +1 -0
  151. package/dist/schema/user-preferences.js +15 -0
  152. package/dist/schema/user-preferences.js.map +1 -0
  153. package/dist/schema/user-servers.d.ts +63 -0
  154. package/dist/schema/user-servers.d.ts.map +1 -0
  155. package/dist/schema/user-servers.js +16 -0
  156. package/dist/schema/user-servers.js.map +1 -0
  157. package/dist/schema/workshop-saves.d.ts +156 -0
  158. package/dist/schema/workshop-saves.d.ts.map +1 -0
  159. package/dist/schema/workshop-saves.js +12 -0
  160. package/dist/schema/workshop-saves.js.map +1 -0
  161. package/dist/utils.d.ts +3 -0
  162. package/dist/utils.d.ts.map +1 -0
  163. package/dist/utils.js +9 -0
  164. package/dist/utils.js.map +1 -0
  165. package/package.json +58 -0
  166. package/src/index.ts +7 -0
  167. package/src/relations.ts +258 -0
  168. package/src/schema/activity-bins.ts +23 -0
  169. package/src/schema/agent-groups.ts +31 -0
  170. package/src/schema/agents.ts +24 -0
  171. package/src/schema/auth/index.ts +190 -0
  172. package/src/schema/backup-configs.ts +22 -0
  173. package/src/schema/bugs.ts +30 -0
  174. package/src/schema/builder.ts +151 -0
  175. package/src/schema/channel-assignments.ts +23 -0
  176. package/src/schema/channel-identities.ts +25 -0
  177. package/src/schema/channels.ts +30 -0
  178. package/src/schema/chat-messages.ts +27 -0
  179. package/src/schema/config-snapshots.ts +20 -0
  180. package/src/schema/connection-events.ts +26 -0
  181. package/src/schema/credential-health.ts +23 -0
  182. package/src/schema/device-identities.ts +14 -0
  183. package/src/schema/files.ts +20 -0
  184. package/src/schema/flows.ts +12 -0
  185. package/src/schema/gateway-heartbeats.ts +27 -0
  186. package/src/schema/index.ts +59 -0
  187. package/src/schema/marketplace-agents.ts +25 -0
  188. package/src/schema/marketplace-installs.ts +25 -0
  189. package/src/schema/missions.ts +33 -0
  190. package/src/schema/personal-agents.ts +41 -0
  191. package/src/schema/reliability-events.ts +32 -0
  192. package/src/schema/server-backups.ts +27 -0
  193. package/src/schema/server-provision-configs.ts +57 -0
  194. package/src/schema/servers.ts +26 -0
  195. package/src/schema/session-tasks.ts +30 -0
  196. package/src/schema/sessions.ts +31 -0
  197. package/src/schema/settings.ts +23 -0
  198. package/src/schema/skill-execution-stats.ts +28 -0
  199. package/src/schema/skills.ts +28 -0
  200. package/src/schema/tasks.ts +26 -0
  201. package/src/schema/unified-events.ts +33 -0
  202. package/src/schema/user-agents.ts +21 -0
  203. package/src/schema/user-preferences.ts +19 -0
  204. package/src/schema/user-servers.ts +20 -0
  205. package/src/schema/workshop-saves.ts +12 -0
  206. package/src/utils.ts +11 -0
@@ -0,0 +1,190 @@
1
+ /**
2
+ * Better Auth schema tables.
3
+ * Generated manually based on Better Auth 1.x field definitions.
4
+ * Provider: sqlite, plugins: emailAndPassword, google OAuth, jwt, organization
5
+ */
6
+ import { sqliteTable, text, integer, index, uniqueIndex } from 'drizzle-orm/sqlite-core';
7
+
8
+ // ── Core: user ──────────────────────────────────────────────────────────────
9
+ export const user = sqliteTable('user', {
10
+ id: text('id').primaryKey(),
11
+ name: text('name').notNull(),
12
+ email: text('email').notNull().unique(),
13
+ emailVerified: integer('email_verified', { mode: 'boolean' }).notNull(),
14
+ image: text('image'),
15
+ createdAt: integer('created_at', { mode: 'timestamp' }).notNull(),
16
+ updatedAt: integer('updated_at', { mode: 'timestamp' }).notNull(),
17
+ role: text('role', { enum: ['user', 'admin'] })
18
+ .notNull()
19
+ .default('user'),
20
+ personalAgentId: text('personal_agent_id'),
21
+ });
22
+
23
+ // ── Core: session ────────────────────────────────────────────────────────────
24
+ export const session = sqliteTable(
25
+ 'session',
26
+ {
27
+ id: text('id').primaryKey(),
28
+ expiresAt: integer('expires_at', { mode: 'timestamp' }).notNull(),
29
+ token: text('token').notNull().unique(),
30
+ createdAt: integer('created_at', { mode: 'timestamp' }).notNull(),
31
+ updatedAt: integer('updated_at', { mode: 'timestamp' }).notNull(),
32
+ ipAddress: text('ip_address'),
33
+ userAgent: text('user_agent'),
34
+ userId: text('user_id')
35
+ .notNull()
36
+ .references(() => user.id, { onDelete: 'cascade' }),
37
+ // Added by organization plugin
38
+ activeOrganizationId: text('active_organization_id'),
39
+ },
40
+ (t) => [index('idx_session_user').on(t.userId)],
41
+ );
42
+
43
+ // ── Core: account ────────────────────────────────────────────────────────────
44
+ export const account = sqliteTable(
45
+ 'account',
46
+ {
47
+ id: text('id').primaryKey(),
48
+ accountId: text('account_id').notNull(),
49
+ providerId: text('provider_id').notNull(),
50
+ userId: text('user_id')
51
+ .notNull()
52
+ .references(() => user.id, { onDelete: 'cascade' }),
53
+ accessToken: text('access_token'),
54
+ refreshToken: text('refresh_token'),
55
+ idToken: text('id_token'),
56
+ accessTokenExpiresAt: integer('access_token_expires_at', { mode: 'timestamp' }),
57
+ refreshTokenExpiresAt: integer('refresh_token_expires_at', { mode: 'timestamp' }),
58
+ scope: text('scope'),
59
+ password: text('password'),
60
+ createdAt: integer('created_at', { mode: 'timestamp' }).notNull(),
61
+ updatedAt: integer('updated_at', { mode: 'timestamp' }).notNull(),
62
+ },
63
+ (t) => [index('idx_account_user').on(t.userId)],
64
+ );
65
+
66
+ // ── Core: verification ────────────────────────────────────────────────────────
67
+ export const verification = sqliteTable(
68
+ 'verification',
69
+ {
70
+ id: text('id').primaryKey(),
71
+ identifier: text('identifier').notNull(),
72
+ value: text('value').notNull(),
73
+ expiresAt: integer('expires_at', { mode: 'timestamp' }).notNull(),
74
+ createdAt: integer('created_at', { mode: 'timestamp' }).notNull(),
75
+ updatedAt: integer('updated_at', { mode: 'timestamp' }).notNull(),
76
+ },
77
+ (t) => [index('idx_verification_identifier').on(t.identifier)],
78
+ );
79
+
80
+ // ── JWT plugin: jwks ─────────────────────────────────────────────────────────
81
+ export const jwks = sqliteTable('jwks', {
82
+ id: text('id').primaryKey(),
83
+ publicKey: text('public_key').notNull(),
84
+ privateKey: text('private_key').notNull(),
85
+ createdAt: integer('created_at', { mode: 'timestamp' }).notNull(),
86
+ });
87
+
88
+ // ── Organization plugin: organization ────────────────────────────────────────
89
+ export const organization = sqliteTable('organization', {
90
+ id: text('id').primaryKey(),
91
+ name: text('name').notNull(),
92
+ slug: text('slug').unique(),
93
+ logo: text('logo'),
94
+ createdAt: integer('created_at', { mode: 'timestamp' }).notNull(),
95
+ metadata: text('metadata'),
96
+ });
97
+
98
+ // ── Organization plugin: member ───────────────────────────────────────────────
99
+ export const member = sqliteTable(
100
+ 'member',
101
+ {
102
+ id: text('id').primaryKey(),
103
+ organizationId: text('organization_id')
104
+ .notNull()
105
+ .references(() => organization.id, { onDelete: 'cascade' }),
106
+ userId: text('user_id')
107
+ .notNull()
108
+ .references(() => user.id, { onDelete: 'cascade' }),
109
+ role: text('role').notNull(),
110
+ createdAt: integer('created_at', { mode: 'timestamp' }).notNull(),
111
+ },
112
+ (t) => [index('idx_member_org').on(t.organizationId), index('idx_member_user').on(t.userId)],
113
+ );
114
+
115
+ // ── Organization plugin: invitation ──────────────────────────────────────────
116
+ export const invitation = sqliteTable(
117
+ 'invitation',
118
+ {
119
+ id: text('id').primaryKey(),
120
+ organizationId: text('organization_id')
121
+ .notNull()
122
+ .references(() => organization.id, { onDelete: 'cascade' }),
123
+ email: text('email').notNull(),
124
+ role: text('role'),
125
+ status: text('status').notNull(),
126
+ expiresAt: integer('expires_at', { mode: 'timestamp' }).notNull(),
127
+ inviterId: text('inviter_id')
128
+ .notNull()
129
+ .references(() => user.id, { onDelete: 'cascade' }),
130
+ createdAt: integer('created_at', { mode: 'timestamp' }).notNull(),
131
+ },
132
+ (t) => [index('idx_invitation_org').on(t.organizationId)],
133
+ );
134
+
135
+ // ── OIDC provider plugin: oauthApplication ──────────────────────────────────
136
+ export const oauthApplication = sqliteTable('oauth_application', {
137
+ id: text('id').primaryKey(),
138
+ name: text('name').notNull(),
139
+ icon: text('icon'),
140
+ metadata: text('metadata'),
141
+ clientId: text('client_id').notNull().unique(),
142
+ clientSecret: text('client_secret'),
143
+ redirectUrls: text('redirect_urls').notNull(),
144
+ type: text('type').notNull(),
145
+ disabled: integer('disabled', { mode: 'boolean' }).default(false),
146
+ userId: text('user_id').references(() => user.id, { onDelete: 'cascade' }),
147
+ createdAt: integer('created_at', { mode: 'timestamp' }).notNull(),
148
+ updatedAt: integer('updated_at', { mode: 'timestamp' }).notNull(),
149
+ });
150
+
151
+ // ── OIDC provider plugin: oauthAccessToken ──────────────────────────────────
152
+ export const oauthAccessToken = sqliteTable(
153
+ 'oauth_access_token',
154
+ {
155
+ id: text('id').primaryKey(),
156
+ accessToken: text('access_token').notNull().unique(),
157
+ refreshToken: text('refresh_token').notNull().unique(),
158
+ accessTokenExpiresAt: integer('access_token_expires_at', { mode: 'timestamp' }).notNull(),
159
+ refreshTokenExpiresAt: integer('refresh_token_expires_at', { mode: 'timestamp' }).notNull(),
160
+ clientId: text('client_id').notNull(),
161
+ userId: text('user_id').references(() => user.id, { onDelete: 'cascade' }),
162
+ scopes: text('scopes').notNull(),
163
+ createdAt: integer('created_at', { mode: 'timestamp' }).notNull(),
164
+ updatedAt: integer('updated_at', { mode: 'timestamp' }).notNull(),
165
+ },
166
+ (t) => [
167
+ index('idx_oauth_access_token_client').on(t.clientId),
168
+ index('idx_oauth_access_token_user').on(t.userId),
169
+ ],
170
+ );
171
+
172
+ // ── OIDC provider plugin: oauthConsent ──────────────────────────────────────
173
+ export const oauthConsent = sqliteTable(
174
+ 'oauth_consent',
175
+ {
176
+ id: text('id').primaryKey(),
177
+ clientId: text('client_id').notNull(),
178
+ userId: text('user_id')
179
+ .notNull()
180
+ .references(() => user.id, { onDelete: 'cascade' }),
181
+ scopes: text('scopes').notNull(),
182
+ createdAt: integer('created_at', { mode: 'timestamp' }).notNull(),
183
+ updatedAt: integer('updated_at', { mode: 'timestamp' }).notNull(),
184
+ consentGiven: integer('consent_given', { mode: 'boolean' }).notNull(),
185
+ },
186
+ (t) => [
187
+ index('idx_oauth_consent_client').on(t.clientId),
188
+ index('idx_oauth_consent_user').on(t.userId),
189
+ ],
190
+ );
@@ -0,0 +1,22 @@
1
+ import { sqliteTable, text, integer, index } from 'drizzle-orm/sqlite-core';
2
+ import { organization } from './auth/index.js';
3
+
4
+ export const backupConfigs = sqliteTable(
5
+ 'backup_configs',
6
+ {
7
+ id: text('id').primaryKey(),
8
+ tenantId: text('tenant_id')
9
+ .notNull()
10
+ .references(() => organization.id, { onDelete: 'cascade' }),
11
+ backupHost: text('backup_host'),
12
+ backupUser: text('backup_user').default('root'),
13
+ backupPort: integer('backup_port').default(22),
14
+ backupBasePath: text('backup_base_path').default('/mnt/agent-data/backups'),
15
+ schedule: text('schedule'),
16
+ retentionCount: integer('retention_count').default(7),
17
+ enabled: integer('enabled').default(0),
18
+ createdAt: integer('created_at').notNull(),
19
+ updatedAt: integer('updated_at').notNull(),
20
+ },
21
+ (t) => [index('idx_backup_configs_tenant').on(t.tenantId)],
22
+ );
@@ -0,0 +1,30 @@
1
+ import { sqliteTable, text, integer, index } from 'drizzle-orm/sqlite-core';
2
+ import { organization } from './auth/index.js';
3
+ import { servers } from './servers.js';
4
+
5
+ export const bugs = sqliteTable(
6
+ 'bugs',
7
+ {
8
+ id: text('id').primaryKey(),
9
+ tenantId: text('tenant_id')
10
+ .notNull()
11
+ .references(() => organization.id, { onDelete: 'cascade' }),
12
+ serverId: text('server_id')
13
+ .notNull()
14
+ .references(() => servers.id, { onDelete: 'cascade' }),
15
+ agentId: text('agent_id'),
16
+ errorCode: text('error_code'),
17
+ message: text('message').notNull(),
18
+ stack: text('stack'),
19
+ severity: text('severity', { enum: ['critical', 'high', 'medium', 'low'] })
20
+ .notNull()
21
+ .default('medium'),
22
+ status: text('status', { enum: ['new', 'acknowledged', 'resolved', 'ignored'] })
23
+ .notNull()
24
+ .default('new'),
25
+ metadata: text('metadata'),
26
+ createdAt: integer('created_at').notNull(),
27
+ updatedAt: integer('updated_at').notNull(),
28
+ },
29
+ (t) => [index('idx_bugs_tenant').on(t.tenantId), index('idx_bugs_server').on(t.serverId)],
30
+ );
@@ -0,0 +1,151 @@
1
+ import { sqliteTable, text, integer, real } from 'drizzle-orm/sqlite-core';
2
+ import { servers } from './servers.js';
3
+ import { organization } from './auth/index.js';
4
+
5
+ // ── Built Skills ──────────────────────────────────────────────────────
6
+ export const builtSkills = sqliteTable('built_skills', {
7
+ id: text('id').primaryKey(),
8
+ name: text('name').notNull(),
9
+ description: text('description').default(''),
10
+ emoji: text('emoji').default('📖'),
11
+ status: text('status', { enum: ['draft', 'published'] })
12
+ .notNull()
13
+ .default('draft'),
14
+ maxCycles: integer('max_cycles').notNull().default(3),
15
+ serverId: text('server_id').references(() => servers.id, { onDelete: 'cascade' }),
16
+ tenantId: text('tenant_id').references(() => organization.id, { onDelete: 'cascade' }),
17
+ createdBy: text('created_by'),
18
+ publishedAt: integer('published_at'),
19
+ createdAt: integer('created_at').notNull(),
20
+ updatedAt: integer('updated_at').notNull(),
21
+ });
22
+
23
+ // ── Skill Tool Pool (junction: skill → gateway tool IDs) ─────────────
24
+ export const builtSkillTools = sqliteTable('built_skill_tools', {
25
+ id: text('id').primaryKey(),
26
+ skillId: text('skill_id')
27
+ .notNull()
28
+ .references(() => builtSkills.id, { onDelete: 'cascade' }),
29
+ toolId: text('tool_id').notNull(), // gateway tool ID string (e.g., 'web-search')
30
+ });
31
+
32
+ // ── Chapters (subprocess nodes in the DAG) ───────────────────────────
33
+ export const builtChapters = sqliteTable('built_chapters', {
34
+ id: text('id').primaryKey(),
35
+ skillId: text('skill_id')
36
+ .notNull()
37
+ .references(() => builtSkills.id, { onDelete: 'cascade' }),
38
+ type: text('type', { enum: ['chapter', 'condition'] })
39
+ .notNull()
40
+ .default('chapter'),
41
+ name: text('name').notNull(),
42
+ description: text('description').default(''),
43
+ guide: text('guide').default(''), // instructions/markdown
44
+ context: text('context').default(''), // constraints, additional context
45
+ outputDef: text('output_def').default(''), // what this chapter produces
46
+ conditionText: text('condition_text').default(''), // binary question for condition nodes
47
+ positionX: real('position_x').notNull().default(0),
48
+ positionY: real('position_y').notNull().default(0),
49
+ createdAt: integer('created_at').notNull(),
50
+ updatedAt: integer('updated_at').notNull(),
51
+ });
52
+
53
+ // ── Chapter Edges (DAG connections between chapters) ─────────────────
54
+ export const builtChapterEdges = sqliteTable('built_chapter_edges', {
55
+ id: text('id').primaryKey(),
56
+ skillId: text('skill_id')
57
+ .notNull()
58
+ .references(() => builtSkills.id, { onDelete: 'cascade' }),
59
+ sourceChapterId: text('source_chapter_id')
60
+ .notNull()
61
+ .references(() => builtChapters.id, { onDelete: 'cascade' }),
62
+ targetChapterId: text('target_chapter_id')
63
+ .notNull()
64
+ .references(() => builtChapters.id, { onDelete: 'cascade' }),
65
+ label: text('label'),
66
+ });
67
+
68
+ // ── Chapter Tools (junction: chapter → subset of skill's tool pool) ──
69
+ export const builtChapterTools = sqliteTable('built_chapter_tools', {
70
+ id: text('id').primaryKey(),
71
+ chapterId: text('chapter_id')
72
+ .notNull()
73
+ .references(() => builtChapters.id, { onDelete: 'cascade' }),
74
+ toolId: text('tool_id').notNull(), // must exist in parent skill's pool
75
+ });
76
+
77
+ // ── Built Agents ─────────────────────────────────────────────────────
78
+ export const builtAgents = sqliteTable('built_agents', {
79
+ id: text('id').primaryKey(),
80
+ name: text('name').notNull(),
81
+ emoji: text('emoji').default('🤖'),
82
+ description: text('description').default(''),
83
+ model: text('model'),
84
+ systemPrompt: text('system_prompt').default(''),
85
+ temperature: real('temperature').default(0.7),
86
+ maxTokens: integer('max_tokens').default(4096),
87
+ retryPolicy: text('retry_policy').default('{}'), // JSON
88
+ fallbackAgentId: text('fallback_agent_id'),
89
+ status: text('status', { enum: ['draft', 'published'] })
90
+ .notNull()
91
+ .default('draft'),
92
+ serverId: text('server_id').references(() => servers.id, { onDelete: 'cascade' }),
93
+ tenantId: text('tenant_id').references(() => organization.id, { onDelete: 'cascade' }),
94
+ createdBy: text('created_by'),
95
+ publishedAt: integer('published_at'),
96
+ createdAt: integer('created_at').notNull(),
97
+ updatedAt: integer('updated_at').notNull(),
98
+ });
99
+
100
+ // ── Agent Skill Slots (junction: agent → skill with order) ───────────
101
+ export const builtAgentSkills = sqliteTable('built_agent_skills', {
102
+ id: text('id').primaryKey(),
103
+ agentId: text('agent_id')
104
+ .notNull()
105
+ .references(() => builtAgents.id, { onDelete: 'cascade' }),
106
+ skillId: text('skill_id')
107
+ .notNull()
108
+ .references(() => builtSkills.id, { onDelete: 'cascade' }),
109
+ position: integer('position').notNull().default(0),
110
+ configOverrides: text('config_overrides').default('{}'), // JSON
111
+ });
112
+
113
+ // ── Agent Built Skills (junction: gateway agent → built skill) ────────
114
+ export const agentBuiltSkills = sqliteTable('agent_built_skills', {
115
+ id: text('id').primaryKey(),
116
+ gatewayAgentId: text('gateway_agent_id').notNull(),
117
+ serverId: text('server_id')
118
+ .notNull()
119
+ .references(() => servers.id, { onDelete: 'cascade' }),
120
+ tenantId: text('tenant_id')
121
+ .notNull()
122
+ .references(() => organization.id, { onDelete: 'cascade' }),
123
+ skillId: text('skill_id')
124
+ .notNull()
125
+ .references(() => builtSkills.id, { onDelete: 'cascade' }),
126
+ position: integer('position').notNull().default(0),
127
+ createdAt: integer('created_at').notNull(),
128
+ });
129
+
130
+ // ── Built Tools (admin-only playground) ──────────────────────────────
131
+ export const builtTools = sqliteTable('built_tools', {
132
+ id: text('id').primaryKey(),
133
+ name: text('name').notNull(),
134
+ description: text('description').default(''),
135
+ scriptCode: text('script_code').default(''),
136
+ scriptLang: text('script_lang', { enum: ['javascript', 'python', 'bash'] })
137
+ .notNull()
138
+ .default('javascript'),
139
+ envVars: text('env_vars').default('{}'), // JSON key-value
140
+ validationRules: text('validation_rules').default('{}'), // JSON input schema
141
+ executionConfig: text('execution_config').default('{}'), // JSON timeout, retries
142
+ status: text('status', { enum: ['draft', 'published'] })
143
+ .notNull()
144
+ .default('draft'),
145
+ serverId: text('server_id').references(() => servers.id, { onDelete: 'cascade' }),
146
+ tenantId: text('tenant_id').references(() => organization.id, { onDelete: 'cascade' }),
147
+ createdBy: text('created_by'),
148
+ publishedAt: integer('published_at'),
149
+ createdAt: integer('created_at').notNull(),
150
+ updatedAt: integer('updated_at').notNull(),
151
+ });
@@ -0,0 +1,23 @@
1
+ import { sqliteTable, text, integer, index, uniqueIndex } from 'drizzle-orm/sqlite-core';
2
+ import { organization } from './auth/index.js';
3
+ import { channels } from './channels.js';
4
+
5
+ export const channelAssignments = sqliteTable(
6
+ 'channel_assignments',
7
+ {
8
+ id: text('id').primaryKey(),
9
+ tenantId: text('tenant_id')
10
+ .notNull()
11
+ .references(() => organization.id, { onDelete: 'cascade' }),
12
+ channelId: text('channel_id')
13
+ .notNull()
14
+ .references(() => channels.id, { onDelete: 'cascade' }),
15
+ targetType: text('target_type', { enum: ['user', 'session'] }).notNull(),
16
+ targetId: text('target_id').notNull(),
17
+ createdAt: integer('created_at').notNull(),
18
+ },
19
+ (t) => [
20
+ index('idx_channel_assign_channel').on(t.channelId),
21
+ uniqueIndex('channel_assign_uniq').on(t.channelId, t.targetType, t.targetId),
22
+ ],
23
+ );
@@ -0,0 +1,25 @@
1
+ import { sqliteTable, text, integer, uniqueIndex, index } from 'drizzle-orm/sqlite-core';
2
+ import { user } from './auth/index.js';
3
+
4
+ /**
5
+ * Maps channel sender IDs (e.g. telegram:12345, discord:67890) to hub users.
6
+ * Used by the gateway to resolve user identity from channel messages.
7
+ */
8
+ export const channelIdentities = sqliteTable(
9
+ 'channel_identities',
10
+ {
11
+ id: text('id').primaryKey(),
12
+ userId: text('user_id')
13
+ .notNull()
14
+ .references(() => user.id, { onDelete: 'cascade' }),
15
+ channel: text('channel').notNull(),
16
+ channelUserId: text('channel_user_id').notNull(),
17
+ displayName: text('display_name'),
18
+ verifiedAt: integer('verified_at'),
19
+ createdAt: integer('created_at').notNull(),
20
+ },
21
+ (t) => [
22
+ uniqueIndex('idx_channel_identity_unique').on(t.channel, t.channelUserId),
23
+ index('idx_channel_identity_user').on(t.userId),
24
+ ],
25
+ );
@@ -0,0 +1,30 @@
1
+ import { sqliteTable, text, integer, index, uniqueIndex } from 'drizzle-orm/sqlite-core';
2
+ import { organization } from './auth/index.js';
3
+ import { servers } from './servers.js';
4
+
5
+ export const channels = sqliteTable(
6
+ 'channels',
7
+ {
8
+ id: text('id').primaryKey(),
9
+ tenantId: text('tenant_id')
10
+ .notNull()
11
+ .references(() => organization.id, { onDelete: 'cascade' }),
12
+ serverId: text('server_id')
13
+ .notNull()
14
+ .references(() => servers.id, { onDelete: 'cascade' }),
15
+ type: text('type', { enum: ['discord', 'whatsapp', 'telegram'] }).notNull(),
16
+ label: text('label').notNull(),
17
+ credentials: text('credentials').notNull().default(''),
18
+ credentialsIv: text('credentials_iv').notNull().default(''),
19
+ credentialsMeta: text('credentials_meta').notNull().default('{}'),
20
+ status: text('status', { enum: ['active', 'inactive', 'pairing'] })
21
+ .notNull()
22
+ .default('inactive'),
23
+ createdAt: integer('created_at').notNull(),
24
+ updatedAt: integer('updated_at').notNull(),
25
+ },
26
+ (t) => [
27
+ index('idx_channels_tenant_server').on(t.tenantId, t.serverId),
28
+ uniqueIndex('channels_uniq_type_label').on(t.tenantId, t.serverId, t.type, t.label),
29
+ ],
30
+ );
@@ -0,0 +1,27 @@
1
+ import { sqliteTable, text, integer, index } from 'drizzle-orm/sqlite-core';
2
+ import { organization } from './auth/index.js';
3
+ import { servers } from './servers.js';
4
+
5
+ export const chatMessages = sqliteTable(
6
+ 'chat_messages',
7
+ {
8
+ id: integer('id').primaryKey({ autoIncrement: true }),
9
+ tenantId: text('tenant_id')
10
+ .notNull()
11
+ .references(() => organization.id, { onDelete: 'cascade' }),
12
+ serverId: text('server_id')
13
+ .notNull()
14
+ .references(() => servers.id, { onDelete: 'cascade' }),
15
+ agentId: text('agent_id').notNull(),
16
+ sessionKey: text('session_key').notNull(),
17
+ role: text('role', { enum: ['user', 'assistant'] }).notNull(),
18
+ content: text('content').notNull(),
19
+ runId: text('run_id'),
20
+ timestamp: integer('timestamp').notNull(),
21
+ createdAt: integer('created_at').notNull(),
22
+ },
23
+ (t) => [
24
+ index('idx_chat_tenant').on(t.tenantId),
25
+ index('idx_chat_by_agent').on(t.agentId, t.sessionKey, t.timestamp),
26
+ ],
27
+ );
@@ -0,0 +1,20 @@
1
+ import { sqliteTable, text, integer, uniqueIndex } from 'drizzle-orm/sqlite-core';
2
+ import { organization } from './auth/index.js';
3
+ import { servers } from './servers.js';
4
+
5
+ export const configSnapshots = sqliteTable(
6
+ 'config_snapshots',
7
+ {
8
+ id: text('id').primaryKey(),
9
+ tenantId: text('tenant_id')
10
+ .notNull()
11
+ .references(() => organization.id, { onDelete: 'cascade' }),
12
+ serverId: text('server_id')
13
+ .notNull()
14
+ .references(() => servers.id, { onDelete: 'cascade' }),
15
+ configJson: text('config_json').notNull(),
16
+ configHash: text('config_hash').notNull(),
17
+ fetchedAt: integer('fetched_at').notNull(),
18
+ },
19
+ (t) => [uniqueIndex('idx_config_snapshots_server').on(t.serverId)],
20
+ );
@@ -0,0 +1,26 @@
1
+ import { sqliteTable, text, integer, index } from 'drizzle-orm/sqlite-core';
2
+ import { organization } from './auth/index.js';
3
+ import { servers } from './servers.js';
4
+
5
+ export const connectionEvents = sqliteTable(
6
+ 'connection_events',
7
+ {
8
+ id: integer('id').primaryKey({ autoIncrement: true }),
9
+ tenantId: text('tenant_id')
10
+ .notNull()
11
+ .references(() => organization.id, { onDelete: 'cascade' }),
12
+ serverId: text('server_id')
13
+ .notNull()
14
+ .references(() => servers.id, { onDelete: 'cascade' }),
15
+ eventType: text('event_type').notNull(),
16
+ hostName: text('host_name'),
17
+ hostUrl: text('host_url'),
18
+ durationMs: integer('duration_ms'),
19
+ reason: text('reason'),
20
+ occurredAt: integer('occurred_at').notNull(),
21
+ },
22
+ (t) => [
23
+ index('idx_conn_events_tenant').on(t.tenantId),
24
+ index('idx_conn_events_server').on(t.serverId),
25
+ ],
26
+ );
@@ -0,0 +1,23 @@
1
+ import { sqliteTable, text, integer, index } from 'drizzle-orm/sqlite-core';
2
+ import { organization } from './auth/index.js';
3
+ import { servers } from './servers.js';
4
+
5
+ export const credentialHealthSnapshots = sqliteTable(
6
+ 'credential_health_snapshots',
7
+ {
8
+ id: integer('id').primaryKey({ autoIncrement: true }),
9
+ tenantId: text('tenant_id')
10
+ .notNull()
11
+ .references(() => organization.id, { onDelete: 'cascade' }),
12
+ serverId: text('server_id')
13
+ .notNull()
14
+ .references(() => servers.id, { onDelete: 'cascade' }),
15
+ snapshotJson: text('snapshot_json').notNull(),
16
+ capturedAt: integer('captured_at').notNull(),
17
+ createdAt: integer('created_at').notNull(),
18
+ },
19
+ (t) => [
20
+ index('idx_cred_health_server_time').on(t.serverId, t.capturedAt),
21
+ index('idx_cred_health_tenant').on(t.tenantId),
22
+ ],
23
+ );
@@ -0,0 +1,14 @@
1
+ import { sqliteTable, text, integer } from 'drizzle-orm/sqlite-core';
2
+ import { organization } from './auth/index.js';
3
+
4
+ export const deviceIdentities = sqliteTable('device_identities', {
5
+ id: text('id').primaryKey(),
6
+ tenantId: text('tenant_id')
7
+ .notNull()
8
+ .references(() => organization.id, { onDelete: 'cascade' })
9
+ .unique(),
10
+ deviceId: text('device_id').notNull(),
11
+ publicKeyPem: text('public_key_pem').notNull(),
12
+ privateKeyPem: text('private_key_pem').notNull(),
13
+ createdAt: integer('created_at').notNull(),
14
+ });
@@ -0,0 +1,20 @@
1
+ import { sqliteTable, text, integer, index } from 'drizzle-orm/sqlite-core';
2
+ import { organization, user } from './auth/index.js';
3
+
4
+ export const files = sqliteTable(
5
+ 'files',
6
+ {
7
+ id: text('id').primaryKey(),
8
+ tenantId: text('tenant_id')
9
+ .notNull()
10
+ .references(() => organization.id, { onDelete: 'cascade' }),
11
+ uploadedBy: text('uploaded_by').references(() => user.id, { onDelete: 'set null' }),
12
+ b2FileKey: text('b2_file_key').notNull(),
13
+ fileName: text('file_name').notNull(),
14
+ contentType: text('content_type').notNull(),
15
+ sizeBytes: integer('size_bytes').notNull(),
16
+ category: text('category').notNull().default('general'),
17
+ createdAt: integer('created_at').notNull(),
18
+ },
19
+ (t) => [index('idx_files_tenant').on(t.tenantId)],
20
+ );
@@ -0,0 +1,12 @@
1
+ import { sqliteTable, text, integer } from 'drizzle-orm/sqlite-core';
2
+
3
+ export const flows = sqliteTable('flows', {
4
+ id: text('id').primaryKey(),
5
+ name: text('name').notNull(),
6
+ nodes: text('nodes').notNull().default('[]'), // JSON string of FlowNode[]
7
+ edges: text('edges').notNull().default('[]'), // JSON string of FlowEdge[]
8
+ userId: text('user_id'), // owner — null for pre-migration rows (treated as shared)
9
+ tenantId: text('tenant_id'), // tenant scope — null for pre-migration rows
10
+ createdAt: integer('created_at').notNull(),
11
+ updatedAt: integer('updated_at').notNull(),
12
+ });
@@ -0,0 +1,27 @@
1
+ import { sqliteTable, text, integer, real, index } from 'drizzle-orm/sqlite-core';
2
+ import { organization } from './auth/index.js';
3
+ import { servers } from './servers.js';
4
+
5
+ export const gatewayHeartbeats = sqliteTable(
6
+ 'gateway_heartbeats',
7
+ {
8
+ id: integer('id').primaryKey({ autoIncrement: true }),
9
+ tenantId: text('tenant_id')
10
+ .notNull()
11
+ .references(() => organization.id, { onDelete: 'cascade' }),
12
+ serverId: text('server_id')
13
+ .notNull()
14
+ .references(() => servers.id, { onDelete: 'cascade' }),
15
+ uptimeMs: integer('uptime_ms').notNull(),
16
+ activeSessions: integer('active_sessions').notNull(),
17
+ activeAgents: integer('active_agents').notNull(),
18
+ memoryRssMb: real('memory_rss_mb'),
19
+ credentialSummaryJson: text('credential_summary_json'),
20
+ channelStatusJson: text('channel_status_json'),
21
+ capturedAt: integer('captured_at').notNull(),
22
+ },
23
+ (t) => [
24
+ index('idx_gw_heartbeats_server_time').on(t.serverId, t.capturedAt),
25
+ index('idx_gw_heartbeats_tenant').on(t.tenantId),
26
+ ],
27
+ );