insforge 0.3.3 → 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (635) hide show
  1. package/.claude-plugin/marketplace.json +20 -0
  2. package/.dockerignore +60 -57
  3. package/.env.example +84 -49
  4. package/.github/ISSUE_TEMPLATE/bug_report.yml +36 -83
  5. package/.github/ISSUE_TEMPLATE/config.yml +11 -11
  6. package/.github/ISSUE_TEMPLATE/feature_request.yml +26 -79
  7. package/.github/PULL_REQUEST_TEMPLATE.md +7 -0
  8. package/.github/copilot-instructions.md +146 -146
  9. package/.github/workflows/build-image.yml +66 -65
  10. package/.github/workflows/ci-premerge-check.yml +23 -23
  11. package/.github/workflows/e2e.yml +63 -0
  12. package/.github/workflows/lint-and-format.yml +32 -32
  13. package/.prettierignore +64 -64
  14. package/CHANGELOG.md +44 -3
  15. package/CLAUDE_PLUGIN.md +104 -0
  16. package/CODE_OF_CONDUCT.md +128 -0
  17. package/CONTRIBUTING.md +125 -125
  18. package/Dockerfile +30 -27
  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 -134
  23. package/assets/Dark.svg +23 -23
  24. package/assets/mcpInstallv2.png +0 -0
  25. package/assets/sampleResponse.png +0 -0
  26. package/auth/index.html +13 -0
  27. package/auth/package.json +28 -0
  28. package/auth/public/favicon.ico +0 -0
  29. package/auth/src/App.tsx +33 -0
  30. package/auth/src/components/ErrorCard.tsx +37 -0
  31. package/auth/src/components/Layout.tsx +13 -0
  32. package/auth/src/index.css +19 -0
  33. package/auth/src/lib/broadcastService.ts +117 -0
  34. package/auth/src/lib/utils.ts +11 -0
  35. package/auth/src/main.tsx +22 -0
  36. package/auth/src/pages/ForgotPasswordPage.tsx +11 -0
  37. package/auth/src/pages/ResetPasswordPage.tsx +11 -0
  38. package/auth/src/pages/SignInPage.tsx +60 -0
  39. package/auth/src/pages/SignUpPage.tsx +60 -0
  40. package/auth/src/pages/VerifyEmailPage.tsx +20 -0
  41. package/auth/src/vite-env.d.ts +10 -0
  42. package/auth/tsconfig.json +32 -0
  43. package/auth/tsconfig.node.json +11 -0
  44. package/auth/vite.config.ts +25 -0
  45. package/backend/package.json +78 -75
  46. package/backend/src/api/{middleware → middlewares}/auth.ts +8 -9
  47. package/backend/src/api/middlewares/rate-limiters.ts +127 -0
  48. package/backend/src/api/routes/{ai.ts → ai/index.routes.ts} +22 -26
  49. package/backend/src/api/routes/auth/index.routes.ts +667 -0
  50. package/backend/src/api/routes/auth/oauth.routes.ts +473 -0
  51. package/backend/src/api/routes/{database.advance.ts → database/advance.routes.ts} +128 -65
  52. package/backend/src/api/routes/database/index.routes.ts +90 -0
  53. package/backend/src/api/routes/{database.records.ts → database/records.routes.ts} +26 -12
  54. package/backend/src/api/routes/{database.tables.ts → database/tables.routes.ts} +6 -23
  55. package/backend/src/api/routes/docs/index.routes.ts +75 -0
  56. package/backend/src/api/routes/email/index.routes.ts +35 -0
  57. package/backend/src/api/routes/functions/index.routes.ts +194 -0
  58. package/backend/src/api/routes/{logs.ts → logs/index.routes.ts} +25 -30
  59. package/backend/src/api/routes/{metadata.ts → metadata/index.routes.ts} +33 -31
  60. package/backend/src/api/routes/realtime/channels.routes.ts +81 -0
  61. package/backend/src/api/routes/realtime/index.routes.ts +12 -0
  62. package/backend/src/api/routes/realtime/messages.routes.ts +48 -0
  63. package/backend/src/api/routes/realtime/permissions.routes.ts +19 -0
  64. package/backend/src/api/routes/{secrets.ts → secrets/index.routes.ts} +27 -22
  65. package/backend/src/api/routes/{storage.ts → storage/index.routes.ts} +48 -61
  66. package/backend/src/api/routes/usage/index.routes.ts +91 -0
  67. package/backend/src/infra/config/app.config.ts +51 -0
  68. package/backend/src/infra/database/database.manager.ts +182 -0
  69. package/backend/{migrations → src/infra/database/migrations}/000_create-base-tables.sql +141 -141
  70. package/backend/{migrations → src/infra/database/migrations}/001_create-helper-functions.sql +40 -40
  71. package/backend/{migrations → src/infra/database/migrations}/002_rename-auth-tables.sql +29 -29
  72. package/backend/{migrations → src/infra/database/migrations}/003_create-users-table.sql +55 -55
  73. package/backend/{migrations → src/infra/database/migrations}/004_add-reload-postgrest-func.sql +23 -23
  74. package/backend/{migrations → src/infra/database/migrations}/005_enable-project-admin-modify-users.sql +29 -29
  75. package/backend/{migrations → src/infra/database/migrations}/006_modify-ai-usage-table.sql +24 -24
  76. package/backend/{migrations → src/infra/database/migrations}/007_drop-metadata-table.sql +1 -1
  77. package/backend/{migrations → src/infra/database/migrations}/008_add-system-tables.sql +76 -76
  78. package/backend/{migrations → src/infra/database/migrations}/009_add-function-secrets.sql +23 -23
  79. package/backend/{migrations → src/infra/database/migrations}/010_modify-ai-config-modalities.sql +93 -93
  80. package/backend/{migrations → src/infra/database/migrations}/011_refactor-secrets-table.sql +15 -15
  81. package/backend/{migrations → src/infra/database/migrations}/012_add-storage-uploaded-by.sql +7 -7
  82. package/backend/src/infra/database/migrations/013_create-auth-schema-functions.sql +44 -0
  83. package/backend/src/infra/database/migrations/014_add-updated-at-trigger-user-table.sql +8 -0
  84. package/backend/src/infra/database/migrations/015_create-auth-config-and-email-otp-tables.sql +60 -0
  85. package/backend/src/infra/database/migrations/016_update-auth-config-and-email-otp.sql +24 -0
  86. package/backend/src/infra/database/migrations/017_create-realtime-schema.sql +233 -0
  87. package/backend/src/infra/realtime/realtime.manager.ts +246 -0
  88. package/backend/src/infra/realtime/webhook-sender.ts +82 -0
  89. package/backend/src/{core/secrets/encryption.ts → infra/security/encryption.manager.ts} +3 -2
  90. package/backend/src/infra/security/token.manager.ts +219 -0
  91. package/backend/src/infra/socket/socket.manager.ts +522 -0
  92. package/backend/src/providers/ai/openrouter.provider.ts +380 -0
  93. package/backend/src/providers/email/base.provider.ts +38 -0
  94. package/backend/src/providers/email/cloud.provider.ts +271 -0
  95. package/backend/src/{core/logs/providers → providers/logs}/base.provider.ts +11 -11
  96. package/backend/src/{core/logs/providers → providers/logs}/cloudwatch.provider.ts +61 -38
  97. package/backend/src/providers/logs/local.provider.ts +185 -0
  98. package/backend/src/providers/oauth/apple.provider.ts +266 -0
  99. package/backend/src/providers/oauth/base.provider.ts +29 -0
  100. package/backend/src/providers/oauth/discord.provider.ts +195 -0
  101. package/backend/src/providers/oauth/facebook.provider.ts +194 -0
  102. package/backend/src/providers/oauth/github.provider.ts +208 -0
  103. package/backend/src/providers/oauth/google.provider.ts +249 -0
  104. package/backend/src/providers/oauth/index.ts +8 -0
  105. package/backend/src/providers/oauth/linkedin.provider.ts +240 -0
  106. package/backend/src/providers/oauth/microsoft.provider.ts +169 -0
  107. package/backend/src/providers/oauth/x.provider.ts +202 -0
  108. package/backend/src/providers/storage/base.provider.ts +29 -0
  109. package/backend/src/providers/storage/local.provider.ts +103 -0
  110. package/backend/src/providers/storage/s3.provider.ts +313 -0
  111. package/backend/src/server.ts +317 -288
  112. package/backend/src/{core/ai/config.ts → services/ai/ai-config.service.ts} +19 -24
  113. package/backend/src/services/ai/ai-model.service.ts +60 -0
  114. package/backend/src/{core/ai/usage.ts → services/ai/ai-usage.service.ts} +28 -35
  115. package/backend/src/{core/ai/chat.ts → services/ai/chat-completion.service.ts} +37 -24
  116. package/backend/src/services/ai/helpers.ts +64 -0
  117. package/backend/src/{core/ai/image.ts → services/ai/image-generation.service.ts} +17 -19
  118. package/backend/src/services/ai/index.ts +13 -0
  119. package/backend/src/services/auth/auth-config.service.ts +250 -0
  120. package/backend/src/services/auth/auth-otp.service.ts +424 -0
  121. package/backend/src/services/auth/auth.service.ts +1150 -0
  122. package/backend/src/services/auth/index.ts +4 -0
  123. package/backend/src/{core/auth/oauth.ts → services/auth/oauth-config.service.ts} +106 -52
  124. package/backend/src/{core/database/advance.ts → services/database/database-advance.service.ts} +97 -131
  125. package/backend/src/services/database/database-table.service.ts +802 -0
  126. package/backend/src/services/database/database.service.ts +127 -0
  127. package/backend/src/services/email/email.service.ts +73 -0
  128. package/backend/src/{core/functions/functions.ts → services/functions/function.service.ts} +95 -88
  129. package/backend/src/{core/logs/audit.ts → services/logs/audit.service.ts} +92 -75
  130. package/backend/src/services/logs/log.service.ts +73 -0
  131. package/backend/src/services/realtime/index.ts +3 -0
  132. package/backend/src/services/realtime/realtime-auth.service.ts +104 -0
  133. package/backend/src/services/realtime/realtime-channel.service.ts +237 -0
  134. package/backend/src/services/realtime/realtime-message.service.ts +260 -0
  135. package/backend/src/{core/secrets/secrets.ts → services/secrets/secret.service.ts} +48 -66
  136. package/backend/src/services/storage/storage.service.ts +617 -0
  137. package/backend/src/services/usage/usage.service.ts +149 -0
  138. package/backend/src/types/auth.ts +77 -2
  139. package/backend/src/types/email.ts +8 -0
  140. package/backend/src/types/error-constants.ts +4 -0
  141. package/backend/src/types/logs.ts +0 -29
  142. package/backend/src/types/realtime.ts +18 -0
  143. package/backend/src/{core/socket/types.ts → types/socket.ts} +11 -36
  144. package/backend/src/utils/cookies.ts +35 -0
  145. package/backend/src/utils/environment.ts +9 -3
  146. package/backend/src/utils/logger.ts +20 -2
  147. package/backend/src/utils/s3-config-loader.ts +64 -0
  148. package/backend/src/utils/seed.ts +301 -205
  149. package/backend/src/utils/sql-parser.ts +91 -1
  150. package/backend/src/utils/utils.ts +114 -0
  151. package/backend/src/utils/validations.ts +40 -4
  152. package/backend/tests/README.md +133 -133
  153. package/backend/tests/cleanup-all-test-data.sh +230 -230
  154. package/backend/tests/cloud/test-s3-multitenant.sh +131 -131
  155. package/backend/tests/local/comprehensive-curl-tests.sh +155 -155
  156. package/backend/tests/local/test-ai-config.sh +129 -0
  157. package/backend/tests/local/test-ai-usage.sh +80 -0
  158. package/backend/tests/local/test-auth-router.sh +143 -143
  159. package/backend/tests/local/test-database-router.sh +222 -222
  160. package/backend/tests/local/test-e2e.sh +240 -240
  161. package/backend/tests/local/test-fk-errors.sh +96 -96
  162. package/backend/tests/local/test-functions.sh +123 -0
  163. package/backend/tests/local/test-id-field.sh +200 -200
  164. package/backend/tests/local/test-logs.sh +132 -0
  165. package/backend/tests/local/test-public-bucket.sh +264 -264
  166. package/backend/tests/local/test-secrets.sh +249 -247
  167. package/backend/tests/local/test-serverless-functions.sh.disabled +325 -325
  168. package/backend/tests/local/test-traditional-rest.sh +208 -208
  169. package/backend/tests/manual/README.md +50 -50
  170. package/backend/tests/manual/create-large-table-simple.sql +10 -10
  171. package/backend/tests/manual/seed-large-table.sql +100 -100
  172. package/backend/tests/manual/setup-large-table-extras.sql +33 -33
  173. package/backend/tests/manual/test-bulk-upsert.sh +409 -409
  174. package/backend/tests/manual/test-database-advance.sh +296 -296
  175. package/backend/tests/manual/test-postgrest-stability.sh +191 -191
  176. package/backend/tests/manual/test-rawsql-export-import.sh +411 -411
  177. package/backend/tests/manual/test-rawsql-modes.sh +244 -0
  178. package/backend/tests/manual/test-universal-storage.sh +263 -263
  179. package/backend/tests/manual/test-users.sql +17 -17
  180. package/backend/tests/run-all-tests.sh +139 -139
  181. package/backend/tests/setup.ts +0 -0
  182. package/backend/tests/test-config.sh +338 -302
  183. package/backend/tests/unit/analyze-query.test.ts +697 -0
  184. package/backend/tests/unit/cloud-token.test.ts +48 -0
  185. package/backend/tests/unit/constant.test.ts +8 -0
  186. package/backend/tests/unit/email.test.ts +372 -0
  187. package/backend/tests/unit/environment.test.ts +59 -0
  188. package/backend/tests/unit/helpers.test.ts +63 -0
  189. package/backend/tests/unit/logger.test.ts +22 -0
  190. package/backend/tests/unit/rate-limit.test.ts +154 -0
  191. package/backend/tests/unit/response.test.ts +58 -0
  192. package/backend/tests/unit/sql-parser.test.ts +74 -0
  193. package/backend/tests/unit/uuid.test.ts +21 -0
  194. package/backend/tests/unit/validations.test.ts +80 -0
  195. package/backend/tsconfig.json +22 -22
  196. package/backend/vitest.config.ts +11 -0
  197. package/claude-plugin/.claude-plugin/plugin.json +24 -0
  198. package/claude-plugin/README.md +133 -0
  199. package/claude-plugin/skills/insforge-schema-patterns/SKILL.md +270 -0
  200. package/docker-compose.prod.yml +204 -144
  201. package/docker-compose.yml +232 -167
  202. package/docker-init/db/db-init.sql +97 -125
  203. package/docker-init/db/jwt.sql +5 -5
  204. package/docker-init/db/postgresql.conf +16 -16
  205. package/docker-init/logs/vector.yml +236 -0
  206. package/docs/README.md +44 -0
  207. package/docs/agent-docs/real-time.md +269 -0
  208. package/docs/changelog.mdx +119 -0
  209. package/docs/core-concepts/ai/architecture.mdx +373 -0
  210. package/docs/core-concepts/ai/sdk.mdx +213 -0
  211. package/docs/core-concepts/authentication/architecture.mdx +278 -0
  212. package/docs/core-concepts/authentication/sdk.mdx +414 -0
  213. package/docs/core-concepts/authentication/ui-components/customization.mdx +529 -0
  214. package/docs/core-concepts/authentication/ui-components/nextjs.mdx +221 -0
  215. package/docs/core-concepts/authentication/ui-components/react-router.mdx +184 -0
  216. package/docs/core-concepts/authentication/ui-components/react.mdx +129 -0
  217. package/docs/core-concepts/database/architecture.mdx +256 -0
  218. package/docs/core-concepts/database/sdk.mdx +382 -0
  219. package/docs/core-concepts/email/architecture.mdx +101 -0
  220. package/docs/core-concepts/email/sdk.mdx +53 -0
  221. package/docs/core-concepts/functions/architecture.mdx +105 -0
  222. package/docs/core-concepts/functions/sdk.mdx +184 -0
  223. package/docs/core-concepts/realtime/architecture.mdx +446 -0
  224. package/docs/core-concepts/realtime/sdk.mdx +409 -0
  225. package/docs/core-concepts/storage/architecture.mdx +243 -0
  226. package/docs/core-concepts/storage/sdk.mdx +253 -0
  227. package/docs/deployment/README.md +94 -0
  228. package/docs/deployment/deploy-to-aws-ec2.md +565 -0
  229. package/docs/deployment/deploy-to-azure-virtual-machines.md +313 -0
  230. package/docs/deployment/deploy-to-google-cloud-compute-engine.md +613 -0
  231. package/docs/deployment/deploy-to-render.md +441 -0
  232. package/docs/deprecated/insforge-auth-api.md +214 -214
  233. package/docs/deprecated/insforge-auth-sdk.md +99 -99
  234. package/docs/deprecated/insforge-db-api.md +358 -358
  235. package/docs/deprecated/insforge-db-sdk.md +139 -139
  236. package/docs/deprecated/insforge-debug-sdk.md +156 -156
  237. package/docs/deprecated/insforge-debug.md +64 -64
  238. package/docs/deprecated/insforge-instructions.md +123 -123
  239. package/docs/deprecated/insforge-project.md +117 -117
  240. package/docs/deprecated/insforge-storage-api.md +278 -278
  241. package/docs/deprecated/insforge-storage-sdk.md +158 -158
  242. package/docs/docs.json +232 -0
  243. package/docs/examples/framework-guides/nextjs.mdx +131 -0
  244. package/docs/examples/framework-guides/nuxt.mdx +165 -0
  245. package/docs/examples/framework-guides/react.mdx +165 -0
  246. package/docs/examples/framework-guides/svelte.mdx +153 -0
  247. package/docs/examples/framework-guides/vue.mdx +159 -0
  248. package/docs/examples/overview.mdx +67 -0
  249. package/docs/favicon.svg +19 -0
  250. package/docs/images/changelog/dec-2025/ai-integration.png +0 -0
  251. package/docs/images/changelog/dec-2025/ai-models.webp +0 -0
  252. package/docs/images/changelog/dec-2025/alipay-payment.webp +0 -0
  253. package/docs/images/changelog/dec-2025/apple-login.jpg +0 -0
  254. package/docs/images/changelog/dec-2025/mcp-installer.png +0 -0
  255. package/docs/images/changelog/dec-2025/realtime-module.jpg +0 -0
  256. package/docs/images/changelog/nov-2025/auth-components.webp +0 -0
  257. package/docs/images/changelog/nov-2025/database-metadata.webp +0 -0
  258. package/docs/images/changelog/nov-2025/quickstart-prompts.webp +0 -0
  259. package/docs/images/changelog/nov-2025/sql-editor.webp +0 -0
  260. package/docs/images/changelog/nov-2025/usage-page.webp +0 -0
  261. package/docs/images/changelog/october-2025/csv-upload.webp +0 -0
  262. package/docs/images/changelog/october-2025/logs-feature.webp +0 -0
  263. package/docs/images/changelog/october-2025/oauth-providers.webp +0 -0
  264. package/docs/images/checks-passed.png +0 -0
  265. package/docs/images/dashboard-connect-expanded.png +0 -0
  266. package/docs/images/dashboard-connect.png +0 -0
  267. package/docs/images/hero-dark.png +0 -0
  268. package/docs/images/hero-light.png +0 -0
  269. package/docs/images/icons/ai.svg +4 -0
  270. package/docs/images/icons/auth.svg +1 -0
  271. package/docs/images/icons/database.svg +1 -0
  272. package/docs/images/icons/function.svg +1 -0
  273. package/docs/images/icons/storage.svg +1 -0
  274. package/docs/images/logos/nextjs.svg +4 -0
  275. package/docs/images/logos/nuxt.svg +4 -0
  276. package/docs/images/logos/react.svg +5 -0
  277. package/docs/images/logos/svelte.svg +4 -0
  278. package/docs/images/logos/vue.svg +5 -0
  279. package/docs/images/mcp-install.png +0 -0
  280. package/docs/images/onboarding-mcp.png +0 -0
  281. package/docs/insforge-instructions-sdk.md +89 -407
  282. package/docs/introduction.mdx +45 -0
  283. package/docs/logo/dark.svg +22 -0
  284. package/docs/logo/light.svg +20 -0
  285. package/docs/partnership.mdx +652 -0
  286. package/docs/quickstart.mdx +83 -0
  287. package/docs/showcase/2048-arena.png +0 -0
  288. package/docs/showcase/framegen-cloud.png +0 -0
  289. package/docs/showcase/line-connect-race.png +0 -0
  290. package/docs/showcase/moment-vibe.png +0 -0
  291. package/docs/showcase/national-flags.png +0 -0
  292. package/docs/showcase/pokemon-vibe.png +0 -0
  293. package/docs/showcase/pure-browse-buy.png +0 -0
  294. package/docs/showcase.mdx +52 -0
  295. package/docs/snippets/sdk-installation.mdx +22 -0
  296. package/docs/snippets/service-icons.mdx +27 -0
  297. package/eslint.config.js +10 -3
  298. package/examples/oauth/frontend-oauth-example.html +250 -250
  299. package/examples/response-examples.md +443 -443
  300. package/frontend/components.json +17 -17
  301. package/frontend/package.json +69 -63
  302. package/frontend/src/App.tsx +13 -82
  303. package/frontend/src/assets/icons/checkbox_checked.svg +6 -6
  304. package/frontend/src/assets/icons/checkbox_undetermined.svg +6 -6
  305. package/frontend/src/assets/icons/checked.svg +3 -3
  306. package/frontend/src/assets/icons/connected.svg +3 -0
  307. package/frontend/src/assets/icons/error.svg +3 -3
  308. package/frontend/src/assets/icons/loader.svg +9 -0
  309. package/frontend/src/assets/icons/pencil.svg +4 -4
  310. package/frontend/src/assets/icons/refresh.svg +4 -4
  311. package/frontend/src/assets/icons/step_active.svg +3 -3
  312. package/frontend/src/assets/icons/step_inactive.svg +11 -11
  313. package/frontend/src/assets/icons/warning.svg +3 -3
  314. package/frontend/src/assets/logos/apple.svg +4 -0
  315. package/frontend/src/assets/logos/claude_code.svg +3 -3
  316. package/frontend/src/assets/logos/cline.svg +6 -6
  317. package/frontend/src/assets/logos/cursor.svg +20 -20
  318. package/frontend/src/assets/logos/discord.svg +8 -8
  319. package/frontend/src/assets/logos/facebook.svg +3 -0
  320. package/frontend/src/assets/logos/gemini.svg +19 -19
  321. package/frontend/src/assets/logos/github.svg +5 -5
  322. package/frontend/src/assets/logos/google.svg +13 -13
  323. package/frontend/src/assets/logos/grok.svg +10 -10
  324. package/frontend/src/assets/logos/insforge_dark.svg +15 -15
  325. package/frontend/src/assets/logos/insforge_light.svg +15 -15
  326. package/frontend/src/assets/logos/instagram.svg +2 -0
  327. package/frontend/src/assets/logos/linkedin.svg +3 -0
  328. package/frontend/src/assets/logos/microsoft.svg +1 -0
  329. package/frontend/src/assets/logos/openai.svg +10 -10
  330. package/frontend/src/assets/logos/roo_code.svg +9 -9
  331. package/frontend/src/assets/logos/spotify.svg +17 -0
  332. package/frontend/src/assets/logos/tiktok.svg +6 -0
  333. package/frontend/src/assets/logos/trae.svg +3 -3
  334. package/frontend/src/assets/logos/windsurf.svg +10 -10
  335. package/frontend/src/assets/logos/x.svg +3 -0
  336. package/frontend/src/components/Checkbox.tsx +27 -29
  337. package/frontend/src/components/CodeBlock.tsx +55 -2
  338. package/frontend/src/components/CodeEditor.tsx +92 -0
  339. package/frontend/src/components/ConfirmDialog.tsx +1 -1
  340. package/frontend/src/components/ConnectCTA.tsx +38 -0
  341. package/frontend/src/components/CopyButton.tsx +52 -15
  342. package/frontend/src/components/ErrorState.tsx +1 -2
  343. package/frontend/src/components/FeatureSidebar.tsx +6 -6
  344. package/frontend/src/components/FeatureSidebarItem.tsx +2 -2
  345. package/frontend/src/components/JsonHighlight.tsx +21 -9
  346. package/frontend/src/components/ProjectInfoModal.tsx +128 -0
  347. package/frontend/src/components/PromptDialog.tsx +1 -4
  348. package/frontend/src/components/SearchInput.tsx +1 -2
  349. package/frontend/src/components/Stepper.tsx +53 -0
  350. package/frontend/src/components/ThemeToggle.tsx +3 -3
  351. package/frontend/src/components/datagrid/DataGrid.tsx +25 -32
  352. package/frontend/src/components/datagrid/cell-editors/DateCellEditor.tsx +1 -2
  353. package/frontend/src/components/datagrid/cell-editors/JsonCellEditor.tsx +2 -4
  354. package/frontend/src/components/datagrid/index.ts +23 -0
  355. package/frontend/src/components/index.ts +23 -30
  356. package/frontend/src/components/layout/AppHeader.tsx +131 -91
  357. package/frontend/src/components/layout/AppSidebar.tsx +80 -170
  358. package/frontend/src/components/layout/Layout.tsx +12 -23
  359. package/frontend/src/components/layout/PrimaryMenu.tsx +187 -0
  360. package/frontend/src/components/layout/SecondaryMenu.tsx +70 -0
  361. package/frontend/src/components/layout/index.ts +5 -0
  362. package/frontend/src/components/radix/Tooltip.tsx +24 -13
  363. package/frontend/src/components/radix/index.ts +22 -0
  364. package/frontend/src/features/ai/components/AIConfigCard.tsx +129 -83
  365. package/frontend/src/features/ai/components/AIEmptyState.tsx +12 -7
  366. package/frontend/src/features/ai/components/ModalityFilterSidebar.tsx +101 -0
  367. package/frontend/src/features/ai/components/ModelSelectionDialog.tsx +135 -0
  368. package/frontend/src/features/ai/components/ModelSelectionGrid.tsx +51 -0
  369. package/frontend/src/features/ai/components/SystemPromptDialog.tsx +118 -0
  370. package/frontend/src/features/ai/components/index.ts +6 -0
  371. package/frontend/src/features/ai/helpers.ts +57 -71
  372. package/frontend/src/features/ai/hooks/useAIConfigs.ts +39 -113
  373. package/frontend/src/features/ai/hooks/useAIUsage.ts +0 -2
  374. package/frontend/src/features/ai/pages/AIPage.tsx +166 -0
  375. package/frontend/src/features/ai/services/ai.service.ts +5 -5
  376. package/frontend/src/features/auth/components/AuthPreview.tsx +96 -0
  377. package/frontend/src/features/auth/components/OAuthConfigDialog.tsx +54 -30
  378. package/frontend/src/features/auth/components/UserFormDialog.tsx +13 -6
  379. package/frontend/src/features/auth/components/UsersDataGrid.tsx +50 -14
  380. package/frontend/src/features/auth/components/index.ts +5 -0
  381. package/frontend/src/features/auth/helpers.tsx +208 -0
  382. package/frontend/src/features/auth/hooks/useAnonToken.ts +30 -0
  383. package/frontend/src/features/auth/hooks/useAuthConfig.ts +48 -0
  384. package/frontend/src/features/auth/hooks/useOAuthConfig.ts +14 -10
  385. package/frontend/src/features/auth/hooks/useUsers.ts +43 -5
  386. package/frontend/src/features/auth/index.ts +3 -2
  387. package/frontend/src/features/auth/pages/AuthMethodsPage.tsx +275 -0
  388. package/frontend/src/features/auth/pages/ConfigurationPage.tsx +395 -0
  389. package/frontend/src/features/auth/pages/UsersPage.tsx +257 -0
  390. package/frontend/src/features/auth/services/anonToken.service.ts +11 -0
  391. package/frontend/src/features/auth/services/config.service.ts +19 -0
  392. package/frontend/src/features/auth/services/{oauth.service.ts → oauth-config.service.ts} +4 -4
  393. package/frontend/src/features/auth/services/{auth.service.ts → user.service.ts} +7 -53
  394. package/frontend/src/features/dashboard/components/ConnectionSuccessBanner.tsx +35 -0
  395. package/frontend/src/features/dashboard/components/PromptCard.tsx +21 -0
  396. package/frontend/src/features/dashboard/components/PromptDialog.tsx +103 -0
  397. package/frontend/src/features/dashboard/components/StatsCard.tsx +50 -0
  398. package/frontend/src/features/dashboard/components/index.ts +4 -0
  399. package/frontend/src/features/dashboard/pages/DashboardPage.tsx +212 -0
  400. package/frontend/src/features/dashboard/prompts/ai-chatbot.ts +13 -0
  401. package/frontend/src/features/dashboard/prompts/crm-system.ts +13 -0
  402. package/frontend/src/features/dashboard/prompts/ecommerce-platform.ts +12 -0
  403. package/frontend/src/features/dashboard/prompts/index.ts +31 -0
  404. package/frontend/src/features/dashboard/prompts/instagram-clone.ts +11 -0
  405. package/frontend/src/features/dashboard/prompts/notion-clone.ts +14 -0
  406. package/frontend/src/features/dashboard/prompts/reddit-clone.ts +12 -0
  407. package/frontend/src/features/database/components/DatabaseDataGrid.tsx +48 -17
  408. package/frontend/src/features/database/components/ForeignKeyCell.tsx +15 -34
  409. package/frontend/src/features/database/components/ForeignKeyPopover.tsx +19 -20
  410. package/frontend/src/features/database/components/LinkRecordModal.tsx +120 -125
  411. package/frontend/src/features/database/components/RecordFormDialog.tsx +22 -33
  412. package/frontend/src/features/database/components/RecordFormField.tsx +45 -47
  413. package/frontend/src/features/database/components/SQLModal.tsx +75 -0
  414. package/frontend/src/features/database/components/TableEmptyState.tsx +6 -5
  415. package/frontend/src/features/database/components/TableForm.tsx +28 -19
  416. package/frontend/src/features/database/components/TableFormColumn.tsx +2 -3
  417. package/frontend/src/features/database/components/TableSidebar.tsx +1 -1
  418. package/frontend/src/features/database/components/TablesEmptyState.tsx +48 -0
  419. package/frontend/src/features/database/components/TemplateCard.tsx +37 -0
  420. package/frontend/src/features/database/components/TemplatePreview.tsx +92 -0
  421. package/frontend/src/features/database/components/index.ts +19 -0
  422. package/frontend/src/features/database/constants.ts +28 -2
  423. package/frontend/src/features/database/contexts/SQLEditorContext.tsx +188 -0
  424. package/frontend/src/features/database/helpers.ts +2 -2
  425. package/frontend/src/features/database/hooks/useCSVImport.ts +29 -0
  426. package/frontend/src/features/database/hooks/useDatabase.ts +66 -0
  427. package/frontend/src/features/database/hooks/useRawSQL.ts +55 -0
  428. package/frontend/src/features/database/hooks/useRecords.ts +139 -0
  429. package/frontend/src/features/database/hooks/useTables.ts +135 -0
  430. package/frontend/src/features/database/index.ts +7 -1
  431. package/frontend/src/features/database/pages/FunctionsPage.tsx +203 -0
  432. package/frontend/src/features/database/pages/IndexesPage.tsx +228 -0
  433. package/frontend/src/features/database/pages/PoliciesPage.tsx +237 -0
  434. package/frontend/src/features/database/pages/SQLEditorPage.tsx +382 -0
  435. package/frontend/src/features/database/{page/DatabasePage.tsx → pages/TablesPage.tsx} +168 -209
  436. package/frontend/src/features/database/pages/TemplatesPage.tsx +39 -0
  437. package/frontend/src/features/database/pages/TriggersPage.tsx +230 -0
  438. package/frontend/src/features/database/services/advance.service.ts +40 -0
  439. package/frontend/src/features/database/services/database.service.ts +33 -194
  440. package/frontend/src/features/database/services/record.service.ts +219 -0
  441. package/frontend/src/features/database/services/table.service.ts +58 -0
  442. package/frontend/src/features/database/templates/ai-chatbot.ts +402 -0
  443. package/frontend/src/features/database/templates/crm-system.ts +528 -0
  444. package/frontend/src/features/database/templates/ecommerce-platform.ts +553 -0
  445. package/frontend/src/features/database/templates/index.ts +34 -0
  446. package/frontend/src/features/database/templates/instagram-clone.ts +222 -0
  447. package/frontend/src/features/database/templates/notion-clone.ts +483 -0
  448. package/frontend/src/features/database/templates/reddit-clone.ts +526 -0
  449. package/frontend/src/features/functions/components/FunctionRow.tsx +2 -1
  450. package/frontend/src/features/functions/components/FunctionsSidebar.tsx +1 -1
  451. package/frontend/src/features/functions/components/SecretRow.tsx +1 -1
  452. package/frontend/src/features/functions/components/index.ts +5 -0
  453. package/frontend/src/features/functions/hooks/useFunctions.ts +4 -4
  454. package/frontend/src/features/{secrets → functions}/hooks/useSecrets.ts +5 -5
  455. package/frontend/src/features/functions/pages/FunctionsPage.tsx +148 -0
  456. package/frontend/src/features/functions/{components/SecretsContent.tsx → pages/SecretsPage.tsx} +19 -21
  457. package/frontend/src/features/functions/services/{functions.service.ts → function.service.ts} +2 -2
  458. package/frontend/src/features/{secrets/services/secrets.service.ts → functions/services/secret.service.ts} +2 -2
  459. package/frontend/src/features/login/hooks/usePartnerOrigin.ts +27 -0
  460. package/frontend/src/features/login/pages/CloudLoginPage.tsx +118 -0
  461. package/frontend/src/features/login/{page → pages}/LoginPage.tsx +16 -23
  462. package/frontend/src/features/login/services/partnership.service.ts +65 -0
  463. package/frontend/src/features/logs/components/LogsDataGrid.tsx +89 -0
  464. package/frontend/src/features/logs/components/SeverityBadge.tsx +18 -0
  465. package/frontend/src/features/logs/components/index.ts +2 -0
  466. package/frontend/src/features/logs/helpers.ts +24 -0
  467. package/frontend/src/features/logs/hooks/useAuditLogs.ts +4 -4
  468. package/frontend/src/features/logs/hooks/useLogSources.ts +137 -0
  469. package/frontend/src/features/logs/hooks/useLogs.ts +163 -0
  470. package/frontend/src/features/logs/hooks/useMcpUsage.ts +128 -0
  471. package/frontend/src/features/logs/index.ts +8 -2
  472. package/frontend/src/features/logs/{page → pages}/AuditsPage.tsx +91 -38
  473. package/frontend/src/features/logs/pages/LogsPage.tsx +152 -0
  474. package/frontend/src/features/logs/pages/MCPLogsPage.tsx +84 -0
  475. package/frontend/src/features/logs/services/audit.service.ts +63 -0
  476. package/frontend/src/features/logs/services/log.service.ts +15 -110
  477. package/frontend/src/features/logs/services/usage.service.ts +31 -0
  478. package/frontend/src/features/onboard/components/McpConnectionStatus.tsx +68 -0
  479. package/frontend/src/features/onboard/components/OnboardingModal.tsx +267 -0
  480. package/frontend/src/features/onboard/components/VideoDemoModal.tsx +38 -0
  481. package/frontend/src/features/onboard/components/index.ts +4 -0
  482. package/frontend/src/features/onboard/components/mcp/CursorDeeplinkGenerator.tsx +2 -2
  483. package/frontend/src/features/onboard/components/mcp/{mcp-helper.tsx → helpers.tsx} +8 -8
  484. package/frontend/src/features/onboard/components/mcp/index.ts +2 -3
  485. package/frontend/src/features/onboard/index.ts +13 -3
  486. package/frontend/src/features/realtime/components/ChannelRow.tsx +83 -0
  487. package/frontend/src/features/realtime/components/EditChannelModal.tsx +246 -0
  488. package/frontend/src/features/realtime/components/MessageRow.tsx +85 -0
  489. package/frontend/src/features/realtime/components/RealtimeEmptyState.tsx +30 -0
  490. package/frontend/src/features/realtime/hooks/useRealtime.ts +218 -0
  491. package/frontend/src/features/realtime/index.ts +11 -0
  492. package/frontend/src/features/realtime/pages/RealtimeChannelsPage.tsx +172 -0
  493. package/frontend/src/features/realtime/pages/RealtimeMessagesPage.tsx +211 -0
  494. package/frontend/src/features/realtime/pages/RealtimePermissionsPage.tsx +191 -0
  495. package/frontend/src/features/realtime/services/realtime.service.ts +107 -0
  496. package/frontend/src/features/storage/components/BucketEmptyState.tsx +9 -6
  497. package/frontend/src/features/storage/components/BucketFormDialog.tsx +25 -41
  498. package/frontend/src/features/storage/components/FilePreviewDialog.tsx +20 -8
  499. package/frontend/src/features/storage/components/StorageDataGrid.tsx +4 -3
  500. package/frontend/src/features/storage/components/StorageManager.tsx +23 -34
  501. package/frontend/src/features/storage/components/index.ts +12 -0
  502. package/frontend/src/features/storage/hooks/useStorage.ts +208 -0
  503. package/frontend/src/features/storage/{page → pages}/StoragePage.tsx +41 -143
  504. package/frontend/src/features/storage/services/storage.service.ts +22 -1
  505. package/frontend/src/features/visualizer/components/AuthNode.tsx +72 -56
  506. package/frontend/src/features/visualizer/components/BucketNode.tsx +4 -4
  507. package/frontend/src/features/visualizer/components/SchemaVisualizer.tsx +108 -80
  508. package/frontend/src/features/visualizer/components/TableNode.tsx +34 -41
  509. package/frontend/src/features/visualizer/components/VisualizerSkeleton.tsx +12 -4
  510. package/frontend/src/features/visualizer/pages/VisualizerPage.tsx +97 -0
  511. package/frontend/src/index.css +1 -0
  512. package/frontend/src/lib/analytics/posthog.tsx +27 -0
  513. package/frontend/src/lib/contexts/AuthContext.tsx +38 -31
  514. package/frontend/src/lib/contexts/SocketContext.tsx +123 -80
  515. package/frontend/src/{features/metadata → lib}/hooks/useMetadata.ts +1 -1
  516. package/frontend/src/lib/hooks/useToast.tsx +6 -2
  517. package/frontend/src/lib/routing/AppRoutes.tsx +99 -0
  518. package/frontend/src/lib/routing/RequireAuth.tsx +27 -0
  519. package/frontend/src/lib/utils/cloudMessaging.ts +20 -0
  520. package/frontend/src/lib/utils/menuItems.ts +207 -0
  521. package/frontend/src/lib/utils/{validation-schemas.ts → schemaValidations.ts} +10 -5
  522. package/frontend/src/lib/utils/utils.ts +32 -1
  523. package/frontend/src/vite-env.d.ts +1 -0
  524. package/frontend/tsconfig.json +25 -25
  525. package/frontend/tsconfig.node.json +9 -9
  526. package/frontend/vite.config.ts +5 -3
  527. package/functions/deno.json +24 -24
  528. package/functions/server.ts +315 -290
  529. package/functions/worker-template.js +15 -4
  530. package/i18n/README.ar.md +130 -0
  531. package/i18n/README.de.md +130 -0
  532. package/i18n/README.es.md +154 -0
  533. package/i18n/README.fr.md +134 -0
  534. package/i18n/README.hi.md +129 -0
  535. package/i18n/README.ja.md +174 -0
  536. package/i18n/README.ko.md +137 -0
  537. package/i18n/README.pt-BR.md +131 -0
  538. package/i18n/README.ru.md +129 -0
  539. package/i18n/README.zh-CN.md +133 -0
  540. package/openapi/ai.yaml +715 -688
  541. package/openapi/auth.yaml +1244 -563
  542. package/openapi/email.yaml +158 -0
  543. package/openapi/functions.yaml +475 -475
  544. package/openapi/health.yaml +29 -29
  545. package/openapi/logs.yaml +223 -223
  546. package/openapi/metadata.yaml +177 -177
  547. package/openapi/realtime.yaml +699 -0
  548. package/openapi/records.yaml +381 -381
  549. package/openapi/secrets.yaml +370 -370
  550. package/openapi/storage.yaml +875 -875
  551. package/openapi/tables.yaml +463 -463
  552. package/package.json +97 -88
  553. package/shared-schemas/package.json +31 -31
  554. package/shared-schemas/src/ai-api.schema.ts +34 -58
  555. package/shared-schemas/src/ai.schema.ts +63 -54
  556. package/shared-schemas/src/auth-api.schema.ts +352 -193
  557. package/shared-schemas/src/auth.schema.ts +43 -7
  558. package/shared-schemas/src/cloud-events.schema.ts +57 -0
  559. package/shared-schemas/src/database-api.schema.ts +35 -4
  560. package/shared-schemas/src/database.schema.ts +40 -1
  561. package/shared-schemas/src/docs.schema.ts +26 -0
  562. package/shared-schemas/src/email-api.schema.ts +30 -0
  563. package/shared-schemas/src/index.ts +5 -0
  564. package/shared-schemas/src/logs-api.schema.ts +7 -1
  565. package/shared-schemas/src/logs.schema.ts +26 -0
  566. package/shared-schemas/src/metadata.schema.ts +18 -4
  567. package/shared-schemas/src/realtime-api.schema.ts +111 -0
  568. package/shared-schemas/src/realtime.schema.ts +143 -0
  569. package/shared-schemas/tsconfig.json +21 -21
  570. package/tsconfig.json +7 -7
  571. package/zeabur/README.md +13 -0
  572. package/zeabur/template.yml +1032 -0
  573. package/.github/workflows/deploy-aws.yml +0 -130
  574. package/backend/src/api/routes/agent.ts +0 -29
  575. package/backend/src/api/routes/auth.oauth.ts +0 -482
  576. package/backend/src/api/routes/auth.ts +0 -386
  577. package/backend/src/api/routes/docs.ts +0 -66
  578. package/backend/src/api/routes/functions.ts +0 -183
  579. package/backend/src/api/routes/openapi.ts +0 -82
  580. package/backend/src/api/routes/usage.ts +0 -96
  581. package/backend/src/core/ai/client.ts +0 -242
  582. package/backend/src/core/ai/model.ts +0 -117
  583. package/backend/src/core/auth/auth.ts +0 -780
  584. package/backend/src/core/database/manager.ts +0 -178
  585. package/backend/src/core/database/table.ts +0 -772
  586. package/backend/src/core/documentation/agent.ts +0 -689
  587. package/backend/src/core/documentation/openapi.ts +0 -856
  588. package/backend/src/core/logs/analytics.ts +0 -76
  589. package/backend/src/core/logs/providers/localdb.provider.ts +0 -246
  590. package/backend/src/core/socket/socket.ts +0 -388
  591. package/backend/src/core/storage/storage.ts +0 -923
  592. package/backend/src/utils/cloud-token.ts +0 -39
  593. package/backend/src/utils/helpers.ts +0 -49
  594. package/backend/src/utils/uuid.ts +0 -9
  595. package/backend/tests/manual/test-better-auth.sh +0 -303
  596. package/docker-init/db/logs.sql +0 -9
  597. package/frontend/README.md +0 -112
  598. package/frontend/src/components/datagrid/index.tsx +0 -20
  599. package/frontend/src/components/layout/CloudLayout.tsx +0 -95
  600. package/frontend/src/features/ai/components/AIConfigDialog.tsx +0 -76
  601. package/frontend/src/features/ai/components/AIConfigForm.tsx +0 -222
  602. package/frontend/src/features/ai/components/fields/ModalityField.tsx +0 -87
  603. package/frontend/src/features/ai/components/fields/ModelSelectionField.tsx +0 -134
  604. package/frontend/src/features/ai/components/fields/SystemPromptField.tsx +0 -33
  605. package/frontend/src/features/ai/page/AIPage.tsx +0 -178
  606. package/frontend/src/features/auth/components/AddOAuthDialog.tsx +0 -106
  607. package/frontend/src/features/auth/components/AuthMethodTab.tsx +0 -238
  608. package/frontend/src/features/auth/components/UsersTab.tsx +0 -114
  609. package/frontend/src/features/auth/page/AuthenticationPage.tsx +0 -169
  610. package/frontend/src/features/dashboard/page/DashboardPage.tsx +0 -194
  611. package/frontend/src/features/database/hooks/UseLinkModal.tsx +0 -78
  612. package/frontend/src/features/functions/components/FunctionViewer.tsx +0 -46
  613. package/frontend/src/features/functions/components/FunctionsContent.tsx +0 -88
  614. package/frontend/src/features/functions/page/FunctionsPage.tsx +0 -28
  615. package/frontend/src/features/login/components/AuthErrorBoundary.tsx +0 -87
  616. package/frontend/src/features/login/components/PrivateRoute.tsx +0 -24
  617. package/frontend/src/features/login/page/CloudLoginPage.tsx +0 -93
  618. package/frontend/src/features/logs/components/AnalyticsLogsTable.tsx +0 -313
  619. package/frontend/src/features/logs/components/LogsTable.tsx +0 -199
  620. package/frontend/src/features/logs/page/AnalyticsLogsPage.tsx +0 -530
  621. package/frontend/src/features/metadata/index.ts +0 -0
  622. package/frontend/src/features/metadata/page/MetadataPage.tsx +0 -136
  623. package/frontend/src/features/onboard/components/CompletionCard.tsx +0 -41
  624. package/frontend/src/features/onboard/components/OnboardButton.tsx +0 -84
  625. package/frontend/src/features/onboard/components/StepContent.tsx +0 -91
  626. package/frontend/src/features/onboard/components/TestConnectionStep.tsx +0 -53
  627. package/frontend/src/features/onboard/components/mcp/McpInstallation.tsx +0 -144
  628. package/frontend/src/features/onboard/page/OnBoardPage.tsx +0 -104
  629. package/frontend/src/features/onboard/types.ts +0 -8
  630. package/frontend/src/features/visualizer/page/VisualizerPage.tsx +0 -127
  631. package/frontend/src/lib/contexts/OnboardStepContext.tsx +0 -68
  632. package/frontend/src/lib/hooks/useOnboardingCompletion.ts +0 -29
  633. /package/backend/src/api/{middleware → middlewares}/error.ts +0 -0
  634. /package/backend/src/api/{middleware → middlewares}/upload.ts +0 -0
  635. /package/frontend/src/{features/metadata → lib}/services/metadata.service.ts +0 -0
@@ -1,42 +1,40 @@
1
- import { useState, useEffect, useCallback } from 'react';
2
- import { useQuery, useQueryClient } from '@tanstack/react-query';
3
- import { Plus } from 'lucide-react';
1
+ import { useState, useEffect, useCallback, useMemo, useRef } from 'react';
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';
6
- import { databaseService } from '@/features/database/services/database.service';
7
- import { useMetadata } from '@/features/metadata/hooks/useMetadata';
8
- import { Button } from '@/components/radix/Button';
9
- import { Alert, AlertDescription } from '@/components/radix/Alert';
5
+ import { useTables } from '@/features/database/hooks/useTables';
6
+ import { useRecords } from '@/features/database/hooks/useRecords';
10
7
  import { TableSidebar } from '@/features/database/components/TableSidebar';
11
8
  import { RecordFormDialog } from '@/features/database/components/RecordFormDialog';
12
9
  import { TableForm } from '@/features/database/components/TableForm';
13
- import { ConfirmDialog } from '@/components/ConfirmDialog';
14
- import { EmptyState } from '@/components/EmptyState';
10
+ import { TablesEmptyState } from '@/features/database/components/TablesEmptyState';
11
+ import { TemplatePreview } from '@/features/database/components/TemplatePreview';
12
+ import { DATABASE_TEMPLATES, DatabaseTemplate } from '@/features/database/templates';
15
13
  import {
14
+ Alert,
15
+ AlertDescription,
16
+ Button,
17
+ ConfirmDialog,
18
+ ConnectCTA,
19
+ EmptyState,
20
+ SearchInput,
21
+ SelectionClearButton,
22
+ DeleteActionButton,
16
23
  Tooltip,
17
24
  TooltipContent,
18
25
  TooltipProvider,
19
26
  TooltipTrigger,
20
- } from '@/components/radix/Tooltip';
27
+ } from '@/components';
21
28
  import { useConfirm } from '@/lib/hooks/useConfirm';
22
29
  import { useToast } from '@/lib/hooks/useToast';
23
30
  import { DatabaseDataGrid } from '@/features/database/components/DatabaseDataGrid';
24
- import { SearchInput, SelectionClearButton, DeleteActionButton } from '@/components';
25
31
  import { SortColumn } from 'react-data-grid';
26
32
  import { convertValueForColumn } from '@/lib/utils/utils';
27
- import { LinkModalProvider, useLinkModal } from '@/features/database/hooks/UseLinkModal';
28
- import { LinkRecordModal } from '@/features/database/components/LinkRecordModal';
29
- import {
30
- DataUpdatePayload,
31
- DataUpdateResourceType,
32
- ServerEvents,
33
- SocketMessage,
34
- useSocket,
35
- } from '@/lib/contexts/SocketContext';
33
+ import { useCSVImport } from '@/features/database/hooks/useCSVImport';
36
34
 
37
35
  const PAGE_SIZE = 50;
38
36
 
39
- function DatabasePageContent() {
37
+ export default function TablesPage() {
40
38
  // Load selected table from localStorage on mount
41
39
  const [selectedTable, setSelectedTable] = useState<string | null>(() => {
42
40
  return localStorage.getItem('selectedTable');
@@ -52,13 +50,26 @@ function DatabasePageContent() {
52
50
  const [currentPage, setCurrentPage] = useState(1);
53
51
  const [isSorting, setIsSorting] = useState(false);
54
52
  const [isRefreshing, setIsRefreshing] = useState(false);
53
+ const [previewingTemplate, setPreviewingTemplate] = useState<DatabaseTemplate | null>(null);
55
54
 
56
55
  const { confirm, confirmDialogProps } = useConfirm();
57
56
  const { showToast } = useToast();
58
- const queryClient = useQueryClient();
59
- const { modalState, closeModal } = useLinkModal();
57
+ const fileInputRef = useRef<HTMLInputElement>(null);
58
+ const { tables, isLoadingTables, tablesError, deleteTable, useTableSchema, refetchTables } =
59
+ useTables();
60
+
61
+ const recordsHook = useRecords(selectedTable || '');
60
62
 
61
- const { socket, isConnected } = useSocket();
63
+ const handleFileSelect = (event: React.ChangeEvent<HTMLInputElement>) => {
64
+ const file = event.target.files?.[0];
65
+ if (file && selectedTable) {
66
+ importCSV(file);
67
+ }
68
+ // Reset file input to allow re-uploading the same file
69
+ if (event.target) {
70
+ event.target.value = '';
71
+ }
72
+ };
62
73
 
63
74
  // Persist selected table to localStorage when it changes
64
75
  useEffect(() => {
@@ -96,96 +107,71 @@ function DatabasePageContent() {
96
107
  [showToast]
97
108
  );
98
109
 
99
- // Fetch metadata
100
- const { tables, isLoading, error: metadataError, refetch: refetchMetadata } = useMetadata();
110
+ // Fetch schema for selected table
111
+ const { data: schemaData } = useTableSchema(selectedTable || '', !!selectedTable);
101
112
 
102
- // Fetch table data when selected
103
- const {
104
- data: tableData,
105
- isLoading: isLoadingTable,
106
- error: tableError,
107
- refetch: refetchTableData,
108
- } = useQuery({
109
- queryKey: [
110
- 'table',
111
- selectedTable,
112
- currentPage,
113
- PAGE_SIZE,
114
- searchQuery,
115
- JSON.stringify(sortColumns),
116
- ],
117
- queryFn: async () => {
118
- if (!selectedTable) {
119
- return null;
120
- }
113
+ // Fetch schema for editing table
114
+ const { data: editingTableSchema } = useTableSchema(editingTable || '', !!editingTable);
121
115
 
122
- const offset = (currentPage - 1) * PAGE_SIZE;
116
+ const primaryKeyColumn = useMemo(() => {
117
+ return schemaData?.columns.find((col) => col.isPrimaryKey)?.columnName;
118
+ }, [schemaData]);
123
119
 
124
- try {
125
- const [schema, records] = await Promise.all([
126
- databaseService.getTableSchema(selectedTable),
127
- databaseService.getTableRecords(
128
- selectedTable,
129
- PAGE_SIZE,
130
- offset,
131
- searchQuery,
132
- sortColumns
133
- ),
134
- ]);
135
-
136
- return {
137
- name: selectedTable,
138
- schema,
139
- records: records.records,
140
- totalRecords: records.pagination.total ?? schema.recordCount,
141
- };
142
- } catch (error) {
143
- // If sorting caused the error, retry without sorting
144
- if (sortColumns && sortColumns.length > 0) {
145
- setSortColumns([]);
146
-
147
- const [schema, records] = await Promise.all([
148
- databaseService.getTableSchema(selectedTable),
149
- databaseService.getTableRecords(selectedTable, PAGE_SIZE, offset, searchQuery, []),
150
- ]);
151
-
152
- showToast('Sorting not supported for this table. Showing unsorted results.', 'info');
153
-
154
- return {
155
- name: selectedTable,
156
- schema,
157
- records: records.records,
158
- totalRecords: records.pagination.total || schema.recordCount,
159
- };
160
- }
161
- throw error;
120
+ const {
121
+ mutate: importCSV,
122
+ isPending: isImporting,
123
+ reset: resetImport,
124
+ } = useCSVImport(selectedTable || '', {
125
+ onSuccess: (data) => {
126
+ if (data.success) {
127
+ showToast(data.message || 'Import successful!', 'success');
128
+ void refetchTableData();
129
+ } else {
130
+ // This case handles validation errors returned with a 200 OK but success: false
131
+ const errorMessage =
132
+ data.message || 'CSV import failed due to validation errors. Please check the file.';
133
+ showToast(errorMessage, 'error');
162
134
  }
135
+ resetImport();
136
+ },
137
+ onError: (error: Error) => {
138
+ // This handles 400/500 errors from the API client
139
+ const message =
140
+ error?.message || 'An unexpected error occurred during import. Please try again.';
141
+ showToast(message, 'error');
142
+ resetImport();
163
143
  },
164
- enabled: !!selectedTable,
165
- placeholderData: (previousData) => previousData, // Keep previous data while loading new sorted data
166
144
  });
167
145
 
168
- useEffect(() => {
169
- if (!socket || !isConnected) {
170
- return;
171
- }
172
-
173
- const handleDataUpdate = (message: SocketMessage<DataUpdatePayload>) => {
174
- if (
175
- message.payload?.resource === DataUpdateResourceType.METADATA ||
176
- message.payload?.resource === DataUpdateResourceType.DATABASE_SCHEMA
177
- ) {
178
- // Invalidate all tables queries
179
- void queryClient.invalidateQueries({ queryKey: ['tables'] });
180
- }
181
- };
146
+ // Fetch table records using the hook
147
+ const offset = (currentPage - 1) * PAGE_SIZE;
148
+ const {
149
+ data: recordsData,
150
+ isLoading: isLoadingRecords,
151
+ error: recordsError,
152
+ refetch: refetchRecords,
153
+ } = recordsHook.useTableRecords(
154
+ PAGE_SIZE,
155
+ offset,
156
+ searchQuery,
157
+ sortColumns,
158
+ !!selectedTable && !!schemaData
159
+ );
182
160
 
183
- socket.on(ServerEvents.DATA_UPDATE, handleDataUpdate);
161
+ // Combine schema and records data
162
+ const tableData =
163
+ selectedTable && schemaData && recordsData
164
+ ? {
165
+ name: selectedTable,
166
+ schema: schemaData,
167
+ records: recordsData.records,
168
+ totalRecords: recordsData.pagination.total ?? schemaData.recordCount,
169
+ }
170
+ : null;
184
171
 
185
- return () => {
186
- socket.off(ServerEvents.DATA_UPDATE, handleDataUpdate);
187
- };
188
- }, [socket, isConnected, queryClient]);
172
+ const isLoadingTable = isLoadingRecords;
173
+ const tableError = recordsError;
174
+ const refetchTableData = refetchRecords;
189
175
 
190
176
  // Reset sorting flag when loading completes
191
177
  useEffect(() => {
@@ -196,7 +182,7 @@ function DatabasePageContent() {
196
182
 
197
183
  // Auto-select first table (excluding system tables)
198
184
  useEffect(() => {
199
- if (!isLoading && tables) {
185
+ if (!isLoadingTables && tables) {
200
186
  if (pendingTableSelection && tables.includes(pendingTableSelection)) {
201
187
  setSelectedTable(pendingTableSelection);
202
188
  setPendingTableSelection(undefined);
@@ -208,11 +194,11 @@ function DatabasePageContent() {
208
194
  return;
209
195
  }
210
196
 
211
- if (!selectedTable && tables.length > 0 && !showTableForm && !pendingTableSelection) {
197
+ if (!selectedTable && tables.length && !showTableForm && !pendingTableSelection) {
212
198
  setSelectedTable(tables[0]);
213
199
  }
214
200
  }
215
- }, [tables, pendingTableSelection, selectedTable, showTableForm, isLoading]);
201
+ }, [tables, pendingTableSelection, selectedTable, showTableForm, isLoadingTables]);
216
202
 
217
203
  const handleRefresh = async () => {
218
204
  setIsRefreshing(true);
@@ -227,7 +213,7 @@ function DatabasePageContent() {
227
213
  if (selectedTable) {
228
214
  await refetchTableData();
229
215
  }
230
- await refetchMetadata();
216
+ await refetchTables();
231
217
  } finally {
232
218
  setIsRefreshing(false);
233
219
  }
@@ -291,28 +277,23 @@ function DatabasePageContent() {
291
277
  const shouldDelete = await confirm(confirmOptions);
292
278
 
293
279
  if (shouldDelete) {
294
- try {
295
- // Update selectedTable BEFORE deleting to prevent queries on deleted table
296
- if (selectedTable === tableName) {
297
- setSelectedTable(null);
298
- }
299
-
300
- await databaseService.deleteTable(tableName);
301
- showToast('Table deleted successfully', 'success');
302
-
303
- // Invalidate all related queries for the deleted table
304
- void queryClient.invalidateQueries({ queryKey: ['metadata'] });
305
- void queryClient.invalidateQueries({ queryKey: ['tables'] });
306
- void queryClient.invalidateQueries({ queryKey: ['table', tableName] });
307
- void queryClient.invalidateQueries({ queryKey: ['table-schema', tableName] });
308
- void queryClient.invalidateQueries({ queryKey: ['metadata'] });
309
- } catch (error) {
310
- const errorMessage = error instanceof Error ? error.message : 'Failed to delete table';
311
- showToast(errorMessage, 'error');
280
+ // Update selectedTable BEFORE deleting to prevent queries on deleted table
281
+ if (selectedTable === tableName) {
282
+ setSelectedTable(null);
312
283
  }
284
+
285
+ deleteTable(tableName);
313
286
  }
314
287
  };
315
288
 
289
+ const handleTemplateClick = (template: DatabaseTemplate) => {
290
+ setPreviewingTemplate(template);
291
+ };
292
+
293
+ const handleCancelPreview = () => {
294
+ setPreviewingTemplate(null);
295
+ };
296
+
316
297
  // Handle record update
317
298
  const handleRecordUpdate = async (rowId: string, columnKey: string, newValue: string) => {
318
299
  if (!selectedTable) {
@@ -331,9 +312,11 @@ function DatabasePageContent() {
331
312
  return;
332
313
  }
333
314
  const updates = { [columnKey]: conversionResult.value };
334
- await databaseService.updateRecord(selectedTable, rowId, updates);
335
- await refetchTableData();
336
- showToast('Record updated successfully', 'success');
315
+ await recordsHook.updateRecord({
316
+ pkColumn: primaryKeyColumn || 'id',
317
+ pkValue: rowId,
318
+ data: updates,
319
+ });
337
320
  }
338
321
  } catch (error) {
339
322
  showToast('Failed to update record', 'error');
@@ -343,7 +326,7 @@ function DatabasePageContent() {
343
326
 
344
327
  // Handle bulk delete
345
328
  const handleBulkDelete = async (ids: string[]) => {
346
- if (!selectedTable || ids.length === 0) {
329
+ if (!selectedTable || !ids.length) {
347
330
  return;
348
331
  }
349
332
 
@@ -355,51 +338,25 @@ function DatabasePageContent() {
355
338
  });
356
339
 
357
340
  if (shouldDelete) {
358
- try {
359
- await Promise.all(ids.map((id) => databaseService.deleteRecord(selectedTable, id)));
360
- await Promise.all([
361
- refetchTableData(),
362
- refetchMetadata(), // Also refresh metadata to update sidebar record counts
363
- ]);
364
- setSelectedRows(new Set());
365
- showToast(`${ids.length} records deleted successfully`, 'success');
366
- } catch {
367
- showToast('Failed to delete some records', 'error');
368
- }
341
+ await recordsHook.deleteRecords({ pkColumn: primaryKeyColumn || 'id', pkValues: ids });
342
+ // Query invalidation is handled by the mutation, no manual refetch needed
343
+ setSelectedRows(new Set());
369
344
  }
370
345
  };
371
346
 
372
- const error = metadataError || tableError;
373
-
374
- // Fetch schema for selected table
375
- const { data: schemaData } = useQuery({
376
- queryKey: ['table-schema', selectedTable],
377
- queryFn: async () => {
378
- if (!selectedTable) {
379
- return undefined;
380
- }
381
- return await databaseService.getTableSchema(selectedTable);
382
- },
383
- enabled: !!selectedTable,
384
- staleTime: 30 * 1000, // 30 seconds
385
- });
386
-
387
- // Fetch schema for editing table
388
- const { data: editingTableSchema } = useQuery({
389
- queryKey: ['table-schema', editingTable],
390
- queryFn: async () => {
391
- if (!editingTable) {
392
- return undefined;
393
- }
394
- const editingTableSchema = await databaseService.getTableSchema(editingTable);
395
- return editingTableSchema;
396
- },
397
- enabled: !!editingTable,
398
- });
347
+ const error = tablesError || tableError;
399
348
 
400
349
  // Calculate pagination
401
350
  const totalPages = Math.ceil((tableData?.totalRecords || 0) / PAGE_SIZE);
402
351
 
352
+ // Show empty state when there are no tables and not loading
353
+ const showEmptyState = !isLoadingTables && tables?.length === 0 && !showTableForm;
354
+
355
+ // Show template preview - takes full width without sidebar
356
+ if (previewingTemplate) {
357
+ return <TemplatePreview template={previewingTemplate} onCancel={handleCancelPreview} />;
358
+ }
359
+
403
360
  return (
404
361
  <div className="flex h-full bg-bg-gray dark:bg-neutral-800">
405
362
  {/* Secondary Sidebar - Table List */}
@@ -407,7 +364,7 @@ function DatabasePageContent() {
407
364
  tables={tables}
408
365
  selectedTable={selectedTable || undefined}
409
366
  onTableSelect={handleSelectTable}
410
- loading={isLoading}
367
+ loading={isLoadingTables}
411
368
  onNewTable={handleCreateTable}
412
369
  onEditTable={handleEditTable}
413
370
  onDeleteTable={(tableName) => void handleDeleteTable(tableName)}
@@ -428,7 +385,7 @@ function DatabasePageContent() {
428
385
  editTable={editingTable ? editingTableSchema : undefined}
429
386
  setFormIsDirty={setIsTableFormDirty}
430
387
  onSuccess={(newTableName?: string) => {
431
- void refetchMetadata();
388
+ void refetchTables();
432
389
  void refetchTableData();
433
390
  setShowTableForm(false);
434
391
  setPendingTableSelection(newTableName);
@@ -469,7 +426,6 @@ function DatabasePageContent() {
469
426
  <p>Edit Table</p>
470
427
  </TooltipContent>
471
428
  </Tooltip>
472
-
473
429
  <Tooltip>
474
430
  <TooltipTrigger asChild>
475
431
  <Button
@@ -503,11 +459,13 @@ function DatabasePageContent() {
503
459
  itemType="record"
504
460
  onClear={() => setSelectedRows(new Set())}
505
461
  />
506
- <DeleteActionButton
507
- selectedCount={selectedRows.size}
508
- itemType="record"
509
- onDelete={() => void handleBulkDelete(Array.from(selectedRows))}
510
- />
462
+ {
463
+ <DeleteActionButton
464
+ selectedCount={selectedRows.size}
465
+ itemType="record"
466
+ onDelete={() => void handleBulkDelete(Array.from(selectedRows))}
467
+ />
468
+ }
511
469
  </div>
512
470
  ) : (
513
471
  <SearchInput
@@ -519,8 +477,18 @@ function DatabasePageContent() {
519
477
  />
520
478
  )}
521
479
  <div className="flex items-center gap-2 ml-4">
522
- {selectedRows.size === 0 && selectedTable !== 'users' && (
480
+ {selectedRows.size === 0 && (
523
481
  <>
482
+ {/* Import CSV Button */}
483
+ <Button
484
+ variant="secondary"
485
+ className="h-10 px-4 font-medium gap-1.5 border border-zinc-200 dark:border-neutral-600"
486
+ onClick={() => fileInputRef.current?.click()}
487
+ disabled={isImporting}
488
+ >
489
+ <Upload className="w-5 h-5" />
490
+ {isImporting ? 'Importing...' : 'Import CSV'}
491
+ </Button>
524
492
  {/* Add Record Button */}
525
493
  <Button
526
494
  className="h-10 px-4 font-medium gap-1.5 dark:bg-emerald-300 dark:hover:bg-emerald-400"
@@ -546,7 +514,13 @@ function DatabasePageContent() {
546
514
  </Alert>
547
515
  )}
548
516
 
549
- {!selectedTable ? (
517
+ {showEmptyState ? (
518
+ <TablesEmptyState
519
+ templates={DATABASE_TEMPLATES}
520
+ onCreateTable={handleCreateTable}
521
+ onTemplateClick={handleTemplateClick}
522
+ />
523
+ ) : !selectedTable ? (
550
524
  <div className="flex-1 flex items-center justify-center">
551
525
  <EmptyState
552
526
  title="No Table Selected"
@@ -560,18 +534,24 @@ function DatabasePageContent() {
560
534
  loading={isLoadingTable && !tableData}
561
535
  isSorting={isSorting}
562
536
  isRefreshing={isRefreshing}
537
+ rowKeyGetter={(row) => String(row[primaryKeyColumn || 'id'])}
563
538
  selectedRows={selectedRows}
564
539
  onSelectedRowsChange={setSelectedRows}
565
540
  sortColumns={sortColumns}
566
541
  onSortColumnsChange={handleSortColumnsChange}
567
542
  onCellEdit={handleRecordUpdate}
568
543
  onJumpToTable={setSelectedTable}
569
- searchQuery={searchQuery}
570
544
  currentPage={currentPage}
571
545
  totalPages={totalPages}
572
546
  pageSize={PAGE_SIZE}
573
547
  totalRecords={tableData?.totalRecords || 0}
574
548
  onPageChange={setCurrentPage}
549
+ emptyState={
550
+ <div className="text-sm text-black dark:text-white">
551
+ {searchQuery ? 'No records match your search criteria' : 'No records found'}.{' '}
552
+ <ConnectCTA />
553
+ </div>
554
+ }
575
555
  />
576
556
  )}
577
557
  </div>
@@ -579,6 +559,14 @@ function DatabasePageContent() {
579
559
  )}
580
560
  </div>
581
561
 
562
+ <input
563
+ type="file"
564
+ ref={fileInputRef}
565
+ onChange={handleFileSelect}
566
+ accept=".csv,text/csv"
567
+ style={{ display: 'none' }}
568
+ />
569
+
582
570
  {/* Add Record Form */}
583
571
  {selectedTable && schemaData && (
584
572
  // In the RecordForm onSuccess callback
@@ -587,40 +575,11 @@ function DatabasePageContent() {
587
575
  onOpenChange={setShowRecordForm}
588
576
  tableName={selectedTable}
589
577
  schema={schemaData.columns}
590
- onSuccess={() => {
591
- void refetchTableData();
592
- void refetchMetadata();
593
- // Also invalidate the schema cache to ensure fresh data
594
- void queryClient.invalidateQueries({ queryKey: ['table-schema', selectedTable] });
595
- }}
596
578
  />
597
579
  )}
598
580
 
599
581
  {/* Confirm Dialog */}
600
582
  <ConfirmDialog {...confirmDialogProps} />
601
-
602
- {/* Global Link Record Modal */}
603
- {modalState.isOpen && modalState.referenceTable && modalState.referenceColumn && (
604
- <LinkRecordModal
605
- open={modalState.isOpen}
606
- onOpenChange={closeModal}
607
- referenceTable={modalState.referenceTable}
608
- referenceColumn={modalState.referenceColumn}
609
- currentValue={modalState.currentValue}
610
- onSelectRecord={(record) => {
611
- modalState.onSelectRecord?.(record);
612
- closeModal();
613
- }}
614
- />
615
- )}
616
583
  </div>
617
584
  );
618
585
  }
619
-
620
- export default function DatabasePage() {
621
- return (
622
- <LinkModalProvider>
623
- <DatabasePageContent />
624
- </LinkModalProvider>
625
- );
626
- }
@@ -0,0 +1,39 @@
1
+ import { useNavigate } from 'react-router-dom';
2
+ import { DATABASE_TEMPLATES, type DatabaseTemplate } from '@/features/database/templates';
3
+ import { useSQLEditorContext } from '@/features/database/contexts/SQLEditorContext';
4
+ import { TemplateCard } from '@/features/database/components/TemplateCard';
5
+
6
+ export default function TemplatesPage() {
7
+ const navigate = useNavigate();
8
+ const { addTab } = useSQLEditorContext();
9
+
10
+ const handleTemplateClick = (template: DatabaseTemplate) => {
11
+ // Create a new tab with the template's SQL query prefilled
12
+ addTab(template.sql, template.title);
13
+ // Navigate to the SQL Editor page
14
+ void navigate('/dashboard/database/sql-editor');
15
+ };
16
+
17
+ return (
18
+ <div className="flex flex-col h-full items-center bg-bg-gray dark:bg-neutral-800 overflow-auto">
19
+ {/* Main Content - Centered */}
20
+ <div className="flex flex-col max-w-[1024px] justify-center px-6 pb-6">
21
+ {/* Header */}
22
+ <div className="flex items-center justify-start gap-3 h-[72px] bg-bg-gray dark:bg-neutral-800 flex-shrink-0">
23
+ <h1 className="text-xl font-semibold text-zinc-950 dark:text-white">Database Template</h1>
24
+ </div>
25
+ <div className="w-full max-w-[1024px]">
26
+ <div className="grid grid-cols-2 xl:grid-cols-3 gap-6">
27
+ {DATABASE_TEMPLATES.map((template) => (
28
+ <TemplateCard
29
+ key={template.id}
30
+ template={template}
31
+ onClick={() => handleTemplateClick(template)}
32
+ />
33
+ ))}
34
+ </div>
35
+ </div>
36
+ </div>
37
+ </div>
38
+ );
39
+ }