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,76 +0,0 @@
1
- import { LogSource, AnalyticsLogRecord, LogSourceStats } from '@/types/logs.js';
2
- import logger from '@/utils/logger.js';
3
- import { isCloudEnvironment } from '@/utils/environment.js';
4
- import { LocalDBProvider } from './providers/localdb.provider.js';
5
- import { CloudWatchProvider } from './providers/cloudwatch.provider.js';
6
- import { AnalyticsProvider } from './providers/base.provider.js';
7
-
8
- export class AnalyticsManager {
9
- private static instance: AnalyticsManager;
10
- private provider!: AnalyticsProvider;
11
-
12
- private constructor() {}
13
-
14
- static getInstance(): AnalyticsManager {
15
- if (!AnalyticsManager.instance) {
16
- AnalyticsManager.instance = new AnalyticsManager();
17
- }
18
- return AnalyticsManager.instance;
19
- }
20
-
21
- async initialize(): Promise<void> {
22
- // Decide provider based on explicit override or cloud environment
23
- const explicitProvider = (process.env.ANALYTICS_PROVIDER || '').toLowerCase();
24
- const shouldUseCloudwatch =
25
- explicitProvider === 'cloudwatch' ||
26
- (!explicitProvider && isCloudEnvironment() && !!process.env.CLOUDWATCH_LOG_GROUP);
27
-
28
- logger.info(
29
- `Using analytics provider: ${shouldUseCloudwatch ? 'CloudWatch' : 'LocalDB/Postgres'}`
30
- );
31
-
32
- if (shouldUseCloudwatch) {
33
- this.provider = new CloudWatchProvider();
34
- } else {
35
- this.provider = new LocalDBProvider();
36
- }
37
-
38
- await this.provider.initialize();
39
- }
40
-
41
- async getLogSources(): Promise<LogSource[]> {
42
- return this.provider.getLogSources();
43
- }
44
-
45
- async getLogsBySource(
46
- sourceName: string,
47
- limit: number = 100,
48
- beforeTimestamp?: string
49
- ): Promise<{
50
- logs: AnalyticsLogRecord[];
51
- total: number;
52
- tableName: string;
53
- }> {
54
- return this.provider.getLogsBySource(sourceName, limit, beforeTimestamp);
55
- }
56
-
57
- async getLogSourceStats(): Promise<LogSourceStats[]> {
58
- return this.provider.getLogSourceStats();
59
- }
60
-
61
- async searchLogs(
62
- query: string,
63
- sourceName?: string,
64
- limit: number = 100,
65
- offset: number = 0
66
- ): Promise<{
67
- logs: (AnalyticsLogRecord & { source: string })[];
68
- total: number;
69
- }> {
70
- return this.provider.searchLogs(query, sourceName, limit, offset);
71
- }
72
-
73
- async close(): Promise<void> {
74
- await this.provider.close();
75
- }
76
- }
@@ -1,246 +0,0 @@
1
- import { Pool } from 'pg';
2
- import { LogSource, AnalyticsLogRecord, LogSourceStats } from '@/types/logs.js';
3
- import logger from '@/utils/logger.js';
4
- import { BaseAnalyticsProvider } from './base.provider.js';
5
-
6
- export class LocalDBProvider extends BaseAnalyticsProvider {
7
- private pool!: Pool;
8
-
9
- async initialize(): Promise<void> {
10
- this.pool = new Pool({
11
- host: process.env.POSTGRES_HOST || 'localhost',
12
- port: parseInt(process.env.POSTGRES_PORT || '5432'),
13
- database: '_insforge',
14
- user: process.env.POSTGRES_USER || 'postgres',
15
- password: process.env.POSTGRES_PASSWORD || 'postgres',
16
- max: 10,
17
- idleTimeoutMillis: 30000,
18
- connectionTimeoutMillis: 2000,
19
- });
20
-
21
- try {
22
- const client = await this.pool.connect();
23
- client.release();
24
- logger.info('Analytics database connection established');
25
- } catch (error) {
26
- logger.error('Failed to connect to analytics database', {
27
- error: error instanceof Error ? error.message : String(error),
28
- });
29
- throw error;
30
- }
31
- }
32
-
33
- async getLogSources(): Promise<LogSource[]> {
34
- const client = await this.pool.connect();
35
- try {
36
- const result = await client.query(`
37
- SELECT id, name, token
38
- FROM _analytics.sources
39
- ORDER BY name
40
- `);
41
-
42
- const sourcesWithData: LogSource[] = [];
43
- for (const source of result.rows) {
44
- const tableName = `log_events_${source.token.replace(/-/g, '_')}`;
45
- try {
46
- const countResult = await client.query(`
47
- SELECT COUNT(*) as count
48
- FROM _analytics.${tableName}
49
- `);
50
- const count = parseInt(countResult.rows[0].count);
51
- if (count > 0) {
52
- sourcesWithData.push({
53
- ...source,
54
- name: this.getDisplayName(source.name),
55
- });
56
- }
57
- } catch (error) {
58
- logger.warn(`Source ${source.name} has no accessible data`, {
59
- error: error instanceof Error ? error.message : String(error),
60
- });
61
- }
62
- }
63
- return sourcesWithData;
64
- } finally {
65
- client.release();
66
- }
67
- }
68
-
69
- async getLogsBySource(
70
- sourceName: string,
71
- limit: number = 100,
72
- beforeTimestamp?: string
73
- ): Promise<{
74
- logs: AnalyticsLogRecord[];
75
- total: number;
76
- tableName: string;
77
- }> {
78
- const client = await this.pool.connect();
79
- try {
80
- // Convert display name to internal name for query
81
- const internalSourceName = this.getInternalName(sourceName);
82
-
83
- // First, get the source token to determine the table name
84
- const sourceResult = await client.query(
85
- `SELECT token FROM _analytics.sources WHERE name = $1`,
86
- [internalSourceName]
87
- );
88
-
89
- if (sourceResult.rows.length === 0) {
90
- throw new Error(`Log source '${sourceName}' not found`);
91
- }
92
-
93
- const token = sourceResult.rows[0].token;
94
- const tableName = `log_events_${token.replace(/-/g, '_')}`;
95
-
96
- // Build the query with timestamp-based pagination
97
- // If no beforeTimestamp provided, use current time
98
- const beforeTs = beforeTimestamp || new Date().toISOString();
99
-
100
- const query = `
101
- SELECT id, event_message, timestamp, body
102
- FROM _analytics.${tableName}
103
- WHERE timestamp < $1
104
- ORDER BY timestamp DESC
105
- LIMIT $2
106
- `;
107
- const params = [beforeTs, limit];
108
-
109
- const logsResult = await client.query(query, params);
110
-
111
- // Get total count of all records (not filtered by timestamp)
112
- const countQuery = `SELECT COUNT(*) as count FROM _analytics.${tableName}`;
113
- const countResult = await client.query(countQuery);
114
-
115
- return {
116
- logs: logsResult.rows,
117
- total: parseInt(countResult.rows[0].count),
118
- tableName: `_analytics.${tableName}`,
119
- };
120
- } finally {
121
- client.release();
122
- }
123
- }
124
-
125
- async getLogSourceStats(): Promise<LogSourceStats[]> {
126
- const client = await this.pool.connect();
127
- try {
128
- const sources = await this.getLogSources();
129
- const stats: LogSourceStats[] = [];
130
-
131
- for (const source of sources) {
132
- const tableName = `log_events_${source.token.replace(/-/g, '_')}`;
133
- try {
134
- const result = await client.query(`
135
- SELECT
136
- COUNT(*) as count,
137
- MAX(timestamp) as last_activity
138
- FROM _analytics.${tableName}
139
- `);
140
- stats.push({
141
- source: source.name,
142
- count: parseInt(result.rows[0].count),
143
- lastActivity: result.rows[0].last_activity || '',
144
- });
145
- } catch (error) {
146
- logger.warn(`Failed to get stats for source ${source.name}`, {
147
- error: error instanceof Error ? error.message : String(error),
148
- });
149
- stats.push({
150
- source: source.name,
151
- count: 0,
152
- lastActivity: '',
153
- });
154
- }
155
- }
156
- return stats.sort((a, b) => b.count - a.count);
157
- } finally {
158
- client.release();
159
- }
160
- }
161
-
162
- async searchLogs(
163
- query: string,
164
- sourceName?: string,
165
- limit: number = 100,
166
- offset: number = 0
167
- ): Promise<{
168
- logs: (AnalyticsLogRecord & { source: string })[];
169
- total: number;
170
- }> {
171
- const client = await this.pool.connect();
172
- try {
173
- let sources: LogSource[];
174
-
175
- if (sourceName) {
176
- // Convert display name to internal name for query
177
- const internalSourceName = this.getInternalName(sourceName);
178
- const sourceResult = await client.query(
179
- `SELECT id, name, token FROM _analytics.sources WHERE name = $1`,
180
- [internalSourceName]
181
- );
182
- // Apply name mapping to the result
183
- sources = sourceResult.rows.map((source) => ({
184
- ...source,
185
- name: this.getDisplayName(source.name),
186
- }));
187
- } else {
188
- // getLogSources already returns mapped names
189
- sources = await this.getLogSources();
190
- }
191
-
192
- const results: (AnalyticsLogRecord & { source: string })[] = [];
193
- let totalCount = 0;
194
-
195
- for (const source of sources) {
196
- const tableName = `log_events_${source.token.replace(/-/g, '_')}`;
197
-
198
- try {
199
- // Search in event_message and body fields
200
- const searchResult = await client.query(
201
- `SELECT id, event_message, timestamp, body, $1 as source
202
- FROM _analytics.${tableName}
203
- WHERE event_message ILIKE $2
204
- OR body::text ILIKE $2
205
- ORDER BY timestamp DESC
206
- LIMIT $3 OFFSET $4`,
207
- [source.name, `%${query}%`, limit, offset]
208
- );
209
-
210
- results.push(...searchResult.rows);
211
-
212
- // Get count for this source
213
- const countResult = await client.query(
214
- `SELECT COUNT(*) as count
215
- FROM _analytics.${tableName}
216
- WHERE event_message ILIKE $1
217
- OR body::text ILIKE $1`,
218
- [`%${query}%`]
219
- );
220
-
221
- totalCount += parseInt(countResult.rows[0].count);
222
- } catch (error) {
223
- logger.warn(`Failed to search in source ${source.name}`, {
224
- error: error instanceof Error ? error.message : String(error),
225
- });
226
- }
227
- }
228
-
229
- // Sort combined results by timestamp
230
- results.sort((a, b) => new Date(b.timestamp).getTime() - new Date(a.timestamp).getTime());
231
-
232
- return {
233
- logs: results.slice(0, limit),
234
- total: totalCount,
235
- };
236
- } finally {
237
- client.release();
238
- }
239
- }
240
-
241
- async close(): Promise<void> {
242
- if (this.pool) {
243
- await this.pool.end();
244
- }
245
- }
246
- }
@@ -1,388 +0,0 @@
1
- import { Server as HttpServer } from 'http';
2
- import { Server as SocketIOServer, Socket } from 'socket.io';
3
- import logger from '@/utils/logger.js';
4
- import { AuthService } from '../auth/auth.js';
5
- import {
6
- ServerEvents,
7
- ClientEvents,
8
- SocketMessage,
9
- SocketMetadata,
10
- NotificationPayload,
11
- SubscribePayload,
12
- UnsubscribePayload,
13
- } from './types.js';
14
- import { AppError } from '@/api/middleware/error.js';
15
- import { ERROR_CODES, NEXT_ACTION } from '@/types/error-constants.js';
16
-
17
- const authService = AuthService.getInstance();
18
-
19
- /**
20
- * SocketService - Industrial-grade Socket.IO implementation
21
- * Follows best practices for real-time communication
22
- */
23
- export class SocketService {
24
- private static instance: SocketService;
25
- private io: SocketIOServer | null = null;
26
- private socketMetadata: Map<string, SocketMetadata> = new Map();
27
-
28
- private constructor() {}
29
-
30
- /**
31
- * Singleton pattern for global socket service access
32
- */
33
- static getInstance(): SocketService {
34
- if (!SocketService.instance) {
35
- SocketService.instance = new SocketService();
36
- }
37
- return SocketService.instance;
38
- }
39
-
40
- /**
41
- * Initialize Socket.IO server
42
- */
43
- initialize(server: HttpServer): void {
44
- this.io = new SocketIOServer(server, {
45
- cors: {
46
- origin: true,
47
- credentials: true,
48
- },
49
- });
50
-
51
- this.setupConnectionHandlers();
52
- this.setupMiddleware();
53
-
54
- logger.info('Socket.IO server initialized');
55
- }
56
-
57
- /**
58
- * Setup authentication and validation middleware
59
- */
60
- private setupMiddleware(): void {
61
- if (!this.io) {
62
- return;
63
- }
64
-
65
- // Authentication middleware
66
- this.io.use((socket, next) => {
67
- try {
68
- const token = socket.handshake.auth.token;
69
- const payload = authService.verifyToken(token);
70
- if (!payload.role) {
71
- throw new AppError(
72
- 'Invalid token: missing role',
73
- 401,
74
- ERROR_CODES.AUTH_INVALID_CREDENTIALS,
75
- NEXT_ACTION.CHECK_TOKEN
76
- );
77
- }
78
- socket.data.user = {
79
- id: payload.sub,
80
- email: payload.email,
81
- role: payload.role,
82
- };
83
-
84
- next();
85
- } catch {
86
- next(
87
- new AppError(
88
- 'Invalid token',
89
- 401,
90
- ERROR_CODES.AUTH_INVALID_CREDENTIALS,
91
- NEXT_ACTION.CHECK_TOKEN
92
- )
93
- );
94
- }
95
- });
96
- }
97
-
98
- /**
99
- * Setup main connection handlers
100
- */
101
- private setupConnectionHandlers(): void {
102
- if (!this.io) {
103
- return;
104
- }
105
-
106
- this.io.on('connection', (socket: Socket) => {
107
- this.onSocketConnect(socket);
108
-
109
- // Setup event listeners
110
- this.setupClientEventHandlers(socket);
111
-
112
- // Handle disconnection
113
- socket.on('disconnect', (reason) => {
114
- this.onSocketDisconnect(socket, reason);
115
- });
116
-
117
- // Handle errors
118
- socket.on('error', (error: Error) => {
119
- this.onSocketError(socket, error);
120
- });
121
- });
122
- }
123
-
124
- /**
125
- * Handle new socket connection (includes reconnections)
126
- */
127
- private onSocketConnect(socket: Socket): void {
128
- // Initialize socket metadata
129
- const metadata: SocketMetadata = {
130
- userId: socket.data.user?.id,
131
- role: socket.data.user?.role,
132
- connectedAt: new Date(),
133
- lastActivity: new Date(),
134
- subscriptions: new Set(),
135
- };
136
-
137
- this.socketMetadata.set(socket.id, metadata);
138
-
139
- // Join appropriate rooms based on user role
140
- if (metadata.userId) {
141
- void socket.join(`user:${metadata.userId}`);
142
- }
143
- if (metadata.role) {
144
- void socket.join(`role:${metadata.role}`);
145
- }
146
-
147
- // Log connection with reconnection status
148
- logger.info('Socket client connected', {
149
- socketId: socket.id,
150
- userId: metadata.userId,
151
- role: metadata.role,
152
- restoredSubscriptions: metadata.subscriptions.size,
153
- });
154
- }
155
-
156
- /**
157
- * Handle socket disconnection
158
- */
159
- private onSocketDisconnect(socket: Socket, reason: string): void {
160
- const metadata = this.socketMetadata.get(socket.id);
161
-
162
- logger.info('Socket client disconnected', {
163
- socketId: socket.id,
164
- userId: metadata?.userId,
165
- reason,
166
- connectionDuration: metadata ? Date.now() - metadata.connectedAt.getTime() : 0,
167
- });
168
-
169
- // Cleanup
170
- this.socketMetadata.delete(socket.id);
171
- }
172
-
173
- /**
174
- * Handle socket errors
175
- */
176
- private onSocketError(socket: Socket, error: Error): void {
177
- logger.error('Socket error occurred', {
178
- socketId: socket.id,
179
- error: error.message,
180
- stack: error.stack,
181
- });
182
-
183
- // DO NOT clean up metadata here - the socket might recover
184
- // The 'disconnect' event will handle cleanup when/if the socket actually disconnects
185
- }
186
-
187
- /**
188
- * Setup handlers for client events
189
- */
190
- private setupClientEventHandlers(socket: Socket): void {
191
- // Handle subscription requests
192
- socket.on(ClientEvents.SUBSCRIBE, (payload: SubscribePayload) => {
193
- this.handleSubscribe(socket, payload);
194
- });
195
-
196
- // Handle unsubscription requests
197
- socket.on(ClientEvents.UNSUBSCRIBE, (payload: UnsubscribePayload) => {
198
- this.handleUnsubscribe(socket, payload);
199
- });
200
-
201
- // Update last activity on any event
202
- socket.onAny(() => {
203
- const metadata = this.socketMetadata.get(socket.id);
204
- if (metadata) {
205
- metadata.lastActivity = new Date();
206
- }
207
- });
208
- }
209
-
210
- /**
211
- * Handle channel subscription
212
- */
213
- private handleSubscribe(socket: Socket, payload: SubscribePayload): void {
214
- const metadata = this.socketMetadata.get(socket.id);
215
- if (!metadata) {
216
- return;
217
- }
218
-
219
- void socket.join(payload.channel);
220
- metadata.subscriptions.add(payload.channel);
221
-
222
- logger.debug('Socket subscribed to channel', {
223
- socketId: socket.id,
224
- channel: payload.channel,
225
- });
226
- }
227
-
228
- /**
229
- * Handle channel unsubscription
230
- */
231
- private handleUnsubscribe(socket: Socket, payload: UnsubscribePayload): void {
232
- const metadata = this.socketMetadata.get(socket.id);
233
- if (!metadata) {
234
- return;
235
- }
236
-
237
- void socket.leave(payload.channel);
238
- metadata.subscriptions.delete(payload.channel);
239
-
240
- logger.debug('Socket unsubscribed from channel', {
241
- socketId: socket.id,
242
- channel: payload.channel,
243
- });
244
- }
245
-
246
- /**
247
- * Emit event to specific socket with type safety
248
- */
249
- emitToSocket<T>(socket: Socket, event: ServerEvents, payload: T): void {
250
- const message: SocketMessage<T> = {
251
- type: event,
252
- payload,
253
- timestamp: Date.now(),
254
- id: this.generateMessageId(),
255
- };
256
- socket.emit(event, message);
257
- }
258
-
259
- /**
260
- * Broadcast to all connected clients
261
- */
262
- broadcastToAll<T>(event: ServerEvents, payload: T): void {
263
- if (!this.io) {
264
- logger.warn('Socket.IO server not initialized');
265
- return;
266
- }
267
-
268
- const message: SocketMessage<T> = {
269
- type: event,
270
- payload,
271
- timestamp: Date.now(),
272
- id: this.generateMessageId(),
273
- };
274
-
275
- this.io.emit(event, message);
276
-
277
- logger.info('Broadcasted message to all clients', {
278
- event,
279
- clientsCount: this.getConnectionCount(),
280
- });
281
- }
282
-
283
- /**
284
- * Broadcast to specific room
285
- */
286
- broadcastToRoom<T>(room: string, event: ServerEvents, payload?: T): void {
287
- if (!this.io) {
288
- logger.warn('Socket.IO server not initialized');
289
- return;
290
- }
291
-
292
- const message: SocketMessage<T> = {
293
- type: event,
294
- payload,
295
- timestamp: Date.now(),
296
- id: this.generateMessageId(),
297
- };
298
-
299
- this.io.to(room).emit(event, message);
300
-
301
- logger.info('Broadcasted message to room', {
302
- event,
303
- room,
304
- });
305
- }
306
-
307
- /**
308
- * Generate unique message ID
309
- */
310
- private generateMessageId(): string {
311
- return crypto.randomUUID();
312
- }
313
-
314
- /**
315
- * Get current connection count
316
- */
317
- getConnectionCount(): number {
318
- return this.socketMetadata.size;
319
- }
320
-
321
- /**
322
- * Get connection statistics
323
- */
324
- getConnectionStats(): {
325
- total: number;
326
- authenticated: number;
327
- averageConnectionTime: number;
328
- } {
329
- const connections = Array.from(this.socketMetadata.values());
330
- const authenticated = connections.filter((m) => m.userId).length;
331
- const avgTime =
332
- connections.reduce((acc, m) => {
333
- return acc + (Date.now() - m.connectedAt.getTime());
334
- }, 0) / (connections.length || 1);
335
-
336
- return {
337
- total: connections.length,
338
- authenticated,
339
- averageConnectionTime: avgTime,
340
- };
341
- }
342
-
343
- /**
344
- * Clean up inactive connections (can be called periodically)
345
- */
346
- cleanupInactiveConnections(maxInactivityMs: number = 300000): void {
347
- const now = Date.now();
348
-
349
- this.socketMetadata.forEach((metadata, socketId) => {
350
- const inactivityTime = now - metadata.lastActivity.getTime();
351
-
352
- if (inactivityTime > maxInactivityMs) {
353
- const socket = this.io?.sockets.sockets.get(socketId);
354
- if (socket) {
355
- logger.info('Disconnecting inactive socket', {
356
- socketId,
357
- inactivityTime,
358
- });
359
- socket.disconnect(true);
360
- }
361
- }
362
- });
363
- }
364
-
365
- /**
366
- * Gracefully close the Socket.IO server
367
- */
368
- close(): void {
369
- if (this.io) {
370
- // Notify all clients about server shutdown
371
- this.broadcastToAll<NotificationPayload>(ServerEvents.NOTIFICATION, {
372
- level: 'warning',
373
- title: 'Server Shutdown',
374
- message: 'Server is shutting down',
375
- });
376
-
377
- // Close all connections
378
- void this.io.close();
379
- logger.info('Socket.IO server closed');
380
- }
381
-
382
- // Clear metadata
383
- this.socketMetadata.clear();
384
- }
385
- }
386
-
387
- // Export singleton instance for convenience
388
- export const socketService = SocketService.getInstance();