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
@@ -0,0 +1,149 @@
1
+ import { Pool } from 'pg';
2
+ import { DatabaseManager } from '@/infra/database/database.manager.js';
3
+ import logger from '@/utils/logger.js';
4
+
5
+ export interface AIUsageByModel {
6
+ model: string;
7
+ total_input_tokens: number;
8
+ total_output_tokens: number;
9
+ total_images: number;
10
+ }
11
+
12
+ export interface UsageStats {
13
+ mcp_usage_count: number;
14
+ database_size_bytes: number;
15
+ storage_size_bytes: number;
16
+ ai_usage_by_model: AIUsageByModel[];
17
+ }
18
+
19
+ export interface MCPUsageRecord {
20
+ tool_name: string;
21
+ success: boolean;
22
+ created_at: string;
23
+ }
24
+
25
+ /**
26
+ * UsageService - Handles usage tracking and statistics
27
+ * Business logic layer for MCP usage, system resource tracking, and AI usage
28
+ */
29
+ export class UsageService {
30
+ private static instance: UsageService;
31
+ private pool: Pool | null = null;
32
+
33
+ private constructor() {
34
+ logger.info('UsageService initialized');
35
+ }
36
+
37
+ private getPool(): Pool {
38
+ if (!this.pool) {
39
+ this.pool = DatabaseManager.getInstance().getPool();
40
+ }
41
+ return this.pool;
42
+ }
43
+
44
+ public static getInstance(): UsageService {
45
+ if (!UsageService.instance) {
46
+ UsageService.instance = new UsageService();
47
+ }
48
+ return UsageService.instance;
49
+ }
50
+
51
+ /**
52
+ * Record MCP tool usage
53
+ */
54
+ async recordMCPUsage(toolName: string, success: boolean = true): Promise<{ created_at: string }> {
55
+ try {
56
+ const result = await this.getPool().query(
57
+ `INSERT INTO _mcp_usage (tool_name, success)
58
+ VALUES ($1, $2)
59
+ RETURNING created_at`,
60
+ [toolName, success]
61
+ );
62
+
63
+ logger.info('MCP usage recorded', { toolName, success });
64
+ return { created_at: result.rows[0].created_at };
65
+ } catch (error) {
66
+ logger.error('Failed to record MCP usage', { error, toolName });
67
+ throw new Error('Failed to record MCP usage');
68
+ }
69
+ }
70
+
71
+ /**
72
+ * Get recent MCP usage records
73
+ */
74
+ async getMCPUsage(limit: number = 5, success: boolean = true): Promise<MCPUsageRecord[]> {
75
+ try {
76
+ const result = await this.getPool().query(
77
+ `SELECT tool_name, success, created_at
78
+ FROM _mcp_usage
79
+ WHERE success = $1
80
+ ORDER BY created_at DESC
81
+ LIMIT $2`,
82
+ [success, limit]
83
+ );
84
+
85
+ return result.rows as MCPUsageRecord[];
86
+ } catch (error) {
87
+ logger.error('Failed to get MCP usage', { error });
88
+ throw new Error('Failed to get MCP usage');
89
+ }
90
+ }
91
+
92
+ /**
93
+ * Get comprehensive usage statistics for a date range
94
+ * Returns MCP usage, database size, storage size, and AI usage by model
95
+ */
96
+ async getUsageStats(startDate: Date, endDate: Date): Promise<UsageStats> {
97
+ try {
98
+ // Get MCP tool usage count
99
+ const mcpResult = await this.getPool().query(
100
+ `SELECT COUNT(*) as count
101
+ FROM _mcp_usage
102
+ WHERE success = true
103
+ AND created_at >= $1
104
+ AND created_at < $2`,
105
+ [startDate, endDate]
106
+ );
107
+
108
+ // Get database size
109
+ const dbSizeResult = await this.getPool().query(
110
+ `SELECT pg_database_size(current_database()) as size`
111
+ );
112
+
113
+ // Get total storage size
114
+ const storageResult = await this.getPool().query(
115
+ `SELECT COALESCE(SUM(size), 0) as total_size FROM _storage`
116
+ );
117
+
118
+ // Get AI usage breakdown by model (only billable metrics)
119
+ const aiUsageByModel = await this.getPool().query(
120
+ `SELECT
121
+ COALESCE(u.model_id, c.model_id) as model,
122
+ COALESCE(SUM(u.input_tokens), 0) as total_input_tokens,
123
+ COALESCE(SUM(u.output_tokens), 0) as total_output_tokens,
124
+ COALESCE(SUM(u.image_count), 0) as total_images
125
+ FROM _ai_usage u
126
+ LEFT JOIN _ai_configs c ON u.config_id = c.id
127
+ WHERE u.created_at >= $1 AND u.created_at < $2
128
+ GROUP BY COALESCE(u.model_id, c.model_id)
129
+ ORDER BY (COALESCE(SUM(u.input_tokens), 0) + COALESCE(SUM(u.output_tokens), 0)) DESC`,
130
+ [startDate, endDate]
131
+ );
132
+
133
+ return {
134
+ mcp_usage_count: parseInt(mcpResult.rows[0]?.count || '0'),
135
+ database_size_bytes: parseInt(dbSizeResult.rows[0]?.size || '0'),
136
+ storage_size_bytes: parseInt(storageResult.rows[0]?.total_size || '0'),
137
+ ai_usage_by_model: aiUsageByModel.rows.map((row) => ({
138
+ model: (row.model as string) || 'unknown',
139
+ total_input_tokens: parseInt(String(row.total_input_tokens || '0')),
140
+ total_output_tokens: parseInt(String(row.total_output_tokens || '0')),
141
+ total_images: parseInt(String(row.total_images || '0')),
142
+ })),
143
+ };
144
+ } catch (error) {
145
+ logger.error('Failed to get usage stats', { error });
146
+ throw new Error('Failed to get usage stats');
147
+ }
148
+ }
149
+ }
@@ -6,8 +6,8 @@ export interface UserRecord {
6
6
  email_verified: boolean;
7
7
  created_at: string;
8
8
  updated_at: string;
9
- password: string | null;
10
- providers: string | null;
9
+ password?: string;
10
+ providers?: string;
11
11
  }
12
12
 
13
13
  // OAuth provider data from external providers
@@ -88,3 +88,67 @@ export interface GitHubEmailInfo {
88
88
  verified: boolean;
89
89
  visibility?: string;
90
90
  }
91
+
92
+ export interface MicrosoftUserInfo {
93
+ id: string;
94
+ email: string;
95
+ name: string;
96
+ avatar_url?: string;
97
+ }
98
+ export interface DiscordUserInfo {
99
+ id: string;
100
+ username: string;
101
+ email?: string;
102
+ avatar?: string;
103
+ }
104
+
105
+ export interface LinkedInUserInfo {
106
+ sub: string;
107
+ email: string;
108
+ email_verified?: boolean;
109
+ name?: string;
110
+ picture?: string;
111
+ given_name?: string;
112
+ family_name?: string;
113
+ locale?: string;
114
+ }
115
+
116
+ export interface FacebookUserInfo {
117
+ id: string;
118
+ email: string;
119
+ name?: string;
120
+ picture?: {
121
+ data?: {
122
+ url?: string;
123
+ };
124
+ };
125
+ first_name?: string;
126
+ last_name?: string;
127
+ }
128
+
129
+ export interface XUserInfo {
130
+ id: string;
131
+ name: string;
132
+ username?: string;
133
+ profile_image_url?: string;
134
+ verified?: boolean;
135
+ created_at?: string;
136
+ }
137
+
138
+ // Generic OAuth user data returned by provider services
139
+ export interface OAuthUserData {
140
+ provider: string;
141
+ providerId: string;
142
+ email: string;
143
+ userName: string;
144
+ avatarUrl: string;
145
+ identityData:
146
+ | GoogleUserInfo
147
+ | GitHubUserInfo
148
+ | DiscordUserInfo
149
+ | LinkedInUserInfo
150
+ | FacebookUserInfo
151
+ | MicrosoftUserInfo
152
+ | XUserInfo
153
+ | Record<string, unknown>;
154
+ }
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Email template types supported by email providers
3
+ */
4
+ export type EmailTemplate =
5
+ | 'email-verification-code' // Numeric OTP for email verification
6
+ | 'email-verification-link' // Magic link for email verification
7
+ | 'reset-password-code' // Numeric OTP for password reset
8
+ | 'reset-password-link'; // Magic link for password reset
@@ -39,6 +39,9 @@ export enum ERROR_CODES {
39
39
  // AI module
40
40
  AI_INVALID_API_KEY = 'AI_INVALID_API_KEY',
41
41
 
42
+ // LOGS module
43
+ LOGS_AWS_NOT_CONFIGURED = 'LOGS_AWS_NOT_CONFIGURED',
44
+
42
45
  // Billing module
43
46
  BILLING_INSUFFICIENT_BALANCE = 'BILLING_INSUFFICIENT_BALANCE',
44
47
 
@@ -51,6 +54,7 @@ export enum ERROR_CODES {
51
54
  INTERNAL_ERROR = 'INTERNAL_ERROR',
52
55
  TOO_MANY_REQUESTS = 'TOO_MANY_REQUESTS',
53
56
  FORBIDDEN = 'FORBIDDEN',
57
+ RATE_LIMITED = 'RATE_LIMITED',
54
58
  }
55
59
 
56
60
  // Next actions - what the user should do
@@ -16,32 +16,3 @@ export interface AuditLogQuery {
16
16
  limit?: number;
17
17
  offset?: number;
18
18
  }
19
-
20
- // Types for Logflare analytics logs
21
- export interface LogSource {
22
- id: number;
23
- name: string;
24
- token: string;
25
- }
26
-
27
- export interface AnalyticsLogRecord {
28
- id: string;
29
- event_message: string;
30
- timestamp: string;
31
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
32
- body: Record<string, any>;
33
- }
34
-
35
- export interface AnalyticsLogResponse {
36
- source: string;
37
- logs: AnalyticsLogRecord[];
38
- total: number;
39
- page: number;
40
- pageSize: number;
41
- }
42
-
43
- export interface LogSourceStats {
44
- source: string;
45
- count: number;
46
- lastActivity: string;
47
- }
@@ -41,12 +41,11 @@ export interface NotificationPayload {
41
41
  }
42
42
 
43
43
  export enum DataUpdateResourceType {
44
- METADATA = 'metadata',
45
- DATABASE_SCHEMA = 'database_schema',
46
- TABLE_SCHEMA = 'table_schema',
47
- STORAGE_SCHEMA = 'storage_schema',
48
- BUCKET_SCHEMA = 'bucket_schema',
49
- AUTH_SCHEMA = 'auth_schmea',
44
+ DATABASE = 'database',
45
+ USERS = 'users',
46
+ RECORDS = 'records',
47
+ BUCKETS = 'buckets',
48
+ FUNCTIONS = 'functions',
50
49
  }
51
50
 
52
51
  export interface DataUpdatePayload {
@@ -7,9 +7,7 @@
7
7
  * Currently checks for AWS instance profile, but can be extended for other cloud providers
8
8
  */
9
9
  export function isCloudEnvironment(): boolean {
10
- return !!(
11
- process.env.AWS_INSTANCE_PROFILE_NAME && process.env.AWS_INSTANCE_PROFILE_NAME.trim().length > 0
12
- );
10
+ return !!(process.env.AWS_INSTANCE_PROFILE_NAME && process.env.AWS_INSTANCE_PROFILE_NAME.trim());
13
11
  }
14
12
 
15
13
  /**
@@ -33,3 +31,11 @@ export function isDevelopment(): boolean {
33
31
  export function isProduction(): boolean {
34
32
  return process.env.NODE_ENV === 'production';
35
33
  }
34
+
35
+ /**
36
+ * Get the API base URL from environment variable or default to localhost
37
+ * @returns The API base URL
38
+ */
39
+ export function getApiBaseUrl(): string {
40
+ return process.env.API_BASE_URL || 'http://localhost:7130';
41
+ }
@@ -1,13 +1,31 @@
1
1
  import winston from 'winston';
2
+ import path from 'path';
2
3
 
3
- const logger = winston.createLogger({
4
+ const logsDir = process.env.LOGS_DIR || path.join(process.cwd(), 'logs');
5
+
6
+ export const logger = winston.createLogger({
4
7
  level: process.env.LOG_LEVEL || 'info',
5
8
  format: winston.format.combine(
6
9
  winston.format.timestamp(),
7
10
  winston.format.errors({ stack: true }),
8
11
  winston.format.json()
9
12
  ),
10
- transports: [new winston.transports.Console()],
13
+ transports: [
14
+ new winston.transports.Console(),
15
+ new winston.transports.File({
16
+ filename: path.join(logsDir, 'insforge.logs.jsonl'),
17
+ format: winston.format.printf((info) => {
18
+ const { timestamp, level, message, ...metadata } = info;
19
+ return JSON.stringify({
20
+ id: `${Date.now()}-${Math.random()}`,
21
+ timestamp,
22
+ message,
23
+ level,
24
+ metadata,
25
+ });
26
+ }),
27
+ }),
28
+ ],
11
29
  });
12
30
 
13
31
  export default logger;
@@ -1,9 +1,12 @@
1
- import { DatabaseManager } from '@/core/database/manager.js';
2
- import { AIConfigService } from '@/core/ai/config.js';
1
+ import { DatabaseManager } from '@/infra/database/database.manager.js';
2
+ import { TokenManager } from '@/infra/security/token.manager.js';
3
+ import { AIConfigService } from '@/services/ai/ai-config.service.js';
3
4
  import { isCloudEnvironment } from '@/utils/environment.js';
4
5
  import logger from '@/utils/logger.js';
5
- import { SecretsService } from '@/core/secrets/secrets';
6
- import { OAuthConfigService } from '@/core/auth/oauth.js';
6
+ import { SecretService } from '@/services/secrets/secret.service.js';
7
+ import { OAuthConfigService } from '@/services/auth/oauth-config.service.js';
8
+ import { OAuthProvidersSchema } from '@insforge/shared-schemas';
9
+ import { AuthConfigService } from '@/services/auth/auth-config.service.js';
7
10
 
8
11
  /**
9
12
  * Validates admin credentials are configured
@@ -26,12 +29,12 @@ async function seedDefaultAIConfigs(): Promise<void> {
26
29
  return;
27
30
  }
28
31
 
29
- const aiConfigService = new AIConfigService();
32
+ const aiConfigService = AIConfigService.getInstance();
30
33
 
31
34
  // Check if AI configs already exist
32
35
  const existingConfigs = await aiConfigService.findAll();
33
36
 
34
- if (existingConfigs.length > 0) {
37
+ if (existingConfigs.length) {
35
38
  return;
36
39
  }
37
40
 
@@ -47,39 +50,92 @@ async function seedDefaultAIConfigs(): Promise<void> {
47
50
  ['text', 'image'],
48
51
  ['text', 'image'],
49
52
  'openrouter',
50
- 'google/gemini-2.5-flash-image-preview'
53
+ 'google/gemini-3-pro-image-preview'
51
54
  );
52
55
 
53
56
  logger.info('✅ Default AI models configured (cloud environment)');
54
57
  }
55
58
 
56
59
  /**
57
- * Seeds default OAuth configurations for Google and GitHub
60
+ * Seeds default auth configuration for cloud environments
61
+ * Enables email verification with code-based verification method
62
+ * Only inserts config if table is empty (first startup, never configured)
63
+ */
64
+ async function seedDefaultAuthConfig(): Promise<void> {
65
+ const dbManager = DatabaseManager.getInstance();
66
+ const pool = dbManager.getPool();
67
+ const client = await pool.connect();
68
+
69
+ try {
70
+ const result = await client.query('SELECT COUNT(*) as count FROM _auth_configs');
71
+ const hasConfig = result.rows.length > 0 && Number(result.rows[0].count) > 0;
72
+
73
+ if (hasConfig) {
74
+ const authConfigService = AuthConfigService.getInstance();
75
+ const currentConfig = await authConfigService.getAuthConfig();
76
+ logger.info(
77
+ '✅ Email verification configured:',
78
+ currentConfig.requireEmailVerification ? 'enabled' : 'disabled'
79
+ );
80
+ return;
81
+ }
82
+
83
+ // Table is empty - this is first startup, insert default cloud configuration
84
+ // Note: Migration 016 will add verify_email_method, reset_password_method, sign_in_redirect_to
85
+ // so we only insert fields that exist in migration 015
86
+ await client.query(
87
+ `INSERT INTO _auth_configs (
88
+ require_email_verification,
89
+ password_min_length,
90
+ require_number,
91
+ require_lowercase,
92
+ require_uppercase,
93
+ require_special_char
94
+ ) VALUES ($1, $2, $3, $4, $5, $6)
95
+ ON CONFLICT DO NOTHING`,
96
+ [
97
+ isCloudEnvironment(), // Enable email verification for cloud
98
+ 6, // password_min_length
99
+ false, // require_number
100
+ false, // require_lowercase
101
+ false, // require_uppercase
102
+ false, // require_special_char
103
+ ]
104
+ );
105
+
106
+ logger.info('✅ Email verification enabled (cloud environment)');
107
+ } catch (error) {
108
+ logger.error('Failed to seed default auth config', {
109
+ error: error instanceof Error ? error.message : String(error),
110
+ });
111
+ // Don't throw - this is not critical for app startup
112
+ } finally {
113
+ client.release();
114
+ }
115
+ }
116
+
117
+ /**
118
+ * Seeds default OAuth configurations for supported providers
58
119
  */
59
120
  async function seedDefaultOAuthConfigs(): Promise<void> {
60
- const oauthService = OAuthConfigService.getInstance();
121
+ const oauthConfigService = OAuthConfigService.getInstance();
61
122
 
62
123
  try {
63
124
  // Check if OAuth configs already exist
64
- const existingConfigs = await oauthService.getAllConfigs();
125
+ const existingConfigs = await oauthConfigService.getAllConfigs();
65
126
  const existingProviders = existingConfigs.map((config) => config.provider.toLowerCase());
66
127
 
67
- // Seed Google OAuth config if not exists
68
- if (!existingProviders.includes('google')) {
69
- await oauthService.createConfig({
70
- provider: 'google',
71
- useSharedKey: true,
72
- });
73
- logger.info('✅ Default Google OAuth config created');
74
- }
128
+ // Default providers to seed
129
+ const defaultProviders: OAuthProvidersSchema[] = ['google', 'github'];
75
130
 
76
- // Seed GitHub OAuth config if not exists
77
- if (!existingProviders.includes('github')) {
78
- await oauthService.createConfig({
79
- provider: 'github',
80
- useSharedKey: true,
81
- });
82
- logger.info('✅ Default GitHub OAuth config created');
131
+ for (const provider of defaultProviders) {
132
+ if (!existingProviders.includes(provider)) {
133
+ await oauthConfigService.createConfig({
134
+ provider,
135
+ useSharedKey: true,
136
+ });
137
+ logger.info(`✅ Default ${provider} OAuth config created`);
138
+ }
83
139
  }
84
140
  } catch (error) {
85
141
  logger.warn('Failed to seed OAuth configs', {
@@ -93,41 +149,59 @@ async function seedDefaultOAuthConfigs(): Promise<void> {
93
149
  * Seeds OAuth configurations from local environment variables
94
150
  */
95
151
  async function seedLocalOAuthConfigs(): Promise<void> {
96
- const oauthService = OAuthConfigService.getInstance();
152
+ const oauthConfigService = OAuthConfigService.getInstance();
97
153
 
98
154
  try {
99
155
  // Check if OAuth configs already exist
100
- const existingConfigs = await oauthService.getAllConfigs();
156
+ const existingConfigs = await oauthConfigService.getAllConfigs();
101
157
  const existingProviders = existingConfigs.map((config) => config.provider.toLowerCase());
102
158
 
103
- // Seed Google OAuth config from environment variables if credentials exist
104
- const googleClientId = process.env.GOOGLE_CLIENT_ID;
105
- const googleClientSecret = process.env.GOOGLE_CLIENT_SECRET;
106
-
107
- if (googleClientId && googleClientSecret && !existingProviders.includes('google')) {
108
- await oauthService.createConfig({
159
+ // Environment variable mappings for OAuth providers
160
+ const envMappings: Array<{
161
+ provider: OAuthProvidersSchema;
162
+ clientIdEnv: string;
163
+ clientSecretEnv: string;
164
+ }> = [
165
+ {
109
166
  provider: 'google',
110
- clientId: googleClientId,
111
- clientSecret: googleClientSecret,
112
- scopes: ['openid', 'email', 'profile'],
113
- useSharedKey: false,
114
- });
115
- logger.info('✅ Google OAuth config loaded from environment variables');
116
- }
167
+ clientIdEnv: 'GOOGLE_CLIENT_ID',
168
+ clientSecretEnv: 'GOOGLE_CLIENT_SECRET',
169
+ },
170
+ {
171
+ provider: 'github',
172
+ clientIdEnv: 'GITHUB_CLIENT_ID',
173
+ clientSecretEnv: 'GITHUB_CLIENT_SECRET',
174
+ },
175
+ {
176
+ provider: 'discord',
177
+ clientIdEnv: 'DISCORD_CLIENT_ID',
178
+ clientSecretEnv: 'DISCORD_CLIENT_SECRET',
179
+ },
180
+ {
181
+ provider: 'linkedin',
182
+ clientIdEnv: 'LINKEDIN_CLIENT_ID',
183
+ clientSecretEnv: 'LINKEDIN_CLIENT_SECRET',
184
+ },
185
+ {
186
+ provider: 'microsoft',
187
+ clientIdEnv: 'MICROSOFT_CLIENT_ID',
188
+ clientSecretEnv: 'MICROSOFT_CLIENT_SECRET',
189
+ },
190
+ ];
117
191
 
118
- // Seed GitHub OAuth config from environment variables if credentials exist
119
- const githubClientId = process.env.GITHUB_CLIENT_ID;
120
- const githubClientSecret = process.env.GITHUB_CLIENT_SECRET;
192
+ for (const { provider, clientIdEnv, clientSecretEnv } of envMappings) {
193
+ const clientId = process.env[clientIdEnv];
194
+ const clientSecret = process.env[clientSecretEnv];
121
195
 
122
- if (githubClientId && githubClientSecret && !existingProviders.includes('github')) {
123
- await oauthService.createConfig({
124
- provider: 'github',
125
- clientId: githubClientId,
126
- clientSecret: githubClientSecret,
127
- scopes: ['user:email'],
128
- useSharedKey: false,
129
- });
130
- logger.info('✅ GitHub OAuth config loaded from environment variables');
196
+ if (clientId && clientSecret && !existingProviders.includes(provider)) {
197
+ await oauthConfigService.createConfig({
198
+ provider,
199
+ clientId,
200
+ clientSecret,
201
+ useSharedKey: false,
202
+ });
203
+ logger.info(`✅ ${provider} OAuth config loaded from environment variables`);
204
+ }
131
205
  }
132
206
  } catch (error) {
133
207
  logger.warn('Failed to seed local OAuth configs', {
@@ -138,7 +212,8 @@ async function seedLocalOAuthConfigs(): Promise<void> {
138
212
 
139
213
  // Create api key, admin user, and default AI configs
140
214
  export async function seedBackend(): Promise<void> {
141
- const secretService = new SecretsService();
215
+ const secretService = SecretService.getInstance();
216
+
142
217
  const dbManager = DatabaseManager.getInstance();
143
218
 
144
219
  const adminEmail = process.env.ADMIN_EMAIL || 'admin@example.com';
@@ -163,13 +238,16 @@ export async function seedBackend(): Promise<void> {
163
238
  });
164
239
  // Database connection info is already logged above
165
240
 
166
- if (tables.length > 0) {
241
+ if (tables.length) {
167
242
  logger.info(`✅ Found ${tables.length} user tables`);
168
243
  }
169
244
 
170
245
  // seed AI configs for cloud environment
171
246
  await seedDefaultAIConfigs();
172
247
 
248
+ // Enable email verification in cloud environment
249
+ await seedDefaultAuthConfig();
250
+
173
251
  // add default OAuth configs in Cloud hosting
174
252
  if (isCloudEnvironment()) {
175
253
  await seedDefaultOAuthConfigs();
@@ -180,15 +258,30 @@ export async function seedBackend(): Promise<void> {
180
258
  // Initialize reserved secrets for edge functions
181
259
  // Add INSFORGE_INTERNAL_URL for Deno-to-backend container communication
182
260
  const insforgInternalUrl = 'http://insforge:7130';
183
- const existingSecret = await secretService.getSecretByKey('INSFORGE_INTERNAL_URL');
261
+ const existingInternalUrlSecret = await secretService.getSecretByKey('INSFORGE_INTERNAL_URL');
184
262
 
185
- if (existingSecret === null) {
263
+ if (existingInternalUrlSecret === null) {
186
264
  await secretService.createSecret({
187
265
  key: 'INSFORGE_INTERNAL_URL',
188
266
  isReserved: true,
189
267
  value: insforgInternalUrl,
190
268
  });
191
- logger.info('✅ System secrets initialized');
269
+ logger.info('✅ INSFORGE_INTERNAL_URL secret initialized');
270
+ }
271
+
272
+ // Add ANON_KEY for public edge function access
273
+ const existingAnonKeySecret = await secretService.getSecretByKey('ANON_KEY');
274
+
275
+ if (existingAnonKeySecret === null) {
276
+ const tokenManager = TokenManager.getInstance();
277
+ const anonToken = tokenManager.generateAnonToken();
278
+
279
+ await secretService.createSecret({
280
+ key: 'ANON_KEY',
281
+ isReserved: true,
282
+ value: anonToken,
283
+ });
284
+ logger.info('✅ ANON_KEY secret initialized');
192
285
  }
193
286
 
194
287
  logger.info(`API key generated: ${apiKey}`);
@@ -49,7 +49,7 @@ export function parseSQLStatements(sqlText: string): string[] {
49
49
  .replace(/--.*$/gm, '') // Remove line comments
50
50
  .replace(/\/\*[\s\S]*?\*\//g, '') // Remove block comments
51
51
  .trim();
52
- return withoutComments.length > 0;
52
+ return withoutComments.length;
53
53
  });
54
54
 
55
55
  logger.debug(`Parsed ${statements.length} SQL statements from input`);