insforge 0.3.3 → 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (635) hide show
  1. package/.claude-plugin/marketplace.json +20 -0
  2. package/.dockerignore +60 -57
  3. package/.env.example +84 -49
  4. package/.github/ISSUE_TEMPLATE/bug_report.yml +36 -83
  5. package/.github/ISSUE_TEMPLATE/config.yml +11 -11
  6. package/.github/ISSUE_TEMPLATE/feature_request.yml +26 -79
  7. package/.github/PULL_REQUEST_TEMPLATE.md +7 -0
  8. package/.github/copilot-instructions.md +146 -146
  9. package/.github/workflows/build-image.yml +66 -65
  10. package/.github/workflows/ci-premerge-check.yml +23 -23
  11. package/.github/workflows/e2e.yml +63 -0
  12. package/.github/workflows/lint-and-format.yml +32 -32
  13. package/.prettierignore +64 -64
  14. package/CHANGELOG.md +44 -3
  15. package/CLAUDE_PLUGIN.md +104 -0
  16. package/CODE_OF_CONDUCT.md +128 -0
  17. package/CONTRIBUTING.md +125 -125
  18. package/Dockerfile +30 -27
  19. package/GITHUB_OAUTH_SETUP.md +49 -49
  20. package/GOOGLE_OAUTH_SETUP.md +148 -148
  21. package/LICENSE +201 -201
  22. package/README.md +182 -134
  23. package/assets/Dark.svg +23 -23
  24. package/assets/mcpInstallv2.png +0 -0
  25. package/assets/sampleResponse.png +0 -0
  26. package/auth/index.html +13 -0
  27. package/auth/package.json +28 -0
  28. package/auth/public/favicon.ico +0 -0
  29. package/auth/src/App.tsx +33 -0
  30. package/auth/src/components/ErrorCard.tsx +37 -0
  31. package/auth/src/components/Layout.tsx +13 -0
  32. package/auth/src/index.css +19 -0
  33. package/auth/src/lib/broadcastService.ts +117 -0
  34. package/auth/src/lib/utils.ts +11 -0
  35. package/auth/src/main.tsx +22 -0
  36. package/auth/src/pages/ForgotPasswordPage.tsx +11 -0
  37. package/auth/src/pages/ResetPasswordPage.tsx +11 -0
  38. package/auth/src/pages/SignInPage.tsx +60 -0
  39. package/auth/src/pages/SignUpPage.tsx +60 -0
  40. package/auth/src/pages/VerifyEmailPage.tsx +20 -0
  41. package/auth/src/vite-env.d.ts +10 -0
  42. package/auth/tsconfig.json +32 -0
  43. package/auth/tsconfig.node.json +11 -0
  44. package/auth/vite.config.ts +25 -0
  45. package/backend/package.json +78 -75
  46. package/backend/src/api/{middleware → middlewares}/auth.ts +8 -9
  47. package/backend/src/api/middlewares/rate-limiters.ts +127 -0
  48. package/backend/src/api/routes/{ai.ts → ai/index.routes.ts} +22 -26
  49. package/backend/src/api/routes/auth/index.routes.ts +667 -0
  50. package/backend/src/api/routes/auth/oauth.routes.ts +473 -0
  51. package/backend/src/api/routes/{database.advance.ts → database/advance.routes.ts} +128 -65
  52. package/backend/src/api/routes/database/index.routes.ts +90 -0
  53. package/backend/src/api/routes/{database.records.ts → database/records.routes.ts} +26 -12
  54. package/backend/src/api/routes/{database.tables.ts → database/tables.routes.ts} +6 -23
  55. package/backend/src/api/routes/docs/index.routes.ts +75 -0
  56. package/backend/src/api/routes/email/index.routes.ts +35 -0
  57. package/backend/src/api/routes/functions/index.routes.ts +194 -0
  58. package/backend/src/api/routes/{logs.ts → logs/index.routes.ts} +25 -30
  59. package/backend/src/api/routes/{metadata.ts → metadata/index.routes.ts} +33 -31
  60. package/backend/src/api/routes/realtime/channels.routes.ts +81 -0
  61. package/backend/src/api/routes/realtime/index.routes.ts +12 -0
  62. package/backend/src/api/routes/realtime/messages.routes.ts +48 -0
  63. package/backend/src/api/routes/realtime/permissions.routes.ts +19 -0
  64. package/backend/src/api/routes/{secrets.ts → secrets/index.routes.ts} +27 -22
  65. package/backend/src/api/routes/{storage.ts → storage/index.routes.ts} +48 -61
  66. package/backend/src/api/routes/usage/index.routes.ts +91 -0
  67. package/backend/src/infra/config/app.config.ts +51 -0
  68. package/backend/src/infra/database/database.manager.ts +182 -0
  69. package/backend/{migrations → src/infra/database/migrations}/000_create-base-tables.sql +141 -141
  70. package/backend/{migrations → src/infra/database/migrations}/001_create-helper-functions.sql +40 -40
  71. package/backend/{migrations → src/infra/database/migrations}/002_rename-auth-tables.sql +29 -29
  72. package/backend/{migrations → src/infra/database/migrations}/003_create-users-table.sql +55 -55
  73. package/backend/{migrations → src/infra/database/migrations}/004_add-reload-postgrest-func.sql +23 -23
  74. package/backend/{migrations → src/infra/database/migrations}/005_enable-project-admin-modify-users.sql +29 -29
  75. package/backend/{migrations → src/infra/database/migrations}/006_modify-ai-usage-table.sql +24 -24
  76. package/backend/{migrations → src/infra/database/migrations}/007_drop-metadata-table.sql +1 -1
  77. package/backend/{migrations → src/infra/database/migrations}/008_add-system-tables.sql +76 -76
  78. package/backend/{migrations → src/infra/database/migrations}/009_add-function-secrets.sql +23 -23
  79. package/backend/{migrations → src/infra/database/migrations}/010_modify-ai-config-modalities.sql +93 -93
  80. package/backend/{migrations → src/infra/database/migrations}/011_refactor-secrets-table.sql +15 -15
  81. package/backend/{migrations → src/infra/database/migrations}/012_add-storage-uploaded-by.sql +7 -7
  82. package/backend/src/infra/database/migrations/013_create-auth-schema-functions.sql +44 -0
  83. package/backend/src/infra/database/migrations/014_add-updated-at-trigger-user-table.sql +8 -0
  84. package/backend/src/infra/database/migrations/015_create-auth-config-and-email-otp-tables.sql +60 -0
  85. package/backend/src/infra/database/migrations/016_update-auth-config-and-email-otp.sql +24 -0
  86. package/backend/src/infra/database/migrations/017_create-realtime-schema.sql +233 -0
  87. package/backend/src/infra/realtime/realtime.manager.ts +246 -0
  88. package/backend/src/infra/realtime/webhook-sender.ts +82 -0
  89. package/backend/src/{core/secrets/encryption.ts → infra/security/encryption.manager.ts} +3 -2
  90. package/backend/src/infra/security/token.manager.ts +219 -0
  91. package/backend/src/infra/socket/socket.manager.ts +522 -0
  92. package/backend/src/providers/ai/openrouter.provider.ts +380 -0
  93. package/backend/src/providers/email/base.provider.ts +38 -0
  94. package/backend/src/providers/email/cloud.provider.ts +271 -0
  95. package/backend/src/{core/logs/providers → providers/logs}/base.provider.ts +11 -11
  96. package/backend/src/{core/logs/providers → providers/logs}/cloudwatch.provider.ts +61 -38
  97. package/backend/src/providers/logs/local.provider.ts +185 -0
  98. package/backend/src/providers/oauth/apple.provider.ts +266 -0
  99. package/backend/src/providers/oauth/base.provider.ts +29 -0
  100. package/backend/src/providers/oauth/discord.provider.ts +195 -0
  101. package/backend/src/providers/oauth/facebook.provider.ts +194 -0
  102. package/backend/src/providers/oauth/github.provider.ts +208 -0
  103. package/backend/src/providers/oauth/google.provider.ts +249 -0
  104. package/backend/src/providers/oauth/index.ts +8 -0
  105. package/backend/src/providers/oauth/linkedin.provider.ts +240 -0
  106. package/backend/src/providers/oauth/microsoft.provider.ts +169 -0
  107. package/backend/src/providers/oauth/x.provider.ts +202 -0
  108. package/backend/src/providers/storage/base.provider.ts +29 -0
  109. package/backend/src/providers/storage/local.provider.ts +103 -0
  110. package/backend/src/providers/storage/s3.provider.ts +313 -0
  111. package/backend/src/server.ts +317 -288
  112. package/backend/src/{core/ai/config.ts → services/ai/ai-config.service.ts} +19 -24
  113. package/backend/src/services/ai/ai-model.service.ts +60 -0
  114. package/backend/src/{core/ai/usage.ts → services/ai/ai-usage.service.ts} +28 -35
  115. package/backend/src/{core/ai/chat.ts → services/ai/chat-completion.service.ts} +37 -24
  116. package/backend/src/services/ai/helpers.ts +64 -0
  117. package/backend/src/{core/ai/image.ts → services/ai/image-generation.service.ts} +17 -19
  118. package/backend/src/services/ai/index.ts +13 -0
  119. package/backend/src/services/auth/auth-config.service.ts +250 -0
  120. package/backend/src/services/auth/auth-otp.service.ts +424 -0
  121. package/backend/src/services/auth/auth.service.ts +1150 -0
  122. package/backend/src/services/auth/index.ts +4 -0
  123. package/backend/src/{core/auth/oauth.ts → services/auth/oauth-config.service.ts} +106 -52
  124. package/backend/src/{core/database/advance.ts → services/database/database-advance.service.ts} +97 -131
  125. package/backend/src/services/database/database-table.service.ts +802 -0
  126. package/backend/src/services/database/database.service.ts +127 -0
  127. package/backend/src/services/email/email.service.ts +73 -0
  128. package/backend/src/{core/functions/functions.ts → services/functions/function.service.ts} +95 -88
  129. package/backend/src/{core/logs/audit.ts → services/logs/audit.service.ts} +92 -75
  130. package/backend/src/services/logs/log.service.ts +73 -0
  131. package/backend/src/services/realtime/index.ts +3 -0
  132. package/backend/src/services/realtime/realtime-auth.service.ts +104 -0
  133. package/backend/src/services/realtime/realtime-channel.service.ts +237 -0
  134. package/backend/src/services/realtime/realtime-message.service.ts +260 -0
  135. package/backend/src/{core/secrets/secrets.ts → services/secrets/secret.service.ts} +48 -66
  136. package/backend/src/services/storage/storage.service.ts +617 -0
  137. package/backend/src/services/usage/usage.service.ts +149 -0
  138. package/backend/src/types/auth.ts +77 -2
  139. package/backend/src/types/email.ts +8 -0
  140. package/backend/src/types/error-constants.ts +4 -0
  141. package/backend/src/types/logs.ts +0 -29
  142. package/backend/src/types/realtime.ts +18 -0
  143. package/backend/src/{core/socket/types.ts → types/socket.ts} +11 -36
  144. package/backend/src/utils/cookies.ts +35 -0
  145. package/backend/src/utils/environment.ts +9 -3
  146. package/backend/src/utils/logger.ts +20 -2
  147. package/backend/src/utils/s3-config-loader.ts +64 -0
  148. package/backend/src/utils/seed.ts +301 -205
  149. package/backend/src/utils/sql-parser.ts +91 -1
  150. package/backend/src/utils/utils.ts +114 -0
  151. package/backend/src/utils/validations.ts +40 -4
  152. package/backend/tests/README.md +133 -133
  153. package/backend/tests/cleanup-all-test-data.sh +230 -230
  154. package/backend/tests/cloud/test-s3-multitenant.sh +131 -131
  155. package/backend/tests/local/comprehensive-curl-tests.sh +155 -155
  156. package/backend/tests/local/test-ai-config.sh +129 -0
  157. package/backend/tests/local/test-ai-usage.sh +80 -0
  158. package/backend/tests/local/test-auth-router.sh +143 -143
  159. package/backend/tests/local/test-database-router.sh +222 -222
  160. package/backend/tests/local/test-e2e.sh +240 -240
  161. package/backend/tests/local/test-fk-errors.sh +96 -96
  162. package/backend/tests/local/test-functions.sh +123 -0
  163. package/backend/tests/local/test-id-field.sh +200 -200
  164. package/backend/tests/local/test-logs.sh +132 -0
  165. package/backend/tests/local/test-public-bucket.sh +264 -264
  166. package/backend/tests/local/test-secrets.sh +249 -247
  167. package/backend/tests/local/test-serverless-functions.sh.disabled +325 -325
  168. package/backend/tests/local/test-traditional-rest.sh +208 -208
  169. package/backend/tests/manual/README.md +50 -50
  170. package/backend/tests/manual/create-large-table-simple.sql +10 -10
  171. package/backend/tests/manual/seed-large-table.sql +100 -100
  172. package/backend/tests/manual/setup-large-table-extras.sql +33 -33
  173. package/backend/tests/manual/test-bulk-upsert.sh +409 -409
  174. package/backend/tests/manual/test-database-advance.sh +296 -296
  175. package/backend/tests/manual/test-postgrest-stability.sh +191 -191
  176. package/backend/tests/manual/test-rawsql-export-import.sh +411 -411
  177. package/backend/tests/manual/test-rawsql-modes.sh +244 -0
  178. package/backend/tests/manual/test-universal-storage.sh +263 -263
  179. package/backend/tests/manual/test-users.sql +17 -17
  180. package/backend/tests/run-all-tests.sh +139 -139
  181. package/backend/tests/setup.ts +0 -0
  182. package/backend/tests/test-config.sh +338 -302
  183. package/backend/tests/unit/analyze-query.test.ts +697 -0
  184. package/backend/tests/unit/cloud-token.test.ts +48 -0
  185. package/backend/tests/unit/constant.test.ts +8 -0
  186. package/backend/tests/unit/email.test.ts +372 -0
  187. package/backend/tests/unit/environment.test.ts +59 -0
  188. package/backend/tests/unit/helpers.test.ts +63 -0
  189. package/backend/tests/unit/logger.test.ts +22 -0
  190. package/backend/tests/unit/rate-limit.test.ts +154 -0
  191. package/backend/tests/unit/response.test.ts +58 -0
  192. package/backend/tests/unit/sql-parser.test.ts +74 -0
  193. package/backend/tests/unit/uuid.test.ts +21 -0
  194. package/backend/tests/unit/validations.test.ts +80 -0
  195. package/backend/tsconfig.json +22 -22
  196. package/backend/vitest.config.ts +11 -0
  197. package/claude-plugin/.claude-plugin/plugin.json +24 -0
  198. package/claude-plugin/README.md +133 -0
  199. package/claude-plugin/skills/insforge-schema-patterns/SKILL.md +270 -0
  200. package/docker-compose.prod.yml +204 -144
  201. package/docker-compose.yml +232 -167
  202. package/docker-init/db/db-init.sql +97 -125
  203. package/docker-init/db/jwt.sql +5 -5
  204. package/docker-init/db/postgresql.conf +16 -16
  205. package/docker-init/logs/vector.yml +236 -0
  206. package/docs/README.md +44 -0
  207. package/docs/agent-docs/real-time.md +269 -0
  208. package/docs/changelog.mdx +119 -0
  209. package/docs/core-concepts/ai/architecture.mdx +373 -0
  210. package/docs/core-concepts/ai/sdk.mdx +213 -0
  211. package/docs/core-concepts/authentication/architecture.mdx +278 -0
  212. package/docs/core-concepts/authentication/sdk.mdx +414 -0
  213. package/docs/core-concepts/authentication/ui-components/customization.mdx +529 -0
  214. package/docs/core-concepts/authentication/ui-components/nextjs.mdx +221 -0
  215. package/docs/core-concepts/authentication/ui-components/react-router.mdx +184 -0
  216. package/docs/core-concepts/authentication/ui-components/react.mdx +129 -0
  217. package/docs/core-concepts/database/architecture.mdx +256 -0
  218. package/docs/core-concepts/database/sdk.mdx +382 -0
  219. package/docs/core-concepts/email/architecture.mdx +101 -0
  220. package/docs/core-concepts/email/sdk.mdx +53 -0
  221. package/docs/core-concepts/functions/architecture.mdx +105 -0
  222. package/docs/core-concepts/functions/sdk.mdx +184 -0
  223. package/docs/core-concepts/realtime/architecture.mdx +446 -0
  224. package/docs/core-concepts/realtime/sdk.mdx +409 -0
  225. package/docs/core-concepts/storage/architecture.mdx +243 -0
  226. package/docs/core-concepts/storage/sdk.mdx +253 -0
  227. package/docs/deployment/README.md +94 -0
  228. package/docs/deployment/deploy-to-aws-ec2.md +565 -0
  229. package/docs/deployment/deploy-to-azure-virtual-machines.md +313 -0
  230. package/docs/deployment/deploy-to-google-cloud-compute-engine.md +613 -0
  231. package/docs/deployment/deploy-to-render.md +441 -0
  232. package/docs/deprecated/insforge-auth-api.md +214 -214
  233. package/docs/deprecated/insforge-auth-sdk.md +99 -99
  234. package/docs/deprecated/insforge-db-api.md +358 -358
  235. package/docs/deprecated/insforge-db-sdk.md +139 -139
  236. package/docs/deprecated/insforge-debug-sdk.md +156 -156
  237. package/docs/deprecated/insforge-debug.md +64 -64
  238. package/docs/deprecated/insforge-instructions.md +123 -123
  239. package/docs/deprecated/insforge-project.md +117 -117
  240. package/docs/deprecated/insforge-storage-api.md +278 -278
  241. package/docs/deprecated/insforge-storage-sdk.md +158 -158
  242. package/docs/docs.json +232 -0
  243. package/docs/examples/framework-guides/nextjs.mdx +131 -0
  244. package/docs/examples/framework-guides/nuxt.mdx +165 -0
  245. package/docs/examples/framework-guides/react.mdx +165 -0
  246. package/docs/examples/framework-guides/svelte.mdx +153 -0
  247. package/docs/examples/framework-guides/vue.mdx +159 -0
  248. package/docs/examples/overview.mdx +67 -0
  249. package/docs/favicon.svg +19 -0
  250. package/docs/images/changelog/dec-2025/ai-integration.png +0 -0
  251. package/docs/images/changelog/dec-2025/ai-models.webp +0 -0
  252. package/docs/images/changelog/dec-2025/alipay-payment.webp +0 -0
  253. package/docs/images/changelog/dec-2025/apple-login.jpg +0 -0
  254. package/docs/images/changelog/dec-2025/mcp-installer.png +0 -0
  255. package/docs/images/changelog/dec-2025/realtime-module.jpg +0 -0
  256. package/docs/images/changelog/nov-2025/auth-components.webp +0 -0
  257. package/docs/images/changelog/nov-2025/database-metadata.webp +0 -0
  258. package/docs/images/changelog/nov-2025/quickstart-prompts.webp +0 -0
  259. package/docs/images/changelog/nov-2025/sql-editor.webp +0 -0
  260. package/docs/images/changelog/nov-2025/usage-page.webp +0 -0
  261. package/docs/images/changelog/october-2025/csv-upload.webp +0 -0
  262. package/docs/images/changelog/october-2025/logs-feature.webp +0 -0
  263. package/docs/images/changelog/october-2025/oauth-providers.webp +0 -0
  264. package/docs/images/checks-passed.png +0 -0
  265. package/docs/images/dashboard-connect-expanded.png +0 -0
  266. package/docs/images/dashboard-connect.png +0 -0
  267. package/docs/images/hero-dark.png +0 -0
  268. package/docs/images/hero-light.png +0 -0
  269. package/docs/images/icons/ai.svg +4 -0
  270. package/docs/images/icons/auth.svg +1 -0
  271. package/docs/images/icons/database.svg +1 -0
  272. package/docs/images/icons/function.svg +1 -0
  273. package/docs/images/icons/storage.svg +1 -0
  274. package/docs/images/logos/nextjs.svg +4 -0
  275. package/docs/images/logos/nuxt.svg +4 -0
  276. package/docs/images/logos/react.svg +5 -0
  277. package/docs/images/logos/svelte.svg +4 -0
  278. package/docs/images/logos/vue.svg +5 -0
  279. package/docs/images/mcp-install.png +0 -0
  280. package/docs/images/onboarding-mcp.png +0 -0
  281. package/docs/insforge-instructions-sdk.md +89 -407
  282. package/docs/introduction.mdx +45 -0
  283. package/docs/logo/dark.svg +22 -0
  284. package/docs/logo/light.svg +20 -0
  285. package/docs/partnership.mdx +652 -0
  286. package/docs/quickstart.mdx +83 -0
  287. package/docs/showcase/2048-arena.png +0 -0
  288. package/docs/showcase/framegen-cloud.png +0 -0
  289. package/docs/showcase/line-connect-race.png +0 -0
  290. package/docs/showcase/moment-vibe.png +0 -0
  291. package/docs/showcase/national-flags.png +0 -0
  292. package/docs/showcase/pokemon-vibe.png +0 -0
  293. package/docs/showcase/pure-browse-buy.png +0 -0
  294. package/docs/showcase.mdx +52 -0
  295. package/docs/snippets/sdk-installation.mdx +22 -0
  296. package/docs/snippets/service-icons.mdx +27 -0
  297. package/eslint.config.js +10 -3
  298. package/examples/oauth/frontend-oauth-example.html +250 -250
  299. package/examples/response-examples.md +443 -443
  300. package/frontend/components.json +17 -17
  301. package/frontend/package.json +69 -63
  302. package/frontend/src/App.tsx +13 -82
  303. package/frontend/src/assets/icons/checkbox_checked.svg +6 -6
  304. package/frontend/src/assets/icons/checkbox_undetermined.svg +6 -6
  305. package/frontend/src/assets/icons/checked.svg +3 -3
  306. package/frontend/src/assets/icons/connected.svg +3 -0
  307. package/frontend/src/assets/icons/error.svg +3 -3
  308. package/frontend/src/assets/icons/loader.svg +9 -0
  309. package/frontend/src/assets/icons/pencil.svg +4 -4
  310. package/frontend/src/assets/icons/refresh.svg +4 -4
  311. package/frontend/src/assets/icons/step_active.svg +3 -3
  312. package/frontend/src/assets/icons/step_inactive.svg +11 -11
  313. package/frontend/src/assets/icons/warning.svg +3 -3
  314. package/frontend/src/assets/logos/apple.svg +4 -0
  315. package/frontend/src/assets/logos/claude_code.svg +3 -3
  316. package/frontend/src/assets/logos/cline.svg +6 -6
  317. package/frontend/src/assets/logos/cursor.svg +20 -20
  318. package/frontend/src/assets/logos/discord.svg +8 -8
  319. package/frontend/src/assets/logos/facebook.svg +3 -0
  320. package/frontend/src/assets/logos/gemini.svg +19 -19
  321. package/frontend/src/assets/logos/github.svg +5 -5
  322. package/frontend/src/assets/logos/google.svg +13 -13
  323. package/frontend/src/assets/logos/grok.svg +10 -10
  324. package/frontend/src/assets/logos/insforge_dark.svg +15 -15
  325. package/frontend/src/assets/logos/insforge_light.svg +15 -15
  326. package/frontend/src/assets/logos/instagram.svg +2 -0
  327. package/frontend/src/assets/logos/linkedin.svg +3 -0
  328. package/frontend/src/assets/logos/microsoft.svg +1 -0
  329. package/frontend/src/assets/logos/openai.svg +10 -10
  330. package/frontend/src/assets/logos/roo_code.svg +9 -9
  331. package/frontend/src/assets/logos/spotify.svg +17 -0
  332. package/frontend/src/assets/logos/tiktok.svg +6 -0
  333. package/frontend/src/assets/logos/trae.svg +3 -3
  334. package/frontend/src/assets/logos/windsurf.svg +10 -10
  335. package/frontend/src/assets/logos/x.svg +3 -0
  336. package/frontend/src/components/Checkbox.tsx +27 -29
  337. package/frontend/src/components/CodeBlock.tsx +55 -2
  338. package/frontend/src/components/CodeEditor.tsx +92 -0
  339. package/frontend/src/components/ConfirmDialog.tsx +1 -1
  340. package/frontend/src/components/ConnectCTA.tsx +38 -0
  341. package/frontend/src/components/CopyButton.tsx +52 -15
  342. package/frontend/src/components/ErrorState.tsx +1 -2
  343. package/frontend/src/components/FeatureSidebar.tsx +6 -6
  344. package/frontend/src/components/FeatureSidebarItem.tsx +2 -2
  345. package/frontend/src/components/JsonHighlight.tsx +21 -9
  346. package/frontend/src/components/ProjectInfoModal.tsx +128 -0
  347. package/frontend/src/components/PromptDialog.tsx +1 -4
  348. package/frontend/src/components/SearchInput.tsx +1 -2
  349. package/frontend/src/components/Stepper.tsx +53 -0
  350. package/frontend/src/components/ThemeToggle.tsx +3 -3
  351. package/frontend/src/components/datagrid/DataGrid.tsx +25 -32
  352. package/frontend/src/components/datagrid/cell-editors/DateCellEditor.tsx +1 -2
  353. package/frontend/src/components/datagrid/cell-editors/JsonCellEditor.tsx +2 -4
  354. package/frontend/src/components/datagrid/index.ts +23 -0
  355. package/frontend/src/components/index.ts +23 -30
  356. package/frontend/src/components/layout/AppHeader.tsx +131 -91
  357. package/frontend/src/components/layout/AppSidebar.tsx +80 -170
  358. package/frontend/src/components/layout/Layout.tsx +12 -23
  359. package/frontend/src/components/layout/PrimaryMenu.tsx +187 -0
  360. package/frontend/src/components/layout/SecondaryMenu.tsx +70 -0
  361. package/frontend/src/components/layout/index.ts +5 -0
  362. package/frontend/src/components/radix/Tooltip.tsx +24 -13
  363. package/frontend/src/components/radix/index.ts +22 -0
  364. package/frontend/src/features/ai/components/AIConfigCard.tsx +129 -83
  365. package/frontend/src/features/ai/components/AIEmptyState.tsx +12 -7
  366. package/frontend/src/features/ai/components/ModalityFilterSidebar.tsx +101 -0
  367. package/frontend/src/features/ai/components/ModelSelectionDialog.tsx +135 -0
  368. package/frontend/src/features/ai/components/ModelSelectionGrid.tsx +51 -0
  369. package/frontend/src/features/ai/components/SystemPromptDialog.tsx +118 -0
  370. package/frontend/src/features/ai/components/index.ts +6 -0
  371. package/frontend/src/features/ai/helpers.ts +57 -71
  372. package/frontend/src/features/ai/hooks/useAIConfigs.ts +39 -113
  373. package/frontend/src/features/ai/hooks/useAIUsage.ts +0 -2
  374. package/frontend/src/features/ai/pages/AIPage.tsx +166 -0
  375. package/frontend/src/features/ai/services/ai.service.ts +5 -5
  376. package/frontend/src/features/auth/components/AuthPreview.tsx +96 -0
  377. package/frontend/src/features/auth/components/OAuthConfigDialog.tsx +54 -30
  378. package/frontend/src/features/auth/components/UserFormDialog.tsx +13 -6
  379. package/frontend/src/features/auth/components/UsersDataGrid.tsx +50 -14
  380. package/frontend/src/features/auth/components/index.ts +5 -0
  381. package/frontend/src/features/auth/helpers.tsx +208 -0
  382. package/frontend/src/features/auth/hooks/useAnonToken.ts +30 -0
  383. package/frontend/src/features/auth/hooks/useAuthConfig.ts +48 -0
  384. package/frontend/src/features/auth/hooks/useOAuthConfig.ts +14 -10
  385. package/frontend/src/features/auth/hooks/useUsers.ts +43 -5
  386. package/frontend/src/features/auth/index.ts +3 -2
  387. package/frontend/src/features/auth/pages/AuthMethodsPage.tsx +275 -0
  388. package/frontend/src/features/auth/pages/ConfigurationPage.tsx +395 -0
  389. package/frontend/src/features/auth/pages/UsersPage.tsx +257 -0
  390. package/frontend/src/features/auth/services/anonToken.service.ts +11 -0
  391. package/frontend/src/features/auth/services/config.service.ts +19 -0
  392. package/frontend/src/features/auth/services/{oauth.service.ts → oauth-config.service.ts} +4 -4
  393. package/frontend/src/features/auth/services/{auth.service.ts → user.service.ts} +7 -53
  394. package/frontend/src/features/dashboard/components/ConnectionSuccessBanner.tsx +35 -0
  395. package/frontend/src/features/dashboard/components/PromptCard.tsx +21 -0
  396. package/frontend/src/features/dashboard/components/PromptDialog.tsx +103 -0
  397. package/frontend/src/features/dashboard/components/StatsCard.tsx +50 -0
  398. package/frontend/src/features/dashboard/components/index.ts +4 -0
  399. package/frontend/src/features/dashboard/pages/DashboardPage.tsx +212 -0
  400. package/frontend/src/features/dashboard/prompts/ai-chatbot.ts +13 -0
  401. package/frontend/src/features/dashboard/prompts/crm-system.ts +13 -0
  402. package/frontend/src/features/dashboard/prompts/ecommerce-platform.ts +12 -0
  403. package/frontend/src/features/dashboard/prompts/index.ts +31 -0
  404. package/frontend/src/features/dashboard/prompts/instagram-clone.ts +11 -0
  405. package/frontend/src/features/dashboard/prompts/notion-clone.ts +14 -0
  406. package/frontend/src/features/dashboard/prompts/reddit-clone.ts +12 -0
  407. package/frontend/src/features/database/components/DatabaseDataGrid.tsx +48 -17
  408. package/frontend/src/features/database/components/ForeignKeyCell.tsx +15 -34
  409. package/frontend/src/features/database/components/ForeignKeyPopover.tsx +19 -20
  410. package/frontend/src/features/database/components/LinkRecordModal.tsx +120 -125
  411. package/frontend/src/features/database/components/RecordFormDialog.tsx +22 -33
  412. package/frontend/src/features/database/components/RecordFormField.tsx +45 -47
  413. package/frontend/src/features/database/components/SQLModal.tsx +75 -0
  414. package/frontend/src/features/database/components/TableEmptyState.tsx +6 -5
  415. package/frontend/src/features/database/components/TableForm.tsx +28 -19
  416. package/frontend/src/features/database/components/TableFormColumn.tsx +2 -3
  417. package/frontend/src/features/database/components/TableSidebar.tsx +1 -1
  418. package/frontend/src/features/database/components/TablesEmptyState.tsx +48 -0
  419. package/frontend/src/features/database/components/TemplateCard.tsx +37 -0
  420. package/frontend/src/features/database/components/TemplatePreview.tsx +92 -0
  421. package/frontend/src/features/database/components/index.ts +19 -0
  422. package/frontend/src/features/database/constants.ts +28 -2
  423. package/frontend/src/features/database/contexts/SQLEditorContext.tsx +188 -0
  424. package/frontend/src/features/database/helpers.ts +2 -2
  425. package/frontend/src/features/database/hooks/useCSVImport.ts +29 -0
  426. package/frontend/src/features/database/hooks/useDatabase.ts +66 -0
  427. package/frontend/src/features/database/hooks/useRawSQL.ts +55 -0
  428. package/frontend/src/features/database/hooks/useRecords.ts +139 -0
  429. package/frontend/src/features/database/hooks/useTables.ts +135 -0
  430. package/frontend/src/features/database/index.ts +7 -1
  431. package/frontend/src/features/database/pages/FunctionsPage.tsx +203 -0
  432. package/frontend/src/features/database/pages/IndexesPage.tsx +228 -0
  433. package/frontend/src/features/database/pages/PoliciesPage.tsx +237 -0
  434. package/frontend/src/features/database/pages/SQLEditorPage.tsx +382 -0
  435. package/frontend/src/features/database/{page/DatabasePage.tsx → pages/TablesPage.tsx} +168 -209
  436. package/frontend/src/features/database/pages/TemplatesPage.tsx +39 -0
  437. package/frontend/src/features/database/pages/TriggersPage.tsx +230 -0
  438. package/frontend/src/features/database/services/advance.service.ts +40 -0
  439. package/frontend/src/features/database/services/database.service.ts +33 -194
  440. package/frontend/src/features/database/services/record.service.ts +219 -0
  441. package/frontend/src/features/database/services/table.service.ts +58 -0
  442. package/frontend/src/features/database/templates/ai-chatbot.ts +402 -0
  443. package/frontend/src/features/database/templates/crm-system.ts +528 -0
  444. package/frontend/src/features/database/templates/ecommerce-platform.ts +553 -0
  445. package/frontend/src/features/database/templates/index.ts +34 -0
  446. package/frontend/src/features/database/templates/instagram-clone.ts +222 -0
  447. package/frontend/src/features/database/templates/notion-clone.ts +483 -0
  448. package/frontend/src/features/database/templates/reddit-clone.ts +526 -0
  449. package/frontend/src/features/functions/components/FunctionRow.tsx +2 -1
  450. package/frontend/src/features/functions/components/FunctionsSidebar.tsx +1 -1
  451. package/frontend/src/features/functions/components/SecretRow.tsx +1 -1
  452. package/frontend/src/features/functions/components/index.ts +5 -0
  453. package/frontend/src/features/functions/hooks/useFunctions.ts +4 -4
  454. package/frontend/src/features/{secrets → functions}/hooks/useSecrets.ts +5 -5
  455. package/frontend/src/features/functions/pages/FunctionsPage.tsx +148 -0
  456. package/frontend/src/features/functions/{components/SecretsContent.tsx → pages/SecretsPage.tsx} +19 -21
  457. package/frontend/src/features/functions/services/{functions.service.ts → function.service.ts} +2 -2
  458. package/frontend/src/features/{secrets/services/secrets.service.ts → functions/services/secret.service.ts} +2 -2
  459. package/frontend/src/features/login/hooks/usePartnerOrigin.ts +27 -0
  460. package/frontend/src/features/login/pages/CloudLoginPage.tsx +118 -0
  461. package/frontend/src/features/login/{page → pages}/LoginPage.tsx +16 -23
  462. package/frontend/src/features/login/services/partnership.service.ts +65 -0
  463. package/frontend/src/features/logs/components/LogsDataGrid.tsx +89 -0
  464. package/frontend/src/features/logs/components/SeverityBadge.tsx +18 -0
  465. package/frontend/src/features/logs/components/index.ts +2 -0
  466. package/frontend/src/features/logs/helpers.ts +24 -0
  467. package/frontend/src/features/logs/hooks/useAuditLogs.ts +4 -4
  468. package/frontend/src/features/logs/hooks/useLogSources.ts +137 -0
  469. package/frontend/src/features/logs/hooks/useLogs.ts +163 -0
  470. package/frontend/src/features/logs/hooks/useMcpUsage.ts +128 -0
  471. package/frontend/src/features/logs/index.ts +8 -2
  472. package/frontend/src/features/logs/{page → pages}/AuditsPage.tsx +91 -38
  473. package/frontend/src/features/logs/pages/LogsPage.tsx +152 -0
  474. package/frontend/src/features/logs/pages/MCPLogsPage.tsx +84 -0
  475. package/frontend/src/features/logs/services/audit.service.ts +63 -0
  476. package/frontend/src/features/logs/services/log.service.ts +15 -110
  477. package/frontend/src/features/logs/services/usage.service.ts +31 -0
  478. package/frontend/src/features/onboard/components/McpConnectionStatus.tsx +68 -0
  479. package/frontend/src/features/onboard/components/OnboardingModal.tsx +267 -0
  480. package/frontend/src/features/onboard/components/VideoDemoModal.tsx +38 -0
  481. package/frontend/src/features/onboard/components/index.ts +4 -0
  482. package/frontend/src/features/onboard/components/mcp/CursorDeeplinkGenerator.tsx +2 -2
  483. package/frontend/src/features/onboard/components/mcp/{mcp-helper.tsx → helpers.tsx} +8 -8
  484. package/frontend/src/features/onboard/components/mcp/index.ts +2 -3
  485. package/frontend/src/features/onboard/index.ts +13 -3
  486. package/frontend/src/features/realtime/components/ChannelRow.tsx +83 -0
  487. package/frontend/src/features/realtime/components/EditChannelModal.tsx +246 -0
  488. package/frontend/src/features/realtime/components/MessageRow.tsx +85 -0
  489. package/frontend/src/features/realtime/components/RealtimeEmptyState.tsx +30 -0
  490. package/frontend/src/features/realtime/hooks/useRealtime.ts +218 -0
  491. package/frontend/src/features/realtime/index.ts +11 -0
  492. package/frontend/src/features/realtime/pages/RealtimeChannelsPage.tsx +172 -0
  493. package/frontend/src/features/realtime/pages/RealtimeMessagesPage.tsx +211 -0
  494. package/frontend/src/features/realtime/pages/RealtimePermissionsPage.tsx +191 -0
  495. package/frontend/src/features/realtime/services/realtime.service.ts +107 -0
  496. package/frontend/src/features/storage/components/BucketEmptyState.tsx +9 -6
  497. package/frontend/src/features/storage/components/BucketFormDialog.tsx +25 -41
  498. package/frontend/src/features/storage/components/FilePreviewDialog.tsx +20 -8
  499. package/frontend/src/features/storage/components/StorageDataGrid.tsx +4 -3
  500. package/frontend/src/features/storage/components/StorageManager.tsx +23 -34
  501. package/frontend/src/features/storage/components/index.ts +12 -0
  502. package/frontend/src/features/storage/hooks/useStorage.ts +208 -0
  503. package/frontend/src/features/storage/{page → pages}/StoragePage.tsx +41 -143
  504. package/frontend/src/features/storage/services/storage.service.ts +22 -1
  505. package/frontend/src/features/visualizer/components/AuthNode.tsx +72 -56
  506. package/frontend/src/features/visualizer/components/BucketNode.tsx +4 -4
  507. package/frontend/src/features/visualizer/components/SchemaVisualizer.tsx +108 -80
  508. package/frontend/src/features/visualizer/components/TableNode.tsx +34 -41
  509. package/frontend/src/features/visualizer/components/VisualizerSkeleton.tsx +12 -4
  510. package/frontend/src/features/visualizer/pages/VisualizerPage.tsx +97 -0
  511. package/frontend/src/index.css +1 -0
  512. package/frontend/src/lib/analytics/posthog.tsx +27 -0
  513. package/frontend/src/lib/contexts/AuthContext.tsx +38 -31
  514. package/frontend/src/lib/contexts/SocketContext.tsx +123 -80
  515. package/frontend/src/{features/metadata → lib}/hooks/useMetadata.ts +1 -1
  516. package/frontend/src/lib/hooks/useToast.tsx +6 -2
  517. package/frontend/src/lib/routing/AppRoutes.tsx +99 -0
  518. package/frontend/src/lib/routing/RequireAuth.tsx +27 -0
  519. package/frontend/src/lib/utils/cloudMessaging.ts +20 -0
  520. package/frontend/src/lib/utils/menuItems.ts +207 -0
  521. package/frontend/src/lib/utils/{validation-schemas.ts → schemaValidations.ts} +10 -5
  522. package/frontend/src/lib/utils/utils.ts +32 -1
  523. package/frontend/src/vite-env.d.ts +1 -0
  524. package/frontend/tsconfig.json +25 -25
  525. package/frontend/tsconfig.node.json +9 -9
  526. package/frontend/vite.config.ts +5 -3
  527. package/functions/deno.json +24 -24
  528. package/functions/server.ts +315 -290
  529. package/functions/worker-template.js +15 -4
  530. package/i18n/README.ar.md +130 -0
  531. package/i18n/README.de.md +130 -0
  532. package/i18n/README.es.md +154 -0
  533. package/i18n/README.fr.md +134 -0
  534. package/i18n/README.hi.md +129 -0
  535. package/i18n/README.ja.md +174 -0
  536. package/i18n/README.ko.md +137 -0
  537. package/i18n/README.pt-BR.md +131 -0
  538. package/i18n/README.ru.md +129 -0
  539. package/i18n/README.zh-CN.md +133 -0
  540. package/openapi/ai.yaml +715 -688
  541. package/openapi/auth.yaml +1244 -563
  542. package/openapi/email.yaml +158 -0
  543. package/openapi/functions.yaml +475 -475
  544. package/openapi/health.yaml +29 -29
  545. package/openapi/logs.yaml +223 -223
  546. package/openapi/metadata.yaml +177 -177
  547. package/openapi/realtime.yaml +699 -0
  548. package/openapi/records.yaml +381 -381
  549. package/openapi/secrets.yaml +370 -370
  550. package/openapi/storage.yaml +875 -875
  551. package/openapi/tables.yaml +463 -463
  552. package/package.json +97 -88
  553. package/shared-schemas/package.json +31 -31
  554. package/shared-schemas/src/ai-api.schema.ts +34 -58
  555. package/shared-schemas/src/ai.schema.ts +63 -54
  556. package/shared-schemas/src/auth-api.schema.ts +352 -193
  557. package/shared-schemas/src/auth.schema.ts +43 -7
  558. package/shared-schemas/src/cloud-events.schema.ts +57 -0
  559. package/shared-schemas/src/database-api.schema.ts +35 -4
  560. package/shared-schemas/src/database.schema.ts +40 -1
  561. package/shared-schemas/src/docs.schema.ts +26 -0
  562. package/shared-schemas/src/email-api.schema.ts +30 -0
  563. package/shared-schemas/src/index.ts +5 -0
  564. package/shared-schemas/src/logs-api.schema.ts +7 -1
  565. package/shared-schemas/src/logs.schema.ts +26 -0
  566. package/shared-schemas/src/metadata.schema.ts +18 -4
  567. package/shared-schemas/src/realtime-api.schema.ts +111 -0
  568. package/shared-schemas/src/realtime.schema.ts +143 -0
  569. package/shared-schemas/tsconfig.json +21 -21
  570. package/tsconfig.json +7 -7
  571. package/zeabur/README.md +13 -0
  572. package/zeabur/template.yml +1032 -0
  573. package/.github/workflows/deploy-aws.yml +0 -130
  574. package/backend/src/api/routes/agent.ts +0 -29
  575. package/backend/src/api/routes/auth.oauth.ts +0 -482
  576. package/backend/src/api/routes/auth.ts +0 -386
  577. package/backend/src/api/routes/docs.ts +0 -66
  578. package/backend/src/api/routes/functions.ts +0 -183
  579. package/backend/src/api/routes/openapi.ts +0 -82
  580. package/backend/src/api/routes/usage.ts +0 -96
  581. package/backend/src/core/ai/client.ts +0 -242
  582. package/backend/src/core/ai/model.ts +0 -117
  583. package/backend/src/core/auth/auth.ts +0 -780
  584. package/backend/src/core/database/manager.ts +0 -178
  585. package/backend/src/core/database/table.ts +0 -772
  586. package/backend/src/core/documentation/agent.ts +0 -689
  587. package/backend/src/core/documentation/openapi.ts +0 -856
  588. package/backend/src/core/logs/analytics.ts +0 -76
  589. package/backend/src/core/logs/providers/localdb.provider.ts +0 -246
  590. package/backend/src/core/socket/socket.ts +0 -388
  591. package/backend/src/core/storage/storage.ts +0 -923
  592. package/backend/src/utils/cloud-token.ts +0 -39
  593. package/backend/src/utils/helpers.ts +0 -49
  594. package/backend/src/utils/uuid.ts +0 -9
  595. package/backend/tests/manual/test-better-auth.sh +0 -303
  596. package/docker-init/db/logs.sql +0 -9
  597. package/frontend/README.md +0 -112
  598. package/frontend/src/components/datagrid/index.tsx +0 -20
  599. package/frontend/src/components/layout/CloudLayout.tsx +0 -95
  600. package/frontend/src/features/ai/components/AIConfigDialog.tsx +0 -76
  601. package/frontend/src/features/ai/components/AIConfigForm.tsx +0 -222
  602. package/frontend/src/features/ai/components/fields/ModalityField.tsx +0 -87
  603. package/frontend/src/features/ai/components/fields/ModelSelectionField.tsx +0 -134
  604. package/frontend/src/features/ai/components/fields/SystemPromptField.tsx +0 -33
  605. package/frontend/src/features/ai/page/AIPage.tsx +0 -178
  606. package/frontend/src/features/auth/components/AddOAuthDialog.tsx +0 -106
  607. package/frontend/src/features/auth/components/AuthMethodTab.tsx +0 -238
  608. package/frontend/src/features/auth/components/UsersTab.tsx +0 -114
  609. package/frontend/src/features/auth/page/AuthenticationPage.tsx +0 -169
  610. package/frontend/src/features/dashboard/page/DashboardPage.tsx +0 -194
  611. package/frontend/src/features/database/hooks/UseLinkModal.tsx +0 -78
  612. package/frontend/src/features/functions/components/FunctionViewer.tsx +0 -46
  613. package/frontend/src/features/functions/components/FunctionsContent.tsx +0 -88
  614. package/frontend/src/features/functions/page/FunctionsPage.tsx +0 -28
  615. package/frontend/src/features/login/components/AuthErrorBoundary.tsx +0 -87
  616. package/frontend/src/features/login/components/PrivateRoute.tsx +0 -24
  617. package/frontend/src/features/login/page/CloudLoginPage.tsx +0 -93
  618. package/frontend/src/features/logs/components/AnalyticsLogsTable.tsx +0 -313
  619. package/frontend/src/features/logs/components/LogsTable.tsx +0 -199
  620. package/frontend/src/features/logs/page/AnalyticsLogsPage.tsx +0 -530
  621. package/frontend/src/features/metadata/index.ts +0 -0
  622. package/frontend/src/features/metadata/page/MetadataPage.tsx +0 -136
  623. package/frontend/src/features/onboard/components/CompletionCard.tsx +0 -41
  624. package/frontend/src/features/onboard/components/OnboardButton.tsx +0 -84
  625. package/frontend/src/features/onboard/components/StepContent.tsx +0 -91
  626. package/frontend/src/features/onboard/components/TestConnectionStep.tsx +0 -53
  627. package/frontend/src/features/onboard/components/mcp/McpInstallation.tsx +0 -144
  628. package/frontend/src/features/onboard/page/OnBoardPage.tsx +0 -104
  629. package/frontend/src/features/onboard/types.ts +0 -8
  630. package/frontend/src/features/visualizer/page/VisualizerPage.tsx +0 -127
  631. package/frontend/src/lib/contexts/OnboardStepContext.tsx +0 -68
  632. package/frontend/src/lib/hooks/useOnboardingCompletion.ts +0 -29
  633. /package/backend/src/api/{middleware → middlewares}/error.ts +0 -0
  634. /package/backend/src/api/{middleware → middlewares}/upload.ts +0 -0
  635. /package/frontend/src/{features/metadata → lib}/services/metadata.service.ts +0 -0
@@ -1,12 +1,13 @@
1
1
  import { Router, Response, NextFunction } from 'express';
2
- import { SecretsService } from '@/core/secrets/secrets.js';
3
- import { verifyAdmin, AuthRequest } from '@/api/middleware/auth.js';
4
- import { AuditService } from '@/core/logs/audit.js';
5
- import { AppError } from '@/api/middleware/error.js';
2
+ import { SecretService } from '@/services/secrets/secret.service.js';
3
+ import { verifyAdmin, AuthRequest } from '@/api/middlewares/auth.js';
4
+ import { AuditService } from '@/services/logs/audit.service.js';
5
+ import { AppError } from '@/api/middlewares/error.js';
6
6
  import { ERROR_CODES } from '@/types/error-constants.js';
7
+ import { successResponse } from '@/utils/response.js';
7
8
 
8
9
  const router = Router();
9
- const secretsService = new SecretsService();
10
+ const secretService = SecretService.getInstance();
10
11
  const auditService = AuditService.getInstance();
11
12
 
12
13
  /**
@@ -15,8 +16,8 @@ const auditService = AuditService.getInstance();
15
16
  */
16
17
  router.get('/', verifyAdmin, async (_req: AuthRequest, res: Response, next: NextFunction) => {
17
18
  try {
18
- const secrets = await secretsService.listSecrets();
19
- res.json({ secrets });
19
+ const secrets = await secretService.listSecrets();
20
+ successResponse(res, { secrets });
20
21
  } catch (error) {
21
22
  next(error);
22
23
  }
@@ -29,7 +30,7 @@ router.get('/', verifyAdmin, async (_req: AuthRequest, res: Response, next: Next
29
30
  router.get('/:key', verifyAdmin, async (req: AuthRequest, res: Response, next: NextFunction) => {
30
31
  try {
31
32
  const { key } = req.params;
32
- const value = await secretsService.getSecretByKey(key);
33
+ const value = await secretService.getSecretByKey(key);
33
34
 
34
35
  if (value === null) {
35
36
  throw new AppError(`Secret not found: ${key}`, 404, ERROR_CODES.NOT_FOUND);
@@ -44,7 +45,7 @@ router.get('/:key', verifyAdmin, async (req: AuthRequest, res: Response, next: N
44
45
  ip_address: req.ip,
45
46
  });
46
47
 
47
- res.json({ key, value });
48
+ successResponse(res, { key, value });
48
49
  } catch (error) {
49
50
  next(error);
50
51
  }
@@ -73,12 +74,12 @@ router.post('/', verifyAdmin, async (req: AuthRequest, res: Response, next: Next
73
74
  }
74
75
 
75
76
  // Check if secret already exists
76
- const existing = await secretsService.getSecretByKey(key);
77
+ const existing = await secretService.getSecretByKey(key);
77
78
  if (existing !== null) {
78
79
  throw new AppError(`Secret already exists: ${key}`, 409, ERROR_CODES.INVALID_INPUT);
79
80
  }
80
81
 
81
- const result = await secretsService.createSecret({
82
+ const result = await secretService.createSecret({
82
83
  key,
83
84
  value,
84
85
  isReserved: isReserved || false,
@@ -94,11 +95,15 @@ router.post('/', verifyAdmin, async (req: AuthRequest, res: Response, next: Next
94
95
  ip_address: req.ip,
95
96
  });
96
97
 
97
- res.status(201).json({
98
- success: true,
99
- message: `Secret ${key} has been created successfully`,
100
- id: result.id,
101
- });
98
+ successResponse(
99
+ res,
100
+ {
101
+ success: true,
102
+ message: `Secret ${key} has been created successfully`,
103
+ id: result.id,
104
+ },
105
+ 201
106
+ );
102
107
  } catch (error) {
103
108
  next(error);
104
109
  }
@@ -114,14 +119,14 @@ router.put('/:key', verifyAdmin, async (req: AuthRequest, res: Response, next: N
114
119
  const { value, isActive, isReserved, expiresAt } = req.body;
115
120
 
116
121
  // Get existing secret
117
- const secrets = await secretsService.listSecrets();
122
+ const secrets = await secretService.listSecrets();
118
123
  const secret = secrets.find((s) => s.key === key);
119
124
 
120
125
  if (!secret) {
121
126
  throw new AppError(`Secret not found: ${key}`, 404, ERROR_CODES.NOT_FOUND);
122
127
  }
123
128
 
124
- const success = await secretsService.updateSecret(secret.id, {
129
+ const success = await secretService.updateSecret(secret.id, {
125
130
  value,
126
131
  isActive,
127
132
  isReserved,
@@ -141,7 +146,7 @@ router.put('/:key', verifyAdmin, async (req: AuthRequest, res: Response, next: N
141
146
  ip_address: req.ip,
142
147
  });
143
148
 
144
- res.json({
149
+ successResponse(res, {
145
150
  success: true,
146
151
  message: `Secret ${key} has been updated successfully`,
147
152
  });
@@ -159,7 +164,7 @@ router.delete('/:key', verifyAdmin, async (req: AuthRequest, res: Response, next
159
164
  const { key } = req.params;
160
165
 
161
166
  // Get existing secret
162
- const secrets = await secretsService.listSecrets();
167
+ const secrets = await secretService.listSecrets();
163
168
  const secret = secrets.find((s) => s.key === key);
164
169
 
165
170
  if (!secret) {
@@ -172,7 +177,7 @@ router.delete('/:key', verifyAdmin, async (req: AuthRequest, res: Response, next
172
177
  }
173
178
 
174
179
  // Mark as inactive instead of hard delete
175
- const success = await secretsService.updateSecret(secret.id, { isActive: false });
180
+ const success = await secretService.updateSecret(secret.id, { isActive: false });
176
181
 
177
182
  if (!success) {
178
183
  throw new AppError(`Failed to delete secret: ${key}`, 500, ERROR_CODES.INTERNAL_ERROR);
@@ -187,7 +192,7 @@ router.delete('/:key', verifyAdmin, async (req: AuthRequest, res: Response, next
187
192
  ip_address: req.ip,
188
193
  });
189
194
 
190
- res.json({
195
+ successResponse(res, {
191
196
  success: true,
192
197
  message: `Secret ${key} has been deleted successfully`,
193
198
  });
@@ -1,20 +1,14 @@
1
1
  import { Router, Request, Response, NextFunction } from 'express';
2
- import path from 'path';
3
- import { verifyAdmin, AuthRequest, verifyUser } from '@/api/middleware/auth.js';
4
- import { AppError } from '@/api/middleware/error.js';
5
- import { StorageService } from '@/core/storage/storage.js';
6
- import { DatabaseManager } from '@/core/database/manager.js';
2
+ import { verifyAdmin, AuthRequest, verifyUser } from '@/api/middlewares/auth.js';
3
+ import { AppError } from '@/api/middlewares/error.js';
4
+ import { StorageService } from '@/services/storage/storage.service.js';
7
5
  import { successResponse } from '@/utils/response.js';
8
- import { upload, handleUploadError } from '@/api/middleware/upload.js';
6
+ import { upload, handleUploadError } from '@/api/middlewares/upload.js';
9
7
  import { ERROR_CODES } from '@/types/error-constants.js';
10
- import {
11
- StorageBucketSchema,
12
- createBucketRequestSchema,
13
- updateBucketRequestSchema,
14
- } from '@insforge/shared-schemas';
15
- import { SocketService } from '@/core/socket/socket';
16
- import { DataUpdateResourceType, ServerEvents } from '@/core/socket/types';
17
- import { AuditService } from '@/core/logs/audit.js';
8
+ import { createBucketRequestSchema, updateBucketRequestSchema } from '@insforge/shared-schemas';
9
+ import { SocketManager } from '@/infra/socket/socket.manager.js';
10
+ import { DataUpdateResourceType, ServerEvents } from '@/types/socket.js';
11
+ import { AuditService } from '@/services/logs/audit.service.js';
18
12
 
19
13
  const router = Router();
20
14
  const auditService = AuditService.getInstance();
@@ -40,24 +34,19 @@ const conditionalAuth = async (req: Request, res: Response, next: NextFunction)
40
34
  return verifyUser(req, res, next);
41
35
  };
42
36
 
43
- // GET /api/storage/buckets - List all buckets (requires auth)
37
+ // GET /api/storage/buckets - List all buckets (requires admin)
44
38
  router.get('/buckets', verifyAdmin, async (req: AuthRequest, res: Response, next: NextFunction) => {
45
39
  try {
46
- const db = DatabaseManager.getInstance().getDb();
40
+ const storageService = StorageService.getInstance();
41
+ const buckets = await storageService.listBuckets();
47
42
 
48
- // Get all buckets with their metadata from _storage_buckets table
49
- const buckets = (await db
50
- .prepare('SELECT name, public, created_at FROM _storage_buckets ORDER BY name')
51
- .all()) as StorageBucketSchema[];
52
-
53
- // Traditional REST: return array directly
54
43
  successResponse(res, buckets);
55
44
  } catch (error) {
56
45
  next(error);
57
46
  }
58
47
  });
59
48
 
60
- // POST /api/storage/buckets - Create a new bucket (requires auth)
49
+ // POST /api/storage/buckets - Create a new bucket (requires admin)
61
50
  router.post(
62
51
  '/buckets',
63
52
  verifyAdmin,
@@ -89,10 +78,13 @@ router.post(
89
78
  ip_address: req.ip,
90
79
  });
91
80
 
92
- const socket = SocketService.getInstance();
93
- socket.broadcastToRoom('role:project_admin', ServerEvents.DATA_UPDATE, {
94
- resource: DataUpdateResourceType.STORAGE_SCHEMA,
95
- });
81
+ const socket = SocketManager.getInstance();
82
+ socket.broadcastToRoom(
83
+ 'role:project_admin',
84
+ ServerEvents.DATA_UPDATE,
85
+ { resource: DataUpdateResourceType.BUCKETS },
86
+ 'system'
87
+ );
96
88
 
97
89
  const accessInfo = isPublic
98
90
  ? 'This is a PUBLIC bucket - objects can be accessed without authentication.'
@@ -160,13 +152,13 @@ router.patch(
160
152
  ip_address: req.ip,
161
153
  });
162
154
 
163
- const socket = SocketService.getInstance();
164
- socket.broadcastToRoom('role:project_admin', ServerEvents.DATA_UPDATE, {
165
- resource: DataUpdateResourceType.BUCKET_SCHEMA,
166
- data: {
167
- name: bucketName,
168
- },
169
- });
155
+ const socket = SocketManager.getInstance();
156
+ socket.broadcastToRoom(
157
+ 'role:project_admin',
158
+ ServerEvents.DATA_UPDATE,
159
+ { resource: DataUpdateResourceType.BUCKETS, data: { bucketName } },
160
+ 'system'
161
+ );
170
162
 
171
163
  const accessInfo = isPublic
172
164
  ? 'Bucket is now PUBLIC - objects can be accessed without authentication.'
@@ -287,17 +279,11 @@ router.post(
287
279
  throw new AppError('File is required', 400, ERROR_CODES.STORAGE_INVALID_PARAMETER);
288
280
  }
289
281
 
290
- // Generate a unique key for the object
291
- const timestamp = Date.now();
292
- const randomStr = Math.random().toString(36).substring(2, 8);
293
- const fileExt = req.file.originalname ? path.extname(req.file.originalname) : '';
294
- const baseName = req.file.originalname
295
- ? path.basename(req.file.originalname, fileExt)
296
- : 'file';
297
- const sanitizedBaseName = baseName.replace(/[^a-zA-Z0-9-_]/g, '-').substring(0, 32);
298
- const objectKey = `${sanitizedBaseName}-${timestamp}-${randomStr}${fileExt}`;
299
-
300
282
  const storageService = StorageService.getInstance();
283
+
284
+ // Generate a unique key for the object using service
285
+ const objectKey = storageService.generateObjectKey(req.file.originalname);
286
+
301
287
  const storedFile = await storageService.putObject(
302
288
  bucketName,
303
289
  objectKey,
@@ -339,12 +325,10 @@ router.get(
339
325
  }
340
326
 
341
327
  const storageService = StorageService.getInstance();
342
- const expiresIn = (await storageService.isBucketPublic(bucketName)) ? 0 : 3600;
343
- const strategy = await storageService.getDownloadStrategy(
344
- bucketName,
345
- objectKey,
346
- Number(expiresIn)
347
- );
328
+
329
+ // Get download strategy (service auto-calculates expiry based on bucket visibility)
330
+ const strategy = await storageService.getDownloadStrategy(bucketName, objectKey);
331
+
348
332
  if (strategy.method === 'presigned') {
349
333
  return res.redirect(strategy.url);
350
334
  }
@@ -397,10 +381,13 @@ router.delete(
397
381
  ip_address: req.ip,
398
382
  });
399
383
 
400
- const socket = SocketService.getInstance();
401
- socket.broadcastToRoom('role:project_admin', ServerEvents.DATA_UPDATE, {
402
- resource: DataUpdateResourceType.STORAGE_SCHEMA,
403
- });
384
+ const socket = SocketManager.getInstance();
385
+ socket.broadcastToRoom(
386
+ 'role:project_admin',
387
+ ServerEvents.DATA_UPDATE,
388
+ { resource: DataUpdateResourceType.BUCKETS },
389
+ 'system'
390
+ );
404
391
 
405
392
  successResponse(
406
393
  res,
@@ -432,7 +419,12 @@ router.delete(
432
419
 
433
420
  // Delete specific object
434
421
  const storageService = StorageService.getInstance();
435
- const deleted = await storageService.deleteObject(bucketName, objectKey, req.user?.id);
422
+ const deleted = await storageService.deleteObject(
423
+ bucketName,
424
+ objectKey,
425
+ req.user?.id,
426
+ req.user?.role === 'project_admin'
427
+ );
436
428
 
437
429
  if (!deleted) {
438
430
  throw new AppError('Object not found', 404, ERROR_CODES.NOT_FOUND);
@@ -525,14 +517,9 @@ router.post(
525
517
  async (req: AuthRequest | Request, res: Response, next: NextFunction) => {
526
518
  try {
527
519
  const { bucketName, objectKey } = req.params;
528
- const { expiresIn = 3600 } = req.body;
529
520
 
530
521
  const storageService = StorageService.getInstance();
531
- const strategy = await storageService.getDownloadStrategy(
532
- bucketName,
533
- objectKey,
534
- Number(expiresIn)
535
- );
522
+ const strategy = await storageService.getDownloadStrategy(bucketName, objectKey);
536
523
 
537
524
  successResponse(res, strategy);
538
525
  } catch (error) {
@@ -0,0 +1,91 @@
1
+ import { Router, NextFunction, Response } from 'express';
2
+ import {
3
+ verifyCloudBackend,
4
+ verifyApiKey,
5
+ verifyAdmin,
6
+ AuthRequest,
7
+ } from '@/api/middlewares/auth.js';
8
+ import { SocketManager } from '@/infra/socket/socket.manager.js';
9
+ import { ServerEvents } from '@/types/socket.js';
10
+ import { UsageService } from '@/services/usage/usage.service.js';
11
+ import { successResponse } from '@/utils/response.js';
12
+ import { AppError } from '@/api/middlewares/error.js';
13
+ import { ERROR_CODES } from '@/types/error-constants.js';
14
+
15
+ export const usageRouter = Router();
16
+ const usageService = UsageService.getInstance();
17
+
18
+ // Create MCP tool usage record
19
+ usageRouter.post(
20
+ '/mcp',
21
+ verifyApiKey,
22
+ async (req: AuthRequest, res: Response, next: NextFunction) => {
23
+ try {
24
+ const { tool_name, success = true } = req.body;
25
+
26
+ if (!tool_name) {
27
+ throw new AppError('tool_name is required', 400, ERROR_CODES.INVALID_INPUT);
28
+ }
29
+
30
+ // Create MCP usage record via service
31
+ const result = await usageService.recordMCPUsage(tool_name, success);
32
+
33
+ // Broadcast MCP tool usage to frontend via socket
34
+ const socketService = SocketManager.getInstance();
35
+
36
+ socketService.broadcastToRoom(
37
+ 'role:project_admin',
38
+ ServerEvents.MCP_CONNECTED,
39
+ { tool_name, created_at: result.created_at },
40
+ 'system'
41
+ );
42
+
43
+ successResponse(res, { success: true });
44
+ } catch (error) {
45
+ next(error);
46
+ }
47
+ }
48
+ );
49
+
50
+ // Get MCP usage records
51
+ usageRouter.get(
52
+ '/mcp',
53
+ verifyAdmin,
54
+ async (req: AuthRequest, res: Response, next: NextFunction) => {
55
+ try {
56
+ const { limit = '5', success = 'true' } = req.query;
57
+
58
+ // Get MCP usage records via service
59
+ const records = await usageService.getMCPUsage(parseInt(limit as string), success === 'true');
60
+
61
+ successResponse(res, { records });
62
+ } catch (error) {
63
+ next(error);
64
+ }
65
+ }
66
+ );
67
+
68
+ // Get usage statistics (called by cloud backend)
69
+ usageRouter.get(
70
+ '/stats',
71
+ verifyCloudBackend,
72
+ async (req: AuthRequest, res: Response, next: NextFunction) => {
73
+ try {
74
+ const { start_date, end_date } = req.query;
75
+
76
+ if (!start_date || !end_date) {
77
+ throw new AppError('start_date and end_date are required', 400, ERROR_CODES.INVALID_INPUT);
78
+ }
79
+
80
+ // Get usage statistics via service
81
+ const stats = await usageService.getUsageStats(
82
+ new Date(start_date as string),
83
+ new Date(end_date as string)
84
+ );
85
+
86
+ successResponse(res, stats);
87
+ } catch (error) {
88
+ next(error);
89
+ }
90
+ }
91
+ );
@@ -0,0 +1,51 @@
1
+ export interface AppConfig {
2
+ app: {
3
+ port: number;
4
+ jwtSecret: string;
5
+ apiKey: string;
6
+ logLevel: string;
7
+ };
8
+ database: {
9
+ host: string;
10
+ port: number;
11
+ username: string;
12
+ password: string;
13
+ databaseName: string;
14
+ };
15
+ cloud: {
16
+ storageBucket: string;
17
+ instanceProfile: string;
18
+ apiHost: string;
19
+ projectId: string;
20
+ appKey: string;
21
+ cloudFrontUrl: string;
22
+ cloudFrontKeyPairId: string;
23
+ cloudFrontPrivateKey: string;
24
+ };
25
+ }
26
+
27
+ export const config: AppConfig = {
28
+ app: {
29
+ port: parseInt(process.env.PORT || '3000', 10),
30
+ jwtSecret: process.env.JWT_SECRET || 'your_jwt_secret',
31
+ apiKey: process.env.ACCESS_API_KEY || 'your_api_key',
32
+ logLevel: process.env.LOG_LEVEL || 'info',
33
+ },
34
+ database: {
35
+ host: process.env.POSTGRES_HOST || 'localhost',
36
+ port: parseInt(process.env.POSTGRES_PORT || '5432', 10),
37
+ username: process.env.POSTGRES_USERNAME || 'user',
38
+ password: process.env.POSTGRES_PASSWORD || 'password',
39
+ databaseName: process.env.POSTGRES_NAME || 'insforge',
40
+ },
41
+ cloud: {
42
+ storageBucket: process.env.AWS_S3_BUCKET || 'insforge-test-bucket',
43
+ instanceProfile: process.env.AWS_INSTANCE_PROFILE_NAME || 'insforge-instance-profile',
44
+ apiHost: process.env.CLOUD_API_HOST || 'https://api.insforge.dev',
45
+ projectId: process.env.PROJECT_ID || 'local',
46
+ appKey: process.env.APP_KEY || 'default-app-key',
47
+ cloudFrontUrl: process.env.AWS_CLOUDFRONT_URL || '',
48
+ cloudFrontKeyPairId: process.env.AWS_CLOUDFRONT_KEY_PAIR_ID || '',
49
+ cloudFrontPrivateKey: process.env.AWS_CLOUDFRONT_PRIVATE_KEY || '',
50
+ },
51
+ };
@@ -0,0 +1,182 @@
1
+ import { Pool, Client } from 'pg';
2
+ import path from 'path';
3
+ import fs from 'fs/promises';
4
+ import { fileURLToPath } from 'url';
5
+ import { DatabaseMetadataSchema } from '@insforge/shared-schemas';
6
+
7
+ const __filename = fileURLToPath(import.meta.url);
8
+ const __dirname = path.dirname(__filename);
9
+
10
+ export class DatabaseManager {
11
+ private static instance: DatabaseManager;
12
+ private pool!: Pool;
13
+ private dataDir: string;
14
+
15
+ private constructor() {
16
+ this.dataDir = process.env.DATABASE_DIR || path.join(__dirname, '../../data');
17
+ }
18
+
19
+ static getInstance(): DatabaseManager {
20
+ if (!DatabaseManager.instance) {
21
+ DatabaseManager.instance = new DatabaseManager();
22
+ }
23
+ return DatabaseManager.instance;
24
+ }
25
+
26
+ async initialize(): Promise<void> {
27
+ await fs.mkdir(this.dataDir, { recursive: true });
28
+
29
+ // PostgreSQL connection configuration
30
+ this.pool = new Pool({
31
+ host: process.env.POSTGRES_HOST || 'localhost',
32
+ port: parseInt(process.env.POSTGRES_PORT || '5432'),
33
+ database: process.env.POSTGRES_DB || 'insforge',
34
+ user: process.env.POSTGRES_USER || 'postgres',
35
+ password: process.env.POSTGRES_PASSWORD || 'postgres',
36
+ max: 20,
37
+ idleTimeoutMillis: 30000,
38
+ connectionTimeoutMillis: 2000,
39
+ });
40
+
41
+ const client = await this.pool.connect();
42
+ await client.query('BEGIN');
43
+
44
+ // Note: Schema migrations are now handled by node-pg-migrate
45
+ // Run: npm run migrate:up
46
+
47
+ await client.query('COMMIT');
48
+ }
49
+
50
+ static async getColumnTypeMap(tableName: string): Promise<Record<string, string>> {
51
+ const instance = DatabaseManager.getInstance();
52
+ const client = await instance.pool.connect();
53
+ try {
54
+ const result = await client.query(
55
+ `SELECT column_name, data_type FROM information_schema.columns WHERE table_schema = 'public' AND table_name = $1`,
56
+ [tableName]
57
+ );
58
+ const map: Record<string, string> = {};
59
+ for (const row of result.rows) {
60
+ map[row.column_name] = row.data_type;
61
+ }
62
+ return map;
63
+ } finally {
64
+ client.release();
65
+ }
66
+ }
67
+
68
+ async getUserTables(): Promise<string[]> {
69
+ const client = await this.pool.connect();
70
+ try {
71
+ const result = await client.query(
72
+ `
73
+ SELECT table_name as name
74
+ FROM information_schema.tables
75
+ WHERE table_schema = 'public'
76
+ AND table_type = 'BASE TABLE'
77
+ AND (table_name NOT LIKE '\\_%')
78
+ ORDER BY table_name
79
+ `
80
+ );
81
+ return result.rows.map((row: { name: string }) => row.name);
82
+ } finally {
83
+ client.release();
84
+ }
85
+ }
86
+
87
+ async getMetadata(): Promise<DatabaseMetadataSchema> {
88
+ const client = await this.pool.connect();
89
+ try {
90
+ // Fetch all tables, database size, and record counts in parallel
91
+ const [allTables, databaseSize, countResults] = await Promise.all([
92
+ this.getUserTables(),
93
+ this.getDatabaseSizeInGB(),
94
+ // Get all counts in a single query using UNION ALL
95
+ (async () => {
96
+ try {
97
+ const tablesResult = await client.query(
98
+ `
99
+ SELECT table_name as name
100
+ FROM information_schema.tables
101
+ WHERE table_schema = 'public'
102
+ AND table_type = 'BASE TABLE'
103
+ AND (table_name NOT LIKE '\\_%')
104
+ ORDER BY table_name
105
+ `
106
+ );
107
+ const tableNames = tablesResult.rows.map((row: { name: string }) => row.name);
108
+
109
+ if (tableNames.length === 0) {
110
+ return [];
111
+ }
112
+
113
+ // Build a UNION ALL query to get all counts in one query
114
+ const unionQuery = tableNames
115
+ .map(
116
+ (tableName) =>
117
+ `SELECT '${tableName.replace(/'/g, "''")}' as table_name, COUNT(*) as count FROM "${tableName}"`
118
+ )
119
+ .join(' UNION ALL ');
120
+
121
+ const result = await client.query(unionQuery);
122
+ return result.rows as { table_name: string; count: number }[];
123
+ } catch {
124
+ return [];
125
+ }
126
+ })(),
127
+ ]);
128
+
129
+ // Map the count results to a lookup object
130
+ const countMap = new Map(countResults.map((r) => [r.table_name, Number(r.count)]));
131
+
132
+ const tableMetadatas = allTables.map((tableName) => ({
133
+ tableName,
134
+ recordCount: countMap.get(tableName) || 0,
135
+ }));
136
+
137
+ return {
138
+ tables: tableMetadatas,
139
+ totalSizeInGB: databaseSize,
140
+ hint: 'To retrieve detailed schema information for a specific table, call the get-table-schema tool with the table name.',
141
+ };
142
+ } finally {
143
+ client.release();
144
+ }
145
+ }
146
+
147
+ async getDatabaseSizeInGB(): Promise<number> {
148
+ const client = await this.pool.connect();
149
+ try {
150
+ // Query PostgreSQL for database size
151
+ const result = await client.query(`SELECT pg_database_size(current_database()) as size`);
152
+
153
+ // PostgreSQL returns size in bytes, convert to GB
154
+ return (result.rows[0]?.size || 0) / (1024 * 1024 * 1024);
155
+ } catch {
156
+ return 0;
157
+ } finally {
158
+ client.release();
159
+ }
160
+ }
161
+
162
+ getPool(): Pool {
163
+ return this.pool;
164
+ }
165
+
166
+ /**
167
+ * Create a dedicated client for operations that can't use pooled connections (e.g., LISTEN/NOTIFY)
168
+ */
169
+ createClient(): Client {
170
+ return new Client({
171
+ host: process.env.POSTGRES_HOST || 'localhost',
172
+ port: parseInt(process.env.POSTGRES_PORT || '5432'),
173
+ database: process.env.POSTGRES_DB || 'insforge',
174
+ user: process.env.POSTGRES_USER || 'postgres',
175
+ password: process.env.POSTGRES_PASSWORD || 'postgres',
176
+ });
177
+ }
178
+
179
+ async close(): Promise<void> {
180
+ await this.pool.end();
181
+ }
182
+ }