insforge 0.3.2 → 1.2.10

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 (507) hide show
  1. package/.claude-plugin/marketplace.json +20 -0
  2. package/.cursor/rules/cursor-rules.mdc +94 -0
  3. package/.dockerignore +3 -0
  4. package/.env.example +33 -4
  5. package/.github/ISSUE_TEMPLATE/bug_report.yml +13 -60
  6. package/.github/ISSUE_TEMPLATE/config.yml +2 -2
  7. package/.github/ISSUE_TEMPLATE/feature_request.yml +10 -63
  8. package/.github/PULL_REQUEST_TEMPLATE.md +7 -0
  9. package/.github/workflows/build-image.yml +2 -1
  10. package/.github/workflows/e2e.yml +63 -0
  11. package/CHANGELOG.md +41 -0
  12. package/CLAUDE_PLUGIN.md +104 -0
  13. package/CODE_OF_CONDUCT.md +128 -0
  14. package/CONTRIBUTING.md +1 -1
  15. package/Dockerfile +4 -1
  16. package/README.md +66 -18
  17. package/assets/mcpInstallv2.png +0 -0
  18. package/assets/sampleResponse.png +0 -0
  19. package/auth/index.html +13 -0
  20. package/auth/package.json +28 -0
  21. package/auth/public/favicon.ico +0 -0
  22. package/auth/src/App.tsx +33 -0
  23. package/auth/src/components/ErrorCard.tsx +37 -0
  24. package/auth/src/components/Layout.tsx +13 -0
  25. package/auth/src/index.css +19 -0
  26. package/auth/src/lib/broadcastService.ts +115 -0
  27. package/auth/src/lib/utils.ts +11 -0
  28. package/auth/src/main.tsx +22 -0
  29. package/auth/src/pages/ForgotPasswordPage.tsx +11 -0
  30. package/auth/src/pages/ResetPasswordPage.tsx +11 -0
  31. package/auth/src/pages/SignInPage.tsx +57 -0
  32. package/auth/src/pages/SignUpPage.tsx +57 -0
  33. package/auth/src/pages/VerifyEmailPage.tsx +20 -0
  34. package/auth/src/vite-env.d.ts +10 -0
  35. package/auth/tsconfig.json +32 -0
  36. package/auth/tsconfig.node.json +11 -0
  37. package/auth/vite.config.ts +25 -0
  38. package/backend/package.json +9 -9
  39. package/backend/src/api/{middleware → middlewares}/auth.ts +8 -9
  40. package/backend/src/api/middlewares/rate-limiters.ts +127 -0
  41. package/backend/src/api/routes/{ai.ts → ai/index.routes.ts} +20 -24
  42. package/backend/src/api/routes/auth/index.routes.ts +570 -0
  43. package/backend/src/api/routes/auth/oauth.routes.ts +448 -0
  44. package/backend/src/api/routes/{database.advance.ts → database/advance.routes.ts} +107 -65
  45. package/backend/src/api/routes/database/index.routes.ts +13 -0
  46. package/backend/src/api/routes/{database.records.ts → database/records.routes.ts} +22 -8
  47. package/backend/src/api/routes/{database.tables.ts → database/tables.routes.ts} +20 -23
  48. package/backend/src/api/routes/docs/index.routes.ts +76 -0
  49. package/backend/src/api/routes/functions/index.routes.ts +188 -0
  50. package/backend/src/api/routes/{logs.ts → logs/index.routes.ts} +25 -30
  51. package/backend/src/api/routes/{metadata.ts → metadata/index.routes.ts} +21 -31
  52. package/backend/src/api/routes/{secrets.ts → secrets/index.routes.ts} +27 -22
  53. package/backend/src/api/routes/{storage.ts → storage/index.routes.ts} +34 -53
  54. package/backend/src/api/routes/usage/index.routes.ts +89 -0
  55. package/backend/src/infra/config/app.config.ts +51 -0
  56. package/backend/src/{core/database/manager.ts → infra/database/database.manager.ts} +76 -85
  57. package/backend/src/infra/database/migrations/013_create-auth-schema-functions.sql +44 -0
  58. package/backend/src/infra/database/migrations/014_add-updated-at-trigger-user-table.sql +8 -0
  59. package/backend/src/infra/database/migrations/015_create-auth-config-and-email-otp-tables.sql +60 -0
  60. package/backend/src/infra/database/migrations/016_update-auth-config-and-email-otp.sql +24 -0
  61. package/backend/src/{core/secrets/encryption.ts → infra/security/encryption.manager.ts} +3 -2
  62. package/backend/src/infra/security/token.manager.ts +125 -0
  63. package/backend/src/{core/socket/socket.ts → infra/socket/socket.manager.ts} +15 -15
  64. package/backend/src/providers/ai/openrouter.provider.ts +377 -0
  65. package/backend/src/providers/email/base.provider.ts +41 -0
  66. package/backend/src/providers/email/cloud.provider.ts +187 -0
  67. package/backend/src/{core/logs/providers → providers/logs}/base.provider.ts +11 -11
  68. package/backend/src/{core/logs/providers → providers/logs}/cloudwatch.provider.ts +61 -38
  69. package/backend/src/providers/logs/local.provider.ts +185 -0
  70. package/backend/src/providers/oauth/base.provider.ts +29 -0
  71. package/backend/src/providers/oauth/discord.provider.ts +195 -0
  72. package/backend/src/providers/oauth/facebook.provider.ts +194 -0
  73. package/backend/src/providers/oauth/github.provider.ts +208 -0
  74. package/backend/src/providers/oauth/google.provider.ts +249 -0
  75. package/backend/src/providers/oauth/index.ts +7 -0
  76. package/backend/src/providers/oauth/linkedin.provider.ts +240 -0
  77. package/backend/src/providers/oauth/microsoft.provider.ts +169 -0
  78. package/backend/src/providers/oauth/x.provider.ts +202 -0
  79. package/backend/src/providers/storage/base.provider.ts +29 -0
  80. package/backend/src/providers/storage/local.provider.ts +103 -0
  81. package/backend/src/providers/storage/s3.provider.ts +313 -0
  82. package/backend/src/server.ts +70 -74
  83. package/backend/src/{core/ai/config.ts → services/ai/ai-config.service.ts} +19 -24
  84. package/backend/src/services/ai/ai-model.service.ts +60 -0
  85. package/backend/src/{core/ai/usage.ts → services/ai/ai-usage.service.ts} +28 -35
  86. package/backend/src/{core/ai/chat.ts → services/ai/chat-completion.service.ts} +37 -24
  87. package/backend/src/services/ai/helpers.ts +64 -0
  88. package/backend/src/{core/ai/image.ts → services/ai/image-generation.service.ts} +17 -19
  89. package/backend/src/services/ai/index.ts +13 -0
  90. package/backend/src/services/auth/auth-config.service.ts +250 -0
  91. package/backend/src/services/auth/auth-otp.service.ts +424 -0
  92. package/backend/src/services/auth/auth.service.ts +1136 -0
  93. package/backend/src/services/auth/index.ts +4 -0
  94. package/backend/src/{core/auth/oauth.ts → services/auth/oauth-config.service.ts} +106 -52
  95. package/backend/src/{core/database/advance.ts → services/database/database-advance.service.ts} +97 -131
  96. package/backend/src/services/database/database-table.service.ts +811 -0
  97. package/backend/src/services/email/email.service.ts +75 -0
  98. package/backend/src/{core/functions/functions.ts → services/functions/function.service.ts} +95 -88
  99. package/backend/src/{core/logs/audit.ts → services/logs/audit.service.ts} +92 -75
  100. package/backend/src/services/logs/log.service.ts +73 -0
  101. package/backend/src/{core/secrets/secrets.ts → services/secrets/secret.service.ts} +48 -66
  102. package/backend/src/services/storage/storage.service.ts +617 -0
  103. package/backend/src/services/usage/usage.service.ts +149 -0
  104. package/backend/src/types/auth.ts +66 -2
  105. package/backend/src/types/email.ts +8 -0
  106. package/backend/src/types/error-constants.ts +4 -0
  107. package/backend/src/types/logs.ts +0 -29
  108. package/backend/src/{core/socket/types.ts → types/socket.ts} +5 -6
  109. package/backend/src/utils/environment.ts +9 -3
  110. package/backend/src/utils/logger.ts +20 -2
  111. package/backend/src/utils/seed.ts +150 -57
  112. package/backend/src/utils/sql-parser.ts +1 -1
  113. package/backend/src/utils/utils.ts +114 -0
  114. package/backend/src/utils/validations.ts +40 -4
  115. package/backend/tests/local/test-ai-config.sh +129 -0
  116. package/backend/tests/local/test-ai-usage.sh +80 -0
  117. package/backend/tests/local/test-auth-router.sh +1 -1
  118. package/backend/tests/local/test-e2e.sh +1 -1
  119. package/backend/tests/local/test-functions.sh +123 -0
  120. package/backend/tests/local/test-logs.sh +132 -0
  121. package/backend/tests/local/test-public-bucket.sh +3 -3
  122. package/backend/tests/local/test-secrets.sh +14 -12
  123. package/backend/tests/local/test-traditional-rest.sh +2 -2
  124. package/backend/tests/manual/test-rawsql-modes.sh +244 -0
  125. package/backend/tests/test-config.sh +37 -1
  126. package/backend/tests/unit/cloud-token.test.ts +48 -0
  127. package/backend/tests/unit/constant.test.ts +8 -0
  128. package/backend/tests/unit/email.test.ts +372 -0
  129. package/backend/tests/unit/environment.test.ts +59 -0
  130. package/backend/tests/unit/helpers.test.ts +63 -0
  131. package/backend/tests/unit/logger.test.ts +22 -0
  132. package/backend/tests/unit/rate-limit.test.ts +154 -0
  133. package/backend/tests/unit/response.test.ts +58 -0
  134. package/backend/tests/unit/sql-parser.test.ts +74 -0
  135. package/backend/tests/unit/uuid.test.ts +21 -0
  136. package/backend/tests/unit/validations.test.ts +80 -0
  137. package/backend/tsconfig.json +1 -1
  138. package/backend/vitest.config.ts +11 -0
  139. package/claude-plugin/.claude-plugin/plugin.json +24 -0
  140. package/claude-plugin/README.md +133 -0
  141. package/claude-plugin/skills/insforge-schema-patterns/SKILL.md +270 -0
  142. package/docker-compose.prod.yml +60 -4
  143. package/docker-compose.yml +65 -4
  144. package/docker-init/db/db-init.sql +6 -34
  145. package/docker-init/logs/vector.yml +236 -0
  146. package/docs/README.md +44 -0
  147. package/docs/changelog.mdx +67 -0
  148. package/docs/core-concepts/ai/architecture.mdx +373 -0
  149. package/docs/core-concepts/ai/sdk.mdx +213 -0
  150. package/docs/core-concepts/authentication/architecture.mdx +278 -0
  151. package/docs/core-concepts/authentication/sdk.mdx +414 -0
  152. package/docs/core-concepts/authentication/ui-components/customization.mdx +529 -0
  153. package/docs/core-concepts/authentication/ui-components/nextjs.mdx +221 -0
  154. package/docs/core-concepts/authentication/ui-components/react-router.mdx +184 -0
  155. package/docs/core-concepts/authentication/ui-components/react.mdx +129 -0
  156. package/docs/core-concepts/database/architecture.mdx +256 -0
  157. package/docs/core-concepts/database/sdk.mdx +382 -0
  158. package/docs/core-concepts/functions/architecture.mdx +105 -0
  159. package/docs/core-concepts/functions/sdk.mdx +184 -0
  160. package/docs/core-concepts/storage/architecture.mdx +243 -0
  161. package/docs/core-concepts/storage/sdk.mdx +253 -0
  162. package/docs/deployment/README.md +94 -0
  163. package/docs/deployment/deploy-to-aws-ec2.md +565 -0
  164. package/docs/deployment/deploy-to-azure-virtual-machines.md +313 -0
  165. package/docs/deployment/deploy-to-google-cloud-compute-engine.md +613 -0
  166. package/docs/deployment/deploy-to-render.md +441 -0
  167. package/docs/docs.json +210 -0
  168. package/docs/examples/framework-guides/nextjs.mdx +131 -0
  169. package/docs/examples/framework-guides/nuxt.mdx +165 -0
  170. package/docs/examples/framework-guides/react.mdx +165 -0
  171. package/docs/examples/framework-guides/svelte.mdx +153 -0
  172. package/docs/examples/framework-guides/vue.mdx +159 -0
  173. package/docs/examples/overview.mdx +67 -0
  174. package/docs/favicon.svg +19 -0
  175. package/docs/images/changelog/nov-2025/auth-components.webp +0 -0
  176. package/docs/images/changelog/nov-2025/database-metadata.webp +0 -0
  177. package/docs/images/changelog/nov-2025/quickstart-prompts.webp +0 -0
  178. package/docs/images/changelog/nov-2025/sql-editor.webp +0 -0
  179. package/docs/images/changelog/nov-2025/usage-page.webp +0 -0
  180. package/docs/images/changelog/october-2025/csv-upload.webp +0 -0
  181. package/docs/images/changelog/october-2025/logs-feature.webp +0 -0
  182. package/docs/images/changelog/october-2025/oauth-providers.webp +0 -0
  183. package/docs/images/checks-passed.png +0 -0
  184. package/docs/images/dashboard-connect-expanded.png +0 -0
  185. package/docs/images/dashboard-connect.png +0 -0
  186. package/docs/images/hero-dark.png +0 -0
  187. package/docs/images/hero-light.png +0 -0
  188. package/docs/images/icons/ai.svg +4 -0
  189. package/docs/images/icons/auth.svg +1 -0
  190. package/docs/images/icons/database.svg +1 -0
  191. package/docs/images/icons/function.svg +1 -0
  192. package/docs/images/icons/storage.svg +1 -0
  193. package/docs/images/logos/nextjs.svg +4 -0
  194. package/docs/images/logos/nuxt.svg +4 -0
  195. package/docs/images/logos/react.svg +5 -0
  196. package/docs/images/logos/svelte.svg +4 -0
  197. package/docs/images/logos/vue.svg +5 -0
  198. package/docs/images/mcp-install.png +0 -0
  199. package/docs/images/onboarding-mcp.png +0 -0
  200. package/docs/insforge-instructions-sdk.md +55 -374
  201. package/docs/introduction.mdx +45 -0
  202. package/docs/logo/dark.svg +22 -0
  203. package/docs/logo/light.svg +20 -0
  204. package/docs/partnership.mdx +647 -0
  205. package/docs/quickstart.mdx +83 -0
  206. package/docs/showcase/2048-arena.png +0 -0
  207. package/docs/showcase/framegen-cloud.png +0 -0
  208. package/docs/showcase/line-connect-race.png +0 -0
  209. package/docs/showcase/moment-vibe.png +0 -0
  210. package/docs/showcase/national-flags.png +0 -0
  211. package/docs/showcase/pokemon-vibe.png +0 -0
  212. package/docs/showcase/pure-browse-buy.png +0 -0
  213. package/docs/showcase.mdx +52 -0
  214. package/docs/snippets/sdk-installation.mdx +22 -0
  215. package/docs/snippets/service-icons.mdx +27 -0
  216. package/eslint.config.js +10 -3
  217. package/frontend/package.json +10 -4
  218. package/frontend/src/App.tsx +13 -82
  219. package/frontend/src/assets/icons/connected.svg +3 -0
  220. package/frontend/src/assets/icons/loader.svg +9 -0
  221. package/frontend/src/assets/logos/apple.svg +4 -0
  222. package/frontend/src/assets/logos/discord.svg +1 -1
  223. package/frontend/src/assets/logos/facebook.svg +3 -0
  224. package/frontend/src/assets/logos/instagram.svg +2 -0
  225. package/frontend/src/assets/logos/linkedin.svg +3 -0
  226. package/frontend/src/assets/logos/microsoft.svg +1 -0
  227. package/frontend/src/assets/logos/spotify.svg +17 -0
  228. package/frontend/src/assets/logos/tiktok.svg +6 -0
  229. package/frontend/src/assets/logos/x.svg +3 -0
  230. package/frontend/src/components/Checkbox.tsx +27 -29
  231. package/frontend/src/components/CodeBlock.tsx +55 -2
  232. package/frontend/src/components/CodeEditor.tsx +92 -0
  233. package/frontend/src/components/ConfirmDialog.tsx +1 -1
  234. package/frontend/src/components/ConnectCTA.tsx +38 -0
  235. package/frontend/src/components/CopyButton.tsx +52 -15
  236. package/frontend/src/components/ErrorState.tsx +1 -2
  237. package/frontend/src/components/FeatureSidebar.tsx +6 -6
  238. package/frontend/src/components/FeatureSidebarItem.tsx +2 -2
  239. package/frontend/src/components/JsonHighlight.tsx +21 -9
  240. package/frontend/src/components/ProjectInfoModal.tsx +128 -0
  241. package/frontend/src/components/PromptDialog.tsx +1 -4
  242. package/frontend/src/components/SearchInput.tsx +1 -2
  243. package/frontend/src/components/Stepper.tsx +53 -0
  244. package/frontend/src/components/ThemeToggle.tsx +3 -3
  245. package/frontend/src/components/datagrid/DataGrid.tsx +25 -32
  246. package/frontend/src/components/datagrid/cell-editors/DateCellEditor.tsx +1 -2
  247. package/frontend/src/components/datagrid/cell-editors/JsonCellEditor.tsx +2 -4
  248. package/frontend/src/components/datagrid/index.ts +23 -0
  249. package/frontend/src/components/index.ts +23 -30
  250. package/frontend/src/components/layout/AppHeader.tsx +133 -92
  251. package/frontend/src/components/layout/AppSidebar.tsx +80 -170
  252. package/frontend/src/components/layout/Layout.tsx +12 -23
  253. package/frontend/src/components/layout/PrimaryMenu.tsx +187 -0
  254. package/frontend/src/components/layout/SecondaryMenu.tsx +70 -0
  255. package/frontend/src/components/layout/index.ts +5 -0
  256. package/frontend/src/components/radix/Tooltip.tsx +24 -13
  257. package/frontend/src/components/radix/index.ts +22 -0
  258. package/frontend/src/features/ai/components/AIConfigCard.tsx +129 -83
  259. package/frontend/src/features/ai/components/AIEmptyState.tsx +12 -7
  260. package/frontend/src/features/ai/components/ModalityFilterSidebar.tsx +101 -0
  261. package/frontend/src/features/ai/components/ModelSelectionDialog.tsx +135 -0
  262. package/frontend/src/features/ai/components/ModelSelectionGrid.tsx +51 -0
  263. package/frontend/src/features/ai/components/SystemPromptDialog.tsx +118 -0
  264. package/frontend/src/features/ai/components/index.ts +6 -0
  265. package/frontend/src/features/ai/helpers.ts +57 -71
  266. package/frontend/src/features/ai/hooks/useAIConfigs.ts +39 -113
  267. package/frontend/src/features/ai/hooks/useAIUsage.ts +0 -2
  268. package/frontend/src/features/ai/page/AIPage.tsx +67 -79
  269. package/frontend/src/features/ai/services/ai.service.ts +5 -5
  270. package/frontend/src/features/auth/components/AuthPreview.tsx +96 -0
  271. package/frontend/src/features/auth/components/OAuthConfigDialog.tsx +53 -30
  272. package/frontend/src/features/auth/components/UserFormDialog.tsx +13 -6
  273. package/frontend/src/features/auth/components/UsersDataGrid.tsx +44 -14
  274. package/frontend/src/features/auth/components/index.ts +5 -0
  275. package/frontend/src/features/auth/helpers.tsx +200 -0
  276. package/frontend/src/features/auth/hooks/useAnonToken.ts +30 -0
  277. package/frontend/src/features/auth/hooks/useAuthConfig.ts +48 -0
  278. package/frontend/src/features/auth/hooks/useOAuthConfig.ts +14 -10
  279. package/frontend/src/features/auth/hooks/useUsers.ts +43 -5
  280. package/frontend/src/features/auth/index.ts +3 -2
  281. package/frontend/src/features/auth/page/AuthMethodsPage.tsx +275 -0
  282. package/frontend/src/features/auth/page/ConfigurationPage.tsx +395 -0
  283. package/frontend/src/features/auth/page/UsersPage.tsx +285 -0
  284. package/frontend/src/features/auth/services/anonToken.service.ts +11 -0
  285. package/frontend/src/features/auth/services/config.service.ts +19 -0
  286. package/frontend/src/features/auth/services/{oauth.service.ts → oauth-config.service.ts} +4 -4
  287. package/frontend/src/features/auth/services/{auth.service.ts → user.service.ts} +7 -53
  288. package/frontend/src/features/dashboard/components/ConnectionSuccessBanner.tsx +35 -0
  289. package/frontend/src/features/dashboard/components/PromptCard.tsx +21 -0
  290. package/frontend/src/features/dashboard/components/PromptDialog.tsx +103 -0
  291. package/frontend/src/features/dashboard/components/StatsCard.tsx +50 -0
  292. package/frontend/src/features/dashboard/components/index.ts +4 -0
  293. package/frontend/src/features/dashboard/page/DashboardPage.tsx +187 -169
  294. package/frontend/src/features/dashboard/prompts/ai-chatbot.ts +13 -0
  295. package/frontend/src/features/dashboard/prompts/crm-system.ts +13 -0
  296. package/frontend/src/features/dashboard/prompts/ecommerce-platform.ts +12 -0
  297. package/frontend/src/features/dashboard/prompts/index.ts +31 -0
  298. package/frontend/src/features/dashboard/prompts/instagram-clone.ts +11 -0
  299. package/frontend/src/features/dashboard/prompts/notion-clone.ts +14 -0
  300. package/frontend/src/features/dashboard/prompts/reddit-clone.ts +12 -0
  301. package/frontend/src/features/database/components/DatabaseDataGrid.tsx +48 -17
  302. package/frontend/src/features/database/components/ForeignKeyCell.tsx +15 -34
  303. package/frontend/src/features/database/components/ForeignKeyPopover.tsx +19 -20
  304. package/frontend/src/features/database/components/LinkRecordModal.tsx +120 -125
  305. package/frontend/src/features/database/components/RecordFormDialog.tsx +22 -33
  306. package/frontend/src/features/database/components/RecordFormField.tsx +45 -47
  307. package/frontend/src/features/database/components/TableEmptyState.tsx +6 -5
  308. package/frontend/src/features/database/components/TableForm.tsx +28 -15
  309. package/frontend/src/features/database/components/TableFormColumn.tsx +2 -3
  310. package/frontend/src/features/database/components/TableSidebar.tsx +1 -1
  311. package/frontend/src/features/database/components/TablesEmptyState.tsx +48 -0
  312. package/frontend/src/features/database/components/TemplateCard.tsx +37 -0
  313. package/frontend/src/features/database/components/TemplatePreview.tsx +92 -0
  314. package/frontend/src/features/database/components/index.ts +19 -0
  315. package/frontend/src/features/database/constants.ts +28 -2
  316. package/frontend/src/features/database/contexts/SQLEditorContext.tsx +188 -0
  317. package/frontend/src/features/database/helpers.ts +2 -2
  318. package/frontend/src/features/database/hooks/useCSVImport.ts +29 -0
  319. package/frontend/src/features/database/hooks/useFullMetadata.ts +18 -0
  320. package/frontend/src/features/database/hooks/useRawSQL.ts +55 -0
  321. package/frontend/src/features/database/hooks/useRecords.ts +139 -0
  322. package/frontend/src/features/database/hooks/useTables.ts +131 -0
  323. package/frontend/src/features/database/index.ts +6 -1
  324. package/frontend/src/features/database/page/FunctionsPage.tsx +211 -0
  325. package/frontend/src/features/database/page/IndexesPage.tsx +240 -0
  326. package/frontend/src/features/database/page/PoliciesPage.tsx +248 -0
  327. package/frontend/src/features/database/page/SQLEditorPage.tsx +382 -0
  328. package/frontend/src/features/database/page/{DatabasePage.tsx → TablesPage.tsx} +186 -185
  329. package/frontend/src/features/database/page/TemplatesPage.tsx +39 -0
  330. package/frontend/src/features/database/page/TriggersPage.tsx +242 -0
  331. package/frontend/src/features/database/services/advance.service.ts +66 -0
  332. package/frontend/src/features/database/services/{database.service.ts → record.service.ts} +67 -64
  333. package/frontend/src/features/database/services/table.service.ts +64 -0
  334. package/frontend/src/features/database/templates/ai-chatbot.ts +402 -0
  335. package/frontend/src/features/database/templates/crm-system.ts +528 -0
  336. package/frontend/src/features/database/templates/ecommerce-platform.ts +553 -0
  337. package/frontend/src/features/database/templates/index.ts +34 -0
  338. package/frontend/src/features/database/templates/instagram-clone.ts +222 -0
  339. package/frontend/src/features/database/templates/notion-clone.ts +483 -0
  340. package/frontend/src/features/database/templates/reddit-clone.ts +526 -0
  341. package/frontend/src/features/functions/components/FunctionRow.tsx +2 -1
  342. package/frontend/src/features/functions/components/FunctionsSidebar.tsx +1 -1
  343. package/frontend/src/features/functions/components/SecretRow.tsx +1 -1
  344. package/frontend/src/features/functions/components/index.ts +5 -0
  345. package/frontend/src/features/functions/hooks/useFunctions.ts +4 -4
  346. package/frontend/src/features/{secrets → functions}/hooks/useSecrets.ts +5 -5
  347. package/frontend/src/features/functions/page/FunctionsPage.tsx +160 -17
  348. package/frontend/src/features/functions/{components/SecretsContent.tsx → page/SecretsPage.tsx} +8 -12
  349. package/frontend/src/features/functions/services/{functions.service.ts → function.service.ts} +2 -2
  350. package/frontend/src/features/{secrets/services/secrets.service.ts → functions/services/secret.service.ts} +2 -2
  351. package/frontend/src/features/login/hooks/usePartnerOrigin.ts +27 -0
  352. package/frontend/src/features/login/page/CloudLoginPage.tsx +79 -54
  353. package/frontend/src/features/login/page/LoginPage.tsx +16 -23
  354. package/frontend/src/features/login/services/partnership.service.ts +65 -0
  355. package/frontend/src/features/logs/components/LogsDataGrid.tsx +89 -0
  356. package/frontend/src/features/logs/components/SeverityBadge.tsx +18 -0
  357. package/frontend/src/features/logs/components/index.ts +2 -0
  358. package/frontend/src/features/logs/helpers.ts +24 -0
  359. package/frontend/src/features/logs/hooks/useAuditLogs.ts +4 -4
  360. package/frontend/src/features/logs/hooks/useLogSources.ts +137 -0
  361. package/frontend/src/features/logs/hooks/useLogs.ts +163 -0
  362. package/frontend/src/features/logs/hooks/useMcpUsage.ts +181 -0
  363. package/frontend/src/features/logs/index.ts +8 -2
  364. package/frontend/src/features/logs/page/AuditsPage.tsx +91 -38
  365. package/frontend/src/features/logs/page/LogsPage.tsx +152 -0
  366. package/frontend/src/features/logs/page/MCPLogsPage.tsx +84 -0
  367. package/frontend/src/features/logs/services/audit.service.ts +63 -0
  368. package/frontend/src/features/logs/services/log.service.ts +15 -110
  369. package/frontend/src/features/logs/services/usage.service.ts +31 -0
  370. package/frontend/src/features/onboard/components/McpConnectionStatus.tsx +68 -0
  371. package/frontend/src/features/onboard/components/OnboardingModal.tsx +267 -0
  372. package/frontend/src/features/onboard/components/VideoDemoModal.tsx +38 -0
  373. package/frontend/src/features/onboard/components/index.ts +4 -0
  374. package/frontend/src/features/onboard/components/mcp/CursorDeeplinkGenerator.tsx +2 -2
  375. package/frontend/src/features/onboard/components/mcp/{mcp-helper.tsx → helpers.tsx} +8 -8
  376. package/frontend/src/features/onboard/components/mcp/index.ts +2 -3
  377. package/frontend/src/features/onboard/index.ts +13 -3
  378. package/frontend/src/features/storage/components/BucketEmptyState.tsx +9 -6
  379. package/frontend/src/features/storage/components/BucketFormDialog.tsx +25 -41
  380. package/frontend/src/features/storage/components/FilePreviewDialog.tsx +20 -8
  381. package/frontend/src/features/storage/components/StorageDataGrid.tsx +4 -3
  382. package/frontend/src/features/storage/components/StorageManager.tsx +23 -34
  383. package/frontend/src/features/storage/components/index.ts +12 -0
  384. package/frontend/src/features/storage/hooks/useStorage.ts +208 -0
  385. package/frontend/src/features/storage/page/StoragePage.tsx +41 -115
  386. package/frontend/src/features/storage/services/storage.service.ts +22 -1
  387. package/frontend/src/features/visualizer/components/AuthNode.tsx +72 -56
  388. package/frontend/src/features/visualizer/components/BucketNode.tsx +4 -4
  389. package/frontend/src/features/visualizer/components/SchemaVisualizer.tsx +108 -80
  390. package/frontend/src/features/visualizer/components/TableNode.tsx +34 -41
  391. package/frontend/src/features/visualizer/components/VisualizerSkeleton.tsx +12 -4
  392. package/frontend/src/features/visualizer/page/VisualizerPage.tsx +33 -29
  393. package/frontend/src/index.css +1 -0
  394. package/frontend/src/lib/analytics/posthog.tsx +27 -0
  395. package/frontend/src/lib/contexts/AuthContext.tsx +38 -31
  396. package/frontend/src/lib/contexts/SocketContext.tsx +5 -6
  397. package/frontend/src/{features/metadata → lib}/hooks/useMetadata.ts +1 -1
  398. package/frontend/src/lib/hooks/useToast.tsx +6 -2
  399. package/frontend/src/lib/routing/AppRoutes.tsx +84 -0
  400. package/frontend/src/lib/routing/RequireAuth.tsx +27 -0
  401. package/frontend/src/lib/utils/cloudMessaging.ts +20 -0
  402. package/frontend/src/lib/utils/menuItems.ts +183 -0
  403. package/frontend/src/lib/utils/{validation-schemas.ts → schemaValidations.ts} +10 -5
  404. package/frontend/src/lib/utils/utils.ts +19 -1
  405. package/frontend/src/vite-env.d.ts +1 -0
  406. package/frontend/vite.config.ts +5 -3
  407. package/functions/server.ts +28 -3
  408. package/functions/worker-template.js +15 -4
  409. package/i18n/README.ar.md +130 -0
  410. package/i18n/README.de.md +130 -0
  411. package/i18n/README.es.md +154 -0
  412. package/i18n/README.fr.md +134 -0
  413. package/i18n/README.hi.md +129 -0
  414. package/i18n/README.ja.md +174 -0
  415. package/i18n/README.ko.md +137 -0
  416. package/i18n/README.pt-BR.md +131 -0
  417. package/i18n/README.ru.md +129 -0
  418. package/i18n/README.zh-CN.md +133 -0
  419. package/openapi/ai.yaml +31 -4
  420. package/openapi/auth.yaml +827 -146
  421. package/package.json +16 -7
  422. package/shared-schemas/package.json +1 -1
  423. package/shared-schemas/src/ai-api.schema.ts +34 -58
  424. package/shared-schemas/src/ai.schema.ts +5 -0
  425. package/shared-schemas/src/auth-api.schema.ts +154 -8
  426. package/shared-schemas/src/auth.schema.ts +42 -6
  427. package/shared-schemas/src/cloud-events.schema.ts +57 -0
  428. package/shared-schemas/src/database-api.schema.ts +3 -3
  429. package/shared-schemas/src/database.schema.ts +1 -1
  430. package/shared-schemas/src/index.ts +1 -0
  431. package/shared-schemas/src/logs-api.schema.ts +7 -1
  432. package/shared-schemas/src/logs.schema.ts +26 -0
  433. package/shared-schemas/src/metadata.schema.ts +9 -4
  434. package/test-gemini.sh +35 -0
  435. package/test-usage-admin.sh +57 -0
  436. package/test-usage.sh +50 -0
  437. package/zeabur/README.md +13 -0
  438. package/zeabur/template.yml +1032 -0
  439. package/.github/workflows/deploy-aws.yml +0 -130
  440. package/backend/src/api/routes/agent.ts +0 -29
  441. package/backend/src/api/routes/auth.oauth.ts +0 -482
  442. package/backend/src/api/routes/auth.ts +0 -386
  443. package/backend/src/api/routes/docs.ts +0 -66
  444. package/backend/src/api/routes/functions.ts +0 -183
  445. package/backend/src/api/routes/openapi.ts +0 -82
  446. package/backend/src/api/routes/usage.ts +0 -96
  447. package/backend/src/core/ai/client.ts +0 -242
  448. package/backend/src/core/ai/model.ts +0 -117
  449. package/backend/src/core/auth/auth.ts +0 -781
  450. package/backend/src/core/database/table.ts +0 -772
  451. package/backend/src/core/documentation/agent.ts +0 -689
  452. package/backend/src/core/documentation/openapi.ts +0 -856
  453. package/backend/src/core/logs/analytics.ts +0 -76
  454. package/backend/src/core/logs/providers/localdb.provider.ts +0 -246
  455. package/backend/src/core/storage/storage.ts +0 -923
  456. package/backend/src/utils/cloud-token.ts +0 -39
  457. package/backend/src/utils/helpers.ts +0 -49
  458. package/backend/src/utils/uuid.ts +0 -9
  459. package/backend/tests/manual/test-better-auth.sh +0 -303
  460. package/docker-init/db/logs.sql +0 -9
  461. package/frontend/README.md +0 -112
  462. package/frontend/src/components/datagrid/index.tsx +0 -20
  463. package/frontend/src/components/layout/CloudLayout.tsx +0 -95
  464. package/frontend/src/features/ai/components/AIConfigDialog.tsx +0 -76
  465. package/frontend/src/features/ai/components/AIConfigForm.tsx +0 -222
  466. package/frontend/src/features/ai/components/fields/ModalityField.tsx +0 -87
  467. package/frontend/src/features/ai/components/fields/ModelSelectionField.tsx +0 -134
  468. package/frontend/src/features/ai/components/fields/SystemPromptField.tsx +0 -33
  469. package/frontend/src/features/auth/components/AddOAuthDialog.tsx +0 -106
  470. package/frontend/src/features/auth/components/AuthMethodTab.tsx +0 -238
  471. package/frontend/src/features/auth/components/UsersTab.tsx +0 -114
  472. package/frontend/src/features/auth/page/AuthenticationPage.tsx +0 -169
  473. package/frontend/src/features/database/hooks/UseLinkModal.tsx +0 -78
  474. package/frontend/src/features/functions/components/FunctionViewer.tsx +0 -46
  475. package/frontend/src/features/functions/components/FunctionsContent.tsx +0 -88
  476. package/frontend/src/features/login/components/AuthErrorBoundary.tsx +0 -87
  477. package/frontend/src/features/login/components/PrivateRoute.tsx +0 -24
  478. package/frontend/src/features/logs/components/AnalyticsLogsTable.tsx +0 -313
  479. package/frontend/src/features/logs/components/LogsTable.tsx +0 -199
  480. package/frontend/src/features/logs/page/AnalyticsLogsPage.tsx +0 -530
  481. package/frontend/src/features/metadata/index.ts +0 -0
  482. package/frontend/src/features/metadata/page/MetadataPage.tsx +0 -136
  483. package/frontend/src/features/onboard/components/CompletionCard.tsx +0 -41
  484. package/frontend/src/features/onboard/components/OnboardButton.tsx +0 -84
  485. package/frontend/src/features/onboard/components/StepContent.tsx +0 -91
  486. package/frontend/src/features/onboard/components/TestConnectionStep.tsx +0 -53
  487. package/frontend/src/features/onboard/components/mcp/McpInstallation.tsx +0 -144
  488. package/frontend/src/features/onboard/page/OnBoardPage.tsx +0 -104
  489. package/frontend/src/features/onboard/types.ts +0 -8
  490. package/frontend/src/lib/contexts/OnboardStepContext.tsx +0 -68
  491. package/frontend/src/lib/hooks/useOnboardingCompletion.ts +0 -29
  492. /package/backend/src/api/{middleware → middlewares}/error.ts +0 -0
  493. /package/backend/src/api/{middleware → middlewares}/upload.ts +0 -0
  494. /package/backend/{migrations → src/infra/database/migrations}/000_create-base-tables.sql +0 -0
  495. /package/backend/{migrations → src/infra/database/migrations}/001_create-helper-functions.sql +0 -0
  496. /package/backend/{migrations → src/infra/database/migrations}/002_rename-auth-tables.sql +0 -0
  497. /package/backend/{migrations → src/infra/database/migrations}/003_create-users-table.sql +0 -0
  498. /package/backend/{migrations → src/infra/database/migrations}/004_add-reload-postgrest-func.sql +0 -0
  499. /package/backend/{migrations → src/infra/database/migrations}/005_enable-project-admin-modify-users.sql +0 -0
  500. /package/backend/{migrations → src/infra/database/migrations}/006_modify-ai-usage-table.sql +0 -0
  501. /package/backend/{migrations → src/infra/database/migrations}/007_drop-metadata-table.sql +0 -0
  502. /package/backend/{migrations → src/infra/database/migrations}/008_add-system-tables.sql +0 -0
  503. /package/backend/{migrations → src/infra/database/migrations}/009_add-function-secrets.sql +0 -0
  504. /package/backend/{migrations → src/infra/database/migrations}/010_modify-ai-config-modalities.sql +0 -0
  505. /package/backend/{migrations → src/infra/database/migrations}/011_refactor-secrets-table.sql +0 -0
  506. /package/backend/{migrations → src/infra/database/migrations}/012_add-storage-uploaded-by.sql +0 -0
  507. /package/frontend/src/{features/metadata → lib}/services/metadata.service.ts +0 -0
@@ -1,34 +1,35 @@
1
- import { Lock, FormInput, Users } from 'lucide-react';
2
- import GoogleIcon from '@/assets/logos/google.svg';
3
- import GithubIcon from '@/assets/logos/github.svg';
1
+ import { Lock, FormInput, Users, Circle } from 'lucide-react';
2
+ import { Handle, Position } from '@xyflow/react';
4
3
  import { AuthMetadataSchema } from '@insforge/shared-schemas';
5
4
  import { cn } from '@/lib/utils/utils';
6
5
  import { useOAuthConfig } from '@/features/auth/hooks/useOAuthConfig';
6
+ import { oauthProviders } from '@/features/auth/helpers';
7
7
 
8
8
  interface AuthNodeProps {
9
9
  data: {
10
10
  authMetadata: AuthMetadataSchema;
11
11
  userCount?: number;
12
+ isReferenced?: boolean; // Whether any tables have foreign keys to users.id
12
13
  };
13
14
  }
14
15
 
15
16
  export function AuthNode({ data }: AuthNodeProps) {
16
- const { authMetadata, userCount } = data;
17
+ const { authMetadata, userCount, isReferenced = false } = data;
17
18
  const { isProviderConfigured } = useOAuthConfig();
18
19
 
19
- const enabledCount = authMetadata.oauths.length;
20
+ const enabledCount = authMetadata.oauths.length + 1;
20
21
 
21
22
  return (
22
- <div className="bg-neutral-900 rounded-lg border border-[#363636] min-w-[280px]">
23
+ <div className="bg-white dark:bg-neutral-900 rounded-lg border border-gray-300 dark:border-[#363636] min-w-[280px] shadow-sm">
23
24
  {/* Auth Header */}
24
- <div className="flex items-center justify-between p-2 border-b border-neutral-800">
25
+ <div className="flex items-center justify-between p-2 border-b border-gray-200 dark:border-neutral-800">
25
26
  <div className="flex items-center gap-2">
26
27
  <div className="flex items-center justify-center w-11 h-11 bg-lime-300 rounded p-1.5">
27
28
  <Lock className="w-5 h-5 text-neutral-900" />
28
29
  </div>
29
30
  <div className="flex-1">
30
- <h3 className="text-sm font-medium text-white">Authentication</h3>
31
- <p className="text-xs text-neutral-300">
31
+ <h3 className="text-sm font-medium text-zinc-950 dark:text-white">Authentication</h3>
32
+ <p className="text-xs text-zinc-600 dark:text-neutral-300">
32
33
  {enabledCount} provider{enabledCount !== 1 ? 's' : ''} enabled
33
34
  </p>
34
35
  </div>
@@ -39,67 +40,82 @@ export function AuthNode({ data }: AuthNodeProps) {
39
40
  </div>
40
41
 
41
42
  {/* Auth Providers */}
42
- <div className="p-2 space-y-2 border-b border-neutral-800">
43
+ <div className="p-2 space-y-2 border-b border-gray-200 dark:border-neutral-800">
43
44
  {/* Email/Password */}
44
- <div className="flex items-center justify-between p-2.5 bg-neutral-800 rounded">
45
+ <div className="flex items-center justify-between p-2.5 bg-gray-100 dark:bg-neutral-800 rounded">
45
46
  <div className="flex items-center gap-2.5">
46
- <FormInput className="w-5 h-5 text-neutral-300" />
47
- <span className="text-sm text-neutral-300">Email/Password</span>
47
+ <FormInput className="w-5 h-5 text-zinc-700 dark:text-neutral-300" />
48
+ <span className="text-sm text-zinc-700 dark:text-neutral-300">Email/Password</span>
48
49
  </div>
49
50
  <div className="px-1.5 py-0.5 bg-lime-200 rounded flex items-center">
50
51
  <span className="text-xs font-medium text-lime-900">Enabled</span>
51
52
  </div>
52
53
  </div>
53
54
 
54
- {/* Google OAuth */}
55
- <div className="flex items-center justify-between p-2.5 bg-neutral-800 rounded">
56
- <div className="flex items-center gap-2.5">
57
- <img src={GoogleIcon} alt="google" className="h-5 w-5" />
58
- <span className="text-sm text-neutral-300">Google OAuth</span>
59
- </div>
60
- <div
61
- className={cn(
62
- 'px-1.5 py-0.5 rounded flex items-center',
63
- isProviderConfigured('google')
64
- ? 'bg-lime-200 text-lime-900'
65
- : 'bg-neutral-700 text-neutral-300'
66
- )}
67
- >
68
- <span className="text-xs font-medium">
69
- {isProviderConfigured('google') ? 'Enabled' : 'Disabled'}
70
- </span>
71
- </div>
72
- </div>
73
-
74
- {/* GitHub OAuth */}
75
- <div className="flex items-center justify-between p-2.5 bg-neutral-800 rounded">
76
- <div className="flex items-center gap-2.5">
77
- <img src={GithubIcon} alt="github" className="h-5 w-5" />
78
- <span className="text-sm text-neutral-300">GitHub OAuth</span>
79
- </div>
80
- <div
81
- className={cn(
82
- 'px-1.5 py-0.5 rounded flex items-center',
83
- isProviderConfigured('github')
84
- ? 'bg-lime-200 text-lime-900'
85
- : 'bg-neutral-700 text-neutral-300'
86
- )}
87
- >
88
- <span className="text-xs font-medium">
89
- {isProviderConfigured('github') ? 'Enabled' : 'Disabled'}
90
- </span>
91
- </div>
92
- </div>
55
+ {/* OAuth Providers */}
56
+ {oauthProviders.map((provider) => {
57
+ const isEnabled = isProviderConfigured(provider.id);
58
+ return (
59
+ <div
60
+ key={provider.id}
61
+ className="flex items-center justify-between p-2.5 bg-gray-100 dark:bg-neutral-800 rounded"
62
+ >
63
+ <div className="flex items-center gap-2.5">
64
+ <div className="w-5 h-5 flex items-center justify-center [&>svg]:w-5 [&>svg]:h-5">
65
+ {provider.icon}
66
+ </div>
67
+ <span className="text-sm text-zinc-700 dark:text-neutral-300">{provider.name}</span>
68
+ </div>
69
+ <div
70
+ className={cn(
71
+ 'px-1.5 py-0.5 rounded flex items-center',
72
+ isEnabled
73
+ ? 'bg-lime-200 text-lime-900'
74
+ : 'bg-gray-200 dark:bg-neutral-700 text-gray-600 dark:text-neutral-300'
75
+ )}
76
+ >
77
+ <span className="text-xs font-medium">{isEnabled ? 'Enabled' : 'Disabled'}</span>
78
+ </div>
79
+ </div>
80
+ );
81
+ })}
93
82
  </div>
94
83
 
95
84
  {/* Users Section */}
96
- <div className="flex items-center justify-between p-3 border-t border-neutral-700">
85
+ <div className="flex items-center justify-between p-3 border-t border-gray-300 dark:border-neutral-700 relative">
86
+ {/* Target handle for auth.id references - positioned at right bottom corner */}
87
+ <Handle
88
+ type="target"
89
+ position={Position.Right}
90
+ id="id-target"
91
+ className="!w-3 !h-3 !opacity-0 !border-0 !pointer-events-none"
92
+ style={{
93
+ right: 16,
94
+ bottom: 16,
95
+ top: 'auto',
96
+ transform: 'none',
97
+ pointerEvents: 'none',
98
+ }}
99
+ isConnectable={false}
100
+ />
101
+
97
102
  <div className="flex items-center gap-2.5">
98
- <Users className="w-5 h-5 text-neutral-300" />
99
- <span className="text-sm text-neutral-300">Users</span>
103
+ <Users className="w-5 h-5 text-zinc-700 dark:text-neutral-300" />
104
+ <span className="text-sm text-zinc-700 dark:text-neutral-300">Users</span>
105
+ <span className="text-xs text-zinc-500 dark:text-neutral-400">{userCount ?? 0}</span>
100
106
  </div>
101
107
  <div className="flex items-center">
102
- {userCount !== undefined && <span className="text-xs text-neutral-400">{userCount}</span>}
108
+ {isReferenced ? (
109
+ <div className="w-5 h-5 flex items-center justify-center relative">
110
+ <Circle
111
+ className="w-5 h-5 text-zinc-950 dark:text-white fill-none stroke-current"
112
+ strokeWidth={1.5}
113
+ />
114
+ <div className="w-2 h-2 bg-zinc-950 dark:bg-white rounded-full absolute" />
115
+ </div>
116
+ ) : (
117
+ <Circle className="w-5 h-5 text-gray-400 dark:text-neutral-700 fill-gray-100 dark:fill-neutral-800 stroke-current" />
118
+ )}
103
119
  </div>
104
120
  </div>
105
121
  </div>
@@ -11,16 +11,16 @@ export function BucketNode({ data }: BucketNodeProps) {
11
11
  const { bucket } = data;
12
12
 
13
13
  return (
14
- <div className="bg-neutral-900 rounded-lg border border-[#363636] min-w-[320px]">
14
+ <div className="bg-white dark:bg-neutral-900 rounded-lg border border-gray-300 dark:border-[#363636] min-w-[320px] shadow-sm">
15
15
  {/* Bucket Header */}
16
- <div className="flex items-center justify-between p-2 border-b border-neutral-800">
16
+ <div className="flex items-center justify-between p-2 border-b border-gray-200 dark:border-neutral-800">
17
17
  <div className="flex items-center gap-2">
18
18
  <div className="flex items-center justify-center w-11 h-11 bg-blue-300 rounded p-1.5">
19
19
  <HardDrive className="w-5 h-5 text-neutral-900" />
20
20
  </div>
21
21
  <div className="flex-1">
22
- <h3 className="text-sm font-medium text-white">{bucket.name}</h3>
23
- <p className="text-xs text-neutral-300">
22
+ <h3 className="text-sm font-medium text-zinc-950 dark:text-white">{bucket.name}</h3>
23
+ <p className="text-xs text-zinc-600 dark:text-neutral-300">
24
24
  {bucket.objectCount ? `${bucket.objectCount} files` : '0 files'}
25
25
  </p>
26
26
  </div>
@@ -12,23 +12,32 @@ import {
12
12
  ConnectionMode,
13
13
  } from '@xyflow/react';
14
14
  import '@xyflow/react/dist/style.css';
15
- import { TableNode, VisualizerTableSchema, VisualizerTableColumnSchema } from './TableNode';
15
+ import { TableNode } from './TableNode';
16
16
  import { AuthNode } from './AuthNode';
17
17
  import { BucketNode } from './BucketNode';
18
+ import { useTables } from '@/features/database/hooks/useTables';
19
+ import { useTheme } from '@/lib/contexts/ThemeContext';
18
20
  import {
19
21
  AppMetadataSchema,
20
22
  StorageBucketSchema,
21
23
  AuthMetadataSchema,
24
+ GetTableSchemaResponse,
22
25
  } from '@insforge/shared-schemas';
23
26
 
24
27
  interface SchemaVisualizerProps {
25
28
  metadata: AppMetadataSchema;
26
29
  userCount?: number;
30
+ // Optional external schemas for templates
31
+ externalSchemas?: GetTableSchemaResponse[];
32
+ // Control visibility of components
33
+ showControls?: boolean;
34
+ showMiniMap?: boolean;
27
35
  }
28
36
 
29
37
  type TableNodeData = {
30
- table: VisualizerTableSchema;
38
+ table: GetTableSchemaResponse;
31
39
  referencedColumns: string[];
40
+ showRecordCount?: boolean;
32
41
  };
33
42
 
34
43
  type BucketNodeData = {
@@ -38,6 +47,7 @@ type BucketNodeData = {
38
47
  type AuthNodeData = {
39
48
  authMetadata: AuthMetadataSchema;
40
49
  userCount?: number;
50
+ isReferenced?: boolean;
41
51
  };
42
52
 
43
53
  type CustomNodeData = TableNodeData | BucketNodeData | AuthNodeData;
@@ -119,7 +129,7 @@ const getLayoutedElements = (nodes: Node<CustomNodeData>[], edges: BuiltInEdge[]
119
129
 
120
130
  // Position table nodes in a grid in the middle
121
131
  let positionedTableNodes: Node<CustomNodeData>[] = [];
122
- if (tableNodes.length > 0) {
132
+ if (tableNodes.length) {
123
133
  const cols = Math.ceil(Math.sqrt(tableNodes.length));
124
134
 
125
135
  // Group tables by column for better height calculation
@@ -179,53 +189,20 @@ const getNodeColor = (node: Node<CustomNodeData>) => {
179
189
  }
180
190
  };
181
191
 
182
- export function SchemaVisualizer({ metadata, userCount }: SchemaVisualizerProps) {
183
- // Transform the new metadata structure to the visualizer format
184
- const tables = useMemo(() => {
185
- const tablesRecord = metadata.database.tables;
186
- return Object.entries(tablesRecord).map(([tableName, tableData]): VisualizerTableSchema => {
187
- // Check for primary key columns from indexes
188
- const primaryKeyColumns = new Set<string>();
189
-
190
- tableData.indexes.forEach((index) => {
191
- if (index.isPrimary) {
192
- // Extract column names from index definition
193
- const match = index.indexdef.match(/\(([^)]+)\)/);
194
- if (match) {
195
- match[1].split(',').forEach((col) => {
196
- primaryKeyColumns.add(col.trim().replace(/"/g, ''));
197
- });
198
- }
199
- }
200
- });
201
-
202
- // Transform columns from the new schema format
203
- const columns = tableData.schema.map((col) => {
204
- const column: VisualizerTableColumnSchema = {
205
- columnName: col.columnName,
206
- type: col.dataType.toLowerCase().substring(0, 4), // Truncate type to first 4 characters
207
- isPrimaryKey: primaryKeyColumns.has(col.columnName),
208
- };
209
-
210
- // Find foreign key info for this column
211
- const foreignKey = tableData.foreignKeys.find((fk) => fk.columnName === col.columnName);
212
- if (foreignKey) {
213
- column.foreignKey = {
214
- referenceTable: foreignKey.foreignTableName,
215
- referenceColumn: foreignKey.foreignColumnName,
216
- };
217
- }
192
+ export function SchemaVisualizer({
193
+ metadata,
194
+ userCount,
195
+ externalSchemas,
196
+ showControls = true,
197
+ showMiniMap = true,
198
+ }: SchemaVisualizerProps) {
199
+ const { resolvedTheme } = useTheme();
218
200
 
219
- return column;
220
- });
201
+ // Fetch all table schemas only if external schemas are not provided
202
+ const { allSchemas, isLoadingSchemas } = useTables();
221
203
 
222
- return {
223
- tableName,
224
- columns,
225
- recordCount: tableData.recordCount ?? 0, // Use actual record count from metadata
226
- };
227
- });
228
- }, [metadata.database.tables]);
204
+ // Use external schemas if provided, otherwise use fetched schemas
205
+ const tables = externalSchemas || allSchemas;
229
206
 
230
207
  const initialNodes = useMemo(() => {
231
208
  // First, collect all referenced columns for each table
@@ -254,19 +231,32 @@ export function SchemaVisualizer({ metadata, userCount }: SchemaVisualizerProps)
254
231
  data: {
255
232
  table,
256
233
  referencedColumns: referencedColumnsByTable[table.tableName] || [],
234
+ showRecordCount: !externalSchemas, // Hide record count when using external schemas (template preview)
257
235
  },
258
236
  }));
259
237
 
238
+ const nodes: Node<CustomNodeData>[] = [...tableNodes];
239
+
240
+ // Add bucket nodes
260
241
  const bucketNodes: Node<BucketNodeData>[] = metadata.storage.buckets.map((bucket) => ({
261
242
  id: `bucket-${bucket.name}`,
262
243
  type: 'bucketNode',
263
244
  position: { x: 0, y: 0 },
264
245
  data: { bucket },
265
246
  }));
247
+ nodes.push(...bucketNodes);
248
+
249
+ // Check if any tables reference users.id
250
+ const isUsersReferenced = tables.some((table) =>
251
+ table.columns.some(
252
+ (column) =>
253
+ column.foreignKey &&
254
+ column.foreignKey.referenceTable === 'users' &&
255
+ column.foreignKey.referenceColumn === 'id'
256
+ )
257
+ );
266
258
 
267
- const nodes: Node<CustomNodeData>[] = [...tableNodes, ...bucketNodes];
268
-
269
- // Add authentication node if authData is provided
259
+ // Add authentication node
270
260
  nodes.push({
271
261
  id: 'authentication',
272
262
  type: 'authNode',
@@ -274,41 +264,66 @@ export function SchemaVisualizer({ metadata, userCount }: SchemaVisualizerProps)
274
264
  data: {
275
265
  authMetadata: metadata.auth,
276
266
  userCount,
267
+ isReferenced: isUsersReferenced,
277
268
  },
278
269
  });
279
270
 
280
271
  return nodes;
281
- }, [metadata, userCount, tables]);
272
+ }, [tables, metadata, externalSchemas, userCount]);
282
273
 
283
274
  const initialEdges = useMemo(() => {
284
275
  const edges: BuiltInEdge[] = [];
276
+ const edgeColor = resolvedTheme === 'dark' ? 'white' : '#18181b'; // zinc-950 for light mode
285
277
 
286
278
  tables.forEach((table) => {
287
279
  table.columns.forEach((column) => {
288
280
  if (column.foreignKey) {
281
+ // Check if this is a reference to users.id
282
+ const isAuthReference =
283
+ column.foreignKey.referenceTable === 'users' &&
284
+ column.foreignKey.referenceColumn === 'id';
285
+
289
286
  const edgeId = `${table.tableName}-${column.columnName}-${column.foreignKey.referenceTable}`;
290
- edges.push({
291
- id: edgeId,
292
- source: table.tableName,
293
- target: column.foreignKey.referenceTable,
294
- sourceHandle: `${column.columnName}-source`,
295
- targetHandle: `${column.foreignKey.referenceColumn}-target`,
296
- type: 'smoothstep',
297
- animated: true,
298
- style: { stroke: 'white', strokeWidth: 2, zIndex: 1000 },
299
- zIndex: 1000,
300
- pathOptions: {
301
- offset: 40,
302
- },
303
- });
287
+
288
+ if (isAuthReference) {
289
+ // Connect to the authentication node
290
+ edges.push({
291
+ id: edgeId,
292
+ source: table.tableName,
293
+ target: 'authentication',
294
+ sourceHandle: `${column.columnName}-source`,
295
+ targetHandle: 'id-target',
296
+ type: 'smoothstep',
297
+ animated: true,
298
+ style: { stroke: edgeColor, strokeWidth: 2, zIndex: 1000 },
299
+ zIndex: 1000,
300
+ pathOptions: {
301
+ offset: 40,
302
+ },
303
+ });
304
+ } else {
305
+ // Regular table-to-table edge
306
+ edges.push({
307
+ id: edgeId,
308
+ source: table.tableName,
309
+ target: column.foreignKey.referenceTable,
310
+ sourceHandle: `${column.columnName}-source`,
311
+ targetHandle: `${column.foreignKey.referenceColumn}-target`,
312
+ type: 'smoothstep',
313
+ animated: true,
314
+ style: { stroke: edgeColor, strokeWidth: 2, zIndex: 1000 },
315
+ zIndex: 1000,
316
+ pathOptions: {
317
+ offset: 40,
318
+ },
319
+ });
320
+ }
304
321
  }
305
322
  });
306
323
  });
307
324
 
308
- // Add authentication edges if authData exists
309
-
310
325
  return edges;
311
- }, [tables]);
326
+ }, [tables, resolvedTheme]);
312
327
 
313
328
  const { nodes: layoutedNodes, edges: layoutedEdges } = useMemo(
314
329
  () => getLayoutedElements(initialNodes, initialEdges),
@@ -319,15 +334,26 @@ export function SchemaVisualizer({ metadata, userCount }: SchemaVisualizerProps)
319
334
  const [edges, setEdges, onEdgesChange] = useEdgesState(layoutedEdges);
320
335
 
321
336
  useEffect(() => {
322
- setNodes(layoutedNodes);
323
- setEdges(layoutedEdges);
324
- }, [layoutedNodes, layoutedEdges, setNodes, setEdges]);
337
+ if (!isLoadingSchemas) {
338
+ setNodes(layoutedNodes);
339
+ setEdges(layoutedEdges);
340
+ }
341
+ }, [layoutedNodes, layoutedEdges, isLoadingSchemas, setNodes, setEdges]);
325
342
 
326
343
  const onConnect = useCallback(
327
344
  (params: Connection) => setEdges((eds) => addEdge(params, eds)),
328
345
  [setEdges]
329
346
  );
330
347
 
348
+ // Don't render ReactFlow until data is loaded (only if not using external schemas)
349
+ if (!externalSchemas && isLoadingSchemas) {
350
+ return (
351
+ <div className="w-full h-full flex items-center justify-center text-white">
352
+ Loading schemas...
353
+ </div>
354
+ );
355
+ }
356
+
331
357
  return (
332
358
  <div className="w-full h-full">
333
359
  <ReactFlow
@@ -339,20 +365,22 @@ export function SchemaVisualizer({ metadata, userCount }: SchemaVisualizerProps)
339
365
  nodeTypes={nodeTypes}
340
366
  connectionMode={ConnectionMode.Loose}
341
367
  fitView
342
- fitViewOptions={{ padding: 1, maxZoom: 2, minZoom: 1 }}
368
+ fitViewOptions={{ padding: 1, maxZoom: 2, minZoom: 0.8 }}
343
369
  minZoom={0.1}
344
370
  maxZoom={2}
345
371
  proOptions={{ hideAttribution: true }}
346
372
  elevateEdgesOnSelect={true}
347
- colorMode="dark"
373
+ colorMode={resolvedTheme === 'dark' ? 'dark' : 'light'}
348
374
  className="!bg-transparent"
349
375
  >
350
- <Controls
351
- showInteractive={false}
352
- className="!border !border-neutral-700 !shadow-lg"
353
- fitViewOptions={{ padding: 1, duration: 300, maxZoom: 2, minZoom: 1 }}
354
- />
355
- <MiniMap nodeColor={(node: Node<CustomNodeData>) => getNodeColor(node)} />
376
+ {showControls && (
377
+ <Controls
378
+ showInteractive={false}
379
+ className="!border !border-neutral-700 !shadow-lg"
380
+ fitViewOptions={{ padding: 1, duration: 300, maxZoom: 2, minZoom: 1 }}
381
+ />
382
+ )}
383
+ {showMiniMap && <MiniMap nodeColor={(node: Node<CustomNodeData>) => getNodeColor(node)} />}
356
384
  </ReactFlow>
357
385
  </div>
358
386
  );
@@ -1,32 +1,17 @@
1
1
  import { Database, Circle, Key } from 'lucide-react';
2
2
  import { Handle, Position } from '@xyflow/react';
3
-
4
- // Define the table structure expected by this component
5
- export interface VisualizerTableColumnSchema {
6
- columnName: string;
7
- type: string;
8
- isPrimaryKey?: boolean;
9
- foreignKey?: {
10
- referenceTable: string;
11
- referenceColumn: string;
12
- };
13
- }
14
-
15
- export interface VisualizerTableSchema {
16
- tableName: string;
17
- columns: VisualizerTableColumnSchema[];
18
- recordCount?: number;
19
- }
3
+ import { TableSchema } from '@insforge/shared-schemas';
20
4
 
21
5
  interface TableNodeProps {
22
6
  data: {
23
- table: VisualizerTableSchema;
7
+ table: TableSchema;
24
8
  referencedColumns?: string[]; // List of column names that are referenced by other tables
9
+ showRecordCount?: boolean; // Control whether to show record count
25
10
  };
26
11
  }
27
12
 
28
13
  export function TableNode({ data }: TableNodeProps) {
29
- const { table, referencedColumns = [] } = data;
14
+ const { table, referencedColumns = [], showRecordCount = true } = data;
30
15
 
31
16
  const getColumnIcon = (isReferenced: boolean = false) => {
32
17
  // If column is referenced by another table (has incoming connections)
@@ -35,35 +20,37 @@ export function TableNode({ data }: TableNodeProps) {
35
20
  return (
36
21
  <div className="w-4 h-4 flex items-center justify-center relative">
37
22
  {/* Outer gray diamond */}
38
- <div className="w-4 h-4 bg-neutral-800 border border-white absolute transform rotate-45" />
23
+ <div className="w-4 h-4 bg-gray-200 dark:bg-neutral-800 border border-zinc-950 dark:border-white absolute transform rotate-45" />
39
24
  {/* Inner white diamond */}
40
- <div className="w-2 h-2 bg-white absolute transform rotate-45" />
25
+ <div className="w-2 h-2 bg-zinc-950 dark:bg-white absolute transform rotate-45" />
41
26
  </div>
42
27
  );
43
28
  }
44
29
  return (
45
30
  <div className="w-4 h-4 flex items-center justify-center relative">
46
31
  {/* Outer gray diamond */}
47
- <div className="w-4 h-4 bg-neutral-800 border border-neutral-700 absolute transform rotate-45" />
32
+ <div className="w-4 h-4 bg-gray-200 dark:bg-neutral-800 border border-gray-400 dark:border-neutral-700 absolute transform rotate-45" />
48
33
  </div>
49
34
  );
50
35
  };
51
36
 
52
37
  return (
53
- <div className="bg-neutral-900 rounded-lg border border-[#363636] min-w-[320px]">
38
+ <div className="bg-white dark:bg-neutral-900 rounded-lg border border-gray-300 dark:border-[#363636] min-w-[320px] shadow-sm">
54
39
  {/* Table Header */}
55
- <div className="flex items-center justify-between p-2 border-b border-neutral-800">
40
+ <div className="flex items-center justify-between p-2 border-b border-gray-200 dark:border-neutral-800">
56
41
  <div className="flex items-center gap-2">
57
42
  <div className="flex items-center justify-center w-11 h-11 bg-teal-300 rounded p-1.5">
58
43
  <Database className="w-5 h-5 text-neutral-900" />
59
44
  </div>
60
45
  <div className="flex-1">
61
- <h3 className="text-sm font-medium text-white">{table.tableName}</h3>
62
- <p className="text-xs text-neutral-300">
63
- {table.recordCount !== undefined
64
- ? `${table.recordCount.toLocaleString()} data`
65
- : '0 data'}
66
- </p>
46
+ <h3 className="text-sm font-medium text-zinc-950 dark:text-white">{table.tableName}</h3>
47
+ {showRecordCount && (
48
+ <p className="text-xs text-zinc-600 dark:text-neutral-300">
49
+ {table.recordCount !== undefined
50
+ ? `${table.recordCount.toLocaleString()} data`
51
+ : '0 data'}
52
+ </p>
53
+ )}
67
54
  </div>
68
55
  </div>
69
56
  {/* <div className="p-1.5">
@@ -76,7 +63,7 @@ export function TableNode({ data }: TableNodeProps) {
76
63
  {table.columns.map((column) => (
77
64
  <div
78
65
  key={column.columnName}
79
- className="flex items-center justify-between p-3 border-b border-neutral-800 relative"
66
+ className="flex items-center justify-between p-3 border-b border-gray-200 dark:border-neutral-800 relative"
80
67
  >
81
68
  {/* Source handle for foreign key columns - invisible and non-interactive */}
82
69
  {column.foreignKey && (
@@ -114,35 +101,41 @@ export function TableNode({ data }: TableNodeProps) {
114
101
 
115
102
  <div className="flex items-center gap-2.5 flex-1">
116
103
  {getColumnIcon(referencedColumns.includes(column.columnName))}
117
- <span className="text-sm text-neutral-300">{column.columnName}</span>
118
- {column.isPrimaryKey && <Key className="w-3 h-3 text-neutral-400" />}
104
+ <span className="text-sm text-zinc-700 dark:text-neutral-300">
105
+ {column.columnName}
106
+ </span>
107
+ {column.isPrimaryKey && (
108
+ <Key className="w-3 h-3 text-zinc-500 dark:text-neutral-400" />
109
+ )}
119
110
  </div>
120
111
  <div className="flex items-center gap-2.5">
121
- <div className="px-1.5 py-0.5 bg-neutral-800 rounded flex items-center">
122
- <span className="text-xs font-medium text-neutral-300">{column.type}</span>
112
+ <div className="px-1.5 py-0.5 bg-gray-100 dark:bg-neutral-800 rounded flex items-center">
113
+ <span className="text-xs font-medium text-zinc-700 dark:text-neutral-300">
114
+ {column.type}
115
+ </span>
123
116
  </div>
124
117
  {/* Show white dot with outer circle for foreign key columns, gray circle for others */}
125
118
  {column.foreignKey ? (
126
119
  <div className="w-5 h-5 flex items-center justify-center relative">
127
120
  <Circle
128
- className="w-5 h-5 text-white fill-none stroke-current"
121
+ className="w-5 h-5 text-zinc-950 dark:text-white fill-none stroke-current"
129
122
  strokeWidth={1.5}
130
123
  />
131
- <div className="w-2 h-2 bg-white rounded-full absolute" />
124
+ <div className="w-2 h-2 bg-zinc-950 dark:bg-white rounded-full absolute" />
132
125
  </div>
133
126
  ) : (
134
- <Circle className="w-5 h-5 text-neutral-700 fill-neutral-800 stroke-current" />
127
+ <Circle className="w-5 h-5 text-gray-400 dark:text-neutral-700 fill-gray-100 dark:fill-neutral-800 stroke-current" />
135
128
  )}
136
129
  </div>
137
130
  </div>
138
131
  ))}
139
132
 
140
133
  {/* Empty state */}
141
- {table.columns.length === 0 && (
134
+ {!table.columns.length && (
142
135
  <div className="flex items-center justify-center p-6">
143
136
  <div className="text-center">
144
- <Database className="w-6 h-6 text-neutral-600 mx-auto mb-2" />
145
- <p className="text-xs text-neutral-500">No columns defined</p>
137
+ <Database className="w-6 h-6 text-gray-400 dark:text-neutral-600 mx-auto mb-2" />
138
+ <p className="text-xs text-gray-500 dark:text-neutral-500">No columns defined</p>
146
139
  </div>
147
140
  </div>
148
141
  )}