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,150 @@
1
+ import { Router, Response, NextFunction } from 'express';
2
+ import { AnalyticsManager } from '@/core/logs/analytics.js';
3
+ import { AuditService } from '@/core/logs/audit.js';
4
+ import { AuthRequest, verifyAdmin } from '@/api/middleware/auth.js';
5
+ import { successResponse, paginatedResponse } from '@/utils/response.js';
6
+ import { AnalyticsLogResponse } from '@/types/logs.js';
7
+
8
+ const router = Router();
9
+
10
+ // All logs routes require admin authentication
11
+ router.use(verifyAdmin);
12
+
13
+ // GET /logs/audits - List audit logs
14
+ router.get('/audits', async (req: AuthRequest, res: Response, next: NextFunction) => {
15
+ try {
16
+ const { limit = 100, offset = 0, actor, action, module, start_date, end_date } = req.query;
17
+
18
+ const auditService = AuditService.getInstance();
19
+
20
+ // Build query parameters for audit service
21
+ const queryParams = {
22
+ limit: Number(limit),
23
+ offset: Number(offset),
24
+ ...(actor && typeof actor === 'string' && { actor }),
25
+ ...(action && typeof action === 'string' && { action }),
26
+ ...(module && typeof module === 'string' && { module }),
27
+ ...(start_date && typeof start_date === 'string' && { start_date: new Date(start_date) }),
28
+ ...(end_date && typeof end_date === 'string' && { end_date: new Date(end_date) }),
29
+ };
30
+
31
+ // Get audit logs with total count
32
+ const { records, total } = await auditService.query(queryParams);
33
+
34
+ paginatedResponse(res, records, total, Number(offset));
35
+ } catch (error) {
36
+ next(error);
37
+ }
38
+ });
39
+
40
+ // GET /logs/audits/stats - Get audit logs statistics
41
+ router.get('/audits/stats', async (req: AuthRequest, res: Response, next: NextFunction) => {
42
+ try {
43
+ const { days = 7 } = req.query;
44
+
45
+ const auditService = AuditService.getInstance();
46
+ const stats = await auditService.getStats(Number(days));
47
+
48
+ successResponse(res, stats);
49
+ } catch (error) {
50
+ next(error);
51
+ }
52
+ });
53
+
54
+ // DELETE /logs/audits - Clear audit logs (admin only)
55
+ router.delete('/audits', async (req: AuthRequest, res: Response, next: NextFunction) => {
56
+ try {
57
+ const { days_to_keep = 90 } = req.query;
58
+
59
+ const auditService = AuditService.getInstance();
60
+ const deletedCount = await auditService.cleanup(Number(days_to_keep));
61
+
62
+ successResponse(res, {
63
+ message: 'Audit logs cleared successfully',
64
+ deleted: deletedCount,
65
+ });
66
+ } catch (error) {
67
+ next(error);
68
+ }
69
+ });
70
+
71
+ // Analytics logs routes
72
+ // GET /logs/analytics/sources - List all log sources
73
+ router.get('/analytics/sources', async (_req: AuthRequest, res: Response, next: NextFunction) => {
74
+ try {
75
+ const analyticsManager = AnalyticsManager.getInstance();
76
+ const sources = await analyticsManager.getLogSources();
77
+
78
+ successResponse(res, sources);
79
+ } catch (error) {
80
+ next(error);
81
+ }
82
+ });
83
+
84
+ // GET /logs/analytics/stats - Get statistics for all log sources
85
+ router.get('/analytics/stats', async (_req: AuthRequest, res: Response, next: NextFunction) => {
86
+ try {
87
+ const analyticsManager = AnalyticsManager.getInstance();
88
+ const stats = await analyticsManager.getLogSourceStats();
89
+
90
+ successResponse(res, stats);
91
+ } catch (error) {
92
+ next(error);
93
+ }
94
+ });
95
+
96
+ // GET /logs/analytics/search - Search across all logs or specific source
97
+ router.get('/analytics/search', async (req: AuthRequest, res: Response, next: NextFunction) => {
98
+ try {
99
+ const { q, source, limit = 100, offset = 0 } = req.query;
100
+
101
+ if (!q || typeof q !== 'string') {
102
+ return res.status(400).json({
103
+ error: 'MISSING_QUERY',
104
+ message: 'Search query parameter (q) is required',
105
+ statusCode: 400,
106
+ });
107
+ }
108
+
109
+ const analyticsManager = AnalyticsManager.getInstance();
110
+ const result = await analyticsManager.searchLogs(
111
+ q,
112
+ source as string | undefined,
113
+ Number(limit),
114
+ Number(offset)
115
+ );
116
+
117
+ paginatedResponse(res, result.logs, result.total, Number(offset));
118
+ } catch (error) {
119
+ next(error);
120
+ }
121
+ });
122
+
123
+ // GET /logs/analytics/:source - Get logs from specific source
124
+ router.get('/analytics/:source', async (req: AuthRequest, res: Response, next: NextFunction) => {
125
+ try {
126
+ const { source } = req.params;
127
+ const { limit = 100, before_timestamp } = req.query;
128
+
129
+ const analyticsManager = AnalyticsManager.getInstance();
130
+ const result = await analyticsManager.getLogsBySource(
131
+ source,
132
+ Number(limit),
133
+ before_timestamp as string | undefined
134
+ );
135
+
136
+ const response: AnalyticsLogResponse = {
137
+ source,
138
+ logs: result.logs,
139
+ total: result.total,
140
+ page: 1, // Not applicable for timestamp-based pagination
141
+ pageSize: Number(limit),
142
+ };
143
+
144
+ successResponse(res, response);
145
+ } catch (error) {
146
+ next(error);
147
+ }
148
+ });
149
+
150
+ export { router as logsRouter };
@@ -0,0 +1,160 @@
1
+ import { Router, Response, NextFunction } from 'express';
2
+ import { DatabaseAdvanceService } from '@/core/database/advance.js';
3
+ import { AuthService } from '@/core/auth/auth.js';
4
+ import { StorageService } from '@/core/storage/storage.js';
5
+ import { AIConfigService } from '@/core/ai/config.js';
6
+ import { FunctionsService } from '@/core/functions/functions.js';
7
+ import { SocketService } from '@/core/socket/socket.js';
8
+ import { verifyAdmin, AuthRequest } from '@/api/middleware/auth.js';
9
+ import { successResponse } from '@/utils/response.js';
10
+ import { ServerEvents } from '@/core/socket/types';
11
+ import { ERROR_CODES } from '@/types/error-constants.js';
12
+ import { AppError } from '@/api/middleware/error.js';
13
+ import type { AppMetadataSchema } from '@insforge/shared-schemas';
14
+ import { SecretsService } from '@/core/secrets/secrets';
15
+
16
+ const router = Router();
17
+ const dbAdvanceService = new DatabaseAdvanceService();
18
+ const aiConfigService = new AIConfigService();
19
+
20
+ router.use(verifyAdmin);
21
+
22
+ // Get full metadata (default endpoint)
23
+ router.get('/', async (req: AuthRequest, res: Response, next: NextFunction) => {
24
+ try {
25
+ // Gather metadata from all modules
26
+ const authService = AuthService.getInstance();
27
+ const storageService = StorageService.getInstance();
28
+ const functionsService = FunctionsService.getInstance();
29
+
30
+ // Fetch all metadata in parallel for better performance
31
+ const [auth, database, storage, aiConfig, functions] = await Promise.all([
32
+ authService.getMetadata(),
33
+ dbAdvanceService.getMetadata(),
34
+ storageService.getMetadata(),
35
+ aiConfigService.getMetadata(),
36
+ functionsService.getMetadata(),
37
+ ]);
38
+
39
+ // Get version from package.json or default
40
+ const version = process.env.npm_package_version || '1.0.0';
41
+
42
+ const metadata: AppMetadataSchema = {
43
+ auth,
44
+ database,
45
+ storage,
46
+ functions,
47
+ aiIntegration: aiConfig,
48
+ version,
49
+ };
50
+
51
+ // Trigger Socket.IO event to notify frontend that MCP is connected
52
+ if (req.query.mcp === 'true') {
53
+ const socketService = SocketService.getInstance();
54
+ //Lyu note: this is triggered everytime when a mcp calls get-metadata. Do we have a better solution for this?
55
+ socketService.broadcastToRoom('role:project_admin', ServerEvents.MCP_CONNECTED);
56
+ }
57
+
58
+ successResponse(res, metadata);
59
+ } catch (error) {
60
+ next(error);
61
+ }
62
+ });
63
+
64
+ // Get auth metadata
65
+ router.get('/auth', async (_req: AuthRequest, res: Response, next: NextFunction) => {
66
+ try {
67
+ const authService = AuthService.getInstance();
68
+ const authMetadata = await authService.getMetadata();
69
+ successResponse(res, authMetadata);
70
+ } catch (error) {
71
+ next(error);
72
+ }
73
+ });
74
+
75
+ // Get database metadata
76
+ router.get('/database', async (_req: AuthRequest, res: Response, next: NextFunction) => {
77
+ try {
78
+ const databaseMetadata = await dbAdvanceService.getMetadata();
79
+ successResponse(res, databaseMetadata);
80
+ } catch (error) {
81
+ next(error);
82
+ }
83
+ });
84
+
85
+ // Get storage metadata
86
+ router.get('/storage', async (_req: AuthRequest, res: Response, next: NextFunction) => {
87
+ try {
88
+ const storageService = StorageService.getInstance();
89
+ const storageMetadata = await storageService.getMetadata();
90
+ successResponse(res, storageMetadata);
91
+ } catch (error) {
92
+ next(error);
93
+ }
94
+ });
95
+
96
+ // Get AI metadata
97
+ router.get('/ai', async (_req: AuthRequest, res: Response, next: NextFunction) => {
98
+ try {
99
+ const aiMetadata = await aiConfigService.getMetadata();
100
+ successResponse(res, aiMetadata);
101
+ } catch (error) {
102
+ next(error);
103
+ }
104
+ });
105
+
106
+ // Get functions metadata
107
+ router.get('/functions', async (_req: AuthRequest, res: Response, next: NextFunction) => {
108
+ try {
109
+ const functionsService = FunctionsService.getInstance();
110
+ const functionsMetadata = await functionsService.getMetadata();
111
+ successResponse(res, functionsMetadata);
112
+ } catch (error) {
113
+ next(error);
114
+ }
115
+ });
116
+
117
+ // Get API key (admin only)
118
+ router.get('/api-key', async (req: AuthRequest, res: Response, next: NextFunction) => {
119
+ try {
120
+ const sercretService = new SecretsService();
121
+ const apiKey = await sercretService.getSecretByKey('API_KEY');
122
+
123
+ successResponse(res, { apiKey: apiKey });
124
+ } catch (error) {
125
+ next(error);
126
+ }
127
+ });
128
+
129
+ // get metadata for a table.
130
+ // Notice: must be after endpoint /api-key in case of conflict.
131
+ router.get('/:tableName', async (req: AuthRequest, res: Response, next: NextFunction) => {
132
+ try {
133
+ const { tableName } = req.params;
134
+ if (!tableName) {
135
+ throw new AppError('Table name is required', 400, ERROR_CODES.INVALID_INPUT);
136
+ }
137
+
138
+ const includeData = false;
139
+ const includeFunctions = false;
140
+ const includeSequences = false;
141
+ const includeViews = false;
142
+ const schemaResponse = await dbAdvanceService.exportDatabase(
143
+ [tableName],
144
+ 'json',
145
+ includeData,
146
+ includeFunctions,
147
+ includeSequences,
148
+ includeViews
149
+ );
150
+
151
+ // When format is 'json', the data contains the tables object
152
+ const jsonData = schemaResponse.data as { tables: Record<string, unknown> };
153
+ const metadata = jsonData.tables;
154
+ successResponse(res, metadata);
155
+ } catch (error) {
156
+ next(error);
157
+ }
158
+ });
159
+
160
+ export { router as metadataRouter };
@@ -0,0 +1,82 @@
1
+ import { Router, Request, Response } from 'express';
2
+ import { OpenAPIService } from '@/core/documentation/openapi.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 openAPIService = OpenAPIService.getInstance();
10
+
11
+ /**
12
+ * GET /api/openapi
13
+ * Get the OpenAPI specification document
14
+ */
15
+ router.get('/', async (_req: Request, res: Response, next) => {
16
+ try {
17
+ const openAPIDocument = await openAPIService.generateOpenAPIDocument();
18
+ successResponse(res, openAPIDocument);
19
+ } catch (error) {
20
+ logger.error('Failed to generate OpenAPI document', {
21
+ error: error instanceof Error ? error.message : String(error),
22
+ });
23
+ next(new AppError('Failed to generate OpenAPI document', 500, ERROR_CODES.INTERNAL_ERROR));
24
+ }
25
+ });
26
+
27
+ /**
28
+ * GET /api/openapi/swagger
29
+ * Serve Swagger UI HTML page
30
+ */
31
+ router.get('/swagger', (_req: Request, res: Response) => {
32
+ const html = `
33
+ <!DOCTYPE html>
34
+ <html lang="en">
35
+ <head>
36
+ <meta charset="utf-8" />
37
+ <meta name="viewport" content="width=device-width, initial-scale=1" />
38
+ <title>InsForge API Documentation</title>
39
+ <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/swagger-ui-dist@5/swagger-ui.css" />
40
+ <style>
41
+ body {
42
+ margin: 0;
43
+ padding: 0;
44
+ }
45
+ .swagger-ui .topbar {
46
+ display: none;
47
+ }
48
+ </style>
49
+ </head>
50
+ <body>
51
+ <div id="swagger-ui"></div>
52
+ <script src="https://cdn.jsdelivr.net/npm/swagger-ui-dist@5/swagger-ui-bundle.js"></script>
53
+ <script>
54
+ window.onload = () => {
55
+ window.ui = SwaggerUIBundle({
56
+ url: '/api/openapi',
57
+ dom_id: '#swagger-ui',
58
+ deepLinking: true,
59
+ presets: [
60
+ SwaggerUIBundle.presets.apis,
61
+ SwaggerUIBundle.SwaggerUIStandalonePreset
62
+ ],
63
+ layout: 'BaseLayout',
64
+ tryItOutEnabled: true,
65
+ requestInterceptor: (request) => {
66
+ // Add API key from localStorage if available
67
+ const apiKey = localStorage.getItem('insforge_api_key');
68
+ if (apiKey) {
69
+ request.headers['x-api-key'] = apiKey;
70
+ }
71
+ return request;
72
+ }
73
+ });
74
+ };
75
+ </script>
76
+ </body>
77
+ </html>
78
+ `;
79
+ res.type('html').send(html);
80
+ });
81
+
82
+ export { router as openAPIRouter };
@@ -0,0 +1,199 @@
1
+ import { Router, Response, NextFunction } from 'express';
2
+ import { SecretsService } from '@/core/secrets/secrets.js';
3
+ import { verifyAdmin, AuthRequest } from '@/api/middleware/auth.js';
4
+ import { AuditService } from '@/core/logs/audit.js';
5
+ import { AppError } from '@/api/middleware/error.js';
6
+ import { ERROR_CODES } from '@/types/error-constants.js';
7
+
8
+ const router = Router();
9
+ const secretsService = new SecretsService();
10
+ const auditService = AuditService.getInstance();
11
+
12
+ /**
13
+ * List all secrets (metadata only, no values)
14
+ * GET /api/secrets
15
+ */
16
+ router.get('/', verifyAdmin, async (_req: AuthRequest, res: Response, next: NextFunction) => {
17
+ try {
18
+ const secrets = await secretsService.listSecrets();
19
+ res.json({ secrets });
20
+ } catch (error) {
21
+ next(error);
22
+ }
23
+ });
24
+
25
+ /**
26
+ * Get a specific secret value by key
27
+ * GET /api/secrets/:key
28
+ */
29
+ router.get('/:key', verifyAdmin, async (req: AuthRequest, res: Response, next: NextFunction) => {
30
+ try {
31
+ const { key } = req.params;
32
+ const value = await secretsService.getSecretByKey(key);
33
+
34
+ if (value === null) {
35
+ throw new AppError(`Secret not found: ${key}`, 404, ERROR_CODES.NOT_FOUND);
36
+ }
37
+
38
+ // Log audit
39
+ await auditService.log({
40
+ actor: req.user?.email || 'api-key',
41
+ action: 'GET_SECRET',
42
+ module: 'SECRETS',
43
+ details: { key },
44
+ ip_address: req.ip,
45
+ });
46
+
47
+ res.json({ key, value });
48
+ } catch (error) {
49
+ next(error);
50
+ }
51
+ });
52
+
53
+ /**
54
+ * Create a new secret
55
+ * POST /api/secrets
56
+ */
57
+ router.post('/', verifyAdmin, async (req: AuthRequest, res: Response, next: NextFunction) => {
58
+ try {
59
+ const { key, value, isReserved, expiresAt } = req.body;
60
+
61
+ // Validate input
62
+ if (!key || !value) {
63
+ throw new AppError('Both key and value are required', 400, ERROR_CODES.INVALID_INPUT);
64
+ }
65
+
66
+ // Validate key format (uppercase alphanumeric with underscores only)
67
+ if (!/^[A-Z0-9_]+$/.test(key)) {
68
+ throw new AppError(
69
+ 'Invalid key format. Use uppercase letters, numbers, and underscores only (e.g., STRIPE_API_KEY)',
70
+ 400,
71
+ ERROR_CODES.INVALID_INPUT
72
+ );
73
+ }
74
+
75
+ // Check if secret already exists
76
+ const existing = await secretsService.getSecretByKey(key);
77
+ if (existing !== null) {
78
+ throw new AppError(`Secret already exists: ${key}`, 409, ERROR_CODES.INVALID_INPUT);
79
+ }
80
+
81
+ const result = await secretsService.createSecret({
82
+ key,
83
+ value,
84
+ isReserved: isReserved || false,
85
+ expiresAt: expiresAt ? new Date(expiresAt) : undefined,
86
+ });
87
+
88
+ // Log audit
89
+ await auditService.log({
90
+ actor: req.user?.email || 'api-key',
91
+ action: 'CREATE_SECRET',
92
+ module: 'SECRETS',
93
+ details: { key, id: result.id },
94
+ ip_address: req.ip,
95
+ });
96
+
97
+ res.status(201).json({
98
+ success: true,
99
+ message: `Secret ${key} has been created successfully`,
100
+ id: result.id,
101
+ });
102
+ } catch (error) {
103
+ next(error);
104
+ }
105
+ });
106
+
107
+ /**
108
+ * Update an existing secret
109
+ * PUT /api/secrets/:key
110
+ */
111
+ router.put('/:key', verifyAdmin, async (req: AuthRequest, res: Response, next: NextFunction) => {
112
+ try {
113
+ const { key } = req.params;
114
+ const { value, isActive, isReserved, expiresAt } = req.body;
115
+
116
+ // Get existing secret
117
+ const secrets = await secretsService.listSecrets();
118
+ const secret = secrets.find((s) => s.key === key);
119
+
120
+ if (!secret) {
121
+ throw new AppError(`Secret not found: ${key}`, 404, ERROR_CODES.NOT_FOUND);
122
+ }
123
+
124
+ const success = await secretsService.updateSecret(secret.id, {
125
+ value,
126
+ isActive,
127
+ isReserved,
128
+ expiresAt: expiresAt !== undefined ? (expiresAt ? new Date(expiresAt) : null) : undefined,
129
+ });
130
+
131
+ if (!success) {
132
+ throw new AppError(`Failed to update secret: ${key}`, 500, ERROR_CODES.INTERNAL_ERROR);
133
+ }
134
+
135
+ // Log audit
136
+ await auditService.log({
137
+ actor: req.user?.email || 'api-key',
138
+ action: 'UPDATE_SECRET',
139
+ module: 'SECRETS',
140
+ details: { key, updates: { hasNewValue: !!value, isActive, isReserved, expiresAt } },
141
+ ip_address: req.ip,
142
+ });
143
+
144
+ res.json({
145
+ success: true,
146
+ message: `Secret ${key} has been updated successfully`,
147
+ });
148
+ } catch (error) {
149
+ next(error);
150
+ }
151
+ });
152
+
153
+ /**
154
+ * Delete a secret (mark as inactive)
155
+ * DELETE /api/secrets/:key
156
+ */
157
+ router.delete('/:key', verifyAdmin, async (req: AuthRequest, res: Response, next: NextFunction) => {
158
+ try {
159
+ const { key } = req.params;
160
+
161
+ // Get existing secret
162
+ const secrets = await secretsService.listSecrets();
163
+ const secret = secrets.find((s) => s.key === key);
164
+
165
+ if (!secret) {
166
+ throw new AppError(`Secret not found: ${key}`, 404, ERROR_CODES.NOT_FOUND);
167
+ }
168
+
169
+ // Check if secret is reserved
170
+ if (secret.isReserved) {
171
+ throw new AppError(`Cannot delete reserved secret: ${key}`, 403, ERROR_CODES.FORBIDDEN);
172
+ }
173
+
174
+ // Mark as inactive instead of hard delete
175
+ const success = await secretsService.updateSecret(secret.id, { isActive: false });
176
+
177
+ if (!success) {
178
+ throw new AppError(`Failed to delete secret: ${key}`, 500, ERROR_CODES.INTERNAL_ERROR);
179
+ }
180
+
181
+ // Log audit
182
+ await auditService.log({
183
+ actor: req.user?.email || 'api-key',
184
+ action: 'DELETE_SECRET',
185
+ module: 'SECRETS',
186
+ details: { key },
187
+ ip_address: req.ip,
188
+ });
189
+
190
+ res.json({
191
+ success: true,
192
+ message: `Secret ${key} has been deleted successfully`,
193
+ });
194
+ } catch (error) {
195
+ next(error);
196
+ }
197
+ });
198
+
199
+ export default router;