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,75 @@
1
+ import { EmailProvider } from '@/providers/email/base.provider.js';
2
+ import { CloudEmailProvider } from '@/providers/email/cloud.provider.js';
3
+ import { EmailTemplate } from '@/types/email.js';
4
+ import logger from '@/utils/logger.js';
5
+
6
+ /**
7
+ * Email service that orchestrates different email providers
8
+ */
9
+ export class EmailService {
10
+ private static instance: EmailService;
11
+ private provider: EmailProvider;
12
+
13
+ private constructor() {
14
+ // For now, we only support cloud provider
15
+ // In the future, this can be configured via environment variables
16
+ // Example:
17
+ // if (process.env.EMAIL_PROVIDER === 'smtp') {
18
+ // this.provider = new SMTPEmailProvider(config.email.smtp);
19
+ // } else if (process.env.EMAIL_PROVIDER === 'sendgrid') {
20
+ // this.provider = new SendGridEmailProvider(config.email.sendgrid);
21
+ // } else {
22
+ // this.provider = new CloudEmailProvider();
23
+ // }
24
+
25
+ this.provider = new CloudEmailProvider();
26
+ logger.info('Using email provider: Cloud (Insforge)');
27
+ }
28
+
29
+ /**
30
+ * Get singleton instance of EmailService
31
+ */
32
+ public static getInstance(): EmailService {
33
+ if (!EmailService.instance) {
34
+ EmailService.instance = new EmailService();
35
+ }
36
+ return EmailService.instance;
37
+ }
38
+
39
+ /**
40
+ * Send email using predefined template
41
+ * @param email - Recipient email address
42
+ * @param name - Recipient name
43
+ * @param template - Template type
44
+ * @param variables - Variables to use in the email template
45
+ */
46
+ public async sendWithTemplate(
47
+ email: string,
48
+ name: string,
49
+ template: EmailTemplate,
50
+ variables?: Record<string, string>
51
+ ): Promise<void> {
52
+ return this.provider.sendWithTemplate(email, name, template, variables);
53
+ }
54
+
55
+ /**
56
+ * Send raw email (if provider supports it)
57
+ * @param to - Recipient email address
58
+ * @param subject - Email subject
59
+ * @param html - HTML email body
60
+ * @param text - Plain text email body (optional)
61
+ */
62
+ public async sendRaw(to: string, subject: string, html: string, text?: string): Promise<void> {
63
+ if (!this.provider.sendRaw) {
64
+ throw new Error('Current email provider does not support raw email sending');
65
+ }
66
+ return this.provider.sendRaw(to, subject, html, text);
67
+ }
68
+
69
+ /**
70
+ * Check if current provider supports templates
71
+ */
72
+ public supportsTemplates(): boolean {
73
+ return this.provider.supportsTemplates();
74
+ }
75
+ }
@@ -1,13 +1,13 @@
1
- import { DatabaseManager } from '@/core/database/manager.js';
1
+ import { DatabaseManager } from '@/infra/database/database.manager.js';
2
2
  import {
3
3
  EdgeFunctionMetadataSchema,
4
4
  FunctionUploadRequest,
5
5
  FunctionUpdateRequest,
6
6
  } from '@insforge/shared-schemas';
7
7
  import logger from '@/utils/logger.js';
8
- import { DatabaseError } from 'pg';
8
+ import { DatabaseError, Pool } from 'pg';
9
9
  import fetch from 'node-fetch';
10
- import { AppError } from '@/api/middleware/error.js';
10
+ import { AppError } from '@/api/middlewares/error.js';
11
11
  import { ERROR_CODES } from '@/types/error-constants.js';
12
12
 
13
13
  export interface FunctionWithRuntime {
@@ -17,19 +17,25 @@ export interface FunctionWithRuntime {
17
17
  };
18
18
  }
19
19
 
20
- export class FunctionsService {
21
- private static instance: FunctionsService;
22
- private db;
20
+ export class FunctionService {
21
+ private static instance: FunctionService;
22
+ private pool: Pool | null = null;
23
23
 
24
- private constructor() {
25
- this.db = DatabaseManager.getInstance();
24
+ private constructor() {}
25
+
26
+ static getInstance(): FunctionService {
27
+ if (!FunctionService.instance) {
28
+ FunctionService.instance = new FunctionService();
29
+ }
30
+ return FunctionService.instance;
26
31
  }
27
32
 
28
- static getInstance(): FunctionsService {
29
- if (!FunctionsService.instance) {
30
- FunctionsService.instance = new FunctionsService();
33
+ private getPool(): Pool {
34
+ if (!this.pool) {
35
+ const dbManager = DatabaseManager.getInstance();
36
+ this.pool = dbManager.getPool();
31
37
  }
32
- return FunctionsService.instance;
38
+ return this.pool;
33
39
  }
34
40
 
35
41
  /**
@@ -37,15 +43,15 @@ export class FunctionsService {
37
43
  */
38
44
  async listFunctions(): Promise<FunctionWithRuntime> {
39
45
  try {
40
- const functions = await this.db
41
- .prepare(
42
- `SELECT
43
- id, slug, name, description, status,
44
- created_at, updated_at, deployed_at
45
- FROM _functions
46
- ORDER BY created_at DESC`
47
- )
48
- .all();
46
+ const result = await this.getPool().query(
47
+ `SELECT
48
+ id, slug, name, description, status,
49
+ created_at, updated_at, deployed_at
50
+ FROM _functions
51
+ ORDER BY created_at DESC`
52
+ );
53
+
54
+ const functions = result.rows;
49
55
 
50
56
  // Check if Deno runtime is healthy
51
57
  let runtimeHealthy = false;
@@ -82,17 +88,16 @@ export class FunctionsService {
82
88
  */
83
89
  async getFunction(slug: string): Promise<Record<string, unknown> | undefined> {
84
90
  try {
85
- const func = await this.db
86
- .prepare(
87
- `SELECT
88
- id, slug, name, description, code, status,
89
- created_at, updated_at, deployed_at
90
- FROM _functions
91
- WHERE slug = ?`
92
- )
93
- .get(slug);
94
-
95
- return func;
91
+ const result = await this.getPool().query(
92
+ `SELECT
93
+ id, slug, name, description, code, status,
94
+ created_at, updated_at, deployed_at
95
+ FROM _functions
96
+ WHERE slug = $1`,
97
+ [slug]
98
+ );
99
+
100
+ return result.rows[0];
96
101
  } catch (error) {
97
102
  logger.error('Failed to get function', {
98
103
  error: error instanceof Error ? error.message : String(error),
@@ -107,6 +112,7 @@ export class FunctionsService {
107
112
  * Create a new function
108
113
  */
109
114
  async createFunction(data: FunctionUploadRequest): Promise<Record<string, unknown>> {
115
+ const client = await this.getPool().connect();
110
116
  try {
111
117
  const { name, code, description, status } = data;
112
118
  const slug = data.slug || name.toLowerCase().replace(/\s+/g, '-');
@@ -118,29 +124,27 @@ export class FunctionsService {
118
124
  const id = crypto.randomUUID();
119
125
 
120
126
  // Insert function
121
- await this.db
122
- .prepare(
123
- `INSERT INTO _functions (id, slug, name, description, code, status)
124
- VALUES (?, ?, ?, ?, ?, ?)`
125
- )
126
- .run(id, slug, name, description || null, code, status);
127
+ await client.query(
128
+ `INSERT INTO _functions (id, slug, name, description, code, status)
129
+ VALUES ($1, $2, $3, $4, $5, $6)`,
130
+ [id, slug, name, description || null, code, status]
131
+ );
127
132
 
128
133
  // If status is active, update deployed_at
129
134
  if (status === 'active') {
130
- await this.db
131
- .prepare(`UPDATE _functions SET deployed_at = CURRENT_TIMESTAMP WHERE id = ?`)
132
- .run(id);
135
+ await client.query(`UPDATE _functions SET deployed_at = CURRENT_TIMESTAMP WHERE id = $1`, [
136
+ id,
137
+ ]);
133
138
  }
134
139
 
135
140
  // Fetch the created function
136
- const created = await this.db
137
- .prepare(
138
- `SELECT id, slug, name, description, status, created_at
139
- FROM _functions WHERE id = ?`
140
- )
141
- .get(id);
142
-
143
- return created;
141
+ const result = await client.query(
142
+ `SELECT id, slug, name, description, status, created_at
143
+ FROM _functions WHERE id = $1`,
144
+ [id]
145
+ );
146
+
147
+ return result.rows[0];
144
148
  } catch (error) {
145
149
  // Re-throw AppErrors as-is
146
150
  if (error instanceof AppError) {
@@ -162,6 +166,8 @@ export class FunctionsService {
162
166
  }
163
167
 
164
168
  throw error;
169
+ } finally {
170
+ client.release();
165
171
  }
166
172
  }
167
173
 
@@ -172,10 +178,13 @@ export class FunctionsService {
172
178
  slug: string,
173
179
  updates: FunctionUpdateRequest
174
180
  ): Promise<Record<string, unknown> | null> {
181
+ const client = await this.getPool().connect();
175
182
  try {
176
183
  // Check if function exists
177
- const existing = await this.db.prepare('SELECT id FROM _functions WHERE slug = ?').get(slug);
178
- if (!existing) {
184
+ const existingResult = await client.query('SELECT id FROM _functions WHERE slug = $1', [
185
+ slug,
186
+ ]);
187
+ if (existingResult.rows.length === 0) {
179
188
  return null;
180
189
  }
181
190
 
@@ -186,50 +195,48 @@ export class FunctionsService {
186
195
 
187
196
  // Update fields
188
197
  if (updates.name !== undefined) {
189
- await this.db
190
- .prepare('UPDATE _functions SET name = ? WHERE slug = ?')
191
- .run(updates.name, slug);
198
+ await client.query('UPDATE _functions SET name = $1 WHERE slug = $2', [updates.name, slug]);
192
199
  }
193
200
 
194
201
  if (updates.description !== undefined) {
195
- await this.db
196
- .prepare('UPDATE _functions SET description = ? WHERE slug = ?')
197
- .run(updates.description, slug);
202
+ await client.query('UPDATE _functions SET description = $1 WHERE slug = $2', [
203
+ updates.description,
204
+ slug,
205
+ ]);
198
206
  }
199
207
 
200
208
  if (updates.code !== undefined) {
201
- await this.db
202
- .prepare('UPDATE _functions SET code = ? WHERE slug = ?')
203
- .run(updates.code, slug);
209
+ await client.query('UPDATE _functions SET code = $1 WHERE slug = $2', [updates.code, slug]);
204
210
  }
205
211
 
206
212
  if (updates.status !== undefined) {
207
- await this.db
208
- .prepare('UPDATE _functions SET status = ? WHERE slug = ?')
209
- .run(updates.status, slug);
213
+ await client.query('UPDATE _functions SET status = $1 WHERE slug = $2', [
214
+ updates.status,
215
+ slug,
216
+ ]);
210
217
 
211
218
  // Update deployed_at if status changes to active
212
219
  if (updates.status === 'active') {
213
- await this.db
214
- .prepare('UPDATE _functions SET deployed_at = CURRENT_TIMESTAMP WHERE slug = ?')
215
- .run(slug);
220
+ await client.query(
221
+ 'UPDATE _functions SET deployed_at = CURRENT_TIMESTAMP WHERE slug = $1',
222
+ [slug]
223
+ );
216
224
  }
217
225
  }
218
226
 
219
227
  // Update updated_at
220
- await this.db
221
- .prepare('UPDATE _functions SET updated_at = CURRENT_TIMESTAMP WHERE slug = ?')
222
- .run(slug);
228
+ await client.query('UPDATE _functions SET updated_at = CURRENT_TIMESTAMP WHERE slug = $1', [
229
+ slug,
230
+ ]);
223
231
 
224
232
  // Fetch updated function
225
- const updated = await this.db
226
- .prepare(
227
- `SELECT id, slug, name, description, status, updated_at
228
- FROM _functions WHERE slug = ?`
229
- )
230
- .get(slug);
231
-
232
- return updated;
233
+ const result = await client.query(
234
+ `SELECT id, slug, name, description, status, updated_at
235
+ FROM _functions WHERE slug = $1`,
236
+ [slug]
237
+ );
238
+
239
+ return result.rows[0];
233
240
  } catch (error) {
234
241
  logger.error('Failed to update function', {
235
242
  error: error instanceof Error ? error.message : String(error),
@@ -237,6 +244,8 @@ export class FunctionsService {
237
244
  slug,
238
245
  });
239
246
  throw error;
247
+ } finally {
248
+ client.release();
240
249
  }
241
250
  }
242
251
 
@@ -245,9 +254,9 @@ export class FunctionsService {
245
254
  */
246
255
  async deleteFunction(slug: string): Promise<boolean> {
247
256
  try {
248
- const result = await this.db.prepare('DELETE FROM _functions WHERE slug = ?').run(slug);
257
+ const result = await this.getPool().query('DELETE FROM _functions WHERE slug = $1', [slug]);
249
258
 
250
- if (result.changes === 0) {
259
+ if (result.rowCount === 0) {
251
260
  return false;
252
261
  }
253
262
 
@@ -267,15 +276,13 @@ export class FunctionsService {
267
276
  */
268
277
  async getMetadata(): Promise<Array<EdgeFunctionMetadataSchema>> {
269
278
  try {
270
- const functions = await this.db
271
- .prepare(
272
- `SELECT slug, name, description, status
273
- FROM _functions
274
- ORDER BY created_at DESC`
275
- )
276
- .all();
277
-
278
- return functions as Array<EdgeFunctionMetadataSchema>;
279
+ const result = await this.getPool().query(
280
+ `SELECT slug, name, description, status
281
+ FROM _functions
282
+ ORDER BY created_at DESC`
283
+ );
284
+
285
+ return result.rows as Array<EdgeFunctionMetadataSchema>;
279
286
  } catch (error) {
280
287
  logger.error('Failed to get edge functions metadata', {
281
288
  error: error instanceof Error ? error.message : String(error),
@@ -1,20 +1,26 @@
1
- import { DatabaseManager } from '@/core/database/manager.js';
1
+ import { Pool } from 'pg';
2
+ import { DatabaseManager } from '@/infra/database/database.manager.js';
2
3
  import logger from '@/utils/logger.js';
3
- import { AppError } from '@/api/middleware/error.js';
4
+ import { AppError } from '@/api/middlewares/error.js';
4
5
  import { ERROR_CODES } from '@/types/error-constants.js';
5
6
  import type { AuditLogEntry, AuditLogQuery } from '@/types/logs.js';
6
7
  import { AuditLogSchema, GetAuditLogStatsResponse } from '@insforge/shared-schemas';
7
8
 
8
9
  export class AuditService {
9
10
  private static instance: AuditService;
10
- private db: ReturnType<DatabaseManager['getDb']>;
11
+ private pool: Pool | null = null;
11
12
 
12
13
  private constructor() {
13
- const dbManager = DatabaseManager.getInstance();
14
- this.db = dbManager.getDb();
15
14
  logger.info('AuditService initialized');
16
15
  }
17
16
 
17
+ private getPool(): Pool {
18
+ if (!this.pool) {
19
+ this.pool = DatabaseManager.getInstance().getPool();
20
+ }
21
+ return this.pool;
22
+ }
23
+
18
24
  public static getInstance(): AuditService {
19
25
  if (!AuditService.instance) {
20
26
  AuditService.instance = new AuditService();
@@ -27,19 +33,21 @@ export class AuditService {
27
33
  */
28
34
  async log(entry: AuditLogEntry): Promise<AuditLogSchema> {
29
35
  try {
30
- const result = await this.db
31
- .prepare(
32
- `INSERT INTO _audit_logs (actor, action, module, details, ip_address)
33
- VALUES ($1, $2, $3, $4, $5)
34
- RETURNING *`
35
- )
36
- .get(
36
+ const pool = this.getPool();
37
+ const result = await pool.query(
38
+ `INSERT INTO _audit_logs (actor, action, module, details, ip_address)
39
+ VALUES ($1, $2, $3, $4, $5)
40
+ RETURNING *`,
41
+ [
37
42
  entry.actor,
38
43
  entry.action,
39
44
  entry.module,
40
45
  entry.details ? JSON.stringify(entry.details) : null,
41
- entry.ip_address || null
42
- );
46
+ entry.ip_address || null,
47
+ ]
48
+ );
49
+
50
+ const row = result.rows[0];
43
51
 
44
52
  logger.info('Audit log created', {
45
53
  actor: entry.actor,
@@ -48,14 +56,14 @@ export class AuditService {
48
56
  });
49
57
 
50
58
  return {
51
- id: result.id,
52
- actor: result.actor,
53
- action: result.action,
54
- module: result.module,
55
- details: result.details,
56
- ipAddress: result.ip_address,
57
- createdAt: result.created_at,
58
- updatedAt: result.updated_at,
59
+ id: row.id,
60
+ actor: row.actor,
61
+ action: row.action,
62
+ module: row.module,
63
+ details: row.details,
64
+ ipAddress: row.ip_address,
65
+ createdAt: row.created_at,
66
+ updatedAt: row.updated_at,
59
67
  };
60
68
  } catch (error) {
61
69
  logger.error('Failed to create audit log', error);
@@ -68,6 +76,8 @@ export class AuditService {
68
76
  */
69
77
  async query(query: AuditLogQuery): Promise<{ records: AuditLogSchema[]; total: number }> {
70
78
  try {
79
+ const pool = this.getPool();
80
+
71
81
  // Build base WHERE clause
72
82
  let whereClause = 'WHERE 1=1';
73
83
  const params: unknown[] = [];
@@ -100,8 +110,8 @@ export class AuditService {
100
110
 
101
111
  // Get total count first
102
112
  const countSql = `SELECT COUNT(*) as count FROM _audit_logs ${whereClause}`;
103
- const countResult = (await this.db.prepare(countSql).get(...params)) as { count: number };
104
- const total = countResult.count;
113
+ const countResult = await pool.query(countSql, params);
114
+ const total = parseInt(countResult.rows[0].count, 10);
105
115
 
106
116
  // Get paginated records
107
117
  let dataSql = `SELECT * FROM _audit_logs ${whereClause} ORDER BY created_at DESC`;
@@ -117,10 +127,10 @@ export class AuditService {
117
127
  dataParams.push(query.offset);
118
128
  }
119
129
 
120
- const records = await this.db.prepare(dataSql).all(...dataParams);
130
+ const dataResult = await pool.query(dataSql, dataParams);
121
131
 
122
132
  return {
123
- records: records.map((record) => ({
133
+ records: dataResult.rows.map((record) => ({
124
134
  id: record.id,
125
135
  actor: record.actor,
126
136
  action: record.action,
@@ -143,18 +153,21 @@ export class AuditService {
143
153
  */
144
154
  async getById(id: string): Promise<AuditLogSchema | null> {
145
155
  try {
146
- const result = await this.db.prepare('SELECT * FROM _audit_logs WHERE id = $1').get(id);
156
+ const pool = this.getPool();
157
+ const result = await pool.query('SELECT * FROM _audit_logs WHERE id = $1', [id]);
158
+
159
+ const row = result.rows[0];
147
160
 
148
- return result
161
+ return row
149
162
  ? {
150
- id: result.id,
151
- actor: result.actor,
152
- action: result.action,
153
- module: result.module,
154
- details: result.details,
155
- ipAddress: result.ip_address,
156
- createdAt: result.created_at,
157
- updatedAt: result.updated_at,
163
+ id: row.id,
164
+ actor: row.actor,
165
+ action: row.action,
166
+ module: row.module,
167
+ details: row.details,
168
+ ipAddress: row.ip_address,
169
+ createdAt: row.created_at,
170
+ updatedAt: row.updated_at,
158
171
  }
159
172
  : null;
160
173
  } catch (error) {
@@ -168,50 +181,52 @@ export class AuditService {
168
181
  */
169
182
  async getStats(days: number = 7): Promise<GetAuditLogStatsResponse> {
170
183
  try {
184
+ const pool = this.getPool();
171
185
  const startDate = new Date();
172
186
  startDate.setDate(startDate.getDate() - days);
173
187
 
174
- const [totalLogs] = await this.db
175
- .prepare('SELECT COUNT(*) as count FROM _audit_logs WHERE created_at >= $1')
176
- .get(startDate.toISOString());
177
-
178
- const [uniqueActors] = await this.db
179
- .prepare('SELECT COUNT(DISTINCT actor) as count FROM _audit_logs WHERE created_at >= $1')
180
- .get(startDate.toISOString());
181
-
182
- const [uniqueModules] = await this.db
183
- .prepare('SELECT COUNT(DISTINCT module) as count FROM _audit_logs WHERE created_at >= $1')
184
- .get(startDate.toISOString());
185
-
186
- const actionsByModule = await this.db
187
- .prepare(
188
- `SELECT module, COUNT(*) as count
189
- FROM _audit_logs
190
- WHERE created_at >= $1
191
- GROUP BY module`
192
- )
193
- .all(startDate.toISOString());
194
-
195
- const recentActivity = await this.db
196
- .prepare(
197
- `SELECT * FROM _audit_logs
198
- WHERE created_at >= $1
199
- ORDER BY created_at DESC
200
- LIMIT 10`
201
- )
202
- .all(startDate.toISOString());
188
+ const totalLogsResult = await pool.query(
189
+ 'SELECT COUNT(*) as count FROM _audit_logs WHERE created_at >= $1',
190
+ [startDate.toISOString()]
191
+ );
192
+
193
+ const uniqueActorsResult = await pool.query(
194
+ 'SELECT COUNT(DISTINCT actor) as count FROM _audit_logs WHERE created_at >= $1',
195
+ [startDate.toISOString()]
196
+ );
197
+
198
+ const uniqueModulesResult = await pool.query(
199
+ 'SELECT COUNT(DISTINCT module) as count FROM _audit_logs WHERE created_at >= $1',
200
+ [startDate.toISOString()]
201
+ );
202
+
203
+ const actionsByModuleResult = await pool.query(
204
+ `SELECT module, COUNT(*) as count
205
+ FROM _audit_logs
206
+ WHERE created_at >= $1
207
+ GROUP BY module`,
208
+ [startDate.toISOString()]
209
+ );
210
+
211
+ const recentActivityResult = await pool.query(
212
+ `SELECT * FROM _audit_logs
213
+ WHERE created_at >= $1
214
+ ORDER BY created_at DESC
215
+ LIMIT 10`,
216
+ [startDate.toISOString()]
217
+ );
203
218
 
204
219
  const moduleStats: Record<string, number> = {};
205
- actionsByModule.forEach((row: { module: string; count: string }) => {
206
- moduleStats[row.module] = parseInt(row.count);
220
+ actionsByModuleResult.rows.forEach((row: { module: string; count: string }) => {
221
+ moduleStats[row.module] = parseInt(row.count, 10);
207
222
  });
208
223
 
209
224
  return {
210
- totalLogs: parseInt(totalLogs?.count || 0),
211
- uniqueActors: parseInt(uniqueActors?.count || 0),
212
- uniqueModules: parseInt(uniqueModules?.count || 0),
225
+ totalLogs: parseInt(totalLogsResult.rows[0]?.count || '0', 10),
226
+ uniqueActors: parseInt(uniqueActorsResult.rows[0]?.count || '0', 10),
227
+ uniqueModules: parseInt(uniqueModulesResult.rows[0]?.count || '0', 10),
213
228
  actionsByModule: moduleStats,
214
- recentActivity: recentActivity.map((record) => ({
229
+ recentActivity: recentActivityResult.rows.map((record) => ({
215
230
  id: record.id,
216
231
  actor: record.actor,
217
232
  action: record.action,
@@ -233,14 +248,16 @@ export class AuditService {
233
248
  */
234
249
  async cleanup(daysToKeep: number = 90): Promise<number> {
235
250
  try {
251
+ const pool = this.getPool();
236
252
  const cutoffDate = new Date();
237
253
  cutoffDate.setDate(cutoffDate.getDate() - daysToKeep);
238
254
 
239
- const result = await this.db
240
- .prepare('DELETE FROM _audit_logs WHERE created_at < $1 RETURNING id')
241
- .all(cutoffDate.toISOString());
255
+ const result = await pool.query(
256
+ 'DELETE FROM _audit_logs WHERE created_at < $1 RETURNING id',
257
+ [cutoffDate.toISOString()]
258
+ );
242
259
 
243
- const deletedCount = result.length;
260
+ const deletedCount = result.rows.length;
244
261
 
245
262
  if (deletedCount > 0) {
246
263
  logger.info(`Cleaned up ${deletedCount} audit logs older than ${daysToKeep} days`);