insforge 1.2.10 → 1.4.8

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 (506) hide show
  1. package/.claude-plugin/marketplace.json +20 -20
  2. package/.dockerignore +60 -60
  3. package/.env.example +83 -77
  4. package/.github/ISSUE_TEMPLATE/bug_report.yml +36 -36
  5. package/.github/ISSUE_TEMPLATE/config.yml +11 -11
  6. package/.github/ISSUE_TEMPLATE/feature_request.yml +26 -26
  7. package/.github/PULL_REQUEST_TEMPLATE.md +7 -7
  8. package/.github/copilot-instructions.md +146 -146
  9. package/.github/workflows/build-image.yml +65 -65
  10. package/.github/workflows/ci-premerge-check.yml +23 -23
  11. package/.github/workflows/e2e.yml +63 -63
  12. package/.github/workflows/lint-and-format.yml +32 -32
  13. package/.prettierignore +64 -64
  14. package/CHANGELOG.md +46 -44
  15. package/CLAUDE_PLUGIN.md +104 -104
  16. package/CODE_OF_CONDUCT.md +128 -128
  17. package/CONTRIBUTING.md +125 -125
  18. package/Dockerfile +30 -30
  19. package/GITHUB_OAUTH_SETUP.md +49 -49
  20. package/GOOGLE_OAUTH_SETUP.md +148 -148
  21. package/LICENSE +201 -201
  22. package/README.md +182 -182
  23. package/assets/Dark.svg +23 -23
  24. package/auth/package.json +30 -28
  25. package/auth/src/lib/broadcastService.ts +4 -4
  26. package/auth/src/lib/insforge.ts +8 -0
  27. package/auth/src/main.tsx +2 -4
  28. package/auth/src/pages/SignInPage.tsx +5 -2
  29. package/auth/src/pages/SignUpPage.tsx +5 -2
  30. package/auth/src/pages/VerifyEmailPage.tsx +18 -0
  31. package/auth/tsconfig.json +33 -32
  32. package/auth/tsconfig.node.json +11 -11
  33. package/backend/package.json +82 -75
  34. package/backend/src/api/middlewares/rate-limiters.ts +127 -127
  35. package/backend/src/api/routes/ai/index.routes.ts +475 -468
  36. package/backend/src/api/routes/auth/index.routes.ts +720 -570
  37. package/backend/src/api/routes/auth/oauth.routes.ts +478 -448
  38. package/backend/src/api/routes/database/advance.routes.ts +37 -16
  39. package/backend/src/api/routes/database/index.routes.ts +80 -1
  40. package/backend/src/api/routes/database/records.routes.ts +48 -184
  41. package/backend/src/api/routes/database/rpc.routes.ts +69 -0
  42. package/backend/src/api/routes/database/tables.routes.ts +0 -14
  43. package/backend/src/api/routes/deployments/index.routes.ts +192 -0
  44. package/backend/src/api/routes/docs/index.routes.ts +76 -76
  45. package/backend/src/api/routes/email/index.routes.ts +35 -0
  46. package/backend/src/api/routes/functions/index.routes.ts +21 -15
  47. package/backend/src/api/routes/metadata/index.routes.ts +38 -0
  48. package/backend/src/api/routes/realtime/channels.routes.ts +81 -0
  49. package/backend/src/api/routes/realtime/index.routes.ts +12 -0
  50. package/backend/src/api/routes/realtime/messages.routes.ts +48 -0
  51. package/backend/src/api/routes/realtime/permissions.routes.ts +19 -0
  52. package/backend/src/api/routes/storage/index.routes.ts +18 -12
  53. package/backend/src/api/routes/usage/index.routes.ts +6 -4
  54. package/backend/src/api/routes/webhooks/index.routes.ts +109 -0
  55. package/backend/src/infra/database/database.manager.ts +14 -11
  56. package/backend/src/infra/database/migrations/000_create-base-tables.sql +141 -141
  57. package/backend/src/infra/database/migrations/001_create-helper-functions.sql +40 -40
  58. package/backend/src/infra/database/migrations/002_rename-auth-tables.sql +29 -29
  59. package/backend/src/infra/database/migrations/003_create-users-table.sql +55 -55
  60. package/backend/src/infra/database/migrations/004_add-reload-postgrest-func.sql +23 -23
  61. package/backend/src/infra/database/migrations/005_enable-project-admin-modify-users.sql +29 -29
  62. package/backend/src/infra/database/migrations/006_modify-ai-usage-table.sql +24 -24
  63. package/backend/src/infra/database/migrations/007_drop-metadata-table.sql +1 -1
  64. package/backend/src/infra/database/migrations/008_add-system-tables.sql +76 -76
  65. package/backend/src/infra/database/migrations/009_add-function-secrets.sql +23 -23
  66. package/backend/src/infra/database/migrations/010_modify-ai-config-modalities.sql +93 -93
  67. package/backend/src/infra/database/migrations/011_refactor-secrets-table.sql +15 -15
  68. package/backend/src/infra/database/migrations/012_add-storage-uploaded-by.sql +7 -7
  69. package/backend/src/infra/database/migrations/013_create-auth-schema-functions.sql +44 -44
  70. package/backend/src/infra/database/migrations/014_add-updated-at-trigger-user-table.sql +7 -7
  71. package/backend/src/infra/database/migrations/015_create-auth-config-and-email-otp-tables.sql +59 -59
  72. package/backend/src/infra/database/migrations/016_update-auth-config-and-email-otp.sql +24 -24
  73. package/backend/src/infra/database/migrations/017_create-realtime-schema.sql +233 -0
  74. package/backend/src/infra/database/migrations/018_schema-rework.sql +441 -0
  75. package/backend/src/infra/database/migrations/019_create-deployments-table.sql +36 -0
  76. package/backend/src/infra/database/migrations/020_add-audio-modality.sql +11 -0
  77. package/backend/src/infra/database/migrations/bootstrap/bootstrap-migrations.js +103 -0
  78. package/backend/src/infra/realtime/realtime.manager.ts +246 -0
  79. package/backend/src/infra/realtime/webhook-sender.ts +82 -0
  80. package/backend/src/infra/security/token.manager.ts +216 -125
  81. package/backend/src/infra/socket/socket.manager.ts +198 -64
  82. package/backend/src/providers/ai/openrouter.provider.ts +24 -12
  83. package/backend/src/providers/database/base.provider.ts +39 -0
  84. package/backend/src/providers/database/cloud.provider.ts +159 -0
  85. package/backend/src/providers/deployments/vercel.provider.ts +516 -0
  86. package/backend/src/providers/email/base.provider.ts +4 -7
  87. package/backend/src/providers/email/cloud.provider.ts +84 -0
  88. package/backend/src/providers/oauth/apple.provider.ts +266 -0
  89. package/backend/src/providers/oauth/index.ts +1 -0
  90. package/backend/src/server.ts +329 -284
  91. package/backend/src/services/ai/ai-config.service.ts +6 -6
  92. package/backend/src/services/ai/ai-model.service.ts +60 -60
  93. package/backend/src/services/ai/ai-usage.service.ts +7 -7
  94. package/backend/src/services/ai/chat-completion.service.ts +415 -220
  95. package/backend/src/services/ai/helpers.ts +64 -64
  96. package/backend/src/services/ai/image-generation.service.ts +3 -3
  97. package/backend/src/services/ai/index.ts +13 -13
  98. package/backend/src/services/auth/auth-config.service.ts +4 -4
  99. package/backend/src/services/auth/auth-otp.service.ts +6 -6
  100. package/backend/src/services/auth/auth.service.ts +148 -74
  101. package/backend/src/services/auth/index.ts +4 -4
  102. package/backend/src/services/auth/oauth-config.service.ts +12 -12
  103. package/backend/src/services/database/database-advance.service.ts +19 -55
  104. package/backend/src/services/database/database-table.service.ts +38 -94
  105. package/backend/src/services/database/database.service.ts +127 -0
  106. package/backend/src/services/database/postgrest-proxy.service.ts +165 -0
  107. package/backend/src/services/deployments/deployment.service.ts +693 -0
  108. package/backend/src/services/email/email.service.ts +5 -7
  109. package/backend/src/services/functions/function.service.ts +61 -41
  110. package/backend/src/services/logs/audit.service.ts +10 -10
  111. package/backend/src/services/realtime/index.ts +3 -0
  112. package/backend/src/services/realtime/realtime-auth.service.ts +104 -0
  113. package/backend/src/services/realtime/realtime-channel.service.ts +237 -0
  114. package/backend/src/services/realtime/realtime-message.service.ts +260 -0
  115. package/backend/src/services/secrets/secret.service.ts +101 -27
  116. package/backend/src/services/storage/storage.service.ts +30 -30
  117. package/backend/src/services/usage/usage.service.ts +6 -6
  118. package/backend/src/types/ai.ts +8 -0
  119. package/backend/src/types/auth.ts +16 -1
  120. package/backend/src/types/database.ts +2 -0
  121. package/backend/src/types/deployments.ts +33 -0
  122. package/backend/src/types/realtime.ts +18 -0
  123. package/backend/src/types/socket.ts +7 -31
  124. package/backend/src/types/storage.ts +1 -1
  125. package/backend/src/types/webhooks.ts +45 -0
  126. package/backend/src/utils/cookies.ts +34 -0
  127. package/backend/src/utils/environment.ts +0 -14
  128. package/backend/src/utils/s3-config-loader.ts +64 -0
  129. package/backend/src/utils/seed.ts +79 -43
  130. package/backend/src/utils/sql-parser.ts +216 -0
  131. package/backend/src/utils/utils.ts +114 -114
  132. package/backend/src/utils/validations.ts +10 -10
  133. package/backend/tests/README.md +133 -133
  134. package/backend/tests/cleanup-all-test-data.sh +230 -230
  135. package/backend/tests/cloud/test-s3-multitenant.sh +131 -131
  136. package/backend/tests/local/comprehensive-curl-tests.sh +155 -155
  137. package/backend/tests/local/test-ai-config.sh +129 -129
  138. package/backend/tests/local/test-ai-usage.sh +80 -80
  139. package/backend/tests/local/test-auth-router.sh +143 -143
  140. package/backend/tests/local/test-database-router.sh +222 -222
  141. package/backend/tests/local/test-e2e.sh +240 -240
  142. package/backend/tests/local/test-fk-errors.sh +96 -96
  143. package/backend/tests/local/test-functions.sh +123 -123
  144. package/backend/tests/local/test-id-field.sh +200 -200
  145. package/backend/tests/local/test-logs.sh +132 -132
  146. package/backend/tests/local/test-public-bucket.sh +264 -264
  147. package/backend/tests/local/test-rpc.sh +141 -0
  148. package/backend/tests/local/test-secrets.sh +249 -249
  149. package/backend/tests/local/test-serverless-functions.sh.disabled +325 -325
  150. package/backend/tests/local/test-traditional-rest.sh +208 -208
  151. package/backend/tests/manual/README.md +50 -50
  152. package/backend/tests/manual/create-large-table-simple.sql +10 -10
  153. package/backend/tests/manual/seed-large-table.sql +100 -100
  154. package/backend/tests/manual/setup-large-table-extras.sql +33 -33
  155. package/backend/tests/manual/test-ai-model-plugins.sh +258 -0
  156. package/backend/tests/manual/test-bulk-upsert.sh +409 -409
  157. package/backend/tests/manual/test-database-advance.sh +296 -296
  158. package/backend/tests/manual/test-postgrest-stability.sh +191 -191
  159. package/backend/tests/manual/test-rawsql-export-import.sh +411 -411
  160. package/backend/tests/manual/test-rawsql-modes.sh +244 -244
  161. package/backend/tests/manual/test-universal-storage.sh +263 -263
  162. package/backend/tests/manual/test-users.sql +17 -17
  163. package/backend/tests/run-all-tests.sh +139 -139
  164. package/backend/tests/setup.ts +0 -0
  165. package/backend/tests/test-config.sh +338 -338
  166. package/backend/tests/unit/analyze-query.test.ts +697 -0
  167. package/backend/tests/unit/database-advance.test.ts +326 -0
  168. package/backend/tests/unit/helpers.test.ts +2 -2
  169. package/backend/tsconfig.json +22 -22
  170. package/claude-plugin/.claude-plugin/plugin.json +24 -24
  171. package/claude-plugin/README.md +133 -133
  172. package/claude-plugin/skills/insforge-schema-patterns/SKILL.md +273 -270
  173. package/docker-compose.prod.yml +204 -200
  174. package/docker-compose.yml +232 -228
  175. package/docker-init/db/db-init.sql +97 -97
  176. package/docker-init/db/jwt.sql +5 -5
  177. package/docker-init/db/postgresql.conf +16 -16
  178. package/docker-init/logs/vector.yml +236 -236
  179. package/docs/README.md +44 -44
  180. package/docs/agent-docs/deployment.md +79 -0
  181. package/docs/agent-docs/real-time.md +269 -0
  182. package/docs/changelog.mdx +212 -67
  183. package/docs/core-concepts/ai/architecture.mdx +350 -372
  184. package/docs/core-concepts/ai/sdk.mdx +238 -213
  185. package/docs/core-concepts/authentication/architecture.mdx +276 -278
  186. package/docs/core-concepts/authentication/sdk.mdx +710 -414
  187. package/docs/core-concepts/authentication/ui-components/customization.mdx +733 -529
  188. package/docs/core-concepts/authentication/ui-components/nextjs.mdx +247 -221
  189. package/docs/core-concepts/authentication/ui-components/react-router.mdx +183 -184
  190. package/docs/core-concepts/authentication/ui-components/react.mdx +136 -129
  191. package/docs/core-concepts/database/architecture.mdx +292 -255
  192. package/docs/core-concepts/database/pgvector.mdx +138 -0
  193. package/docs/core-concepts/database/sdk.mdx +382 -382
  194. package/docs/core-concepts/deployments/architecture.mdx +152 -0
  195. package/docs/core-concepts/email/architecture.mdx +103 -0
  196. package/docs/core-concepts/email/sdk.mdx +53 -0
  197. package/docs/core-concepts/functions/architecture.mdx +105 -105
  198. package/docs/core-concepts/functions/sdk.mdx +183 -184
  199. package/docs/core-concepts/realtime/architecture.mdx +446 -0
  200. package/docs/core-concepts/realtime/sdk.mdx +409 -0
  201. package/docs/core-concepts/storage/architecture.mdx +243 -243
  202. package/docs/core-concepts/storage/sdk.mdx +253 -253
  203. package/docs/deployment/README.md +94 -94
  204. package/docs/deployment/deploy-to-aws-ec2.md +564 -564
  205. package/docs/deployment/deploy-to-azure-virtual-machines.md +312 -312
  206. package/docs/deployment/deploy-to-google-cloud-compute-engine.md +613 -613
  207. package/docs/deployment/deploy-to-render.md +441 -441
  208. package/docs/deprecated/insforge-auth-api.md +214 -214
  209. package/docs/deprecated/insforge-auth-sdk.md +99 -99
  210. package/docs/deprecated/insforge-db-api.md +358 -358
  211. package/docs/deprecated/insforge-db-sdk.md +139 -139
  212. package/docs/deprecated/insforge-debug-sdk.md +156 -156
  213. package/docs/deprecated/insforge-debug.md +64 -64
  214. package/docs/deprecated/insforge-instructions.md +123 -123
  215. package/docs/deprecated/insforge-project.md +117 -117
  216. package/docs/deprecated/insforge-storage-api.md +278 -278
  217. package/docs/deprecated/insforge-storage-sdk.md +158 -158
  218. package/docs/docs.json +240 -210
  219. package/docs/examples/framework-guides/nextjs.mdx +131 -131
  220. package/docs/examples/framework-guides/nuxt.mdx +165 -165
  221. package/docs/examples/framework-guides/react.mdx +165 -165
  222. package/docs/examples/framework-guides/svelte.mdx +153 -153
  223. package/docs/examples/framework-guides/vue.mdx +159 -159
  224. package/docs/examples/overview.mdx +67 -67
  225. package/docs/favicon.png +0 -0
  226. package/docs/favicon.svg +4 -19
  227. package/docs/images/changelog/dec-2025/ai-integration.png +0 -0
  228. package/docs/images/changelog/dec-2025/ai-models.webp +0 -0
  229. package/docs/images/changelog/dec-2025/alipay-payment.webp +0 -0
  230. package/docs/images/changelog/dec-2025/apple-login.jpg +0 -0
  231. package/docs/images/changelog/dec-2025/apple-oauth.mp4 +0 -0
  232. package/docs/images/changelog/dec-2025/mcp-installer.png +0 -0
  233. package/docs/images/changelog/dec-2025/moreModels.png +0 -0
  234. package/docs/images/changelog/dec-2025/multi-region.webp +0 -0
  235. package/docs/images/changelog/dec-2025/postgres-connection.webp +0 -0
  236. package/docs/images/changelog/dec-2025/realtime-module.jpg +0 -0
  237. package/docs/images/changelog/dec-2025/realtime2.png +0 -0
  238. package/docs/images/icons/ai.svg +4 -4
  239. package/docs/images/logos/nextjs.svg +4 -4
  240. package/docs/images/logos/nuxt.svg +4 -4
  241. package/docs/images/logos/react.svg +5 -5
  242. package/docs/images/logos/svelte.svg +4 -4
  243. package/docs/images/logos/vue.svg +5 -5
  244. package/docs/images/mcp-setup/CC-MCP-1.mp4 +0 -0
  245. package/docs/images/mcp-setup/CC-MCP-2.mp4 +0 -0
  246. package/docs/images/mcp-setup/Cursor-MCP-1.mp4 +0 -0
  247. package/docs/images/mcp-setup/Cursor-MCP-2.mp4 +0 -0
  248. package/docs/images/mcp-setup/Cursor-MCP-3.mp4 +0 -0
  249. package/docs/images/mcp-setup/claude-code-connect.png +0 -0
  250. package/docs/images/mcp-setup/cline-1.png +0 -0
  251. package/docs/images/mcp-setup/cline-2.png +0 -0
  252. package/docs/images/mcp-setup/cline-3.png +0 -0
  253. package/docs/images/mcp-setup/connect-project.png +0 -0
  254. package/docs/images/mcp-setup/copilot-1.png +0 -0
  255. package/docs/images/mcp-setup/copilot-2.png +0 -0
  256. package/docs/images/mcp-setup/copilot-3.png +0 -0
  257. package/docs/images/mcp-setup/mcp-json-1.png +0 -0
  258. package/docs/images/mcp-setup/mcp-json-2.png +0 -0
  259. package/docs/images/mcp-setup/qoder-1.png +0 -0
  260. package/docs/images/mcp-setup/qoder-2.png +0 -0
  261. package/docs/images/mcp-setup/roocode-1.png +0 -0
  262. package/docs/images/mcp-setup/roocode-2.png +0 -0
  263. package/docs/images/mcp-setup/trae-1.png +0 -0
  264. package/docs/images/mcp-setup/trae-2.png +0 -0
  265. package/docs/images/mcp-setup/trae-3.png +0 -0
  266. package/docs/images/mcp-setup/trae-4.png +0 -0
  267. package/docs/images/mcp-setup/trae-5.png +0 -0
  268. package/docs/images/mcp-setup/windsurf-1.png +0 -0
  269. package/docs/images/mcp-setup/windsurf-2.png +0 -0
  270. package/docs/insforge-instructions-sdk.md +93 -88
  271. package/docs/introduction.mdx +46 -45
  272. package/docs/logo/dark.svg +22 -22
  273. package/docs/logo/light.svg +20 -20
  274. package/docs/mcp-setup.mdx +332 -0
  275. package/docs/oauth-server.mdx +563 -0
  276. package/docs/partnership.mdx +720 -646
  277. package/docs/quickstart.mdx +82 -82
  278. package/docs/showcase.mdx +52 -52
  279. package/docs/snippets/sdk-installation.mdx +21 -21
  280. package/docs/snippets/service-icons.mdx +27 -27
  281. package/docs/vscode-extension.mdx +74 -0
  282. package/eslint.config.js +1 -0
  283. package/examples/oauth/frontend-oauth-example.html +250 -250
  284. package/examples/response-examples.md +443 -443
  285. package/frontend/components.json +17 -17
  286. package/frontend/package.json +69 -69
  287. package/frontend/src/App.tsx +8 -3
  288. package/frontend/src/assets/icons/checkbox_checked.svg +6 -6
  289. package/frontend/src/assets/icons/checkbox_undetermined.svg +6 -6
  290. package/frontend/src/assets/icons/checked.svg +3 -3
  291. package/frontend/src/assets/icons/connected.svg +3 -3
  292. package/frontend/src/assets/icons/error.svg +3 -3
  293. package/frontend/src/assets/icons/loader.svg +9 -9
  294. package/frontend/src/assets/icons/pencil.svg +4 -4
  295. package/frontend/src/assets/icons/refresh.svg +4 -4
  296. package/frontend/src/assets/icons/step_active.svg +3 -3
  297. package/frontend/src/assets/icons/step_inactive.svg +11 -11
  298. package/frontend/src/assets/icons/warning.svg +3 -3
  299. package/frontend/src/assets/logos/antigravity.svg +1 -0
  300. package/frontend/src/assets/logos/apple.svg +3 -3
  301. package/frontend/src/assets/logos/claude_code.svg +3 -3
  302. package/frontend/src/assets/logos/cline.svg +6 -6
  303. package/frontend/src/assets/logos/copilot.svg +10 -0
  304. package/frontend/src/assets/logos/cursor.svg +20 -20
  305. package/frontend/src/assets/logos/deepseek.svg +139 -0
  306. package/frontend/src/assets/logos/discord.svg +8 -8
  307. package/frontend/src/assets/logos/facebook.svg +3 -3
  308. package/frontend/src/assets/logos/gemini.svg +19 -19
  309. package/frontend/src/assets/logos/github.svg +5 -5
  310. package/frontend/src/assets/logos/google.svg +13 -13
  311. package/frontend/src/assets/logos/grok.svg +10 -10
  312. package/frontend/src/assets/logos/insforge_dark.svg +15 -15
  313. package/frontend/src/assets/logos/insforge_light.svg +15 -15
  314. package/frontend/src/assets/logos/instagram.svg +1 -1
  315. package/frontend/src/assets/logos/kiro.svg +9 -0
  316. package/frontend/src/assets/logos/linkedin.svg +3 -3
  317. package/frontend/src/assets/logos/openai.svg +10 -10
  318. package/frontend/src/assets/logos/qoder.svg +4 -0
  319. package/frontend/src/assets/logos/qwen.svg +15 -0
  320. package/frontend/src/assets/logos/roo_code.svg +9 -9
  321. package/frontend/src/assets/logos/spotify.svg +16 -16
  322. package/frontend/src/assets/logos/tiktok.svg +5 -5
  323. package/frontend/src/assets/logos/trae.svg +3 -3
  324. package/frontend/src/assets/logos/windsurf.svg +10 -10
  325. package/frontend/src/assets/logos/x.svg +3 -3
  326. package/frontend/src/components/CodeBlock.tsx +2 -2
  327. package/frontend/src/components/ConnectCTA.tsx +3 -2
  328. package/frontend/src/components/datagrid/DataGrid.tsx +90 -62
  329. package/frontend/src/components/datagrid/datagridTypes.tsx +2 -1
  330. package/frontend/src/components/datagrid/index.ts +1 -1
  331. package/frontend/src/components/index.ts +0 -1
  332. package/frontend/src/components/layout/AppHeader.tsx +13 -37
  333. package/frontend/src/components/layout/AppSidebar.tsx +85 -100
  334. package/frontend/src/components/layout/Layout.tsx +34 -32
  335. package/frontend/src/components/layout/PrimaryMenu.tsx +12 -4
  336. package/frontend/src/components/radix/Select.tsx +151 -151
  337. package/frontend/src/features/ai/components/AIConfigCard.tsx +200 -200
  338. package/frontend/src/features/ai/components/AIEmptyState.tsx +23 -23
  339. package/frontend/src/features/ai/components/ModalityFilterSidebar.tsx +102 -101
  340. package/frontend/src/features/ai/components/ModelSelectionDialog.tsx +135 -135
  341. package/frontend/src/features/ai/components/ModelSelectionGrid.tsx +51 -51
  342. package/frontend/src/features/ai/components/SystemPromptDialog.tsx +118 -118
  343. package/frontend/src/features/ai/components/index.ts +6 -6
  344. package/frontend/src/features/ai/helpers.ts +147 -141
  345. package/frontend/src/features/ai/{page → pages}/AIPage.tsx +166 -166
  346. package/frontend/src/features/auth/components/AuthPreview.tsx +96 -96
  347. package/frontend/src/features/auth/components/OAuthConfigDialog.tsx +1 -0
  348. package/frontend/src/features/auth/components/UsersDataGrid.tsx +61 -31
  349. package/frontend/src/features/auth/components/index.ts +5 -5
  350. package/frontend/src/features/auth/helpers.tsx +8 -0
  351. package/frontend/src/features/auth/{page → pages}/AuthMethodsPage.tsx +275 -275
  352. package/frontend/src/features/auth/{page → pages}/UsersPage.tsx +0 -28
  353. package/frontend/src/features/dashboard/{page → pages}/DashboardPage.tsx +1 -1
  354. package/frontend/src/features/database/components/DatabaseDataGrid.tsx +0 -2
  355. package/frontend/src/features/database/components/ForeignKeyCell.tsx +38 -11
  356. package/frontend/src/features/database/components/ForeignKeyPopover.tsx +18 -8
  357. package/frontend/src/features/database/components/LinkRecordModal.tsx +61 -13
  358. package/frontend/src/features/database/components/RecordFormField.tsx +1 -1
  359. package/frontend/src/features/database/components/SQLModal.tsx +75 -0
  360. package/frontend/src/features/database/components/TableForm.tsx +0 -4
  361. package/frontend/src/features/database/components/TableSidebar.tsx +0 -3
  362. package/frontend/src/features/database/components/TablesEmptyState.tsx +1 -1
  363. package/frontend/src/features/database/components/TemplatePreview.tsx +1 -2
  364. package/frontend/src/features/database/constants.ts +16 -28
  365. package/frontend/src/features/database/hooks/useCSVImport.ts +3 -2
  366. package/frontend/src/features/database/hooks/useDatabase.ts +66 -0
  367. package/frontend/src/features/database/hooks/useRawSQL.ts +3 -2
  368. package/frontend/src/features/database/hooks/useTables.ts +30 -28
  369. package/frontend/src/features/database/index.ts +1 -0
  370. package/frontend/src/features/database/{page → pages}/FunctionsPage.tsx +29 -42
  371. package/frontend/src/features/database/{page → pages}/IndexesPage.tsx +34 -51
  372. package/frontend/src/features/database/{page → pages}/PoliciesPage.tsx +42 -58
  373. package/frontend/src/features/database/{page → pages}/SQLEditorPage.tsx +2 -2
  374. package/frontend/src/features/database/{page → pages}/TablesPage.tsx +0 -42
  375. package/frontend/src/features/database/{page → pages}/TriggersPage.tsx +34 -51
  376. package/frontend/src/features/database/services/advance.service.ts +1 -41
  377. package/frontend/src/features/database/services/database.service.ts +55 -0
  378. package/frontend/src/features/database/services/record.service.ts +4 -20
  379. package/frontend/src/features/database/services/table.service.ts +1 -10
  380. package/frontend/src/features/database/templates/ai-chatbot.ts +6 -6
  381. package/frontend/src/features/database/templates/ecommerce-platform.ts +2 -2
  382. package/frontend/src/features/database/templates/instagram-clone.ts +10 -10
  383. package/frontend/src/features/database/templates/notion-clone.ts +8 -8
  384. package/frontend/src/features/database/templates/reddit-clone.ts +10 -10
  385. package/frontend/src/features/deployments/components/DeploymentRow.tsx +93 -0
  386. package/frontend/src/features/deployments/components/DeploymentsEmptyState.tsx +15 -0
  387. package/frontend/src/features/deployments/hooks/useDeployments.ts +157 -0
  388. package/frontend/src/features/deployments/pages/DeploymentsPage.tsx +318 -0
  389. package/frontend/src/features/deployments/services/deployments.service.ts +63 -0
  390. package/frontend/src/features/functions/components/FunctionRow.tsx +72 -72
  391. package/frontend/src/features/functions/components/FunctionsSidebar.tsx +56 -56
  392. package/frontend/src/features/functions/components/SecretRow.tsx +3 -3
  393. package/frontend/src/features/functions/components/index.ts +5 -5
  394. package/frontend/src/features/functions/hooks/useFunctions.ts +5 -4
  395. package/frontend/src/features/functions/hooks/useSecrets.ts +6 -9
  396. package/frontend/src/features/functions/{page → pages}/FunctionsPage.tsx +21 -44
  397. package/frontend/src/features/functions/{page → pages}/SecretsPage.tsx +118 -116
  398. package/frontend/src/features/functions/services/function.service.ts +8 -25
  399. package/frontend/src/features/functions/services/secret.service.ts +23 -41
  400. package/frontend/src/features/login/{page → pages}/CloudLoginPage.tsx +125 -118
  401. package/frontend/src/features/logs/components/LogDetailPanel.tsx +41 -0
  402. package/frontend/src/features/logs/components/LogsDataGrid.tsx +32 -1
  403. package/frontend/src/features/logs/components/index.ts +1 -0
  404. package/frontend/src/features/logs/hooks/useMcpUsage.ts +13 -66
  405. package/frontend/src/features/logs/{page → pages}/LogsPage.tsx +36 -6
  406. package/frontend/src/features/onboard/components/ApiCredentialsSection.tsx +59 -0
  407. package/frontend/src/features/onboard/components/ConnectionStringSection.tsx +180 -0
  408. package/frontend/src/features/onboard/components/McpConnectionSection.tsx +159 -0
  409. package/frontend/src/features/onboard/components/OnboardingController.tsx +68 -0
  410. package/frontend/src/features/onboard/components/OnboardingModal.tsx +121 -267
  411. package/frontend/src/features/onboard/components/ShowPasswordButton.tsx +21 -0
  412. package/frontend/src/features/onboard/components/index.ts +9 -4
  413. package/frontend/src/features/onboard/components/mcp/CursorDeeplinkGenerator.tsx +1 -1
  414. package/frontend/src/features/onboard/components/mcp/QoderDeeplinkGenerator.tsx +36 -0
  415. package/frontend/src/features/onboard/components/mcp/helpers.tsx +123 -98
  416. package/frontend/src/features/onboard/components/mcp/index.ts +4 -3
  417. package/frontend/src/features/onboard/index.ts +17 -13
  418. package/frontend/src/features/realtime/components/ChannelRow.tsx +83 -0
  419. package/frontend/src/features/realtime/components/EditChannelModal.tsx +246 -0
  420. package/frontend/src/features/realtime/components/MessageRow.tsx +85 -0
  421. package/frontend/src/features/realtime/components/RealtimeEmptyState.tsx +30 -0
  422. package/frontend/src/features/realtime/hooks/useRealtime.ts +218 -0
  423. package/frontend/src/features/realtime/index.ts +11 -0
  424. package/frontend/src/features/realtime/pages/RealtimeChannelsPage.tsx +172 -0
  425. package/frontend/src/features/realtime/pages/RealtimeMessagesPage.tsx +211 -0
  426. package/frontend/src/features/realtime/pages/RealtimePermissionsPage.tsx +191 -0
  427. package/frontend/src/features/realtime/services/realtime.service.ts +107 -0
  428. package/frontend/src/features/settings/pages/SettingsPage.tsx +349 -0
  429. package/frontend/src/features/storage/{page → pages}/StoragePage.tsx +1 -29
  430. package/frontend/src/features/visualizer/components/AuthNode.tsx +4 -4
  431. package/frontend/src/features/visualizer/components/SchemaVisualizer.tsx +24 -11
  432. package/frontend/src/features/visualizer/{page → pages}/VisualizerPage.tsx +11 -36
  433. package/frontend/src/index.css +249 -249
  434. package/frontend/src/lib/contexts/ModalContext.tsx +35 -0
  435. package/frontend/src/lib/contexts/SocketContext.tsx +119 -75
  436. package/frontend/src/lib/hooks/useMetadata.ts +45 -1
  437. package/frontend/src/lib/hooks/useModal.tsx +2 -0
  438. package/frontend/src/lib/routing/AppRoutes.tsx +103 -84
  439. package/frontend/src/lib/services/metadata.service.ts +20 -3
  440. package/frontend/src/lib/utils/cloudMessaging.ts +1 -1
  441. package/frontend/src/lib/utils/menuItems.ts +223 -183
  442. package/frontend/src/lib/utils/utils.ts +196 -183
  443. package/frontend/tsconfig.json +25 -25
  444. package/frontend/tsconfig.node.json +9 -9
  445. package/functions/deno.json +24 -24
  446. package/functions/server.ts +6 -6
  447. package/functions/worker-template.js +1 -1
  448. package/i18n/README.ar.md +130 -130
  449. package/i18n/README.de.md +130 -130
  450. package/i18n/README.es.md +154 -154
  451. package/i18n/README.fr.md +134 -134
  452. package/i18n/README.hi.md +129 -129
  453. package/i18n/README.ja.md +174 -174
  454. package/i18n/README.ko.md +136 -136
  455. package/i18n/README.pt-BR.md +131 -131
  456. package/i18n/README.ru.md +129 -129
  457. package/i18n/README.zh-CN.md +133 -133
  458. package/openapi/ai.yaml +825 -715
  459. package/openapi/auth.yaml +1324 -1244
  460. package/openapi/email.yaml +158 -0
  461. package/openapi/functions.yaml +475 -475
  462. package/openapi/health.yaml +29 -29
  463. package/openapi/logs.yaml +221 -223
  464. package/openapi/metadata.yaml +175 -177
  465. package/openapi/realtime.yaml +699 -0
  466. package/openapi/records.yaml +381 -381
  467. package/openapi/secrets.yaml +370 -370
  468. package/openapi/storage.yaml +875 -875
  469. package/openapi/tables.yaml +462 -463
  470. package/package.json +97 -97
  471. package/shared-schemas/package.json +31 -31
  472. package/shared-schemas/src/ai-api.schema.ts +251 -143
  473. package/shared-schemas/src/ai.schema.ts +8 -4
  474. package/shared-schemas/src/auth-api.schema.ts +380 -339
  475. package/shared-schemas/src/auth.schema.ts +18 -11
  476. package/shared-schemas/src/cloud-events.schema.ts +26 -0
  477. package/shared-schemas/src/database-api.schema.ts +32 -1
  478. package/shared-schemas/src/database.schema.ts +39 -0
  479. package/shared-schemas/src/deployments-api.schema.ts +55 -0
  480. package/shared-schemas/src/deployments.schema.ts +30 -0
  481. package/shared-schemas/src/docs.schema.ts +32 -0
  482. package/shared-schemas/src/email-api.schema.ts +30 -0
  483. package/shared-schemas/src/functions-api.schema.ts +13 -4
  484. package/shared-schemas/src/functions.schema.ts +1 -1
  485. package/shared-schemas/src/index.ts +22 -14
  486. package/shared-schemas/src/metadata.schema.ts +39 -4
  487. package/shared-schemas/src/realtime-api.schema.ts +111 -0
  488. package/shared-schemas/src/realtime.schema.ts +143 -0
  489. package/shared-schemas/src/secrets-api.schema.ts +44 -0
  490. package/shared-schemas/src/secrets.schema.ts +15 -0
  491. package/shared-schemas/tsconfig.json +21 -21
  492. package/tsconfig.json +7 -7
  493. package/zeabur/README.md +26 -13
  494. package/zeabur/template.yml +1001 -1032
  495. package/.cursor/rules/cursor-rules.mdc +0 -94
  496. package/backend/src/types/profile.ts +0 -55
  497. package/frontend/src/components/ProjectInfoModal.tsx +0 -128
  498. package/frontend/src/features/database/hooks/useFullMetadata.ts +0 -18
  499. package/test-gemini.sh +0 -35
  500. package/test-usage-admin.sh +0 -57
  501. package/test-usage.sh +0 -50
  502. /package/frontend/src/features/auth/{page → pages}/ConfigurationPage.tsx +0 -0
  503. /package/frontend/src/features/database/{page → pages}/TemplatesPage.tsx +0 -0
  504. /package/frontend/src/features/login/{page → pages}/LoginPage.tsx +0 -0
  505. /package/frontend/src/features/logs/{page → pages}/AuditsPage.tsx +0 -0
  506. /package/frontend/src/features/logs/{page → pages}/MCPLogsPage.tsx +0 -0
@@ -54,7 +54,7 @@ export class UsageService {
54
54
  async recordMCPUsage(toolName: string, success: boolean = true): Promise<{ created_at: string }> {
55
55
  try {
56
56
  const result = await this.getPool().query(
57
- `INSERT INTO _mcp_usage (tool_name, success)
57
+ `INSERT INTO system.mcp_usage (tool_name, success)
58
58
  VALUES ($1, $2)
59
59
  RETURNING created_at`,
60
60
  [toolName, success]
@@ -75,7 +75,7 @@ export class UsageService {
75
75
  try {
76
76
  const result = await this.getPool().query(
77
77
  `SELECT tool_name, success, created_at
78
- FROM _mcp_usage
78
+ FROM system.mcp_usage
79
79
  WHERE success = $1
80
80
  ORDER BY created_at DESC
81
81
  LIMIT $2`,
@@ -98,7 +98,7 @@ export class UsageService {
98
98
  // Get MCP tool usage count
99
99
  const mcpResult = await this.getPool().query(
100
100
  `SELECT COUNT(*) as count
101
- FROM _mcp_usage
101
+ FROM system.mcp_usage
102
102
  WHERE success = true
103
103
  AND created_at >= $1
104
104
  AND created_at < $2`,
@@ -112,7 +112,7 @@ export class UsageService {
112
112
 
113
113
  // Get total storage size
114
114
  const storageResult = await this.getPool().query(
115
- `SELECT COALESCE(SUM(size), 0) as total_size FROM _storage`
115
+ `SELECT COALESCE(SUM(size), 0) as total_size FROM storage.objects`
116
116
  );
117
117
 
118
118
  // Get AI usage breakdown by model (only billable metrics)
@@ -122,8 +122,8 @@ export class UsageService {
122
122
  COALESCE(SUM(u.input_tokens), 0) as total_input_tokens,
123
123
  COALESCE(SUM(u.output_tokens), 0) as total_output_tokens,
124
124
  COALESCE(SUM(u.image_count), 0) as total_images
125
- FROM _ai_usage u
126
- LEFT JOIN _ai_configs c ON u.config_id = c.id
125
+ FROM ai.usage u
126
+ LEFT JOIN ai.configs c ON u.config_id = c.id
127
127
  WHERE u.created_at >= $1 AND u.created_at < $2
128
128
  GROUP BY COALESCE(u.model_id, c.model_id)
129
129
  ORDER BY (COALESCE(SUM(u.input_tokens), 0) + COALESCE(SUM(u.output_tokens), 0)) DESC`,
@@ -11,6 +11,14 @@ export interface OpenRouterImageMessage {
11
11
  };
12
12
  }
13
13
 
14
+ export interface OpenRouterAudioMessage {
15
+ type: 'input_audio';
16
+ input_audio: {
17
+ data: string; // Base64-encoded audio data
18
+ format: string; // wav, mp3, aiff, aac, ogg, flac, m4a
19
+ };
20
+ }
21
+
14
22
  // ============= OpenRouter API Types =============
15
23
 
16
24
  export interface RawOpenRouterModel {
@@ -1,9 +1,13 @@
1
1
  // Type definitions for database user records
2
+
2
3
  export interface UserRecord {
3
4
  id: string;
4
5
  email: string;
5
- name: string;
6
+ profile: Record<string, unknown> | null;
7
+ metadata: Record<string, unknown> | null;
6
8
  email_verified: boolean;
9
+ is_project_admin: boolean;
10
+ is_anonymous: boolean;
7
11
  created_at: string;
8
12
  updated_at: string;
9
13
  password?: string;
@@ -135,6 +139,16 @@ export interface XUserInfo {
135
139
  created_at?: string;
136
140
  }
137
141
 
142
+ export interface AppleUserInfo {
143
+ sub: string;
144
+ email: string;
145
+ email_verified?: boolean;
146
+ is_private_email?: boolean;
147
+ name?: string;
148
+ given_name?: string;
149
+ family_name?: string;
150
+ }
151
+
138
152
  // Generic OAuth user data returned by provider services
139
153
  export interface OAuthUserData {
140
154
  provider: string;
@@ -150,5 +164,6 @@ export interface OAuthUserData {
150
164
  | FacebookUserInfo
151
165
  | MicrosoftUserInfo
152
166
  | XUserInfo
167
+ | AppleUserInfo
153
168
  | Record<string, unknown>;
154
169
  }
@@ -102,6 +102,7 @@ export type ForeignKeyInfo = ForeignKeySchema & {
102
102
  export interface ForeignKeyRow {
103
103
  constraint_name: string;
104
104
  from_column: string;
105
+ foreign_schema: string;
105
106
  foreign_table: string;
106
107
  foreign_column: string;
107
108
  on_delete: string;
@@ -112,6 +113,7 @@ export interface ForeignKeyRow {
112
113
  export interface ColumnInfo {
113
114
  column_name: string;
114
115
  data_type: string;
116
+ udt_name: string;
115
117
  is_nullable: string;
116
118
  column_default: string | null;
117
119
  character_maximum_length: number | null;
@@ -0,0 +1,33 @@
1
+ // Backend-only types for deployments
2
+
3
+ /**
4
+ * Deployment status constants
5
+ * WAITING -> UPLOADING -> (Vercel statuses: QUEUED/BUILDING/READY/ERROR/CANCELED)
6
+ */
7
+ export const DeploymentStatus = {
8
+ // InsForge internal statuses
9
+ WAITING: 'WAITING', // Record created, waiting for client to upload zip to S3
10
+ UPLOADING: 'UPLOADING', // Server is downloading from S3 and uploading to Vercel
11
+ // Vercel statuses (stored directly)
12
+ QUEUED: 'QUEUED',
13
+ BUILDING: 'BUILDING',
14
+ READY: 'READY',
15
+ ERROR: 'ERROR',
16
+ CANCELED: 'CANCELED',
17
+ } as const;
18
+
19
+ export type DeploymentStatusType = (typeof DeploymentStatus)[keyof typeof DeploymentStatus];
20
+
21
+ /**
22
+ * Internal deployment record with Date objects (database returns Date, not string)
23
+ */
24
+ export interface DeploymentRecord {
25
+ id: string;
26
+ providerDeploymentId: string | null; // Provider's deployment ID, null until deployment starts
27
+ provider: string;
28
+ status: DeploymentStatusType;
29
+ url: string | null;
30
+ metadata: Record<string, unknown> | null;
31
+ createdAt: Date;
32
+ updatedAt: Date;
33
+ }
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Realtime feature types - Backend-only types
3
+ *
4
+ * Shared types should be imported directly from @insforge/shared-schemas.
5
+ */
6
+
7
+ // ============================================================================
8
+ // Backend-Only Types (Internal Use)
9
+ // ============================================================================
10
+
11
+ /**
12
+ * Delivery statistics after message processing
13
+ */
14
+ export interface DeliveryResult {
15
+ wsAudienceCount: number;
16
+ whAudienceCount: number;
17
+ whDeliveredCount: number;
18
+ }
@@ -10,24 +10,18 @@ export enum ServerEvents {
10
10
  NOTIFICATION = 'notification',
11
11
  DATA_UPDATE = 'data:update',
12
12
  MCP_CONNECTED = 'mcp:connected',
13
+ // Realtime events
14
+ REALTIME_ERROR = 'realtime:error',
13
15
  }
14
16
 
15
17
  /**
16
18
  * Client-to-Server events
17
19
  */
18
20
  export enum ClientEvents {
19
- SUBSCRIBE = 'subscribe',
20
- UNSUBSCRIBE = 'unsubscribe',
21
- }
22
-
23
- /**
24
- * Generic message interface
25
- */
26
- export interface SocketMessage<T = unknown> {
27
- type: string;
28
- payload?: T;
29
- timestamp: number;
30
- id?: string;
21
+ // Realtime events
22
+ REALTIME_SUBSCRIBE = 'realtime:subscribe',
23
+ REALTIME_UNSUBSCRIBE = 'realtime:unsubscribe',
24
+ REALTIME_PUBLISH = 'realtime:publish',
31
25
  }
32
26
 
33
27
  /**
@@ -43,27 +37,9 @@ export interface NotificationPayload {
43
37
  export enum DataUpdateResourceType {
44
38
  DATABASE = 'database',
45
39
  USERS = 'users',
46
- RECORDS = 'records',
47
40
  BUCKETS = 'buckets',
48
41
  FUNCTIONS = 'functions',
49
- }
50
-
51
- export interface DataUpdatePayload {
52
- resource: DataUpdateResourceType;
53
- action: 'created' | 'updated' | 'deleted';
54
- data: unknown;
55
- }
56
-
57
- /**
58
- * Client event payloads
59
- */
60
- export interface SubscribePayload {
61
- channel: string;
62
- filters?: Record<string, unknown>;
63
- }
64
-
65
- export interface UnsubscribePayload {
66
- channel: string;
42
+ REALTIME = 'realtime',
67
43
  }
68
44
 
69
45
  /**
@@ -10,7 +10,7 @@ export interface StorageRecord {
10
10
  uploaded_at: string;
11
11
  }
12
12
 
13
- // Bucket record from _storage_buckets table
13
+ // Bucket record from storage.buckets table
14
14
  export type BucketRecord = Omit<StorageBucketSchema, 'created_at'>;
15
15
 
16
16
  // Form field types for file uploads
@@ -0,0 +1,45 @@
1
+ // Webhook types for external integrations
2
+
3
+ // ============================================================================
4
+ // Vercel Webhooks
5
+ // ============================================================================
6
+
7
+ /**
8
+ * Vercel webhook event types we handle for deployments
9
+ */
10
+ export type VercelDeploymentEventType =
11
+ | 'deployment.created'
12
+ | 'deployment.succeeded'
13
+ | 'deployment.error'
14
+ | 'deployment.canceled';
15
+
16
+ /**
17
+ * Map Vercel webhook event types to our deployment status
18
+ */
19
+ export const VERCEL_EVENT_TO_STATUS: Record<VercelDeploymentEventType, string> = {
20
+ 'deployment.created': 'BUILDING',
21
+ 'deployment.succeeded': 'READY',
22
+ 'deployment.error': 'ERROR',
23
+ 'deployment.canceled': 'CANCELED',
24
+ };
25
+
26
+ /**
27
+ * Vercel webhook payload structure for deployment events
28
+ */
29
+ export interface VercelWebhookPayload {
30
+ type: string;
31
+ id: string;
32
+ createdAt: string;
33
+ payload: {
34
+ team?: { id: string };
35
+ user?: { id: string };
36
+ deployment: {
37
+ id: string;
38
+ url: string;
39
+ name: string;
40
+ meta?: Record<string, unknown>;
41
+ };
42
+ target?: string;
43
+ project?: { id: string };
44
+ };
45
+ }
@@ -0,0 +1,34 @@
1
+ import { Request, Response } from 'express';
2
+
3
+ /**
4
+ * Cookie names
5
+ */
6
+ export const REFRESH_TOKEN_COOKIE_NAME = 'insforge_refresh_token';
7
+
8
+ /**
9
+ * Set an auth cookie on response
10
+ * @param name - Cookie name
11
+ * @param value - Cookie value
12
+ */
13
+ export function setAuthCookie(req: Request, res: Response, name: string, value: string): void {
14
+ res.cookie(name, value, {
15
+ httpOnly: true,
16
+ secure: req.secure,
17
+ sameSite: 'none',
18
+ path: '/api/auth',
19
+ maxAge: 7 * 24 * 60 * 60 * 1000, // 7 days
20
+ });
21
+ }
22
+
23
+ /**
24
+ * Clear an auth cookie on response
25
+ * IMPORTANT: Must use the same options (especially path) as when setting the cookie
26
+ */
27
+ export function clearAuthCookie(req: Request, res: Response, name: string): void {
28
+ res.clearCookie(name, {
29
+ httpOnly: true,
30
+ secure: req.secure,
31
+ sameSite: 'none',
32
+ path: '/api/auth',
33
+ });
34
+ }
@@ -18,20 +18,6 @@ export function isOAuthSharedKeysAvailable(): boolean {
18
18
  return isCloudEnvironment();
19
19
  }
20
20
 
21
- /**
22
- * Check if running in development mode
23
- */
24
- export function isDevelopment(): boolean {
25
- return process.env.NODE_ENV === 'development' || !process.env.NODE_ENV;
26
- }
27
-
28
- /**
29
- * Check if running in production mode
30
- */
31
- export function isProduction(): boolean {
32
- return process.env.NODE_ENV === 'production';
33
- }
34
-
35
21
  /**
36
22
  * Get the API base URL from environment variable or default to localhost
37
23
  * @returns The API base URL
@@ -0,0 +1,64 @@
1
+ import { S3Client, GetObjectCommand } from '@aws-sdk/client-s3';
2
+ import logger from '@/utils/logger.js';
3
+
4
+ // TODO: make these configurable in env variables in cloud backend
5
+ const CONFIG_BUCKET = process.env.AWS_CONFIG_BUCKET || 'insforge-config';
6
+ const CONFIG_REGION = process.env.AWS_CONFIG_REGION || 'us-east-2';
7
+
8
+ let s3Client: S3Client | null = null;
9
+
10
+ /**
11
+ * Get or create S3 client for config loading
12
+ */
13
+ function getS3Client(): S3Client {
14
+ if (s3Client) {
15
+ return s3Client;
16
+ }
17
+
18
+ const s3Config: {
19
+ region: string;
20
+ credentials?: { accessKeyId: string; secretAccessKey: string };
21
+ } = {
22
+ region: CONFIG_REGION,
23
+ };
24
+
25
+ // Use explicit credentials if provided, otherwise IAM role
26
+ if (process.env.AWS_ACCESS_KEY_ID && process.env.AWS_SECRET_ACCESS_KEY) {
27
+ s3Config.credentials = {
28
+ accessKeyId: process.env.AWS_ACCESS_KEY_ID,
29
+ secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY,
30
+ };
31
+ }
32
+
33
+ s3Client = new S3Client(s3Config);
34
+ return s3Client;
35
+ }
36
+
37
+ /**
38
+ * Fetches a JSON config file from the S3 config bucket
39
+ * @param key - The S3 object key (e.g., 'default-ai-models.json')
40
+ * @returns Parsed JSON content or null if fetch fails
41
+ */
42
+ export async function fetchS3Config<T>(key: string): Promise<T | null> {
43
+ try {
44
+ const command = new GetObjectCommand({
45
+ Bucket: CONFIG_BUCKET,
46
+ Key: key,
47
+ });
48
+
49
+ const response = await getS3Client().send(command);
50
+ const body = await response.Body?.transformToString();
51
+
52
+ if (!body) {
53
+ logger.warn(`Empty config file from S3: ${key}`);
54
+ return null;
55
+ }
56
+
57
+ return JSON.parse(body) as T;
58
+ } catch (error) {
59
+ logger.warn(`Failed to fetch config from S3: ${key}`, {
60
+ error: error instanceof Error ? error.message : String(error),
61
+ });
62
+ return null;
63
+ }
64
+ }
@@ -1,3 +1,4 @@
1
+ import bcrypt from 'bcryptjs';
1
2
  import { DatabaseManager } from '@/infra/database/database.manager.js';
2
3
  import { TokenManager } from '@/infra/security/token.manager.js';
3
4
  import { AIConfigService } from '@/services/ai/ai-config.service.js';
@@ -5,55 +6,96 @@ import { isCloudEnvironment } from '@/utils/environment.js';
5
6
  import logger from '@/utils/logger.js';
6
7
  import { SecretService } from '@/services/secrets/secret.service.js';
7
8
  import { OAuthConfigService } from '@/services/auth/oauth-config.service.js';
8
- import { OAuthProvidersSchema } from '@insforge/shared-schemas';
9
+ import { OAuthProvidersSchema, aiConfigurationInputSchema } from '@insforge/shared-schemas';
10
+ import { z } from 'zod';
9
11
  import { AuthConfigService } from '@/services/auth/auth-config.service.js';
12
+ import { fetchS3Config } from '@/utils/s3-config-loader.js';
13
+ import { ADMIN_ID } from '@/utils/constants.js';
10
14
 
11
15
  /**
12
- * Validates admin credentials are configured
13
- * Admin is authenticated via environment variables, not stored in DB
16
+ * Seeds the admin user if it doesn't exist in the database
17
+ * Creates an admin user with is_project_admin = true
14
18
  */
15
- function ensureFirstAdmin(adminEmail: string, adminPassword: string): void {
16
- if (adminEmail && adminPassword) {
17
- logger.info(`✅ Admin configured: ${adminEmail}`);
18
- } else {
19
+ async function seedAdminUser(adminEmail: string, adminPassword: string): Promise<void> {
20
+ if (!adminEmail || !adminPassword) {
19
21
  logger.warn('⚠️ Admin credentials not configured - check ADMIN_EMAIL and ADMIN_PASSWORD');
22
+ return;
23
+ }
24
+
25
+ const dbManager = DatabaseManager.getInstance();
26
+ const pool = dbManager.getPool();
27
+ const client = await pool.connect();
28
+
29
+ try {
30
+ // Check if admin user already exists
31
+ const existingAdmin = await client.query('SELECT id FROM auth.users WHERE id = $1', [ADMIN_ID]);
32
+
33
+ if (existingAdmin.rows.length > 0) {
34
+ logger.info(`✅ Admin configured: ${adminEmail}`);
35
+ return;
36
+ }
37
+
38
+ // Hash password and create admin user
39
+ const hashedPassword = await bcrypt.hash(adminPassword, 10);
40
+ const profile = JSON.stringify({ name: 'Administrator' });
41
+
42
+ await client.query(
43
+ `INSERT INTO auth.users (id, email, password, profile, email_verified, is_project_admin, is_anonymous, created_at, updated_at)
44
+ VALUES ($1, $2, $3, $4::jsonb, true, true, false, NOW(), NOW())
45
+ ON CONFLICT (id) DO NOTHING`,
46
+ [ADMIN_ID, adminEmail, hashedPassword, profile]
47
+ );
48
+
49
+ logger.info(`✅ Admin user seeded: ${adminEmail}`);
50
+ } catch (error) {
51
+ logger.error('Failed to seed admin user', {
52
+ error: error instanceof Error ? error.message : String(error),
53
+ });
54
+ // Don't throw - this is not critical for app startup if admin already exists
55
+ } finally {
56
+ client.release();
20
57
  }
21
58
  }
22
59
 
23
60
  /**
24
- * Seeds default AI configurations for cloud environments
61
+ * Seeds default AI configurations from S3 config
25
62
  */
26
63
  async function seedDefaultAIConfigs(): Promise<void> {
27
- // Only seed default AI configs in cloud environment
28
- if (!isCloudEnvironment()) {
64
+ const aiConfigService = AIConfigService.getInstance();
65
+
66
+ const existingConfigs = await aiConfigService.findAll();
67
+ if (existingConfigs.length) {
29
68
  return;
30
69
  }
31
70
 
32
- const aiConfigService = AIConfigService.getInstance();
71
+ const defaultModels =
72
+ await fetchS3Config<z.infer<typeof aiConfigurationInputSchema>[]>('default-ai-models.json');
33
73
 
34
- // Check if AI configs already exist
35
- const existingConfigs = await aiConfigService.findAll();
74
+ if (!defaultModels || defaultModels.length === 0) {
75
+ logger.warn('⚠️ No default AI models configured - add via dashboard or check S3 config');
76
+ return;
77
+ }
36
78
 
37
- if (existingConfigs.length) {
79
+ const parsed = aiConfigurationInputSchema.array().safeParse(defaultModels);
80
+ if (!parsed.success) {
81
+ logger.error('❌ Invalid AI models configuration from S3', {
82
+ error: parsed.error.message,
83
+ });
38
84
  return;
39
85
  }
40
86
 
41
- await aiConfigService.create(
42
- ['text', 'image'],
43
- ['text'],
44
- 'openrouter',
45
- 'openai/gpt-4o',
46
- 'You are a helpful assistant.'
47
- );
48
-
49
- await aiConfigService.create(
50
- ['text', 'image'],
51
- ['text', 'image'],
52
- 'openrouter',
53
- 'google/gemini-3-pro-image-preview'
54
- );
55
-
56
- logger.info('✅ Default AI models configured (cloud environment)');
87
+ const validatedModels = parsed.data;
88
+ for (const model of validatedModels) {
89
+ await aiConfigService.create(
90
+ model.inputModality,
91
+ model.outputModality,
92
+ model.provider,
93
+ model.modelId,
94
+ model.systemPrompt
95
+ );
96
+ }
97
+
98
+ logger.info(`✅ Default AI models configured (${validatedModels.length} models)`);
57
99
  }
58
100
 
59
101
  /**
@@ -67,7 +109,7 @@ async function seedDefaultAuthConfig(): Promise<void> {
67
109
  const client = await pool.connect();
68
110
 
69
111
  try {
70
- const result = await client.query('SELECT COUNT(*) as count FROM _auth_configs');
112
+ const result = await client.query('SELECT COUNT(*) as count FROM auth.configs');
71
113
  const hasConfig = result.rows.length > 0 && Number(result.rows[0].count) > 0;
72
114
 
73
115
  if (hasConfig) {
@@ -81,10 +123,8 @@ async function seedDefaultAuthConfig(): Promise<void> {
81
123
  }
82
124
 
83
125
  // Table is empty - this is first startup, insert default cloud configuration
84
- // Note: Migration 016 will add verify_email_method, reset_password_method, sign_in_redirect_to
85
- // so we only insert fields that exist in migration 015
86
126
  await client.query(
87
- `INSERT INTO _auth_configs (
127
+ `INSERT INTO auth.configs (
88
128
  require_email_verification,
89
129
  password_min_length,
90
130
  require_number,
@@ -222,8 +262,8 @@ export async function seedBackend(): Promise<void> {
222
262
  try {
223
263
  logger.info(`\n🚀 Insforge Backend Starting...`);
224
264
 
225
- // Validate admin credentials are configured
226
- ensureFirstAdmin(adminEmail, adminPassword);
265
+ // Seed admin user if not exists
266
+ await seedAdminUser(adminEmail, adminPassword);
227
267
 
228
268
  // Initialize API key (from env or generate)
229
269
  const apiKey = await secretService.initializeApiKey();
@@ -242,15 +282,11 @@ export async function seedBackend(): Promise<void> {
242
282
  logger.info(`✅ Found ${tables.length} user tables`);
243
283
  }
244
284
 
245
- // seed AI configs for cloud environment
246
- await seedDefaultAIConfigs();
247
-
248
- // Enable email verification in cloud environment
249
- await seedDefaultAuthConfig();
250
-
251
- // add default OAuth configs in Cloud hosting
285
+ // seed default configs for cloud environment
252
286
  if (isCloudEnvironment()) {
253
287
  await seedDefaultOAuthConfigs();
288
+ await seedDefaultAIConfigs();
289
+ await seedDefaultAuthConfig();
254
290
  } else {
255
291
  await seedLocalOAuthConfigs();
256
292
  }