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,21 +1,21 @@
1
- import { LogSource, AnalyticsLogRecord, LogSourceStats } from '@/types/logs.js';
1
+ import { LogSchema, LogSourceSchema, LogStatsSchema } from '@insforge/shared-schemas';
2
2
 
3
- export interface AnalyticsProvider {
3
+ export interface LogProvider {
4
4
  initialize(): Promise<void>;
5
5
 
6
- getLogSources(): Promise<LogSource[]>;
6
+ getLogSources(): Promise<LogSourceSchema[]>;
7
7
 
8
8
  getLogsBySource(
9
9
  sourceName: string,
10
10
  limit?: number,
11
11
  beforeTimestamp?: string
12
12
  ): Promise<{
13
- logs: AnalyticsLogRecord[];
13
+ logs: LogSchema[];
14
14
  total: number;
15
15
  tableName: string;
16
16
  }>;
17
17
 
18
- getLogSourceStats(): Promise<LogSourceStats[]>;
18
+ getLogSourceStats(): Promise<LogStatsSchema[]>;
19
19
 
20
20
  searchLogs(
21
21
  query: string,
@@ -23,7 +23,7 @@ export interface AnalyticsProvider {
23
23
  limit?: number,
24
24
  offset?: number
25
25
  ): Promise<{
26
- logs: (AnalyticsLogRecord & { source: string })[];
26
+ logs: (LogSchema & { source: string })[];
27
27
  total: number;
28
28
  }>;
29
29
 
@@ -31,7 +31,7 @@ export interface AnalyticsProvider {
31
31
  }
32
32
 
33
33
  // Base class with common functionality
34
- export abstract class BaseAnalyticsProvider implements AnalyticsProvider {
34
+ export abstract class BaseLogProvider implements LogProvider {
35
35
  // Source name mapping for user-friendly display
36
36
  protected sourceNameMap: Record<string, string> = {
37
37
  'cloudflare.logs.prod': 'insforge.logs',
@@ -59,24 +59,24 @@ export abstract class BaseAnalyticsProvider implements AnalyticsProvider {
59
59
  }
60
60
 
61
61
  abstract initialize(): Promise<void>;
62
- abstract getLogSources(): Promise<LogSource[]>;
62
+ abstract getLogSources(): Promise<LogSourceSchema[]>;
63
63
  abstract getLogsBySource(
64
64
  sourceName: string,
65
65
  limit?: number,
66
66
  beforeTimestamp?: string
67
67
  ): Promise<{
68
- logs: AnalyticsLogRecord[];
68
+ logs: LogSchema[];
69
69
  total: number;
70
70
  tableName: string;
71
71
  }>;
72
- abstract getLogSourceStats(): Promise<LogSourceStats[]>;
72
+ abstract getLogSourceStats(): Promise<LogStatsSchema[]>;
73
73
  abstract searchLogs(
74
74
  query: string,
75
75
  sourceName?: string,
76
76
  limit?: number,
77
77
  offset?: number
78
78
  ): Promise<{
79
- logs: (AnalyticsLogRecord & { source: string })[];
79
+ logs: (LogSchema & { source: string })[];
80
80
  total: number;
81
81
  }>;
82
82
  abstract close(): Promise<void>;
@@ -4,23 +4,23 @@ import {
4
4
  FilterLogEventsCommand,
5
5
  StartQueryCommand,
6
6
  GetQueryResultsCommand,
7
+ CreateLogGroupCommand,
8
+ ResourceAlreadyExistsException,
7
9
  } from '@aws-sdk/client-cloudwatch-logs';
8
- import { LogSource, AnalyticsLogRecord, LogSourceStats } from '@/types/logs.js';
9
10
  import logger from '@/utils/logger.js';
10
- import { BaseAnalyticsProvider } from './base.provider.js';
11
+ import { BaseLogProvider } from './base.provider.js';
12
+ import { AppError } from '@/api/middlewares/error.js';
13
+ import { ERROR_CODES } from '@/types/error-constants.js';
14
+ import { LogSchema, LogSourceSchema, LogStatsSchema } from '@insforge/shared-schemas';
11
15
 
12
- export class CloudWatchProvider extends BaseAnalyticsProvider {
16
+ export class CloudWatchProvider extends BaseLogProvider {
13
17
  private cwClient: CloudWatchLogsClient | null = null;
14
18
  private cwLogGroup: string | null = null;
15
19
  private cwRegion: string | null = null;
16
20
 
17
- initialize(): Promise<void> {
21
+ async initialize(): Promise<void> {
18
22
  this.cwRegion = process.env.AWS_REGION || process.env.AWS_DEFAULT_REGION || 'us-east-2';
19
- this.cwLogGroup = process.env.CLOUDWATCH_LOG_GROUP || null;
20
-
21
- if (!this.cwLogGroup) {
22
- throw new Error('CLOUDWATCH_LOG_GROUP is required when using CloudWatch analytics');
23
- }
23
+ this.cwLogGroup = process.env.CLOUDWATCH_LOG_GROUP || '/insforge/local';
24
24
 
25
25
  const cloudwatchOpts: {
26
26
  region: string;
@@ -34,8 +34,18 @@ export class CloudWatchProvider extends BaseAnalyticsProvider {
34
34
  }
35
35
 
36
36
  this.cwClient = new CloudWatchLogsClient({ ...cloudwatchOpts });
37
- logger.info(`Using analytics provider: ${this.cwLogGroup ? 'CloudWatch' : 'LocalDB/Postgres'}`);
38
- return Promise.resolve();
37
+
38
+ // Create log group if it doesn't exist
39
+ try {
40
+ await this.cwClient.send(new CreateLogGroupCommand({ logGroupName: this.cwLogGroup }));
41
+ logger.info(`Created CloudWatch log group: ${this.cwLogGroup}`);
42
+ } catch (error) {
43
+ if (error instanceof ResourceAlreadyExistsException) {
44
+ logger.info(`CloudWatch log group already exists: ${this.cwLogGroup}`);
45
+ } else {
46
+ logger.warn(`Could not create CloudWatch log group: ${error}`);
47
+ }
48
+ }
39
49
  }
40
50
 
41
51
  private getSuffixMapping(): Record<string, string> {
@@ -47,9 +57,13 @@ export class CloudWatchProvider extends BaseAnalyticsProvider {
47
57
  };
48
58
  }
49
59
 
50
- async getLogSources(): Promise<LogSource[]> {
60
+ async getLogSources(): Promise<LogSourceSchema[]> {
51
61
  if (!this.cwLogGroup || !this.cwClient) {
52
- throw new Error('CloudWatch not initialized');
62
+ throw new AppError(
63
+ 'AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY not found in environment variables',
64
+ 500,
65
+ ERROR_CODES.LOGS_AWS_NOT_CONFIGURED
66
+ );
53
67
  }
54
68
  const logGroup = this.cwLogGroup;
55
69
  const client = this.cwClient;
@@ -59,13 +73,13 @@ export class CloudWatchProvider extends BaseAnalyticsProvider {
59
73
  const result = await client.send(cmd);
60
74
  const streams = result.logStreams || [];
61
75
 
62
- const available: LogSource[] = [];
76
+ const available: LogSourceSchema[] = [];
63
77
  let idCounter = 1;
64
78
 
65
79
  for (const [displayName, suffix] of Object.entries(suffixMapping)) {
66
80
  const have = streams.some((s) => (s.logStreamName || '').includes(suffix));
67
81
  if (have) {
68
- available.push({ id: idCounter++, name: displayName, token: suffix });
82
+ available.push({ id: String(idCounter++), name: displayName, token: suffix });
69
83
  }
70
84
  }
71
85
 
@@ -77,12 +91,16 @@ export class CloudWatchProvider extends BaseAnalyticsProvider {
77
91
  limit: number = 100,
78
92
  beforeTimestamp?: string
79
93
  ): Promise<{
80
- logs: AnalyticsLogRecord[];
94
+ logs: LogSchema[];
81
95
  total: number;
82
96
  tableName: string;
83
97
  }> {
84
98
  if (!this.cwLogGroup || !this.cwClient) {
85
- throw new Error('CloudWatch not initialized');
99
+ throw new AppError(
100
+ 'AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY not found in environment variables',
101
+ 500,
102
+ ERROR_CODES.LOGS_AWS_NOT_CONFIGURED
103
+ );
86
104
  }
87
105
  const client = this.cwClient;
88
106
  const logGroup = this.cwLogGroup;
@@ -127,7 +145,7 @@ export class CloudWatchProvider extends BaseAnalyticsProvider {
127
145
  const fle = await client.send(
128
146
  new FilterLogEventsCommand({
129
147
  logGroupName: logGroup,
130
- logStreamNames: streams.length > 0 ? streams.slice(0, 100) : undefined,
148
+ logStreamNames: streams.length ? streams.slice(0, 100) : undefined,
131
149
  startTime: startMs,
132
150
  endTime: endMs,
133
151
  nextToken,
@@ -185,7 +203,7 @@ export class CloudWatchProvider extends BaseAnalyticsProvider {
185
203
  await sleep(300);
186
204
  }
187
205
 
188
- if (results && results.length > 0) {
206
+ if (results && results.length) {
189
207
  // Convert Insights results to our format
190
208
  events = results.map((row) => {
191
209
  const obj = Object.fromEntries(row.map((c) => [c.field || '', c.value || '']));
@@ -225,7 +243,7 @@ export class CloudWatchProvider extends BaseAnalyticsProvider {
225
243
  const fle = await client.send(
226
244
  new FilterLogEventsCommand({
227
245
  logGroupName: logGroup,
228
- logStreamNames: streams.length > 0 ? streams.slice(0, 100) : undefined,
246
+ logStreamNames: streams.length ? streams.slice(0, 100) : undefined,
229
247
  startTime: fallbackStartMs,
230
248
  endTime: beforeMs,
231
249
  limit: limit * 2, // Get a bit more to ensure we have enough
@@ -238,7 +256,7 @@ export class CloudWatchProvider extends BaseAnalyticsProvider {
238
256
  }
239
257
  }
240
258
  // Keep CloudWatch's default order (oldest first, newest last)
241
- const logs: AnalyticsLogRecord[] = events.map((e) => {
259
+ const logs: LogSchema[] = events.map((e) => {
242
260
  const message = e.message || '';
243
261
  let parsed: Record<string, unknown> = {};
244
262
  try {
@@ -251,7 +269,7 @@ export class CloudWatchProvider extends BaseAnalyticsProvider {
251
269
  id: e.eventId || `${e.logStreamName || ''}-${e.timestamp || ''}`,
252
270
  // CloudWatch timestamp is in milliseconds
253
271
  timestamp: e.timestamp ? new Date(e.timestamp).toISOString() : new Date().toISOString(),
254
- event_message:
272
+ eventMessage:
255
273
  typeof parsed === 'object' && parsed && (parsed as Record<string, unknown>).msg
256
274
  ? String((parsed as Record<string, unknown>).msg)
257
275
  : typeof message === 'string'
@@ -268,14 +286,18 @@ export class CloudWatchProvider extends BaseAnalyticsProvider {
268
286
  };
269
287
  }
270
288
 
271
- async getLogSourceStats(): Promise<LogSourceStats[]> {
289
+ async getLogSourceStats(): Promise<LogStatsSchema[]> {
272
290
  if (!this.cwLogGroup || !this.cwClient) {
273
- throw new Error('CloudWatch not initialized');
291
+ throw new AppError(
292
+ 'AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY not found in environment variables',
293
+ 500,
294
+ ERROR_CODES.LOGS_AWS_NOT_CONFIGURED
295
+ );
274
296
  }
275
297
  const client = this.cwClient;
276
298
  const logGroup = this.cwLogGroup;
277
299
  const sources = await this.getLogSources();
278
- const stats: LogSourceStats[] = [];
300
+ const stats: LogStatsSchema[] = [];
279
301
  const suffixMapping = this.getSuffixMapping();
280
302
 
281
303
  const dls = await client.send(new DescribeLogStreamsCommand({ logGroupName: logGroup }));
@@ -289,7 +311,7 @@ export class CloudWatchProvider extends BaseAnalyticsProvider {
289
311
 
290
312
  let lastActivity = '';
291
313
 
292
- if (sourceStreams.length > 0) {
314
+ if (sourceStreams.length) {
293
315
  try {
294
316
  // Use EXACTLY the same approach as getLogsBySource to get consistent results
295
317
  const endMs = Date.now();
@@ -297,16 +319,13 @@ export class CloudWatchProvider extends BaseAnalyticsProvider {
297
319
 
298
320
  // Use CloudWatch Insights to efficiently get the latest timestamp
299
321
  try {
300
- const end = Date.now();
301
- const start = end - 24 * 60 * 60 * 1000; // Last 24 hours
302
-
303
322
  const insights = `fields @timestamp | filter @logStream like /${suffix}/ | sort @timestamp desc | limit 1`;
304
323
 
305
324
  const startQuery = await client.send(
306
325
  new StartQueryCommand({
307
326
  logGroupName: logGroup,
308
- startTime: Math.floor(start / 1000),
309
- endTime: Math.floor(end / 1000),
327
+ startTime: Math.floor(startMs / 1000),
328
+ endTime: Math.floor(endMs / 1000),
310
329
  queryString: insights,
311
330
  limit: 1,
312
331
  })
@@ -326,7 +345,7 @@ export class CloudWatchProvider extends BaseAnalyticsProvider {
326
345
  await sleep(200);
327
346
  }
328
347
 
329
- if (results && results.length > 0) {
348
+ if (results && results.length) {
330
349
  const row = results[0];
331
350
  const timestampField = row.find((field) => field.field === '@timestamp');
332
351
  if (timestampField && timestampField.value) {
@@ -357,7 +376,7 @@ export class CloudWatchProvider extends BaseAnalyticsProvider {
357
376
  const fle = await client.send(
358
377
  new FilterLogEventsCommand({
359
378
  logGroupName: logGroup,
360
- logStreamNames: sourceStreams.length > 0 ? sourceStreams.slice(0, 100) : undefined,
379
+ logStreamNames: sourceStreams.length ? sourceStreams.slice(0, 100) : undefined,
361
380
  startTime: startMs,
362
381
  endTime: endMs,
363
382
  limit: 1000, // Reasonable limit for fallback
@@ -365,7 +384,7 @@ export class CloudWatchProvider extends BaseAnalyticsProvider {
365
384
  );
366
385
 
367
386
  const events = fle.events || [];
368
- if (events.length > 0) {
387
+ if (events.length) {
369
388
  const latestEvent = events[events.length - 1];
370
389
  if (latestEvent.timestamp) {
371
390
  lastActivity = new Date(latestEvent.timestamp).toISOString();
@@ -409,11 +428,15 @@ export class CloudWatchProvider extends BaseAnalyticsProvider {
409
428
  limit: number = 100,
410
429
  _offset = 0 // CloudWatch doesn't support offset-based pagination
411
430
  ): Promise<{
412
- logs: (AnalyticsLogRecord & { source: string })[];
431
+ logs: (LogSchema & { source: string })[];
413
432
  total: number;
414
433
  }> {
415
434
  if (!this.cwLogGroup || !this.cwClient) {
416
- throw new Error('CloudWatch not initialized');
435
+ throw new AppError(
436
+ 'AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY not found in environment variables',
437
+ 500,
438
+ ERROR_CODES.LOGS_AWS_NOT_CONFIGURED
439
+ );
417
440
  }
418
441
  const client = this.cwClient;
419
442
  const logGroup = this.cwLogGroup;
@@ -462,7 +485,7 @@ export class CloudWatchProvider extends BaseAnalyticsProvider {
462
485
  const toObj = (row: Array<{ field?: string; value?: string }>) =>
463
486
  Object.fromEntries(row.map((c) => [c.field || '', c.value || '']));
464
487
 
465
- const mapped: (AnalyticsLogRecord & { source: string })[] = rows.map((r) => {
488
+ const mapped: (LogSchema & { source: string })[] = rows.map((r) => {
466
489
  const o = toObj(r);
467
490
  const msg = o['@message'] || '';
468
491
  let parsed: Record<string, unknown> = {};
@@ -487,7 +510,7 @@ export class CloudWatchProvider extends BaseAnalyticsProvider {
487
510
  timestamp: o['@timestamp']
488
511
  ? new Date(parseInt(o['@timestamp'])).toISOString()
489
512
  : new Date().toISOString(),
490
- event_message:
513
+ eventMessage:
491
514
  typeof parsed === 'object' && (parsed as Record<string, unknown>).msg
492
515
  ? String((parsed as Record<string, unknown>).msg)
493
516
  : typeof msg === 'string'
@@ -0,0 +1,185 @@
1
+ import { promises as fs, createReadStream } from 'fs';
2
+ import { createInterface } from 'readline';
3
+ import path from 'path';
4
+ import { LogSchema, LogSourceSchema, LogStatsSchema } from '@insforge/shared-schemas';
5
+ import { BaseLogProvider } from './base.provider.js';
6
+ import logger from '@/utils/logger.js';
7
+
8
+ export class LocalFileProvider extends BaseLogProvider {
9
+ private logsDir: string = '';
10
+ private logFiles: Record<string, string> = {
11
+ 'insforge.logs': 'insforge.logs.jsonl',
12
+ 'postgres.logs': 'postgres.logs.jsonl',
13
+ 'postgREST.logs': 'postgrest.logs.jsonl',
14
+ 'function.logs': 'function.logs.jsonl',
15
+ };
16
+
17
+ async initialize(): Promise<void> {
18
+ this.logsDir = process.env.LOGS_DIR || path.resolve(process.cwd(), 'insforge-logs');
19
+ try {
20
+ await fs.mkdir(this.logsDir, { recursive: true });
21
+ } catch {
22
+ // Directory already exists
23
+ }
24
+ logger.info(`File-based analytics initialized at: ${this.logsDir}`);
25
+ }
26
+
27
+ getLogSources(): Promise<LogSourceSchema[]> {
28
+ const sources: LogSourceSchema[] = [];
29
+ let id = 1;
30
+
31
+ for (const [name, filename] of Object.entries(this.logFiles)) {
32
+ sources.push({ id: String(id++), name, token: filename });
33
+ }
34
+
35
+ return Promise.resolve(sources);
36
+ }
37
+
38
+ async getLogsBySource(
39
+ sourceName: string,
40
+ limit: number = 100,
41
+ beforeTimestamp?: string
42
+ ): Promise<{
43
+ logs: LogSchema[];
44
+ total: number;
45
+ tableName: string;
46
+ }> {
47
+ const filename = this.logFiles[sourceName];
48
+ if (!filename) {
49
+ return { logs: [], total: 0, tableName: sourceName };
50
+ }
51
+
52
+ const filePath = path.join(this.logsDir, filename);
53
+ const logs = await this.readLogsFromFile(filePath, limit, beforeTimestamp);
54
+
55
+ return {
56
+ logs,
57
+ total: logs.length,
58
+ tableName: sourceName,
59
+ };
60
+ }
61
+
62
+ private async readLogsFromFile(
63
+ filePath: string,
64
+ limit: number,
65
+ beforeTimestamp?: string
66
+ ): Promise<LogSchema[]> {
67
+ try {
68
+ await fs.access(filePath);
69
+ } catch {
70
+ return [];
71
+ }
72
+
73
+ const logs: LogSchema[] = [];
74
+ const beforeMs = beforeTimestamp ? Date.parse(beforeTimestamp) : Date.now();
75
+
76
+ const fileStream = createReadStream(filePath);
77
+ const rl = createInterface({ input: fileStream, crlfDelay: Infinity });
78
+
79
+ for await (const line of rl) {
80
+ if (!line.trim()) {
81
+ continue;
82
+ }
83
+
84
+ try {
85
+ const log = JSON.parse(line);
86
+
87
+ // Only process Vector-transformed logs (have appname field)
88
+ if (!log.appname) {
89
+ continue;
90
+ }
91
+
92
+ const logTime = new Date(log.timestamp).getTime();
93
+
94
+ if (logTime < beforeMs) {
95
+ // For error logs, include error and stack in eventMessage to match CloudWatch display
96
+ let eventMessage = log.event_message || '';
97
+ if (log.level === 'error' && log.error) {
98
+ eventMessage = `${eventMessage}\n\nError: ${log.error}`;
99
+ if (log.stack) {
100
+ eventMessage += `\n\nStack Trace:\n${log.stack}`;
101
+ }
102
+ }
103
+
104
+ logs.push({
105
+ id: `${logTime}-${Math.random()}`,
106
+ timestamp: log.timestamp,
107
+ eventMessage,
108
+ body: log,
109
+ });
110
+ }
111
+ } catch {
112
+ // Skip invalid JSON lines
113
+ }
114
+ }
115
+
116
+ // Return most recent logs up to limit
117
+ return logs.slice(-limit);
118
+ }
119
+
120
+ async getLogSourceStats(): Promise<LogStatsSchema[]> {
121
+ const stats: LogStatsSchema[] = [];
122
+
123
+ for (const [name, filename] of Object.entries(this.logFiles)) {
124
+ const filePath = path.join(this.logsDir, filename);
125
+ try {
126
+ const fileStats = await fs.stat(filePath);
127
+ const logs = await this.readLogsFromFile(filePath, 1000);
128
+
129
+ stats.push({
130
+ source: name,
131
+ count: logs.length,
132
+ lastActivity: fileStats.mtime.toISOString(),
133
+ });
134
+ } catch {
135
+ // File doesn't exist
136
+ }
137
+ }
138
+
139
+ return stats;
140
+ }
141
+
142
+ async searchLogs(
143
+ query: string,
144
+ sourceName?: string,
145
+ limit: number = 100,
146
+ offset: number = 0
147
+ ): Promise<{
148
+ logs: (LogSchema & { source: string })[];
149
+ total: number;
150
+ }> {
151
+ const results: (LogSchema & { source: string })[] = [];
152
+ const searchLower = query.toLowerCase();
153
+
154
+ const filesToSearch = sourceName
155
+ ? [{ name: sourceName, filename: this.logFiles[sourceName] }]
156
+ : Object.entries(this.logFiles).map(([name, filename]) => ({ name, filename }));
157
+
158
+ for (const { name, filename } of filesToSearch) {
159
+ if (!filename) {
160
+ continue;
161
+ }
162
+
163
+ const filePath = path.join(this.logsDir, filename);
164
+ const logs = await this.readLogsFromFile(filePath, 10000);
165
+
166
+ for (const log of logs) {
167
+ const messageMatch = log.eventMessage.toLowerCase().includes(searchLower);
168
+ const metadataMatch = JSON.stringify(log.body).toLowerCase().includes(searchLower);
169
+
170
+ if (messageMatch || metadataMatch) {
171
+ results.push({ ...log, source: name });
172
+ }
173
+ }
174
+ }
175
+
176
+ return {
177
+ logs: results.slice(offset, offset + limit),
178
+ total: results.length,
179
+ };
180
+ }
181
+
182
+ async close(): Promise<void> {
183
+ // No cleanup needed for file-based provider
184
+ }
185
+ }