insforge 0.3.3 → 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 -780
  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,57 @@
1
+ import { useCallback, useEffect } from 'react';
2
+ import { useSearchParams } from 'react-router-dom';
3
+ import { SignIn } from '@insforge/react';
4
+ import broadcastService, { BroadcastEventType, BroadcastEvent } from '../lib/broadcastService';
5
+ import { ErrorCard } from '../components/ErrorCard';
6
+
7
+ export function SignInPage() {
8
+ const [searchParams] = useSearchParams();
9
+ const redirectUrl = searchParams.get('redirect');
10
+
11
+ // Listen for email verification success from other tabs
12
+ useEffect(() => {
13
+ if (!redirectUrl) {
14
+ return;
15
+ }
16
+
17
+ const unsubscribeVerified = broadcastService.subscribe(
18
+ BroadcastEventType.EMAIL_VERIFIED_SUCCESS,
19
+ (event: BroadcastEvent) => {
20
+ const { accessToken, user } = event.data || {};
21
+ if (accessToken && user) {
22
+ // Email verified in another tab, redirect with token
23
+ try {
24
+ const finalUrl = new URL(redirectUrl, window.location.origin);
25
+ const params = new URLSearchParams();
26
+ params.set('access_token', accessToken);
27
+ params.set('user_id', user.id);
28
+ params.set('email', user.email);
29
+ params.set('name', user.name);
30
+ finalUrl.search = params.toString();
31
+ window.location.href = finalUrl.toString();
32
+ } catch {
33
+ console.error('Failed to redirect to final URL');
34
+ }
35
+ }
36
+ }
37
+ );
38
+
39
+ return () => {
40
+ unsubscribeVerified();
41
+ };
42
+ }, [redirectUrl]);
43
+
44
+ const handleError = useCallback((error: Error) => {
45
+ console.error('Sign in failed:', error);
46
+ }, []);
47
+
48
+ if (!redirectUrl) {
49
+ return (
50
+ <ErrorCard title="Missing Redirect URL">
51
+ <p>No redirect URL provided. Please check the URL and try again.</p>
52
+ </ErrorCard>
53
+ );
54
+ }
55
+
56
+ return <SignIn onError={handleError} />;
57
+ }
@@ -0,0 +1,57 @@
1
+ import { useCallback, useEffect } from 'react';
2
+ import { useSearchParams } from 'react-router-dom';
3
+ import { SignUp } from '@insforge/react';
4
+ import broadcastService, { BroadcastEventType, BroadcastEvent } from '../lib/broadcastService';
5
+ import { ErrorCard } from '../components/ErrorCard';
6
+
7
+ export function SignUpPage() {
8
+ const [searchParams] = useSearchParams();
9
+ const redirectUrl = searchParams.get('redirect');
10
+
11
+ // Listen for email verification success from other tabs
12
+ useEffect(() => {
13
+ if (!redirectUrl) {
14
+ return;
15
+ }
16
+
17
+ const unsubscribeVerified = broadcastService.subscribe(
18
+ BroadcastEventType.EMAIL_VERIFIED_SUCCESS,
19
+ (event: BroadcastEvent) => {
20
+ const { accessToken, user } = event.data || {};
21
+ if (accessToken && user) {
22
+ // Email verified in another tab, redirect with token
23
+ try {
24
+ const finalUrl = new URL(redirectUrl, window.location.origin);
25
+ const params = new URLSearchParams();
26
+ params.set('access_token', accessToken);
27
+ params.set('user_id', user.id);
28
+ params.set('email', user.email);
29
+ params.set('name', user.name);
30
+ finalUrl.search = params.toString();
31
+ window.location.href = finalUrl.toString();
32
+ } catch {
33
+ console.error('Failed to redirect to final URL');
34
+ }
35
+ }
36
+ }
37
+ );
38
+
39
+ return () => {
40
+ unsubscribeVerified();
41
+ };
42
+ }, [redirectUrl]);
43
+
44
+ const handleError = useCallback((error: Error) => {
45
+ console.error('Sign up failed:', error);
46
+ }, []);
47
+
48
+ if (!redirectUrl) {
49
+ return (
50
+ <ErrorCard title="Missing Redirect URL">
51
+ <p>No redirect URL provided. Please check the URL and try again.</p>
52
+ </ErrorCard>
53
+ );
54
+ }
55
+
56
+ return <SignUp onError={handleError} />;
57
+ }
@@ -0,0 +1,20 @@
1
+ import { useSearchParams } from 'react-router-dom';
2
+ import { VerifyEmail } from '@insforge/react';
3
+ import broadcastService, { BroadcastEventType } from '../lib/broadcastService';
4
+
5
+ export function VerifyEmailPage() {
6
+ const [searchParams] = useSearchParams();
7
+ const token = searchParams.get('token');
8
+
9
+ return (
10
+ <VerifyEmail
11
+ token={token || ''}
12
+ onSuccess={(data) => {
13
+ broadcastService.broadcast(BroadcastEventType.EMAIL_VERIFIED_SUCCESS, data);
14
+ }}
15
+ onError={(error) => {
16
+ console.error('Email verification failed:', error);
17
+ }}
18
+ />
19
+ );
20
+ }
@@ -0,0 +1,10 @@
1
+ /// <reference types="vite/client" />
2
+ /// <reference types="vite-plugin-svgr/client" />
3
+
4
+ interface ImportMetaEnv {
5
+ readonly VITE_API_BASE_URL?: string;
6
+ }
7
+
8
+ interface ImportMeta {
9
+ readonly env: ImportMetaEnv;
10
+ }
@@ -0,0 +1,32 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2020",
4
+ "useDefineForClassFields": true,
5
+ "lib": ["ES2020", "DOM", "DOM.Iterable"],
6
+ "module": "ESNext",
7
+ "skipLibCheck": true,
8
+
9
+ /* Bundler mode */
10
+ "moduleResolution": "bundler",
11
+ "allowImportingTsExtensions": true,
12
+ "resolveJsonModule": true,
13
+ "isolatedModules": true,
14
+ "noEmit": true,
15
+ "jsx": "react-jsx",
16
+
17
+ /* Linting */
18
+ "strict": true,
19
+ "noUnusedLocals": true,
20
+ "noUnusedParameters": true,
21
+ "noFallthroughCasesInSwitch": true,
22
+
23
+ /* Path mapping */
24
+ "baseUrl": ".",
25
+ "paths": {
26
+ "@/*": ["./src/*"]
27
+ }
28
+ },
29
+ "include": ["src"],
30
+ "references": [{ "path": "./tsconfig.node.json" }]
31
+ }
32
+
@@ -0,0 +1,11 @@
1
+ {
2
+ "compilerOptions": {
3
+ "composite": true,
4
+ "skipLibCheck": true,
5
+ "module": "ESNext",
6
+ "moduleResolution": "bundler",
7
+ "allowSyntheticDefaultImports": true
8
+ },
9
+ "include": ["vite.config.ts"]
10
+ }
11
+
@@ -0,0 +1,25 @@
1
+ import { defineConfig } from 'vite';
2
+ import react from '@vitejs/plugin-react';
3
+ import tailwindcss from '@tailwindcss/vite';
4
+ import path from 'path';
5
+
6
+ export default defineConfig({
7
+ base: '/auth/',
8
+ plugins: [react(), tailwindcss()],
9
+ resolve: {
10
+ alias: {
11
+ '@': path.resolve(__dirname, './src'),
12
+ },
13
+ },
14
+ server: {
15
+ port: 7132,
16
+ host: true,
17
+ strictPort: false,
18
+ watch: {
19
+ usePolling: true,
20
+ },
21
+ },
22
+ build: {
23
+ outDir: '../dist/auth',
24
+ },
25
+ });
@@ -16,12 +16,12 @@
16
16
  "test:coverage": "vitest run --coverage",
17
17
  "test:ui": "vitest --ui",
18
18
  "test:e2e": "./tests/run-all-tests.sh",
19
- "migrate:up": "node-pg-migrate up --migrations-table _migrations",
20
- "migrate:down": "node-pg-migrate down --migrations-table _migrations",
21
- "migrate:create": "node-pg-migrate create --migrations-table _migrations",
22
- "migrate:redo": "node-pg-migrate redo --migrations-table _migrations",
23
- "migrate:up:local": "dotenv -e ../.env -- node-pg-migrate up --migrations-table _migrations",
24
- "migrate:down:local": "dotenv -e ../.env -- node-pg-migrate down --migrations-table _migrations"
19
+ "migrate:up": "node-pg-migrate up --migrations-dir src/infra/database/migrations --migrations-table _migrations",
20
+ "migrate:down": "node-pg-migrate down --migrations-dir src/infra/database/migrations --migrations-table _migrations",
21
+ "migrate:create": "node-pg-migrate create --migrations-dir src/infra/database/migrations --migrations-table _migrations",
22
+ "migrate:redo": "node-pg-migrate redo --migrations-dir src/infra/database/migrations --migrations-table _migrations",
23
+ "migrate:up:local": "dotenv -e ../.env -- node-pg-migrate up --migrations-dir src/infra/database/migrations --migrations-table _migrations",
24
+ "migrate:down:local": "dotenv -e ../.env -- node-pg-migrate down --migrations-dir src/infra/database/migrations --migrations-table _migrations"
25
25
  },
26
26
  "keywords": [
27
27
  "backend-as-a-service",
@@ -32,14 +32,13 @@
32
32
  "@asteasolutions/zod-to-openapi": "^7.3.4",
33
33
  "@aws-sdk/client-cloudwatch-logs": "^3.713.0",
34
34
  "@aws-sdk/client-s3": "^3.713.0",
35
+ "@aws-sdk/cloudfront-signer": "^3.901.0",
35
36
  "@aws-sdk/s3-presigned-post": "^3.879.0",
36
37
  "@aws-sdk/s3-request-presigner": "^3.879.0",
37
38
  "@databases/split-sql-query": "^1.0.4",
38
39
  "@databases/sql": "^3.3.0",
39
40
  "@types/multer": "^1.4.13",
40
- "@types/node-pg-migrate": "^2.3.1",
41
41
  "@types/pg": "^8.15.4",
42
- "@types/socket.io": "^3.0.2",
43
42
  "axios": "^1.11.0",
44
43
  "bcryptjs": "^3.0.2",
45
44
  "cors": "^2.8.5",
@@ -48,7 +47,7 @@
48
47
  "express": "^4.19.2",
49
48
  "express-rate-limit": "^7.1.5",
50
49
  "google-auth-library": "^10.1.0",
51
- "jose": "^6.0.12",
50
+ "jose": "^6.1.0",
52
51
  "jsonwebtoken": "^9.0.2",
53
52
  "multer": "^2.0.2",
54
53
  "node-fetch": "^3.3.2",
@@ -70,6 +69,7 @@
70
69
  "tsup": "^8.5.0",
71
70
  "tsx": "^4.7.1",
72
71
  "typescript": "^5.3.3",
72
+ "vite-tsconfig-paths": "^5.1.4",
73
73
  "vitest": "^3.2.4"
74
74
  }
75
75
  }
@@ -1,9 +1,8 @@
1
1
  import { Request, Response, NextFunction } from 'express';
2
- import { AuthService } from '@/core/auth/auth.js';
2
+ import { TokenManager } from '@/infra/security/token.manager.js';
3
3
  import { AppError } from './error.js';
4
4
  import { ERROR_CODES, NEXT_ACTION } from '@/types/error-constants.js';
5
- import { verifyCloudToken } from '@/utils/cloud-token.js';
6
- import { SecretsService } from '@/core/secrets/secrets.js';
5
+ import { SecretService } from '@/services/secrets/secret.service.js';
7
6
 
8
7
  export interface AuthRequest extends Request {
9
8
  user?: {
@@ -16,8 +15,8 @@ export interface AuthRequest extends Request {
16
15
  projectId?: string;
17
16
  }
18
17
 
19
- const authService = AuthService.getInstance();
20
- const secretService = new SecretsService();
18
+ const tokenManager = TokenManager.getInstance();
19
+ const secretService = SecretService.getInstance();
21
20
 
22
21
  // Helper function to extract Bearer token
23
22
  function extractBearerToken(authHeader: string | undefined): string | null {
@@ -86,7 +85,7 @@ export async function verifyAdmin(req: AuthRequest, res: Response, next: NextFun
86
85
  }
87
86
 
88
87
  // For admin, we use JWT tokens
89
- const payload = authService.verifyToken(token);
88
+ const payload = tokenManager.verifyToken(token);
90
89
 
91
90
  if (payload.role !== 'project_admin') {
92
91
  throw new AppError(
@@ -167,7 +166,7 @@ export function verifyToken(req: AuthRequest, _res: Response, next: NextFunction
167
166
  }
168
167
 
169
168
  // Verify JWT token
170
- const payload = authService.verifyToken(token);
169
+ const payload = tokenManager.verifyToken(token);
171
170
 
172
171
  // Validate token has a role
173
172
  if (!payload.role) {
@@ -215,8 +214,8 @@ export async function verifyCloudBackend(req: AuthRequest, _res: Response, next:
215
214
  );
216
215
  }
217
216
 
218
- // Use helper function to verify cloud token
219
- const { projectId } = await verifyCloudToken(token);
217
+ // Use TokenManager to verify cloud token
218
+ const { projectId } = await tokenManager.verifyCloudToken(token);
220
219
 
221
220
  // Set project_id on request for use in route handlers
222
221
  req.projectId = projectId;
@@ -0,0 +1,127 @@
1
+ import rateLimit from 'express-rate-limit';
2
+ import { Request, Response, NextFunction } from 'express';
3
+ import { AppError } from './error.js';
4
+ import { ERROR_CODES } from '@/types/error-constants.js';
5
+
6
+ /**
7
+ * Store for tracking per-email cooldowns
8
+ * Maps email -> last request timestamp
9
+ */
10
+ const emailCooldowns = new Map<string, number>();
11
+
12
+ /**
13
+ * Cleanup old cooldown entries every 5 minutes
14
+ */
15
+ setInterval(
16
+ () => {
17
+ const now = Date.now();
18
+ const fiveMinutes = 5 * 60 * 1000;
19
+
20
+ for (const [email, timestamp] of emailCooldowns.entries()) {
21
+ if (now - timestamp > fiveMinutes) {
22
+ emailCooldowns.delete(email);
23
+ }
24
+ }
25
+ },
26
+ 5 * 60 * 1000
27
+ );
28
+
29
+ /**
30
+ * Per-IP rate limiter for email otp requests
31
+ * Prevents brute-force attacks, resource exhaustion, and enumeration from single IP
32
+ *
33
+ * Limits: 5 requests per 15 minutes per IP
34
+ * Counts ALL requests (both successful and failed) to prevent abuse
35
+ */
36
+ export const sendEmailOTPRateLimiter = rateLimit({
37
+ windowMs: 15 * 60 * 1000, // 15 minutes
38
+ max: 5, // Limit each IP to 5 requests per windowMs
39
+ standardHeaders: true, // Return rate limit info in the `RateLimit-*` headers
40
+ legacyHeaders: false, // Disable the `X-RateLimit-*` headers
41
+ handler: (_req: Request, _res: Response, next: NextFunction) => {
42
+ next(
43
+ new AppError(
44
+ 'Too many send email verification requests from this IP. Please try again in 15 minutes.',
45
+ 429,
46
+ ERROR_CODES.TOO_MANY_REQUESTS
47
+ )
48
+ );
49
+ },
50
+ // Count all requests (both successes and failures) to prevent resource exhaustion and enumeration
51
+ skipSuccessfulRequests: false,
52
+ skipFailedRequests: false,
53
+ });
54
+
55
+ /**
56
+ * Per-IP rate limiter for email OTP verification attempts
57
+ * Prevents brute-force code guessing
58
+ *
59
+ * Limits: 10 attempts per 15 minutes per IP
60
+ */
61
+ export const verifyOTPRateLimiter = rateLimit({
62
+ windowMs: 15 * 60 * 1000, // 15 minutes
63
+ max: 10, // Limit each IP to 10 verification attempts per windowMs
64
+ standardHeaders: true,
65
+ legacyHeaders: false,
66
+ handler: (_req: Request, _res: Response, next: NextFunction) => {
67
+ next(
68
+ new AppError(
69
+ 'Too many verification attempts from this IP. Please try again in 15 minutes.',
70
+ 429,
71
+ ERROR_CODES.TOO_MANY_REQUESTS
72
+ )
73
+ );
74
+ },
75
+ skipSuccessfulRequests: true, // Don't count successful verifications
76
+ skipFailedRequests: false, // Count failed attempts to prevent brute force
77
+ });
78
+
79
+ /**
80
+ * Per-email cooldown middleware
81
+ * Prevents enumeration attacks by enforcing minimum time between requests for same email
82
+ *
83
+ * Cooldown: 60 seconds between requests for same email
84
+ */
85
+ export const perEmailCooldown = (cooldownMs: number = 60000) => {
86
+ return (req: Request, _res: Response, next: NextFunction) => {
87
+ const email = req.body?.email?.toLowerCase();
88
+
89
+ if (!email) {
90
+ // If no email in body, let it pass (will be caught by validation)
91
+ return next();
92
+ }
93
+
94
+ const now = Date.now();
95
+ const lastRequest = emailCooldowns.get(email);
96
+
97
+ if (lastRequest && now - lastRequest < cooldownMs) {
98
+ const remainingMs = cooldownMs - (now - lastRequest);
99
+ const remainingSec = Math.ceil(remainingMs / 1000);
100
+
101
+ throw new AppError(
102
+ `Please wait ${remainingSec} seconds before requesting another code for this email`,
103
+ 429,
104
+ ERROR_CODES.TOO_MANY_REQUESTS
105
+ );
106
+ }
107
+
108
+ // Update last request time
109
+ emailCooldowns.set(email, now);
110
+ next();
111
+ };
112
+ };
113
+
114
+ /**
115
+ * Combined rate limiter for sending email otp requests
116
+ * Applies both per-IP and per-email limits
117
+ */
118
+ export const sendEmailOTPLimiter = [
119
+ sendEmailOTPRateLimiter,
120
+ perEmailCooldown(60000), // 60 second cooldown per email
121
+ ];
122
+
123
+ /**
124
+ * Rate limiter for OTP verification attempts (email OTP verification)
125
+ * Only per-IP limit, no per-email limit (to allow legitimate retries)
126
+ */
127
+ export const verifyOTPLimiter = [verifyOTPRateLimiter];
@@ -1,15 +1,15 @@
1
1
  import { Router, Response, NextFunction } from 'express';
2
- import { ChatService } from '@/core/ai/chat';
3
- import { AuthRequest, verifyAdmin, verifyUser } from '../middleware/auth';
4
- import { ImageService } from '@/core/ai/image';
5
- import { AIModelService } from '@/core/ai/model';
6
- import { AppError } from '@/api/middleware/error';
7
- import { ERROR_CODES } from '@/types/error-constants';
8
- import { successResponse } from '@/utils/response';
9
- import { AIConfigService } from '@/core/ai/config';
10
- import { AIUsageService } from '@/core/ai/usage';
11
- import { AIClientService } from '@/core/ai/client';
12
- import { AuditService } from '@/core/logs/audit';
2
+ import { ChatCompletionService } from '@/services/ai/chat-completion.service.js';
3
+ import { AuthRequest, verifyAdmin, verifyUser } from '../../middlewares/auth.js';
4
+ import { ImageGenerationService } from '@/services/ai/image-generation.service.js';
5
+ import { AIModelService } from '@/services/ai/ai-model.service.js';
6
+ import { AppError } from '@/api/middlewares/error.js';
7
+ import { ERROR_CODES } from '@/types/error-constants.js';
8
+ import { successResponse } from '@/utils/response.js';
9
+ import { AIConfigService } from '@/services/ai/ai-config.service.js';
10
+ import { AIUsageService } from '@/services/ai/ai-usage.service.js';
11
+ import { AIClientService } from '@/providers/ai/openrouter.provider.js';
12
+ import { AuditService } from '@/services/logs/audit.service.js';
13
13
  import {
14
14
  createAIConfigurationRequestSchema,
15
15
  updateAIConfigurationRequestSchema,
@@ -20,25 +20,21 @@ import {
20
20
  } from '@insforge/shared-schemas';
21
21
 
22
22
  const router = Router();
23
- const chatService = new ChatService();
24
- const aiConfigService = new AIConfigService();
25
- const aiUsageService = new AIUsageService();
23
+ const chatService = ChatCompletionService.getInstance();
24
+ const aiConfigService = AIConfigService.getInstance();
25
+ const aiUsageService = AIUsageService.getInstance();
26
26
  const auditService = AuditService.getInstance();
27
27
 
28
28
  /**
29
29
  * GET /api/ai/models
30
30
  * Get all available AI models in ListModelsResponse format
31
31
  */
32
- router.get('/models', verifyAdmin, async (req: AuthRequest, res: Response) => {
32
+ router.get('/models', verifyAdmin, async (req: AuthRequest, res: Response, next: NextFunction) => {
33
33
  try {
34
34
  const models = await AIModelService.getModels();
35
- res.json(models);
35
+ successResponse(res, models);
36
36
  } catch (error) {
37
- console.error('Error getting models:', error);
38
- res.status(500).json({
39
- error: 'Failed to get models list',
40
- details: error instanceof Error ? error.message : String(error),
41
- });
37
+ next(error);
42
38
  }
43
39
  });
44
40
 
@@ -98,7 +94,7 @@ router.post(
98
94
 
99
95
  // Non-streaming requests
100
96
  const result = await chatService.chat(messages, options);
101
- res.json(result);
97
+ successResponse(res, result);
102
98
  } catch (error) {
103
99
  if (error instanceof AppError) {
104
100
  next(error);
@@ -133,9 +129,9 @@ router.post(
133
129
  );
134
130
  }
135
131
 
136
- const result = await ImageService.generate(validationResult.data);
132
+ const result = await ImageGenerationService.generate(validationResult.data);
137
133
 
138
- res.json(result);
134
+ successResponse(res, result);
139
135
  } catch (error) {
140
136
  if (error instanceof AppError) {
141
137
  next(error);