insforge 0.3.1

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 (395) hide show
  1. package/.dockerignore +58 -0
  2. package/.env.example +49 -0
  3. package/.github/ISSUE_TEMPLATE/bug_report.yml +83 -0
  4. package/.github/ISSUE_TEMPLATE/config.yml +11 -0
  5. package/.github/ISSUE_TEMPLATE/feature_request.yml +79 -0
  6. package/.github/copilot-instructions.md +147 -0
  7. package/.github/workflows/build-image.yml +65 -0
  8. package/.github/workflows/ci-premerge-check.yml +24 -0
  9. package/.github/workflows/deploy-aws.yml +130 -0
  10. package/.github/workflows/lint-and-format.yml +33 -0
  11. package/.prettierignore +65 -0
  12. package/.prettierrc +9 -0
  13. package/CHANGELOG.md +3 -0
  14. package/CONTRIBUTING.md +126 -0
  15. package/Dockerfile +27 -0
  16. package/GITHUB_OAUTH_SETUP.md +49 -0
  17. package/GOOGLE_OAUTH_SETUP.md +148 -0
  18. package/LICENSE +201 -0
  19. package/README.md +134 -0
  20. package/assets/Dark.svg +23 -0
  21. package/assets/archDiagram.png +0 -0
  22. package/assets/banner.png +0 -0
  23. package/assets/mcpInstallv2.png +0 -0
  24. package/assets/sampleResponse.png +0 -0
  25. package/assets/signin.png +0 -0
  26. package/assets/userflow.png +0 -0
  27. package/backend/migrations/000_create-base-tables.sql +142 -0
  28. package/backend/migrations/001_create-helper-functions.sql +41 -0
  29. package/backend/migrations/002_rename-auth-tables.sql +30 -0
  30. package/backend/migrations/003_create-users-table.sql +56 -0
  31. package/backend/migrations/004_add-reload-postgrest-func.sql +24 -0
  32. package/backend/migrations/005_enable-project-admin-modify-users.sql +30 -0
  33. package/backend/migrations/006_modify-ai-usage-table.sql +25 -0
  34. package/backend/migrations/007_drop-metadata-table.sql +2 -0
  35. package/backend/migrations/008_add-system-tables.sql +77 -0
  36. package/backend/migrations/009_add-function-secrets.sql +24 -0
  37. package/backend/migrations/010_modify-ai-config-modalities.sql +93 -0
  38. package/backend/migrations/011_refactor-secrets-table.sql +15 -0
  39. package/backend/migrations/012_add-storage-uploaded-by.sql +8 -0
  40. package/backend/package.json +75 -0
  41. package/backend/src/api/middleware/auth.ts +240 -0
  42. package/backend/src/api/middleware/error.ts +231 -0
  43. package/backend/src/api/middleware/upload.ts +59 -0
  44. package/backend/src/api/routes/agent.ts +29 -0
  45. package/backend/src/api/routes/ai.ts +472 -0
  46. package/backend/src/api/routes/auth.oauth.ts +482 -0
  47. package/backend/src/api/routes/auth.ts +386 -0
  48. package/backend/src/api/routes/database.advance.ts +275 -0
  49. package/backend/src/api/routes/database.records.ts +246 -0
  50. package/backend/src/api/routes/database.tables.ts +161 -0
  51. package/backend/src/api/routes/docs.ts +66 -0
  52. package/backend/src/api/routes/functions.ts +183 -0
  53. package/backend/src/api/routes/logs.ts +150 -0
  54. package/backend/src/api/routes/metadata.ts +160 -0
  55. package/backend/src/api/routes/openapi.ts +82 -0
  56. package/backend/src/api/routes/secrets.ts +199 -0
  57. package/backend/src/api/routes/storage.ts +547 -0
  58. package/backend/src/api/routes/usage.ts +96 -0
  59. package/backend/src/core/ai/chat.ts +207 -0
  60. package/backend/src/core/ai/client.ts +242 -0
  61. package/backend/src/core/ai/config.ts +187 -0
  62. package/backend/src/core/ai/image.ts +156 -0
  63. package/backend/src/core/ai/model.ts +117 -0
  64. package/backend/src/core/ai/usage.ts +290 -0
  65. package/backend/src/core/auth/auth.ts +781 -0
  66. package/backend/src/core/auth/oauth.ts +398 -0
  67. package/backend/src/core/database/advance.ts +1074 -0
  68. package/backend/src/core/database/manager.ts +178 -0
  69. package/backend/src/core/database/table.ts +772 -0
  70. package/backend/src/core/documentation/agent.ts +689 -0
  71. package/backend/src/core/documentation/openapi.ts +856 -0
  72. package/backend/src/core/functions/functions.ts +310 -0
  73. package/backend/src/core/logs/analytics.ts +76 -0
  74. package/backend/src/core/logs/audit.ts +255 -0
  75. package/backend/src/core/logs/providers/base.provider.ts +83 -0
  76. package/backend/src/core/logs/providers/cloudwatch.provider.ts +510 -0
  77. package/backend/src/core/logs/providers/localdb.provider.ts +246 -0
  78. package/backend/src/core/secrets/encryption.ts +58 -0
  79. package/backend/src/core/secrets/secrets.ts +410 -0
  80. package/backend/src/core/socket/socket.ts +388 -0
  81. package/backend/src/core/socket/types.ts +79 -0
  82. package/backend/src/core/storage/storage.ts +923 -0
  83. package/backend/src/server.ts +288 -0
  84. package/backend/src/types/ai.ts +46 -0
  85. package/backend/src/types/auth.ts +90 -0
  86. package/backend/src/types/database.ts +136 -0
  87. package/backend/src/types/error-constants.ts +86 -0
  88. package/backend/src/types/logs.ts +47 -0
  89. package/backend/src/types/profile.ts +55 -0
  90. package/backend/src/types/storage.ts +23 -0
  91. package/backend/src/utils/cloud-token.ts +39 -0
  92. package/backend/src/utils/constants.ts +1 -0
  93. package/backend/src/utils/environment.ts +35 -0
  94. package/backend/src/utils/helpers.ts +49 -0
  95. package/backend/src/utils/logger.ts +13 -0
  96. package/backend/src/utils/response.ts +62 -0
  97. package/backend/src/utils/seed.ts +205 -0
  98. package/backend/src/utils/sql-parser.ts +63 -0
  99. package/backend/src/utils/uuid.ts +9 -0
  100. package/backend/src/utils/validations.ts +129 -0
  101. package/backend/tests/README.md +134 -0
  102. package/backend/tests/cleanup-all-test-data.sh +231 -0
  103. package/backend/tests/cloud/test-s3-multitenant.sh +132 -0
  104. package/backend/tests/local/comprehensive-curl-tests.sh +156 -0
  105. package/backend/tests/local/test-auth-router.sh +144 -0
  106. package/backend/tests/local/test-database-router.sh +222 -0
  107. package/backend/tests/local/test-e2e.sh +241 -0
  108. package/backend/tests/local/test-fk-errors.sh +97 -0
  109. package/backend/tests/local/test-id-field.sh +201 -0
  110. package/backend/tests/local/test-public-bucket.sh +265 -0
  111. package/backend/tests/local/test-secrets.sh +248 -0
  112. package/backend/tests/local/test-serverless-functions.sh.disabled +325 -0
  113. package/backend/tests/local/test-traditional-rest.sh +209 -0
  114. package/backend/tests/manual/README.md +51 -0
  115. package/backend/tests/manual/create-large-table-simple.sql +11 -0
  116. package/backend/tests/manual/seed-large-table.sql +101 -0
  117. package/backend/tests/manual/setup-large-table-extras.sql +34 -0
  118. package/backend/tests/manual/test-better-auth.sh +303 -0
  119. package/backend/tests/manual/test-bulk-upsert.sh +410 -0
  120. package/backend/tests/manual/test-database-advance.sh +297 -0
  121. package/backend/tests/manual/test-postgrest-stability.sh +192 -0
  122. package/backend/tests/manual/test-rawsql-export-import.sh +412 -0
  123. package/backend/tests/manual/test-universal-storage.sh +264 -0
  124. package/backend/tests/manual/test-users.sql +18 -0
  125. package/backend/tests/run-all-tests.sh +140 -0
  126. package/backend/tests/setup.ts +22 -0
  127. package/backend/tests/test-config.sh +303 -0
  128. package/backend/tsconfig.json +23 -0
  129. package/backend/tsup.config.ts +18 -0
  130. package/backend/vitest.config.ts +22 -0
  131. package/docker-compose.prod.yml +145 -0
  132. package/docker-compose.yml +167 -0
  133. package/docker-init/db/db-init.sql +125 -0
  134. package/docker-init/db/jwt.sql +5 -0
  135. package/docker-init/db/logs.sql +9 -0
  136. package/docker-init/db/postgresql.conf +17 -0
  137. package/docs/deprecated/insforge-auth-api.md +215 -0
  138. package/docs/deprecated/insforge-auth-sdk.md +100 -0
  139. package/docs/deprecated/insforge-db-api.md +359 -0
  140. package/docs/deprecated/insforge-db-sdk.md +140 -0
  141. package/docs/deprecated/insforge-debug-sdk.md +157 -0
  142. package/docs/deprecated/insforge-debug.md +65 -0
  143. package/docs/deprecated/insforge-instructions.md +124 -0
  144. package/docs/deprecated/insforge-project.md +118 -0
  145. package/docs/deprecated/insforge-storage-api.md +279 -0
  146. package/docs/deprecated/insforge-storage-sdk.md +159 -0
  147. package/docs/insforge-instructions-sdk.md +407 -0
  148. package/eslint.config.js +317 -0
  149. package/examples/oauth/frontend-oauth-example.html +251 -0
  150. package/examples/response-examples.md +444 -0
  151. package/frontend/README.md +112 -0
  152. package/frontend/components.json +17 -0
  153. package/frontend/index.html +13 -0
  154. package/frontend/package.json +63 -0
  155. package/frontend/public/favicon.ico +0 -0
  156. package/frontend/src/App.tsx +106 -0
  157. package/frontend/src/assets/icons/checkbox_checked.svg +6 -0
  158. package/frontend/src/assets/icons/checkbox_undetermined.svg +6 -0
  159. package/frontend/src/assets/icons/checked.svg +3 -0
  160. package/frontend/src/assets/icons/error.svg +3 -0
  161. package/frontend/src/assets/icons/pencil.svg +4 -0
  162. package/frontend/src/assets/icons/refresh.svg +4 -0
  163. package/frontend/src/assets/icons/step_active.svg +3 -0
  164. package/frontend/src/assets/icons/step_inactive.svg +11 -0
  165. package/frontend/src/assets/icons/warning.svg +3 -0
  166. package/frontend/src/assets/logos/amazon.svg +1 -0
  167. package/frontend/src/assets/logos/claude_code.svg +3 -0
  168. package/frontend/src/assets/logos/cline.svg +6 -0
  169. package/frontend/src/assets/logos/cursor.svg +20 -0
  170. package/frontend/src/assets/logos/discord.svg +9 -0
  171. package/frontend/src/assets/logos/gemini.svg +19 -0
  172. package/frontend/src/assets/logos/github.svg +5 -0
  173. package/frontend/src/assets/logos/google.svg +13 -0
  174. package/frontend/src/assets/logos/grok.svg +10 -0
  175. package/frontend/src/assets/logos/insforge_dark.svg +15 -0
  176. package/frontend/src/assets/logos/insforge_light.svg +15 -0
  177. package/frontend/src/assets/logos/openai.svg +10 -0
  178. package/frontend/src/assets/logos/roo_code.svg +9 -0
  179. package/frontend/src/assets/logos/trae.svg +3 -0
  180. package/frontend/src/assets/logos/windsurf.svg +10 -0
  181. package/frontend/src/components/ButtonWithLoading.tsx +27 -0
  182. package/frontend/src/components/Checkbox.tsx +61 -0
  183. package/frontend/src/components/CodeBlock.tsx +32 -0
  184. package/frontend/src/components/ConfirmDialog.tsx +96 -0
  185. package/frontend/src/components/CopyButton.tsx +69 -0
  186. package/frontend/src/components/DeleteActionButton.tsx +42 -0
  187. package/frontend/src/components/EmptyState.tsx +41 -0
  188. package/frontend/src/components/ErrorState.tsx +35 -0
  189. package/frontend/src/components/FeatureSidebar.tsx +126 -0
  190. package/frontend/src/components/FeatureSidebarItem.tsx +101 -0
  191. package/frontend/src/components/JsonHighlight.tsx +61 -0
  192. package/frontend/src/components/LoadingState.tsx +16 -0
  193. package/frontend/src/components/PaginationControls.tsx +54 -0
  194. package/frontend/src/components/PromptDialog.tsx +68 -0
  195. package/frontend/src/components/SearchInput.tsx +90 -0
  196. package/frontend/src/components/SelectionClearButton.tsx +26 -0
  197. package/frontend/src/components/Stepper.tsx +139 -0
  198. package/frontend/src/components/ThemeToggle.tsx +58 -0
  199. package/frontend/src/components/TypeBadge.tsx +20 -0
  200. package/frontend/src/components/datagrid/DataGrid.tsx +264 -0
  201. package/frontend/src/components/datagrid/DefaultCellRenderer.tsx +114 -0
  202. package/frontend/src/components/datagrid/IdCell.tsx +44 -0
  203. package/frontend/src/components/datagrid/SortableHeader.tsx +74 -0
  204. package/frontend/src/components/datagrid/cell-editors/BooleanCellEditor.tsx +54 -0
  205. package/frontend/src/components/datagrid/cell-editors/DateCellEditor.tsx +483 -0
  206. package/frontend/src/components/datagrid/cell-editors/JsonCellEditor.tsx +362 -0
  207. package/frontend/src/components/datagrid/cell-editors/TextCellEditor.tsx +38 -0
  208. package/frontend/src/components/datagrid/cell-editors/index.ts +14 -0
  209. package/frontend/src/components/datagrid/cell-editors/types.ts +43 -0
  210. package/frontend/src/components/datagrid/datagridTypes.tsx +72 -0
  211. package/frontend/src/components/datagrid/index.tsx +20 -0
  212. package/frontend/src/components/index.ts +39 -0
  213. package/frontend/src/components/layout/AppHeader.tsx +146 -0
  214. package/frontend/src/components/layout/AppSidebar.tsx +190 -0
  215. package/frontend/src/components/layout/CloudLayout.tsx +95 -0
  216. package/frontend/src/components/layout/Layout.tsx +43 -0
  217. package/frontend/src/components/radix/Alert.tsx +45 -0
  218. package/frontend/src/components/radix/AlertDialog.tsx +115 -0
  219. package/frontend/src/components/radix/Avatar.tsx +45 -0
  220. package/frontend/src/components/radix/Badge.tsx +33 -0
  221. package/frontend/src/components/radix/Button.tsx +50 -0
  222. package/frontend/src/components/radix/Card.tsx +58 -0
  223. package/frontend/src/components/radix/Dialog.tsx +98 -0
  224. package/frontend/src/components/radix/DropdownMenu.tsx +185 -0
  225. package/frontend/src/components/radix/Form.tsx +167 -0
  226. package/frontend/src/components/radix/Input.tsx +22 -0
  227. package/frontend/src/components/radix/Label.tsx +19 -0
  228. package/frontend/src/components/radix/Popover.tsx +29 -0
  229. package/frontend/src/components/radix/ScrollArea.tsx +44 -0
  230. package/frontend/src/components/radix/Select.tsx +151 -0
  231. package/frontend/src/components/radix/Separator.tsx +26 -0
  232. package/frontend/src/components/radix/Sheet.tsx +119 -0
  233. package/frontend/src/components/radix/Skeleton.tsx +7 -0
  234. package/frontend/src/components/radix/Switch.tsx +29 -0
  235. package/frontend/src/components/radix/Tabs.tsx +50 -0
  236. package/frontend/src/components/radix/Textarea.tsx +21 -0
  237. package/frontend/src/components/radix/Tooltip.tsx +28 -0
  238. package/frontend/src/features/ai/components/AIConfigCard.tsx +154 -0
  239. package/frontend/src/features/ai/components/AIConfigDialog.tsx +76 -0
  240. package/frontend/src/features/ai/components/AIConfigForm.tsx +222 -0
  241. package/frontend/src/features/ai/components/AIEmptyState.tsx +18 -0
  242. package/frontend/src/features/ai/components/fields/ModalityField.tsx +87 -0
  243. package/frontend/src/features/ai/components/fields/ModelSelectionField.tsx +134 -0
  244. package/frontend/src/features/ai/components/fields/SystemPromptField.tsx +33 -0
  245. package/frontend/src/features/ai/helpers.ts +155 -0
  246. package/frontend/src/features/ai/hooks/useAIConfigs.ts +221 -0
  247. package/frontend/src/features/ai/hooks/useAIUsage.ts +77 -0
  248. package/frontend/src/features/ai/page/AIPage.tsx +178 -0
  249. package/frontend/src/features/ai/services/ai.service.ts +148 -0
  250. package/frontend/src/features/auth/components/AddOAuthDialog.tsx +106 -0
  251. package/frontend/src/features/auth/components/AuthMethodTab.tsx +238 -0
  252. package/frontend/src/features/auth/components/OAuthConfigDialog.tsx +303 -0
  253. package/frontend/src/features/auth/components/OAuthEmptyState.tsx +15 -0
  254. package/frontend/src/features/auth/components/UserFormDialog.tsx +248 -0
  255. package/frontend/src/features/auth/components/UsersDataGrid.tsx +183 -0
  256. package/frontend/src/features/auth/components/UsersTab.tsx +114 -0
  257. package/frontend/src/features/auth/hooks/useOAuthConfig.ts +129 -0
  258. package/frontend/src/features/auth/hooks/useUsers.ts +57 -0
  259. package/frontend/src/features/auth/index.ts +9 -0
  260. package/frontend/src/features/auth/page/AuthenticationPage.tsx +169 -0
  261. package/frontend/src/features/auth/services/auth.service.ts +112 -0
  262. package/frontend/src/features/auth/services/oauth.service.ts +49 -0
  263. package/frontend/src/features/dashboard/page/DashboardPage.tsx +194 -0
  264. package/frontend/src/features/database/components/ColumnTypeSelect.tsx +64 -0
  265. package/frontend/src/features/database/components/DatabaseDataGrid.tsx +282 -0
  266. package/frontend/src/features/database/components/ForeignKeyCell.tsx +187 -0
  267. package/frontend/src/features/database/components/ForeignKeyPopover.tsx +378 -0
  268. package/frontend/src/features/database/components/LinkRecordModal.tsx +288 -0
  269. package/frontend/src/features/database/components/RecordFormDialog.tsx +164 -0
  270. package/frontend/src/features/database/components/RecordFormField.tsx +568 -0
  271. package/frontend/src/features/database/components/TableEmptyState.tsx +21 -0
  272. package/frontend/src/features/database/components/TableForm.tsx +656 -0
  273. package/frontend/src/features/database/components/TableFormColumn.tsx +137 -0
  274. package/frontend/src/features/database/components/TableListSkeleton.tsx +9 -0
  275. package/frontend/src/features/database/components/TableSidebar.tsx +47 -0
  276. package/frontend/src/features/database/constants.ts +26 -0
  277. package/frontend/src/features/database/helpers.ts +125 -0
  278. package/frontend/src/features/database/hooks/UseLinkModal.tsx +78 -0
  279. package/frontend/src/features/database/index.ts +12 -0
  280. package/frontend/src/features/database/page/DatabasePage.tsx +626 -0
  281. package/frontend/src/features/database/schema.ts +25 -0
  282. package/frontend/src/features/database/services/database.service.ts +216 -0
  283. package/frontend/src/features/functions/components/FunctionEmptyState.tsx +15 -0
  284. package/frontend/src/features/functions/components/FunctionRow.tsx +71 -0
  285. package/frontend/src/features/functions/components/FunctionViewer.tsx +46 -0
  286. package/frontend/src/features/functions/components/FunctionsContent.tsx +88 -0
  287. package/frontend/src/features/functions/components/FunctionsSidebar.tsx +56 -0
  288. package/frontend/src/features/functions/components/SecretEmptyState.tsx +23 -0
  289. package/frontend/src/features/functions/components/SecretRow.tsx +68 -0
  290. package/frontend/src/features/functions/components/SecretsContent.tsx +120 -0
  291. package/frontend/src/features/functions/hooks/useFunctions.ts +106 -0
  292. package/frontend/src/features/functions/page/FunctionsPage.tsx +28 -0
  293. package/frontend/src/features/functions/services/functions.service.ts +48 -0
  294. package/frontend/src/features/login/components/AuthErrorBoundary.tsx +87 -0
  295. package/frontend/src/features/login/components/PrivateRoute.tsx +24 -0
  296. package/frontend/src/features/login/page/CloudLoginPage.tsx +93 -0
  297. package/frontend/src/features/login/page/LoginPage.tsx +174 -0
  298. package/frontend/src/features/logs/components/AnalyticsLogsTable.tsx +313 -0
  299. package/frontend/src/features/logs/components/LogsTable.tsx +199 -0
  300. package/frontend/src/features/logs/hooks/useAuditLogs.ts +39 -0
  301. package/frontend/src/features/logs/index.ts +5 -0
  302. package/frontend/src/features/logs/page/AnalyticsLogsPage.tsx +530 -0
  303. package/frontend/src/features/logs/page/AuditsPage.tsx +192 -0
  304. package/frontend/src/features/logs/services/log.service.ts +171 -0
  305. package/frontend/src/features/metadata/hooks/useMetadata.ts +53 -0
  306. package/frontend/src/features/metadata/index.ts +0 -0
  307. package/frontend/src/features/metadata/page/MetadataPage.tsx +136 -0
  308. package/frontend/src/features/metadata/services/metadata.service.ts +17 -0
  309. package/frontend/src/features/onboard/components/CompletionCard.tsx +41 -0
  310. package/frontend/src/features/onboard/components/OnboardButton.tsx +84 -0
  311. package/frontend/src/features/onboard/components/StepContent.tsx +91 -0
  312. package/frontend/src/features/onboard/components/TestConnectionStep.tsx +53 -0
  313. package/frontend/src/features/onboard/components/mcp/CursorDeeplinkGenerator.tsx +35 -0
  314. package/frontend/src/features/onboard/components/mcp/McpInstallation.tsx +144 -0
  315. package/frontend/src/features/onboard/components/mcp/index.ts +4 -0
  316. package/frontend/src/features/onboard/components/mcp/mcp-helper.tsx +98 -0
  317. package/frontend/src/features/onboard/index.ts +3 -0
  318. package/frontend/src/features/onboard/page/OnBoardPage.tsx +104 -0
  319. package/frontend/src/features/onboard/types.ts +8 -0
  320. package/frontend/src/features/secrets/hooks/useSecrets.ts +139 -0
  321. package/frontend/src/features/secrets/services/secrets.service.ts +57 -0
  322. package/frontend/src/features/storage/components/BucketEmptyState.tsx +19 -0
  323. package/frontend/src/features/storage/components/BucketFormDialog.tsx +194 -0
  324. package/frontend/src/features/storage/components/BucketListSkeleton.tsx +17 -0
  325. package/frontend/src/features/storage/components/FilePreviewDialog.tsx +287 -0
  326. package/frontend/src/features/storage/components/StorageDataGrid.tsx +239 -0
  327. package/frontend/src/features/storage/components/StorageManager.tsx +236 -0
  328. package/frontend/src/features/storage/components/StorageSidebar.tsx +44 -0
  329. package/frontend/src/features/storage/components/UploadToast.tsx +46 -0
  330. package/frontend/src/features/storage/index.ts +3 -0
  331. package/frontend/src/features/storage/page/StoragePage.tsx +553 -0
  332. package/frontend/src/features/storage/services/storage.service.ts +144 -0
  333. package/frontend/src/features/visualizer/components/AuthNode.tsx +107 -0
  334. package/frontend/src/features/visualizer/components/BucketNode.tsx +34 -0
  335. package/frontend/src/features/visualizer/components/SchemaVisualizer.tsx +359 -0
  336. package/frontend/src/features/visualizer/components/TableNode.tsx +152 -0
  337. package/frontend/src/features/visualizer/components/VisualizerSkeleton.tsx +24 -0
  338. package/frontend/src/features/visualizer/components/index.ts +5 -0
  339. package/frontend/src/features/visualizer/page/VisualizerPage.tsx +127 -0
  340. package/frontend/src/index.css +248 -0
  341. package/frontend/src/lib/api/client.ts +163 -0
  342. package/frontend/src/lib/contexts/AuthContext.tsx +157 -0
  343. package/frontend/src/lib/contexts/OnboardStepContext.tsx +68 -0
  344. package/frontend/src/lib/contexts/SocketContext.tsx +303 -0
  345. package/frontend/src/lib/contexts/ThemeContext.tsx +125 -0
  346. package/frontend/src/lib/hooks/useAuth.ts +4 -0
  347. package/frontend/src/lib/hooks/useConfirm.ts +55 -0
  348. package/frontend/src/lib/hooks/useInterval.ts +27 -0
  349. package/frontend/src/lib/hooks/useMediaQuery.ts +59 -0
  350. package/frontend/src/lib/hooks/useOnboardingCompletion.ts +29 -0
  351. package/frontend/src/lib/hooks/usePagination.ts +27 -0
  352. package/frontend/src/lib/hooks/useTimeout.ts +27 -0
  353. package/frontend/src/lib/hooks/useToast.tsx +229 -0
  354. package/frontend/src/lib/utils/constants.ts +38 -0
  355. package/frontend/src/lib/utils/utils.ts +165 -0
  356. package/frontend/src/lib/utils/validation-schemas.ts +126 -0
  357. package/frontend/src/main.tsx +16 -0
  358. package/frontend/src/rdg.css +194 -0
  359. package/frontend/src/vite-env.d.ts +12 -0
  360. package/frontend/tailwind.config.js +97 -0
  361. package/frontend/tsconfig.json +26 -0
  362. package/frontend/tsconfig.node.json +10 -0
  363. package/frontend/vite.config.ts +37 -0
  364. package/frontend/vitest.config.ts +36 -0
  365. package/functions/deno.json +25 -0
  366. package/functions/server.ts +290 -0
  367. package/functions/worker-template.js +126 -0
  368. package/openapi/ai.yaml +689 -0
  369. package/openapi/auth.yaml +563 -0
  370. package/openapi/functions.yaml +476 -0
  371. package/openapi/health.yaml +30 -0
  372. package/openapi/logs.yaml +224 -0
  373. package/openapi/metadata.yaml +178 -0
  374. package/openapi/records.yaml +382 -0
  375. package/openapi/secrets.yaml +371 -0
  376. package/openapi/storage.yaml +876 -0
  377. package/openapi/tables.yaml +464 -0
  378. package/package.json +88 -0
  379. package/shared-schemas/package.json +31 -0
  380. package/shared-schemas/src/ai-api.schema.ts +167 -0
  381. package/shared-schemas/src/ai.schema.ts +54 -0
  382. package/shared-schemas/src/auth-api.schema.ts +193 -0
  383. package/shared-schemas/src/auth.schema.ts +94 -0
  384. package/shared-schemas/src/database-api.schema.ts +259 -0
  385. package/shared-schemas/src/database.schema.ts +69 -0
  386. package/shared-schemas/src/functions-api.schema.ts +25 -0
  387. package/shared-schemas/src/functions.schema.ts +16 -0
  388. package/shared-schemas/src/index.ts +13 -0
  389. package/shared-schemas/src/logs-api.schema.ts +49 -0
  390. package/shared-schemas/src/logs.schema.ts +14 -0
  391. package/shared-schemas/src/metadata.schema.ts +56 -0
  392. package/shared-schemas/src/storage-api.schema.ts +65 -0
  393. package/shared-schemas/src/storage.schema.ts +19 -0
  394. package/shared-schemas/tsconfig.json +21 -0
  395. package/tsconfig.json +8 -0
@@ -0,0 +1,59 @@
1
+ import multer from 'multer';
2
+ import { Request, Response, NextFunction } from 'express';
3
+ import { AppError } from './error.js';
4
+ import { ERROR_CODES } from '@/types/error-constants.js';
5
+ import { ProcessedFormData } from '@/types/storage.js';
6
+
7
+ // Constants
8
+ const DEFAULT_MAX_FILE_SIZE = 10 * 1024 * 1024; // 10MB
9
+ const DEFAULT_MAX_FILES = 10;
10
+
11
+ // Create multer instance with memory storage
12
+ export const upload = multer({
13
+ storage: multer.memoryStorage(),
14
+ limits: {
15
+ fileSize: parseInt(process.env.MAX_FILE_SIZE || '') || DEFAULT_MAX_FILE_SIZE,
16
+ files: parseInt(process.env.MAX_FILES_PER_FIELD || '') || DEFAULT_MAX_FILES,
17
+ },
18
+ });
19
+
20
+ // Middleware to handle file upload errors
21
+ export const handleUploadError = (
22
+ err: Error | multer.MulterError,
23
+ _req: Request,
24
+ _res: Response,
25
+ next: NextFunction
26
+ ) => {
27
+ if (err instanceof multer.MulterError) {
28
+ const errorMap: Record<string, { status: number; message: string }> = {
29
+ LIMIT_FILE_SIZE: { status: 413, message: 'File too large' },
30
+ LIMIT_FILE_COUNT: { status: 400, message: 'Too many files' },
31
+ };
32
+
33
+ const error = errorMap[err.code] || { status: 400, message: err.message };
34
+ return next(new AppError(error.message, error.status, ERROR_CODES.STORAGE_INVALID_PARAMETER));
35
+ }
36
+
37
+ if (err) {
38
+ return next(new AppError(err.message, 500, ERROR_CODES.INTERNAL_ERROR));
39
+ }
40
+
41
+ next();
42
+ };
43
+
44
+ // Helper to process form data
45
+
46
+ export function processFormData(req: Request): ProcessedFormData {
47
+ const fields = req.body || {};
48
+ const files: Record<string, Express.Multer.File[]> = {};
49
+
50
+ if (req.files) {
51
+ if (Array.isArray(req.files)) {
52
+ files['files'] = req.files;
53
+ } else {
54
+ Object.assign(files, req.files);
55
+ }
56
+ }
57
+
58
+ return { fields, files };
59
+ }
@@ -0,0 +1,29 @@
1
+ import { Router, Request, Response } from 'express';
2
+ import { AgentAPIDocService } from '@/core/documentation/agent.js';
3
+ import { AppError } from '@/api/middleware/error.js';
4
+ import { ERROR_CODES } from '@/types/error-constants.js';
5
+ import { successResponse } from '@/utils/response.js';
6
+ import logger from '@/utils/logger.js';
7
+
8
+ const router = Router();
9
+ const agentAPIDocService = AgentAPIDocService.getInstance();
10
+
11
+ /**
12
+ * GET /api/agent-docs
13
+ * Get AI-native API documentation optimized for LLMs
14
+ */
15
+ router.get('/', async (_req: Request, res: Response, next) => {
16
+ try {
17
+ const agentDocs = await agentAPIDocService.generateAgentDocumentation();
18
+ successResponse(res, agentDocs);
19
+ } catch (error) {
20
+ logger.error('Failed to generate agent API documentation', {
21
+ error: error instanceof Error ? error.message : String(error),
22
+ });
23
+ next(
24
+ new AppError('Failed to generate agent API documentation', 500, ERROR_CODES.INTERNAL_ERROR)
25
+ );
26
+ }
27
+ });
28
+
29
+ export { router as agentDocsRouter };
@@ -0,0 +1,472 @@
1
+ import { Router, Response, NextFunction } from 'express';
2
+ import { ChatService } from '@/core/ai/chat';
3
+ import { AuthRequest, verifyAdmin, verifyUser } from '../middleware/auth';
4
+ import { ImageService } from '@/core/ai/image';
5
+ import { AIModelService } from '@/core/ai/model';
6
+ import { AppError } from '@/api/middleware/error';
7
+ import { ERROR_CODES } from '@/types/error-constants';
8
+ import { successResponse } from '@/utils/response';
9
+ import { AIConfigService } from '@/core/ai/config';
10
+ import { AIUsageService } from '@/core/ai/usage';
11
+ import { AIClientService } from '@/core/ai/client';
12
+ import { AuditService } from '@/core/logs/audit';
13
+ import {
14
+ createAIConfigurationRequestSchema,
15
+ updateAIConfigurationRequestSchema,
16
+ getAIUsageRequestSchema,
17
+ getAIUsageSummaryRequestSchema,
18
+ chatCompletionRequestSchema,
19
+ imageGenerationRequestSchema,
20
+ } from '@insforge/shared-schemas';
21
+
22
+ const router = Router();
23
+ const chatService = new ChatService();
24
+ const aiConfigService = new AIConfigService();
25
+ const aiUsageService = new AIUsageService();
26
+ const auditService = AuditService.getInstance();
27
+
28
+ /**
29
+ * GET /api/ai/models
30
+ * Get all available AI models in ListModelsResponse format
31
+ */
32
+ router.get('/models', verifyAdmin, async (req: AuthRequest, res: Response) => {
33
+ try {
34
+ const models = await AIModelService.getModels();
35
+ res.json(models);
36
+ } catch (error) {
37
+ console.error('Error getting models:', error);
38
+ res.status(500).json({
39
+ error: 'Failed to get models list',
40
+ details: error instanceof Error ? error.message : String(error),
41
+ });
42
+ }
43
+ });
44
+
45
+ /**
46
+ * POST /api/ai/chat/completion
47
+ * Send a chat message to any supported model
48
+ */
49
+ router.post(
50
+ '/chat/completion',
51
+ verifyUser,
52
+ async (req: AuthRequest, res: Response, next: NextFunction) => {
53
+ try {
54
+ const validationResult = chatCompletionRequestSchema.safeParse(req.body);
55
+ if (!validationResult.success) {
56
+ throw new AppError(
57
+ `Validation error: ${validationResult.error.errors.map((e) => e.message).join(', ')}`,
58
+ 400,
59
+ ERROR_CODES.INVALID_INPUT
60
+ );
61
+ }
62
+
63
+ const { stream, messages, ...options } = validationResult.data;
64
+
65
+ // Handle streaming requests
66
+ if (stream) {
67
+ // Now we know the model is valid, set headers for SSE
68
+ res.setHeader('Content-Type', 'text/event-stream');
69
+ res.setHeader('Cache-Control', 'no-cache');
70
+ res.setHeader('Connection', 'keep-alive');
71
+
72
+ // Create and process the stream
73
+ try {
74
+ const streamGenerator = chatService.streamChat(messages, options);
75
+
76
+ for await (const data of streamGenerator) {
77
+ if (data.chunk) {
78
+ res.write(`data: ${JSON.stringify({ chunk: data.chunk })}\n\n`);
79
+ }
80
+ if (data.tokenUsage) {
81
+ res.write(`data: ${JSON.stringify({ tokenUsage: data.tokenUsage })}\n\n`);
82
+ }
83
+ }
84
+
85
+ // Send completion signal
86
+ res.write(`data: ${JSON.stringify({ done: true })}\n\n`);
87
+ } catch (streamError) {
88
+ // If error occurs during streaming, send it in SSE format
89
+ console.error('Stream error:', streamError);
90
+ res.write(
91
+ `data: ${JSON.stringify({ error: true, meesage: streamError instanceof Error ? streamError.message : String(streamError) })}\n\n`
92
+ );
93
+ }
94
+
95
+ res.end();
96
+ return;
97
+ }
98
+
99
+ // Non-streaming requests
100
+ const result = await chatService.chat(messages, options);
101
+ res.json(result);
102
+ } catch (error) {
103
+ if (error instanceof AppError) {
104
+ next(error);
105
+ } else {
106
+ next(
107
+ new AppError(
108
+ error instanceof Error ? error.message : 'Failed to generate chat',
109
+ 500,
110
+ ERROR_CODES.INTERNAL_ERROR
111
+ )
112
+ );
113
+ }
114
+ }
115
+ }
116
+ );
117
+
118
+ /**
119
+ * POST /api/ai/image/generation
120
+ * Generate images using specified model
121
+ */
122
+ router.post(
123
+ '/image/generation',
124
+ verifyUser,
125
+ async (req: AuthRequest, res: Response, next: NextFunction) => {
126
+ try {
127
+ const validationResult = imageGenerationRequestSchema.safeParse(req.body);
128
+ if (!validationResult.success) {
129
+ throw new AppError(
130
+ `Validation error: ${validationResult.error.errors.map((e) => e.message).join(', ')}`,
131
+ 400,
132
+ ERROR_CODES.INVALID_INPUT
133
+ );
134
+ }
135
+
136
+ const result = await ImageService.generate(validationResult.data);
137
+
138
+ res.json(result);
139
+ } catch (error) {
140
+ if (error instanceof AppError) {
141
+ next(error);
142
+ } else {
143
+ next(
144
+ new AppError(
145
+ error instanceof Error ? error.message : 'Failed to generate image',
146
+ 500,
147
+ ERROR_CODES.INTERNAL_ERROR
148
+ )
149
+ );
150
+ }
151
+ }
152
+ }
153
+ );
154
+
155
+ /**
156
+ * POST /api/ai/configurations
157
+ * Create a new AI configuration
158
+ */
159
+ router.post(
160
+ '/configurations',
161
+ verifyAdmin,
162
+ async (req: AuthRequest, res: Response, next: NextFunction) => {
163
+ try {
164
+ const validationResult = createAIConfigurationRequestSchema.safeParse(req.body);
165
+
166
+ if (!validationResult.success) {
167
+ throw new AppError(
168
+ `Validation error: ${validationResult.error.errors.map((e) => e.message).join(', ')}`,
169
+ 400,
170
+ ERROR_CODES.INVALID_INPUT
171
+ );
172
+ }
173
+ const { inputModality, outputModality, provider, modelId, systemPrompt } =
174
+ validationResult.data;
175
+
176
+ const result = await aiConfigService.create(
177
+ inputModality,
178
+ outputModality,
179
+ provider,
180
+ modelId,
181
+ systemPrompt
182
+ );
183
+
184
+ // Log audit for AI configuration creation
185
+ await auditService.log({
186
+ actor: req.user?.email || 'api-key',
187
+ action: 'CREATE_CONFIGURATION',
188
+ module: 'AI',
189
+ details: {
190
+ configId: result.id,
191
+ inputModality,
192
+ outputModality,
193
+ provider,
194
+ modelId,
195
+ },
196
+ ip_address: req.ip,
197
+ });
198
+
199
+ successResponse(
200
+ res,
201
+ {
202
+ id: result.id,
203
+ message: 'AI configuration created successfully',
204
+ },
205
+ 201
206
+ );
207
+ } catch (error) {
208
+ if (error instanceof AppError) {
209
+ next(error);
210
+ } else {
211
+ next(
212
+ new AppError(
213
+ error instanceof Error ? error.message : 'Failed to create AI configuration',
214
+ 500,
215
+ ERROR_CODES.INTERNAL_ERROR
216
+ )
217
+ );
218
+ }
219
+ }
220
+ }
221
+ );
222
+
223
+ /**
224
+ * GET /api/ai/configurations
225
+ * List all AI configurations
226
+ */
227
+ router.get(
228
+ '/configurations',
229
+ verifyAdmin,
230
+ async (req: AuthRequest, res: Response, next: NextFunction) => {
231
+ try {
232
+ const configurations = await aiConfigService.findAll();
233
+
234
+ successResponse(res, configurations);
235
+ } catch (error) {
236
+ next(
237
+ new AppError(
238
+ error instanceof Error ? error.message : 'Failed to fetch AI configurations',
239
+ 500,
240
+ ERROR_CODES.INTERNAL_ERROR
241
+ )
242
+ );
243
+ }
244
+ }
245
+ );
246
+
247
+ /**
248
+ * PATCH /api/ai/configurations/:id
249
+ * Update an AI configuration
250
+ */
251
+ router.patch(
252
+ '/configurations/:id',
253
+ verifyAdmin,
254
+ async (req: AuthRequest, res: Response, next: NextFunction) => {
255
+ try {
256
+ const validationResult = updateAIConfigurationRequestSchema.safeParse(req.body);
257
+
258
+ if (!validationResult.success) {
259
+ throw new AppError(
260
+ `Validation error: ${validationResult.error.errors.map((e) => e.message).join(', ')}`,
261
+ 400,
262
+ ERROR_CODES.INVALID_INPUT
263
+ );
264
+ }
265
+
266
+ const { systemPrompt } = validationResult.data;
267
+
268
+ const updated = await aiConfigService.update(req.params.id, systemPrompt);
269
+
270
+ if (!updated) {
271
+ throw new AppError('AI configuration not found', 404, ERROR_CODES.NOT_FOUND);
272
+ }
273
+
274
+ // Log audit for AI configuration update
275
+ await auditService.log({
276
+ actor: req.user?.email || 'api-key',
277
+ action: 'UPDATE_CONFIGURATION',
278
+ module: 'AI',
279
+ details: {
280
+ configId: req.params.id,
281
+ changes: { systemPrompt },
282
+ },
283
+ ip_address: req.ip,
284
+ });
285
+
286
+ successResponse(res, {
287
+ message: 'AI configuration updated successfully',
288
+ });
289
+ } catch (error) {
290
+ if (error instanceof AppError) {
291
+ next(error);
292
+ } else {
293
+ next(
294
+ new AppError(
295
+ error instanceof Error ? error.message : 'Failed to update AI configuration',
296
+ 500,
297
+ ERROR_CODES.INTERNAL_ERROR
298
+ )
299
+ );
300
+ }
301
+ }
302
+ }
303
+ );
304
+
305
+ /**
306
+ * DELETE /api/ai/configurations/:id
307
+ * Delete an AI configuration
308
+ */
309
+ router.delete(
310
+ '/configurations/:id',
311
+ verifyAdmin,
312
+ async (req: AuthRequest, res: Response, next: NextFunction) => {
313
+ try {
314
+ const deleted = await aiConfigService.delete(req.params.id);
315
+
316
+ if (!deleted) {
317
+ throw new AppError('AI configuration not found', 404, ERROR_CODES.NOT_FOUND);
318
+ }
319
+
320
+ // Log audit for AI configuration deletion
321
+ await auditService.log({
322
+ actor: req.user?.email || 'api-key',
323
+ action: 'DELETE_CONFIGURATION',
324
+ module: 'AI',
325
+ details: {
326
+ configId: req.params.id,
327
+ },
328
+ ip_address: req.ip,
329
+ });
330
+
331
+ successResponse(res, {
332
+ message: 'AI configuration deleted successfully',
333
+ });
334
+ } catch (error) {
335
+ if (error instanceof AppError) {
336
+ next(error);
337
+ } else {
338
+ next(
339
+ new AppError(
340
+ error instanceof Error ? error.message : 'Failed to delete AI configuration',
341
+ 500,
342
+ ERROR_CODES.INTERNAL_ERROR
343
+ )
344
+ );
345
+ }
346
+ }
347
+ }
348
+ );
349
+
350
+ /**
351
+ * GET /api/ai/usage/summary
352
+ * Get AI usage summary statistics
353
+ */
354
+ router.get(
355
+ '/usage/summary',
356
+ verifyAdmin,
357
+ async (req: AuthRequest, res: Response, next: NextFunction) => {
358
+ try {
359
+ const validationResult = getAIUsageSummaryRequestSchema.safeParse(req.query);
360
+
361
+ if (!validationResult.success) {
362
+ throw new AppError(
363
+ `Validation error: ${validationResult.error.errors.map((e) => e.message).join(', ')}`,
364
+ 400,
365
+ ERROR_CODES.INVALID_INPUT
366
+ );
367
+ }
368
+
369
+ const { configId, startDate, endDate } = validationResult.data;
370
+
371
+ const summary = await aiUsageService.getUsageSummary(
372
+ configId,
373
+ startDate ? new Date(startDate) : undefined,
374
+ endDate ? new Date(endDate) : undefined
375
+ );
376
+
377
+ successResponse(res, summary);
378
+ } catch (error) {
379
+ next(
380
+ new AppError(
381
+ error instanceof Error ? error.message : 'Failed to fetch usage summary',
382
+ 500,
383
+ ERROR_CODES.INTERNAL_ERROR
384
+ )
385
+ );
386
+ }
387
+ }
388
+ );
389
+
390
+ /**
391
+ * GET /api/ai/usage
392
+ * Get AI usage records with pagination
393
+ */
394
+ router.get('/usage', verifyAdmin, async (req: AuthRequest, res: Response, next: NextFunction) => {
395
+ try {
396
+ const validationResult = getAIUsageRequestSchema.safeParse(req.query);
397
+
398
+ if (!validationResult.success) {
399
+ throw new AppError(
400
+ `Validation error: ${validationResult.error.errors.map((e) => e.message).join(', ')}`,
401
+ 400,
402
+ ERROR_CODES.INVALID_INPUT
403
+ );
404
+ }
405
+
406
+ const { startDate, endDate, limit, offset } = validationResult.data;
407
+
408
+ const usage = await aiUsageService.getAllUsage(
409
+ startDate ? new Date(startDate) : undefined,
410
+ endDate ? new Date(endDate) : undefined,
411
+ parseInt(limit),
412
+ parseInt(offset)
413
+ );
414
+
415
+ successResponse(res, usage);
416
+ } catch (error) {
417
+ next(
418
+ new AppError(
419
+ error instanceof Error ? error.message : 'Failed to fetch usage records',
420
+ 500,
421
+ ERROR_CODES.INTERNAL_ERROR
422
+ )
423
+ );
424
+ }
425
+ });
426
+
427
+ /**
428
+ * GET /api/ai/usage/config/:configId
429
+ * Get usage records for a specific AI configuration
430
+ */
431
+ router.get(
432
+ '/usage/config/:configId',
433
+ verifyAdmin,
434
+ async (req: AuthRequest, res: Response, next: NextFunction) => {
435
+ try {
436
+ const { startDate, endDate } = req.query;
437
+
438
+ const records = await aiUsageService.getUsageByConfig(
439
+ req.params.configId,
440
+ startDate ? new Date(startDate as string) : undefined,
441
+ endDate ? new Date(endDate as string) : undefined
442
+ );
443
+
444
+ successResponse(res, records);
445
+ } catch (error) {
446
+ next(
447
+ new AppError(
448
+ error instanceof Error ? error.message : 'Failed to fetch config usage records',
449
+ 500,
450
+ ERROR_CODES.INTERNAL_ERROR
451
+ )
452
+ );
453
+ }
454
+ }
455
+ );
456
+
457
+ /**
458
+ * GET /api/ai/credits
459
+ * Get remaining credits for the current API key
460
+ */
461
+ router.get('/credits', verifyAdmin, async (req: AuthRequest, res: Response, next: NextFunction) => {
462
+ try {
463
+ const aiClientService = AIClientService.getInstance();
464
+ const credits = await aiClientService.getRemainingCredits();
465
+
466
+ successResponse(res, credits);
467
+ } catch (error) {
468
+ next(error);
469
+ }
470
+ });
471
+
472
+ export { router as aiRouter };