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
@@ -1,4 +1,4 @@
1
- import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
1
+ import { useQuery, useQueries, useMutation, useQueryClient } from '@tanstack/react-query';
2
2
  import { tableService } from '../services/table.service';
3
3
  import { useToast } from '@/lib/hooks/useToast';
4
4
  import {
@@ -6,7 +6,6 @@ import {
6
6
  GetTableSchemaResponse,
7
7
  UpdateTableSchemaRequest,
8
8
  } from '@insforge/shared-schemas';
9
- import { useMemo } from 'react';
10
9
 
11
10
  export function useTables() {
12
11
  const queryClient = useQueryClient();
@@ -24,19 +23,7 @@ export function useTables() {
24
23
  staleTime: 2 * 60 * 1000, // Cache for 2 minutes
25
24
  });
26
25
 
27
- // Query to fetch all table schemas
28
- const {
29
- data: allSchemas,
30
- isLoading: isLoadingSchemas,
31
- error: schemasError,
32
- refetch: refetchAllSchemas,
33
- } = useQuery({
34
- queryKey: ['tables', 'schemas'],
35
- queryFn: () => tableService.getAllTableSchemas(),
36
- staleTime: 2 * 60 * 1000,
37
- });
38
-
39
- // Query to fetch a specific table schema
26
+ // Query to fetch a specific table schema (cached per table)
40
27
  const useTableSchema = (tableName: string, enabled = true) => {
41
28
  return useQuery({
42
29
  queryKey: ['tables', tableName, 'schema'],
@@ -52,7 +39,6 @@ export function useTables() {
52
39
  tableService.createTable(tableName, columns),
53
40
  onSuccess: () => {
54
41
  void queryClient.invalidateQueries({ queryKey: ['tables'] });
55
- void queryClient.invalidateQueries({ queryKey: ['tables', 'schemas'] });
56
42
  showToast('Table created successfully', 'success');
57
43
  },
58
44
  onError: (error: Error) => {
@@ -66,7 +52,6 @@ export function useTables() {
66
52
  mutationFn: (tableName: string) => tableService.deleteTable(tableName),
67
53
  onSuccess: () => {
68
54
  void queryClient.invalidateQueries({ queryKey: ['tables'] });
69
- void queryClient.invalidateQueries({ queryKey: ['tables', 'schemas'] });
70
55
  showToast('Table deleted successfully', 'success');
71
56
  },
72
57
  onError: (error: Error) => {
@@ -85,7 +70,6 @@ export function useTables() {
85
70
  operations: UpdateTableSchemaRequest;
86
71
  }) => tableService.updateTableSchema(tableName, operations),
87
72
  onSuccess: (_, { tableName }) => {
88
- void queryClient.invalidateQueries({ queryKey: ['tables', 'schemas'] });
89
73
  void queryClient.invalidateQueries({ queryKey: ['tables', tableName, 'schema'] });
90
74
  showToast('Table schema updated successfully', 'success');
91
75
  },
@@ -98,34 +82,52 @@ export function useTables() {
98
82
  return {
99
83
  // Data
100
84
  tables: tables || [],
101
- allSchemas: useMemo(
102
- () => allSchemas?.filter((schema) => schema.tableName !== 'users') || [],
103
- [allSchemas]
104
- ),
105
85
  tablesCount: tables?.length || 0,
106
86
 
107
87
  // Loading states
108
88
  isLoadingTables,
109
- isLoadingSchemas,
110
89
  isCreating: createTableMutation.isPending,
111
90
  isDeleting: deleteTableMutation.isPending,
112
91
  isUpdating: updateTableSchemaMutation.isPending,
113
92
 
114
93
  // Errors
115
94
  tablesError,
116
- schemasError,
117
95
 
118
96
  // Actions
119
97
  createTable: createTableMutation.mutate,
120
98
  deleteTable: deleteTableMutation.mutate,
121
99
  updateTableSchema: updateTableSchemaMutation.mutate,
122
100
  refetchTables,
123
- refetchAllSchemas,
124
101
 
125
102
  // Helpers
126
103
  useTableSchema,
127
- getSchemaByTableName: (tableName: string): GetTableSchemaResponse | undefined => {
128
- return allSchemas?.find((schema) => schema.tableName === tableName);
129
- },
104
+ };
105
+ }
106
+
107
+ /**
108
+ * Hook to fetch all table schemas on demand.
109
+ * Use this only when you need ALL schemas (e.g., for visualizations).
110
+ * For individual tables, use useTables().useTableSchema() instead.
111
+ */
112
+ export function useAllTableSchemas(enabled = true) {
113
+ const { tables, isLoadingTables } = useTables();
114
+
115
+ const { allSchemas, isLoadingSchemas } = useQueries({
116
+ queries: enabled
117
+ ? tables.map((tableName) => ({
118
+ queryKey: ['tables', tableName, 'schema'],
119
+ queryFn: () => tableService.getTableSchema(tableName),
120
+ staleTime: 2 * 60 * 1000,
121
+ }))
122
+ : [],
123
+ combine: (results) => ({
124
+ allSchemas: results.filter((r) => r.data).map((r) => r.data as GetTableSchemaResponse),
125
+ isLoadingSchemas: results.some((r) => r.isLoading),
126
+ }),
127
+ });
128
+
129
+ return {
130
+ allSchemas,
131
+ isLoading: isLoadingTables || isLoadingSchemas,
130
132
  };
131
133
  }
@@ -4,6 +4,7 @@ export { TableListSkeleton } from './components/TableListSkeleton';
4
4
  export { TableSidebar } from './components/TableSidebar';
5
5
  export { TableForm } from './components/TableForm';
6
6
  export { RecordFormDialog } from './components/RecordFormDialog';
7
+ export { SQLModal, SQLCellButton } from './components/SQLModal';
7
8
 
8
9
  // Services
9
10
  export { tableService } from './services/table.service';
@@ -1,4 +1,4 @@
1
- import { useMemo, useState, useEffect } from 'react';
1
+ import { useMemo, useState } from 'react';
2
2
  import RefreshIcon from '@/assets/icons/refresh.svg?react';
3
3
  import {
4
4
  Button,
@@ -13,16 +13,9 @@ import {
13
13
  TooltipProvider,
14
14
  TooltipTrigger,
15
15
  } from '@/components';
16
- import { useFullMetadata } from '../hooks/useFullMetadata';
17
- import type { ExportDatabaseResponse, ExportDatabaseJsonData } from '@insforge/shared-schemas';
18
- import { isSystemFunction } from '../constants';
19
- import {
20
- DataUpdatePayload,
21
- DataUpdateResourceType,
22
- ServerEvents,
23
- SocketMessage,
24
- useSocket,
25
- } from '@/lib/contexts/SocketContext';
16
+ import { useFunctions } from '../hooks/useDatabase';
17
+ import { SQLModal, SQLCellButton } from '../components/SQLModal';
18
+ import type { DatabaseFunctionsResponse } from '@insforge/shared-schemas';
26
19
 
27
20
  interface FunctionRow extends DataGridRowType {
28
21
  id: string;
@@ -32,19 +25,16 @@ interface FunctionRow extends DataGridRowType {
32
25
  [key: string]: ConvertedValue | { [key: string]: string }[];
33
26
  }
34
27
 
35
- function parseFunctionsFromMetadata(metadata: ExportDatabaseResponse | undefined): FunctionRow[] {
36
- if (!metadata || metadata.format !== 'json' || typeof metadata.data === 'string') {
28
+ function parseFunctionsFromResponse(
29
+ response: DatabaseFunctionsResponse | undefined
30
+ ): FunctionRow[] {
31
+ if (!response?.functions) {
37
32
  return [];
38
33
  }
39
34
 
40
- const data = metadata.data as ExportDatabaseJsonData;
41
35
  const functions: FunctionRow[] = [];
42
36
 
43
- data.functions.forEach((func) => {
44
- if (isSystemFunction(func.functionName)) {
45
- return;
46
- }
47
-
37
+ response.functions.forEach((func) => {
48
38
  functions.push({
49
39
  id: func.functionName,
50
40
  functionName: func.functionName,
@@ -59,29 +49,10 @@ function parseFunctionsFromMetadata(metadata: ExportDatabaseResponse | undefined
59
49
  export default function FunctionsPage() {
60
50
  const [searchQuery, setSearchQuery] = useState('');
61
51
  const [isRefreshing, setIsRefreshing] = useState(false);
62
- const { data: metadata, isLoading, error, refetch } = useFullMetadata(true);
63
-
64
- const { socket, isConnected } = useSocket();
65
-
66
- const allFunctions = useMemo(() => parseFunctionsFromMetadata(metadata), [metadata]);
67
-
68
- useEffect(() => {
69
- if (!socket || !isConnected) {
70
- return;
71
- }
52
+ const { data, isLoading, error, refetch } = useFunctions(true);
53
+ const [sqlModal, setSqlModal] = useState({ open: false, title: '', value: '' });
72
54
 
73
- const handleDataUpdate = (message: SocketMessage<DataUpdatePayload>) => {
74
- if (message.payload?.resource === DataUpdateResourceType.DATABASE) {
75
- void refetch();
76
- }
77
- };
78
-
79
- socket.on(ServerEvents.DATA_UPDATE, handleDataUpdate);
80
-
81
- return () => {
82
- socket.off(ServerEvents.DATA_UPDATE, handleDataUpdate);
83
- };
84
- }, [socket, isConnected, refetch]);
55
+ const allFunctions = useMemo(() => parseFunctionsFromResponse(data), [data]);
85
56
 
86
57
  const filteredFunctions = useMemo(() => {
87
58
  if (!searchQuery.trim()) {
@@ -132,9 +103,17 @@ export default function FunctionsPage() {
132
103
  name: 'Definition',
133
104
  width: 'minmax(400px, 8fr)',
134
105
  resizable: true,
106
+ renderCell: ({ row }) => (
107
+ <SQLCellButton
108
+ value={row.functionDef}
109
+ onClick={() =>
110
+ setSqlModal({ open: true, title: 'Function Definition', value: row.functionDef })
111
+ }
112
+ />
113
+ ),
135
114
  },
136
115
  ],
137
- []
116
+ [setSqlModal]
138
117
  );
139
118
 
140
119
  if (error) {
@@ -206,6 +185,14 @@ export default function FunctionsPage() {
206
185
  />
207
186
  </div>
208
187
  )}
188
+
189
+ {/* SQL Detail Modal */}
190
+ <SQLModal
191
+ open={sqlModal.open}
192
+ onOpenChange={(open) => setSqlModal((prev) => ({ ...prev, open }))}
193
+ title={sqlModal.title}
194
+ value={sqlModal.value}
195
+ />
209
196
  </div>
210
197
  );
211
198
  }
@@ -1,4 +1,4 @@
1
- import { useMemo, useState, useEffect } from 'react';
1
+ import { useMemo, useState } from 'react';
2
2
  import RefreshIcon from '@/assets/icons/refresh.svg?react';
3
3
  import {
4
4
  Button,
@@ -13,16 +13,9 @@ import {
13
13
  TooltipProvider,
14
14
  TooltipTrigger,
15
15
  } from '@/components';
16
- import { useFullMetadata } from '../hooks/useFullMetadata';
17
- import type { ExportDatabaseResponse, ExportDatabaseJsonData } from '@insforge/shared-schemas';
18
- import { isSystemTable } from '../constants';
19
- import {
20
- DataUpdatePayload,
21
- DataUpdateResourceType,
22
- ServerEvents,
23
- SocketMessage,
24
- useSocket,
25
- } from '@/lib/contexts/SocketContext';
16
+ import { useIndexes } from '../hooks/useDatabase';
17
+ import { SQLModal, SQLCellButton } from '../components/SQLModal';
18
+ import type { DatabaseIndexesResponse } from '@insforge/shared-schemas';
26
19
 
27
20
  interface IndexRow extends DataGridRowType {
28
21
  id: string;
@@ -34,28 +27,21 @@ interface IndexRow extends DataGridRowType {
34
27
  [key: string]: ConvertedValue | { [key: string]: string }[];
35
28
  }
36
29
 
37
- function parseIndexesFromMetadata(metadata: ExportDatabaseResponse | undefined): IndexRow[] {
38
- if (!metadata || metadata.format !== 'json' || typeof metadata.data === 'string') {
30
+ function parseIndexesFromResponse(response: DatabaseIndexesResponse | undefined): IndexRow[] {
31
+ if (!response?.indexes) {
39
32
  return [];
40
33
  }
41
34
 
42
- const data = metadata.data as ExportDatabaseJsonData;
43
35
  const indexes: IndexRow[] = [];
44
36
 
45
- Object.entries(data.tables).forEach(([tableName, tableData]) => {
46
- if (isSystemTable(tableName)) {
47
- return;
48
- }
49
-
50
- tableData.indexes.forEach((index) => {
51
- indexes.push({
52
- id: `${tableName}_${index.indexname}`,
53
- tableName,
54
- indexName: index.indexname,
55
- indexDef: index.indexdef,
56
- isUnique: index.isUnique,
57
- isPrimary: index.isPrimary,
58
- });
37
+ response.indexes.forEach((index) => {
38
+ indexes.push({
39
+ id: `${index.tableName}_${index.indexName}`,
40
+ tableName: index.tableName,
41
+ indexName: index.indexName,
42
+ indexDef: index.indexDef,
43
+ isUnique: index.isUnique,
44
+ isPrimary: index.isPrimary,
59
45
  });
60
46
  });
61
47
 
@@ -65,29 +51,10 @@ function parseIndexesFromMetadata(metadata: ExportDatabaseResponse | undefined):
65
51
  export default function IndexesPage() {
66
52
  const [searchQuery, setSearchQuery] = useState('');
67
53
  const [isRefreshing, setIsRefreshing] = useState(false);
68
- const { data: metadata, isLoading, error, refetch } = useFullMetadata(true);
69
-
70
- const { socket, isConnected } = useSocket();
71
-
72
- const allIndexes = useMemo(() => parseIndexesFromMetadata(metadata), [metadata]);
73
-
74
- useEffect(() => {
75
- if (!socket || !isConnected) {
76
- return;
77
- }
54
+ const { data, isLoading, error, refetch } = useIndexes(true);
55
+ const [sqlModal, setSqlModal] = useState({ open: false, title: '', value: '' });
78
56
 
79
- const handleDataUpdate = (message: SocketMessage<DataUpdatePayload>) => {
80
- if (message.payload?.resource === DataUpdateResourceType.DATABASE) {
81
- void refetch();
82
- }
83
- };
84
-
85
- socket.on(ServerEvents.DATA_UPDATE, handleDataUpdate);
86
-
87
- return () => {
88
- socket.off(ServerEvents.DATA_UPDATE, handleDataUpdate);
89
- };
90
- }, [socket, isConnected, refetch]);
57
+ const allIndexes = useMemo(() => parseIndexesFromResponse(data), [data]);
91
58
 
92
59
  const filteredIndexes = useMemo(() => {
93
60
  if (!searchQuery.trim()) {
@@ -161,9 +128,17 @@ export default function IndexesPage() {
161
128
  name: 'Definition',
162
129
  width: 'minmax(300px, 5fr)',
163
130
  resizable: true,
131
+ renderCell: ({ row }) => (
132
+ <SQLCellButton
133
+ value={row.indexDef}
134
+ onClick={() =>
135
+ setSqlModal({ open: true, title: 'Index Definition', value: row.indexDef })
136
+ }
137
+ />
138
+ ),
164
139
  },
165
140
  ],
166
- []
141
+ [setSqlModal]
167
142
  );
168
143
 
169
144
  if (error) {
@@ -235,6 +210,14 @@ export default function IndexesPage() {
235
210
  />
236
211
  </div>
237
212
  )}
213
+
214
+ {/* SQL Detail Modal */}
215
+ <SQLModal
216
+ open={sqlModal.open}
217
+ onOpenChange={(open) => setSqlModal((prev) => ({ ...prev, open }))}
218
+ title={sqlModal.title}
219
+ value={sqlModal.value}
220
+ />
238
221
  </div>
239
222
  );
240
223
  }
@@ -1,4 +1,4 @@
1
- import { useMemo, useState, useEffect } from 'react';
1
+ import { useMemo, useState } from 'react';
2
2
  import RefreshIcon from '@/assets/icons/refresh.svg?react';
3
3
  import {
4
4
  Button,
@@ -13,16 +13,9 @@ import {
13
13
  TooltipProvider,
14
14
  TooltipTrigger,
15
15
  } from '@/components';
16
- import { useFullMetadata } from '../hooks/useFullMetadata';
17
- import type { ExportDatabaseResponse, ExportDatabaseJsonData } from '@insforge/shared-schemas';
18
- import { isSystemTable } from '../constants';
19
- import {
20
- DataUpdatePayload,
21
- DataUpdateResourceType,
22
- ServerEvents,
23
- SocketMessage,
24
- useSocket,
25
- } from '@/lib/contexts/SocketContext';
16
+ import { usePolicies } from '../hooks/useDatabase';
17
+ import { SQLModal, SQLCellButton } from '../components/SQLModal';
18
+ import type { DatabasePoliciesResponse } from '@insforge/shared-schemas';
26
19
 
27
20
  interface PolicyRow extends DataGridRowType {
28
21
  id: string;
@@ -35,29 +28,22 @@ interface PolicyRow extends DataGridRowType {
35
28
  [key: string]: ConvertedValue | { [key: string]: string }[];
36
29
  }
37
30
 
38
- function parsePoliciesFromMetadata(metadata: ExportDatabaseResponse | undefined): PolicyRow[] {
39
- if (!metadata || metadata.format !== 'json' || typeof metadata.data === 'string') {
31
+ function parsePoliciesFromResponse(response: DatabasePoliciesResponse | undefined): PolicyRow[] {
32
+ if (!response?.policies) {
40
33
  return [];
41
34
  }
42
35
 
43
- const data = metadata.data as ExportDatabaseJsonData;
44
36
  const policies: PolicyRow[] = [];
45
37
 
46
- Object.entries(data.tables).forEach(([tableName, tableData]) => {
47
- if (isSystemTable(tableName)) {
48
- return;
49
- }
50
-
51
- tableData.policies.forEach((policy) => {
52
- policies.push({
53
- id: `${tableName}_${policy.policyname}`,
54
- tableName,
55
- policyName: policy.policyname,
56
- cmd: policy.cmd,
57
- roles: Array.isArray(policy.roles) ? policy.roles.join(', ') : String(policy.roles),
58
- qual: policy.qual,
59
- withCheck: policy.withCheck,
60
- });
38
+ response.policies.forEach((policy) => {
39
+ policies.push({
40
+ id: `${policy.tableName}_${policy.policyName}`,
41
+ tableName: policy.tableName,
42
+ policyName: policy.policyName,
43
+ cmd: policy.cmd,
44
+ roles: Array.isArray(policy.roles) ? policy.roles.join(', ') : String(policy.roles),
45
+ qual: policy.qual,
46
+ withCheck: policy.withCheck,
61
47
  });
62
48
  });
63
49
 
@@ -67,29 +53,10 @@ function parsePoliciesFromMetadata(metadata: ExportDatabaseResponse | undefined)
67
53
  export default function PoliciesPage() {
68
54
  const [searchQuery, setSearchQuery] = useState('');
69
55
  const [isRefreshing, setIsRefreshing] = useState(false);
70
- const { data: metadata, isLoading, error, refetch } = useFullMetadata(true);
71
-
72
- const { socket, isConnected } = useSocket();
73
-
74
- const allPolicies = useMemo(() => parsePoliciesFromMetadata(metadata), [metadata]);
75
-
76
- useEffect(() => {
77
- if (!socket || !isConnected) {
78
- return;
79
- }
80
-
81
- const handleDataUpdate = (message: SocketMessage<DataUpdatePayload>) => {
82
- if (message.payload?.resource === DataUpdateResourceType.DATABASE) {
83
- void refetch();
84
- }
85
- };
86
-
87
- socket.on(ServerEvents.DATA_UPDATE, handleDataUpdate);
56
+ const { data, isLoading, error, refetch } = usePolicies(true);
57
+ const [sqlModal, setSqlModal] = useState({ open: false, title: '', value: '' });
88
58
 
89
- return () => {
90
- socket.off(ServerEvents.DATA_UPDATE, handleDataUpdate);
91
- };
92
- }, [socket, isConnected, refetch]);
59
+ const allPolicies = useMemo(() => parsePoliciesFromResponse(data), [data]);
93
60
 
94
61
  const filteredPolicies = useMemo(() => {
95
62
  if (!searchQuery.trim()) {
@@ -157,21 +124,30 @@ export default function PoliciesPage() {
157
124
  name: 'Using',
158
125
  width: 'minmax(200px, 2fr)',
159
126
  resizable: true,
160
- renderCell: ({ row }) => {
161
- return <span className="text-xs font-mono">{row.qual || '-'}</span>;
162
- },
127
+ renderCell: ({ row }) => (
128
+ <SQLCellButton
129
+ value={row.qual}
130
+ onClick={() => row.qual && setSqlModal({ open: true, title: 'Using', value: row.qual })}
131
+ />
132
+ ),
163
133
  },
164
134
  {
165
135
  key: 'withCheck',
166
136
  name: 'With Check',
167
137
  width: 'minmax(200px, 2fr)',
168
138
  resizable: true,
169
- renderCell: ({ row }) => {
170
- return <span className="text-xs font-mono">{row.withCheck || '-'}</span>;
171
- },
139
+ renderCell: ({ row }) => (
140
+ <SQLCellButton
141
+ value={row.withCheck}
142
+ onClick={() =>
143
+ row.withCheck &&
144
+ setSqlModal({ open: true, title: 'With Check', value: row.withCheck })
145
+ }
146
+ />
147
+ ),
172
148
  },
173
149
  ],
174
- []
150
+ [setSqlModal]
175
151
  );
176
152
 
177
153
  if (error) {
@@ -243,6 +219,14 @@ export default function PoliciesPage() {
243
219
  />
244
220
  </div>
245
221
  )}
222
+
223
+ {/* SQL Detail Modal */}
224
+ <SQLModal
225
+ open={sqlModal.open}
226
+ onOpenChange={(open) => setSqlModal((prev) => ({ ...prev, open }))}
227
+ title={sqlModal.title}
228
+ value={sqlModal.value}
229
+ />
246
230
  </div>
247
231
  );
248
232
  }
@@ -304,7 +304,7 @@ export default function SQLEditorPage() {
304
304
  language="sql"
305
305
  value={activeTab?.query || ''}
306
306
  onChange={handleQueryChange}
307
- placeholder="SELECT * FROM users WHERE email = 'user@example.com';"
307
+ placeholder="SELECT * from products LIMIT 10;"
308
308
  />
309
309
  </div>
310
310
  </div>
@@ -362,7 +362,7 @@ export default function SQLEditorPage() {
362
362
  {isError && error ? (
363
363
  <ErrorViewer error={error} />
364
364
  ) : isSuccess && data ? (
365
- <ResultsViewer data={data.rows || data.data || data} />
365
+ <ResultsViewer data={data.rows || data} />
366
366
  ) : (
367
367
  <div
368
368
  className={cn(
@@ -1,5 +1,4 @@
1
1
  import { useState, useEffect, useCallback, useMemo, useRef } from 'react';
2
- import { useQueryClient } from '@tanstack/react-query';
3
2
  import { Plus, Upload } from 'lucide-react';
4
3
  import PencilIcon from '@/assets/icons/pencil.svg?react';
5
4
  import RefreshIcon from '@/assets/icons/refresh.svg?react';
@@ -31,13 +30,6 @@ import { useToast } from '@/lib/hooks/useToast';
31
30
  import { DatabaseDataGrid } from '@/features/database/components/DatabaseDataGrid';
32
31
  import { SortColumn } from 'react-data-grid';
33
32
  import { convertValueForColumn } from '@/lib/utils/utils';
34
- import {
35
- DataUpdatePayload,
36
- DataUpdateResourceType,
37
- ServerEvents,
38
- SocketMessage,
39
- useSocket,
40
- } from '@/lib/contexts/SocketContext';
41
33
  import { useCSVImport } from '@/features/database/hooks/useCSVImport';
42
34
 
43
35
  const PAGE_SIZE = 50;
@@ -62,15 +54,12 @@ export default function TablesPage() {
62
54
 
63
55
  const { confirm, confirmDialogProps } = useConfirm();
64
56
  const { showToast } = useToast();
65
- const queryClient = useQueryClient();
66
57
  const fileInputRef = useRef<HTMLInputElement>(null);
67
58
  const { tables, isLoadingTables, tablesError, deleteTable, useTableSchema, refetchTables } =
68
59
  useTables();
69
60
 
70
61
  const recordsHook = useRecords(selectedTable || '');
71
62
 
72
- const { socket, isConnected } = useSocket();
73
-
74
63
  const handleFileSelect = (event: React.ChangeEvent<HTMLInputElement>) => {
75
64
  const file = event.target.files?.[0];
76
65
  if (file && selectedTable) {
@@ -184,37 +173,6 @@ export default function TablesPage() {
184
173
  const tableError = recordsError;
185
174
  const refetchTableData = refetchRecords;
186
175
 
187
- useEffect(() => {
188
- if (!socket || !isConnected) {
189
- return;
190
- }
191
-
192
- const handleDataUpdate = (message: SocketMessage<DataUpdatePayload>) => {
193
- if (message.payload?.resource === DataUpdateResourceType.DATABASE) {
194
- // Invalidate all tables queries
195
- void queryClient.invalidateQueries({ queryKey: ['tables'] });
196
- void queryClient.invalidateQueries({ queryKey: ['records', selectedTable] });
197
- }
198
-
199
- if (message.payload?.resource === DataUpdateResourceType.RECORDS) {
200
- // Invalidate records queries for the updated table
201
- const data = message.payload.data as { tableName?: string };
202
- const updatedTableName = data?.tableName;
203
-
204
- // Only invalidate if this is the currently selected table
205
- if (updatedTableName && updatedTableName === selectedTable) {
206
- void queryClient.invalidateQueries({ queryKey: ['records', selectedTable] });
207
- }
208
- }
209
- };
210
-
211
- socket.on(ServerEvents.DATA_UPDATE, handleDataUpdate);
212
-
213
- return () => {
214
- socket.off(ServerEvents.DATA_UPDATE, handleDataUpdate);
215
- };
216
- }, [socket, isConnected, queryClient, selectedTable]);
217
-
218
176
  // Reset sorting flag when loading completes
219
177
  useEffect(() => {
220
178
  if (!isLoadingTable && isSorting) {