insforge 0.3.2 → 1.2.10
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.
- package/.claude-plugin/marketplace.json +20 -0
- package/.cursor/rules/cursor-rules.mdc +94 -0
- package/.dockerignore +3 -0
- package/.env.example +33 -4
- package/.github/ISSUE_TEMPLATE/bug_report.yml +13 -60
- package/.github/ISSUE_TEMPLATE/config.yml +2 -2
- package/.github/ISSUE_TEMPLATE/feature_request.yml +10 -63
- package/.github/PULL_REQUEST_TEMPLATE.md +7 -0
- package/.github/workflows/build-image.yml +2 -1
- package/.github/workflows/e2e.yml +63 -0
- package/CHANGELOG.md +41 -0
- package/CLAUDE_PLUGIN.md +104 -0
- package/CODE_OF_CONDUCT.md +128 -0
- package/CONTRIBUTING.md +1 -1
- package/Dockerfile +4 -1
- package/README.md +66 -18
- package/assets/mcpInstallv2.png +0 -0
- package/assets/sampleResponse.png +0 -0
- package/auth/index.html +13 -0
- package/auth/package.json +28 -0
- package/auth/public/favicon.ico +0 -0
- package/auth/src/App.tsx +33 -0
- package/auth/src/components/ErrorCard.tsx +37 -0
- package/auth/src/components/Layout.tsx +13 -0
- package/auth/src/index.css +19 -0
- package/auth/src/lib/broadcastService.ts +115 -0
- package/auth/src/lib/utils.ts +11 -0
- package/auth/src/main.tsx +22 -0
- package/auth/src/pages/ForgotPasswordPage.tsx +11 -0
- package/auth/src/pages/ResetPasswordPage.tsx +11 -0
- package/auth/src/pages/SignInPage.tsx +57 -0
- package/auth/src/pages/SignUpPage.tsx +57 -0
- package/auth/src/pages/VerifyEmailPage.tsx +20 -0
- package/auth/src/vite-env.d.ts +10 -0
- package/auth/tsconfig.json +32 -0
- package/auth/tsconfig.node.json +11 -0
- package/auth/vite.config.ts +25 -0
- package/backend/package.json +9 -9
- package/backend/src/api/{middleware → middlewares}/auth.ts +8 -9
- package/backend/src/api/middlewares/rate-limiters.ts +127 -0
- package/backend/src/api/routes/{ai.ts → ai/index.routes.ts} +20 -24
- package/backend/src/api/routes/auth/index.routes.ts +570 -0
- package/backend/src/api/routes/auth/oauth.routes.ts +448 -0
- package/backend/src/api/routes/{database.advance.ts → database/advance.routes.ts} +107 -65
- package/backend/src/api/routes/database/index.routes.ts +13 -0
- package/backend/src/api/routes/{database.records.ts → database/records.routes.ts} +22 -8
- package/backend/src/api/routes/{database.tables.ts → database/tables.routes.ts} +20 -23
- package/backend/src/api/routes/docs/index.routes.ts +76 -0
- package/backend/src/api/routes/functions/index.routes.ts +188 -0
- package/backend/src/api/routes/{logs.ts → logs/index.routes.ts} +25 -30
- package/backend/src/api/routes/{metadata.ts → metadata/index.routes.ts} +21 -31
- package/backend/src/api/routes/{secrets.ts → secrets/index.routes.ts} +27 -22
- package/backend/src/api/routes/{storage.ts → storage/index.routes.ts} +34 -53
- package/backend/src/api/routes/usage/index.routes.ts +89 -0
- package/backend/src/infra/config/app.config.ts +51 -0
- package/backend/src/{core/database/manager.ts → infra/database/database.manager.ts} +76 -85
- package/backend/src/infra/database/migrations/013_create-auth-schema-functions.sql +44 -0
- package/backend/src/infra/database/migrations/014_add-updated-at-trigger-user-table.sql +8 -0
- package/backend/src/infra/database/migrations/015_create-auth-config-and-email-otp-tables.sql +60 -0
- package/backend/src/infra/database/migrations/016_update-auth-config-and-email-otp.sql +24 -0
- package/backend/src/{core/secrets/encryption.ts → infra/security/encryption.manager.ts} +3 -2
- package/backend/src/infra/security/token.manager.ts +125 -0
- package/backend/src/{core/socket/socket.ts → infra/socket/socket.manager.ts} +15 -15
- package/backend/src/providers/ai/openrouter.provider.ts +377 -0
- package/backend/src/providers/email/base.provider.ts +41 -0
- package/backend/src/providers/email/cloud.provider.ts +187 -0
- package/backend/src/{core/logs/providers → providers/logs}/base.provider.ts +11 -11
- package/backend/src/{core/logs/providers → providers/logs}/cloudwatch.provider.ts +61 -38
- package/backend/src/providers/logs/local.provider.ts +185 -0
- package/backend/src/providers/oauth/base.provider.ts +29 -0
- package/backend/src/providers/oauth/discord.provider.ts +195 -0
- package/backend/src/providers/oauth/facebook.provider.ts +194 -0
- package/backend/src/providers/oauth/github.provider.ts +208 -0
- package/backend/src/providers/oauth/google.provider.ts +249 -0
- package/backend/src/providers/oauth/index.ts +7 -0
- package/backend/src/providers/oauth/linkedin.provider.ts +240 -0
- package/backend/src/providers/oauth/microsoft.provider.ts +169 -0
- package/backend/src/providers/oauth/x.provider.ts +202 -0
- package/backend/src/providers/storage/base.provider.ts +29 -0
- package/backend/src/providers/storage/local.provider.ts +103 -0
- package/backend/src/providers/storage/s3.provider.ts +313 -0
- package/backend/src/server.ts +70 -74
- package/backend/src/{core/ai/config.ts → services/ai/ai-config.service.ts} +19 -24
- package/backend/src/services/ai/ai-model.service.ts +60 -0
- package/backend/src/{core/ai/usage.ts → services/ai/ai-usage.service.ts} +28 -35
- package/backend/src/{core/ai/chat.ts → services/ai/chat-completion.service.ts} +37 -24
- package/backend/src/services/ai/helpers.ts +64 -0
- package/backend/src/{core/ai/image.ts → services/ai/image-generation.service.ts} +17 -19
- package/backend/src/services/ai/index.ts +13 -0
- package/backend/src/services/auth/auth-config.service.ts +250 -0
- package/backend/src/services/auth/auth-otp.service.ts +424 -0
- package/backend/src/services/auth/auth.service.ts +1136 -0
- package/backend/src/services/auth/index.ts +4 -0
- package/backend/src/{core/auth/oauth.ts → services/auth/oauth-config.service.ts} +106 -52
- package/backend/src/{core/database/advance.ts → services/database/database-advance.service.ts} +97 -131
- package/backend/src/services/database/database-table.service.ts +811 -0
- package/backend/src/services/email/email.service.ts +75 -0
- package/backend/src/{core/functions/functions.ts → services/functions/function.service.ts} +95 -88
- package/backend/src/{core/logs/audit.ts → services/logs/audit.service.ts} +92 -75
- package/backend/src/services/logs/log.service.ts +73 -0
- package/backend/src/{core/secrets/secrets.ts → services/secrets/secret.service.ts} +48 -66
- package/backend/src/services/storage/storage.service.ts +617 -0
- package/backend/src/services/usage/usage.service.ts +149 -0
- package/backend/src/types/auth.ts +66 -2
- package/backend/src/types/email.ts +8 -0
- package/backend/src/types/error-constants.ts +4 -0
- package/backend/src/types/logs.ts +0 -29
- package/backend/src/{core/socket/types.ts → types/socket.ts} +5 -6
- package/backend/src/utils/environment.ts +9 -3
- package/backend/src/utils/logger.ts +20 -2
- package/backend/src/utils/seed.ts +150 -57
- package/backend/src/utils/sql-parser.ts +1 -1
- package/backend/src/utils/utils.ts +114 -0
- package/backend/src/utils/validations.ts +40 -4
- package/backend/tests/local/test-ai-config.sh +129 -0
- package/backend/tests/local/test-ai-usage.sh +80 -0
- package/backend/tests/local/test-auth-router.sh +1 -1
- package/backend/tests/local/test-e2e.sh +1 -1
- package/backend/tests/local/test-functions.sh +123 -0
- package/backend/tests/local/test-logs.sh +132 -0
- package/backend/tests/local/test-public-bucket.sh +3 -3
- package/backend/tests/local/test-secrets.sh +14 -12
- package/backend/tests/local/test-traditional-rest.sh +2 -2
- package/backend/tests/manual/test-rawsql-modes.sh +244 -0
- package/backend/tests/test-config.sh +37 -1
- package/backend/tests/unit/cloud-token.test.ts +48 -0
- package/backend/tests/unit/constant.test.ts +8 -0
- package/backend/tests/unit/email.test.ts +372 -0
- package/backend/tests/unit/environment.test.ts +59 -0
- package/backend/tests/unit/helpers.test.ts +63 -0
- package/backend/tests/unit/logger.test.ts +22 -0
- package/backend/tests/unit/rate-limit.test.ts +154 -0
- package/backend/tests/unit/response.test.ts +58 -0
- package/backend/tests/unit/sql-parser.test.ts +74 -0
- package/backend/tests/unit/uuid.test.ts +21 -0
- package/backend/tests/unit/validations.test.ts +80 -0
- package/backend/tsconfig.json +1 -1
- package/backend/vitest.config.ts +11 -0
- package/claude-plugin/.claude-plugin/plugin.json +24 -0
- package/claude-plugin/README.md +133 -0
- package/claude-plugin/skills/insforge-schema-patterns/SKILL.md +270 -0
- package/docker-compose.prod.yml +60 -4
- package/docker-compose.yml +65 -4
- package/docker-init/db/db-init.sql +6 -34
- package/docker-init/logs/vector.yml +236 -0
- package/docs/README.md +44 -0
- package/docs/changelog.mdx +67 -0
- package/docs/core-concepts/ai/architecture.mdx +373 -0
- package/docs/core-concepts/ai/sdk.mdx +213 -0
- package/docs/core-concepts/authentication/architecture.mdx +278 -0
- package/docs/core-concepts/authentication/sdk.mdx +414 -0
- package/docs/core-concepts/authentication/ui-components/customization.mdx +529 -0
- package/docs/core-concepts/authentication/ui-components/nextjs.mdx +221 -0
- package/docs/core-concepts/authentication/ui-components/react-router.mdx +184 -0
- package/docs/core-concepts/authentication/ui-components/react.mdx +129 -0
- package/docs/core-concepts/database/architecture.mdx +256 -0
- package/docs/core-concepts/database/sdk.mdx +382 -0
- package/docs/core-concepts/functions/architecture.mdx +105 -0
- package/docs/core-concepts/functions/sdk.mdx +184 -0
- package/docs/core-concepts/storage/architecture.mdx +243 -0
- package/docs/core-concepts/storage/sdk.mdx +253 -0
- package/docs/deployment/README.md +94 -0
- package/docs/deployment/deploy-to-aws-ec2.md +565 -0
- package/docs/deployment/deploy-to-azure-virtual-machines.md +313 -0
- package/docs/deployment/deploy-to-google-cloud-compute-engine.md +613 -0
- package/docs/deployment/deploy-to-render.md +441 -0
- package/docs/docs.json +210 -0
- package/docs/examples/framework-guides/nextjs.mdx +131 -0
- package/docs/examples/framework-guides/nuxt.mdx +165 -0
- package/docs/examples/framework-guides/react.mdx +165 -0
- package/docs/examples/framework-guides/svelte.mdx +153 -0
- package/docs/examples/framework-guides/vue.mdx +159 -0
- package/docs/examples/overview.mdx +67 -0
- package/docs/favicon.svg +19 -0
- package/docs/images/changelog/nov-2025/auth-components.webp +0 -0
- package/docs/images/changelog/nov-2025/database-metadata.webp +0 -0
- package/docs/images/changelog/nov-2025/quickstart-prompts.webp +0 -0
- package/docs/images/changelog/nov-2025/sql-editor.webp +0 -0
- package/docs/images/changelog/nov-2025/usage-page.webp +0 -0
- package/docs/images/changelog/october-2025/csv-upload.webp +0 -0
- package/docs/images/changelog/october-2025/logs-feature.webp +0 -0
- package/docs/images/changelog/october-2025/oauth-providers.webp +0 -0
- package/docs/images/checks-passed.png +0 -0
- package/docs/images/dashboard-connect-expanded.png +0 -0
- package/docs/images/dashboard-connect.png +0 -0
- package/docs/images/hero-dark.png +0 -0
- package/docs/images/hero-light.png +0 -0
- package/docs/images/icons/ai.svg +4 -0
- package/docs/images/icons/auth.svg +1 -0
- package/docs/images/icons/database.svg +1 -0
- package/docs/images/icons/function.svg +1 -0
- package/docs/images/icons/storage.svg +1 -0
- package/docs/images/logos/nextjs.svg +4 -0
- package/docs/images/logos/nuxt.svg +4 -0
- package/docs/images/logos/react.svg +5 -0
- package/docs/images/logos/svelte.svg +4 -0
- package/docs/images/logos/vue.svg +5 -0
- package/docs/images/mcp-install.png +0 -0
- package/docs/images/onboarding-mcp.png +0 -0
- package/docs/insforge-instructions-sdk.md +55 -374
- package/docs/introduction.mdx +45 -0
- package/docs/logo/dark.svg +22 -0
- package/docs/logo/light.svg +20 -0
- package/docs/partnership.mdx +647 -0
- package/docs/quickstart.mdx +83 -0
- package/docs/showcase/2048-arena.png +0 -0
- package/docs/showcase/framegen-cloud.png +0 -0
- package/docs/showcase/line-connect-race.png +0 -0
- package/docs/showcase/moment-vibe.png +0 -0
- package/docs/showcase/national-flags.png +0 -0
- package/docs/showcase/pokemon-vibe.png +0 -0
- package/docs/showcase/pure-browse-buy.png +0 -0
- package/docs/showcase.mdx +52 -0
- package/docs/snippets/sdk-installation.mdx +22 -0
- package/docs/snippets/service-icons.mdx +27 -0
- package/eslint.config.js +10 -3
- package/frontend/package.json +10 -4
- package/frontend/src/App.tsx +13 -82
- package/frontend/src/assets/icons/connected.svg +3 -0
- package/frontend/src/assets/icons/loader.svg +9 -0
- package/frontend/src/assets/logos/apple.svg +4 -0
- package/frontend/src/assets/logos/discord.svg +1 -1
- package/frontend/src/assets/logos/facebook.svg +3 -0
- package/frontend/src/assets/logos/instagram.svg +2 -0
- package/frontend/src/assets/logos/linkedin.svg +3 -0
- package/frontend/src/assets/logos/microsoft.svg +1 -0
- package/frontend/src/assets/logos/spotify.svg +17 -0
- package/frontend/src/assets/logos/tiktok.svg +6 -0
- package/frontend/src/assets/logos/x.svg +3 -0
- package/frontend/src/components/Checkbox.tsx +27 -29
- package/frontend/src/components/CodeBlock.tsx +55 -2
- package/frontend/src/components/CodeEditor.tsx +92 -0
- package/frontend/src/components/ConfirmDialog.tsx +1 -1
- package/frontend/src/components/ConnectCTA.tsx +38 -0
- package/frontend/src/components/CopyButton.tsx +52 -15
- package/frontend/src/components/ErrorState.tsx +1 -2
- package/frontend/src/components/FeatureSidebar.tsx +6 -6
- package/frontend/src/components/FeatureSidebarItem.tsx +2 -2
- package/frontend/src/components/JsonHighlight.tsx +21 -9
- package/frontend/src/components/ProjectInfoModal.tsx +128 -0
- package/frontend/src/components/PromptDialog.tsx +1 -4
- package/frontend/src/components/SearchInput.tsx +1 -2
- package/frontend/src/components/Stepper.tsx +53 -0
- package/frontend/src/components/ThemeToggle.tsx +3 -3
- package/frontend/src/components/datagrid/DataGrid.tsx +25 -32
- package/frontend/src/components/datagrid/cell-editors/DateCellEditor.tsx +1 -2
- package/frontend/src/components/datagrid/cell-editors/JsonCellEditor.tsx +2 -4
- package/frontend/src/components/datagrid/index.ts +23 -0
- package/frontend/src/components/index.ts +23 -30
- package/frontend/src/components/layout/AppHeader.tsx +133 -92
- package/frontend/src/components/layout/AppSidebar.tsx +80 -170
- package/frontend/src/components/layout/Layout.tsx +12 -23
- package/frontend/src/components/layout/PrimaryMenu.tsx +187 -0
- package/frontend/src/components/layout/SecondaryMenu.tsx +70 -0
- package/frontend/src/components/layout/index.ts +5 -0
- package/frontend/src/components/radix/Tooltip.tsx +24 -13
- package/frontend/src/components/radix/index.ts +22 -0
- package/frontend/src/features/ai/components/AIConfigCard.tsx +129 -83
- package/frontend/src/features/ai/components/AIEmptyState.tsx +12 -7
- package/frontend/src/features/ai/components/ModalityFilterSidebar.tsx +101 -0
- package/frontend/src/features/ai/components/ModelSelectionDialog.tsx +135 -0
- package/frontend/src/features/ai/components/ModelSelectionGrid.tsx +51 -0
- package/frontend/src/features/ai/components/SystemPromptDialog.tsx +118 -0
- package/frontend/src/features/ai/components/index.ts +6 -0
- package/frontend/src/features/ai/helpers.ts +57 -71
- package/frontend/src/features/ai/hooks/useAIConfigs.ts +39 -113
- package/frontend/src/features/ai/hooks/useAIUsage.ts +0 -2
- package/frontend/src/features/ai/page/AIPage.tsx +67 -79
- package/frontend/src/features/ai/services/ai.service.ts +5 -5
- package/frontend/src/features/auth/components/AuthPreview.tsx +96 -0
- package/frontend/src/features/auth/components/OAuthConfigDialog.tsx +53 -30
- package/frontend/src/features/auth/components/UserFormDialog.tsx +13 -6
- package/frontend/src/features/auth/components/UsersDataGrid.tsx +44 -14
- package/frontend/src/features/auth/components/index.ts +5 -0
- package/frontend/src/features/auth/helpers.tsx +200 -0
- package/frontend/src/features/auth/hooks/useAnonToken.ts +30 -0
- package/frontend/src/features/auth/hooks/useAuthConfig.ts +48 -0
- package/frontend/src/features/auth/hooks/useOAuthConfig.ts +14 -10
- package/frontend/src/features/auth/hooks/useUsers.ts +43 -5
- package/frontend/src/features/auth/index.ts +3 -2
- package/frontend/src/features/auth/page/AuthMethodsPage.tsx +275 -0
- package/frontend/src/features/auth/page/ConfigurationPage.tsx +395 -0
- package/frontend/src/features/auth/page/UsersPage.tsx +285 -0
- package/frontend/src/features/auth/services/anonToken.service.ts +11 -0
- package/frontend/src/features/auth/services/config.service.ts +19 -0
- package/frontend/src/features/auth/services/{oauth.service.ts → oauth-config.service.ts} +4 -4
- package/frontend/src/features/auth/services/{auth.service.ts → user.service.ts} +7 -53
- package/frontend/src/features/dashboard/components/ConnectionSuccessBanner.tsx +35 -0
- package/frontend/src/features/dashboard/components/PromptCard.tsx +21 -0
- package/frontend/src/features/dashboard/components/PromptDialog.tsx +103 -0
- package/frontend/src/features/dashboard/components/StatsCard.tsx +50 -0
- package/frontend/src/features/dashboard/components/index.ts +4 -0
- package/frontend/src/features/dashboard/page/DashboardPage.tsx +187 -169
- package/frontend/src/features/dashboard/prompts/ai-chatbot.ts +13 -0
- package/frontend/src/features/dashboard/prompts/crm-system.ts +13 -0
- package/frontend/src/features/dashboard/prompts/ecommerce-platform.ts +12 -0
- package/frontend/src/features/dashboard/prompts/index.ts +31 -0
- package/frontend/src/features/dashboard/prompts/instagram-clone.ts +11 -0
- package/frontend/src/features/dashboard/prompts/notion-clone.ts +14 -0
- package/frontend/src/features/dashboard/prompts/reddit-clone.ts +12 -0
- package/frontend/src/features/database/components/DatabaseDataGrid.tsx +48 -17
- package/frontend/src/features/database/components/ForeignKeyCell.tsx +15 -34
- package/frontend/src/features/database/components/ForeignKeyPopover.tsx +19 -20
- package/frontend/src/features/database/components/LinkRecordModal.tsx +120 -125
- package/frontend/src/features/database/components/RecordFormDialog.tsx +22 -33
- package/frontend/src/features/database/components/RecordFormField.tsx +45 -47
- package/frontend/src/features/database/components/TableEmptyState.tsx +6 -5
- package/frontend/src/features/database/components/TableForm.tsx +28 -15
- package/frontend/src/features/database/components/TableFormColumn.tsx +2 -3
- package/frontend/src/features/database/components/TableSidebar.tsx +1 -1
- package/frontend/src/features/database/components/TablesEmptyState.tsx +48 -0
- package/frontend/src/features/database/components/TemplateCard.tsx +37 -0
- package/frontend/src/features/database/components/TemplatePreview.tsx +92 -0
- package/frontend/src/features/database/components/index.ts +19 -0
- package/frontend/src/features/database/constants.ts +28 -2
- package/frontend/src/features/database/contexts/SQLEditorContext.tsx +188 -0
- package/frontend/src/features/database/helpers.ts +2 -2
- package/frontend/src/features/database/hooks/useCSVImport.ts +29 -0
- package/frontend/src/features/database/hooks/useFullMetadata.ts +18 -0
- package/frontend/src/features/database/hooks/useRawSQL.ts +55 -0
- package/frontend/src/features/database/hooks/useRecords.ts +139 -0
- package/frontend/src/features/database/hooks/useTables.ts +131 -0
- package/frontend/src/features/database/index.ts +6 -1
- package/frontend/src/features/database/page/FunctionsPage.tsx +211 -0
- package/frontend/src/features/database/page/IndexesPage.tsx +240 -0
- package/frontend/src/features/database/page/PoliciesPage.tsx +248 -0
- package/frontend/src/features/database/page/SQLEditorPage.tsx +382 -0
- package/frontend/src/features/database/page/{DatabasePage.tsx → TablesPage.tsx} +186 -185
- package/frontend/src/features/database/page/TemplatesPage.tsx +39 -0
- package/frontend/src/features/database/page/TriggersPage.tsx +242 -0
- package/frontend/src/features/database/services/advance.service.ts +66 -0
- package/frontend/src/features/database/services/{database.service.ts → record.service.ts} +67 -64
- package/frontend/src/features/database/services/table.service.ts +64 -0
- package/frontend/src/features/database/templates/ai-chatbot.ts +402 -0
- package/frontend/src/features/database/templates/crm-system.ts +528 -0
- package/frontend/src/features/database/templates/ecommerce-platform.ts +553 -0
- package/frontend/src/features/database/templates/index.ts +34 -0
- package/frontend/src/features/database/templates/instagram-clone.ts +222 -0
- package/frontend/src/features/database/templates/notion-clone.ts +483 -0
- package/frontend/src/features/database/templates/reddit-clone.ts +526 -0
- package/frontend/src/features/functions/components/FunctionRow.tsx +2 -1
- package/frontend/src/features/functions/components/FunctionsSidebar.tsx +1 -1
- package/frontend/src/features/functions/components/SecretRow.tsx +1 -1
- package/frontend/src/features/functions/components/index.ts +5 -0
- package/frontend/src/features/functions/hooks/useFunctions.ts +4 -4
- package/frontend/src/features/{secrets → functions}/hooks/useSecrets.ts +5 -5
- package/frontend/src/features/functions/page/FunctionsPage.tsx +160 -17
- package/frontend/src/features/functions/{components/SecretsContent.tsx → page/SecretsPage.tsx} +8 -12
- package/frontend/src/features/functions/services/{functions.service.ts → function.service.ts} +2 -2
- package/frontend/src/features/{secrets/services/secrets.service.ts → functions/services/secret.service.ts} +2 -2
- package/frontend/src/features/login/hooks/usePartnerOrigin.ts +27 -0
- package/frontend/src/features/login/page/CloudLoginPage.tsx +79 -54
- package/frontend/src/features/login/page/LoginPage.tsx +16 -23
- package/frontend/src/features/login/services/partnership.service.ts +65 -0
- package/frontend/src/features/logs/components/LogsDataGrid.tsx +89 -0
- package/frontend/src/features/logs/components/SeverityBadge.tsx +18 -0
- package/frontend/src/features/logs/components/index.ts +2 -0
- package/frontend/src/features/logs/helpers.ts +24 -0
- package/frontend/src/features/logs/hooks/useAuditLogs.ts +4 -4
- package/frontend/src/features/logs/hooks/useLogSources.ts +137 -0
- package/frontend/src/features/logs/hooks/useLogs.ts +163 -0
- package/frontend/src/features/logs/hooks/useMcpUsage.ts +181 -0
- package/frontend/src/features/logs/index.ts +8 -2
- package/frontend/src/features/logs/page/AuditsPage.tsx +91 -38
- package/frontend/src/features/logs/page/LogsPage.tsx +152 -0
- package/frontend/src/features/logs/page/MCPLogsPage.tsx +84 -0
- package/frontend/src/features/logs/services/audit.service.ts +63 -0
- package/frontend/src/features/logs/services/log.service.ts +15 -110
- package/frontend/src/features/logs/services/usage.service.ts +31 -0
- package/frontend/src/features/onboard/components/McpConnectionStatus.tsx +68 -0
- package/frontend/src/features/onboard/components/OnboardingModal.tsx +267 -0
- package/frontend/src/features/onboard/components/VideoDemoModal.tsx +38 -0
- package/frontend/src/features/onboard/components/index.ts +4 -0
- package/frontend/src/features/onboard/components/mcp/CursorDeeplinkGenerator.tsx +2 -2
- package/frontend/src/features/onboard/components/mcp/{mcp-helper.tsx → helpers.tsx} +8 -8
- package/frontend/src/features/onboard/components/mcp/index.ts +2 -3
- package/frontend/src/features/onboard/index.ts +13 -3
- package/frontend/src/features/storage/components/BucketEmptyState.tsx +9 -6
- package/frontend/src/features/storage/components/BucketFormDialog.tsx +25 -41
- package/frontend/src/features/storage/components/FilePreviewDialog.tsx +20 -8
- package/frontend/src/features/storage/components/StorageDataGrid.tsx +4 -3
- package/frontend/src/features/storage/components/StorageManager.tsx +23 -34
- package/frontend/src/features/storage/components/index.ts +12 -0
- package/frontend/src/features/storage/hooks/useStorage.ts +208 -0
- package/frontend/src/features/storage/page/StoragePage.tsx +41 -115
- package/frontend/src/features/storage/services/storage.service.ts +22 -1
- package/frontend/src/features/visualizer/components/AuthNode.tsx +72 -56
- package/frontend/src/features/visualizer/components/BucketNode.tsx +4 -4
- package/frontend/src/features/visualizer/components/SchemaVisualizer.tsx +108 -80
- package/frontend/src/features/visualizer/components/TableNode.tsx +34 -41
- package/frontend/src/features/visualizer/components/VisualizerSkeleton.tsx +12 -4
- package/frontend/src/features/visualizer/page/VisualizerPage.tsx +33 -29
- package/frontend/src/index.css +1 -0
- package/frontend/src/lib/analytics/posthog.tsx +27 -0
- package/frontend/src/lib/contexts/AuthContext.tsx +38 -31
- package/frontend/src/lib/contexts/SocketContext.tsx +5 -6
- package/frontend/src/{features/metadata → lib}/hooks/useMetadata.ts +1 -1
- package/frontend/src/lib/hooks/useToast.tsx +6 -2
- package/frontend/src/lib/routing/AppRoutes.tsx +84 -0
- package/frontend/src/lib/routing/RequireAuth.tsx +27 -0
- package/frontend/src/lib/utils/cloudMessaging.ts +20 -0
- package/frontend/src/lib/utils/menuItems.ts +183 -0
- package/frontend/src/lib/utils/{validation-schemas.ts → schemaValidations.ts} +10 -5
- package/frontend/src/lib/utils/utils.ts +19 -1
- package/frontend/src/vite-env.d.ts +1 -0
- package/frontend/vite.config.ts +5 -3
- package/functions/server.ts +28 -3
- package/functions/worker-template.js +15 -4
- package/i18n/README.ar.md +130 -0
- package/i18n/README.de.md +130 -0
- package/i18n/README.es.md +154 -0
- package/i18n/README.fr.md +134 -0
- package/i18n/README.hi.md +129 -0
- package/i18n/README.ja.md +174 -0
- package/i18n/README.ko.md +137 -0
- package/i18n/README.pt-BR.md +131 -0
- package/i18n/README.ru.md +129 -0
- package/i18n/README.zh-CN.md +133 -0
- package/openapi/ai.yaml +31 -4
- package/openapi/auth.yaml +827 -146
- package/package.json +16 -7
- package/shared-schemas/package.json +1 -1
- package/shared-schemas/src/ai-api.schema.ts +34 -58
- package/shared-schemas/src/ai.schema.ts +5 -0
- package/shared-schemas/src/auth-api.schema.ts +154 -8
- package/shared-schemas/src/auth.schema.ts +42 -6
- package/shared-schemas/src/cloud-events.schema.ts +57 -0
- package/shared-schemas/src/database-api.schema.ts +3 -3
- package/shared-schemas/src/database.schema.ts +1 -1
- package/shared-schemas/src/index.ts +1 -0
- package/shared-schemas/src/logs-api.schema.ts +7 -1
- package/shared-schemas/src/logs.schema.ts +26 -0
- package/shared-schemas/src/metadata.schema.ts +9 -4
- package/test-gemini.sh +35 -0
- package/test-usage-admin.sh +57 -0
- package/test-usage.sh +50 -0
- package/zeabur/README.md +13 -0
- package/zeabur/template.yml +1032 -0
- package/.github/workflows/deploy-aws.yml +0 -130
- package/backend/src/api/routes/agent.ts +0 -29
- package/backend/src/api/routes/auth.oauth.ts +0 -482
- package/backend/src/api/routes/auth.ts +0 -386
- package/backend/src/api/routes/docs.ts +0 -66
- package/backend/src/api/routes/functions.ts +0 -183
- package/backend/src/api/routes/openapi.ts +0 -82
- package/backend/src/api/routes/usage.ts +0 -96
- package/backend/src/core/ai/client.ts +0 -242
- package/backend/src/core/ai/model.ts +0 -117
- package/backend/src/core/auth/auth.ts +0 -781
- package/backend/src/core/database/table.ts +0 -772
- package/backend/src/core/documentation/agent.ts +0 -689
- package/backend/src/core/documentation/openapi.ts +0 -856
- package/backend/src/core/logs/analytics.ts +0 -76
- package/backend/src/core/logs/providers/localdb.provider.ts +0 -246
- package/backend/src/core/storage/storage.ts +0 -923
- package/backend/src/utils/cloud-token.ts +0 -39
- package/backend/src/utils/helpers.ts +0 -49
- package/backend/src/utils/uuid.ts +0 -9
- package/backend/tests/manual/test-better-auth.sh +0 -303
- package/docker-init/db/logs.sql +0 -9
- package/frontend/README.md +0 -112
- package/frontend/src/components/datagrid/index.tsx +0 -20
- package/frontend/src/components/layout/CloudLayout.tsx +0 -95
- package/frontend/src/features/ai/components/AIConfigDialog.tsx +0 -76
- package/frontend/src/features/ai/components/AIConfigForm.tsx +0 -222
- package/frontend/src/features/ai/components/fields/ModalityField.tsx +0 -87
- package/frontend/src/features/ai/components/fields/ModelSelectionField.tsx +0 -134
- package/frontend/src/features/ai/components/fields/SystemPromptField.tsx +0 -33
- package/frontend/src/features/auth/components/AddOAuthDialog.tsx +0 -106
- package/frontend/src/features/auth/components/AuthMethodTab.tsx +0 -238
- package/frontend/src/features/auth/components/UsersTab.tsx +0 -114
- package/frontend/src/features/auth/page/AuthenticationPage.tsx +0 -169
- package/frontend/src/features/database/hooks/UseLinkModal.tsx +0 -78
- package/frontend/src/features/functions/components/FunctionViewer.tsx +0 -46
- package/frontend/src/features/functions/components/FunctionsContent.tsx +0 -88
- package/frontend/src/features/login/components/AuthErrorBoundary.tsx +0 -87
- package/frontend/src/features/login/components/PrivateRoute.tsx +0 -24
- package/frontend/src/features/logs/components/AnalyticsLogsTable.tsx +0 -313
- package/frontend/src/features/logs/components/LogsTable.tsx +0 -199
- package/frontend/src/features/logs/page/AnalyticsLogsPage.tsx +0 -530
- package/frontend/src/features/metadata/index.ts +0 -0
- package/frontend/src/features/metadata/page/MetadataPage.tsx +0 -136
- package/frontend/src/features/onboard/components/CompletionCard.tsx +0 -41
- package/frontend/src/features/onboard/components/OnboardButton.tsx +0 -84
- package/frontend/src/features/onboard/components/StepContent.tsx +0 -91
- package/frontend/src/features/onboard/components/TestConnectionStep.tsx +0 -53
- package/frontend/src/features/onboard/components/mcp/McpInstallation.tsx +0 -144
- package/frontend/src/features/onboard/page/OnBoardPage.tsx +0 -104
- package/frontend/src/features/onboard/types.ts +0 -8
- package/frontend/src/lib/contexts/OnboardStepContext.tsx +0 -68
- package/frontend/src/lib/hooks/useOnboardingCompletion.ts +0 -29
- /package/backend/src/api/{middleware → middlewares}/error.ts +0 -0
- /package/backend/src/api/{middleware → middlewares}/upload.ts +0 -0
- /package/backend/{migrations → src/infra/database/migrations}/000_create-base-tables.sql +0 -0
- /package/backend/{migrations → src/infra/database/migrations}/001_create-helper-functions.sql +0 -0
- /package/backend/{migrations → src/infra/database/migrations}/002_rename-auth-tables.sql +0 -0
- /package/backend/{migrations → src/infra/database/migrations}/003_create-users-table.sql +0 -0
- /package/backend/{migrations → src/infra/database/migrations}/004_add-reload-postgrest-func.sql +0 -0
- /package/backend/{migrations → src/infra/database/migrations}/005_enable-project-admin-modify-users.sql +0 -0
- /package/backend/{migrations → src/infra/database/migrations}/006_modify-ai-usage-table.sql +0 -0
- /package/backend/{migrations → src/infra/database/migrations}/007_drop-metadata-table.sql +0 -0
- /package/backend/{migrations → src/infra/database/migrations}/008_add-system-tables.sql +0 -0
- /package/backend/{migrations → src/infra/database/migrations}/009_add-function-secrets.sql +0 -0
- /package/backend/{migrations → src/infra/database/migrations}/010_modify-ai-config-modalities.sql +0 -0
- /package/backend/{migrations → src/infra/database/migrations}/011_refactor-secrets-table.sql +0 -0
- /package/backend/{migrations → src/infra/database/migrations}/012_add-storage-uploaded-by.sql +0 -0
- /package/frontend/src/{features/metadata → lib}/services/metadata.service.ts +0 -0
|
@@ -0,0 +1,285 @@
|
|
|
1
|
+
import { useState, useEffect, useMemo } from 'react';
|
|
2
|
+
import { UserPlus } from 'lucide-react';
|
|
3
|
+
import RefreshIcon from '@/assets/icons/refresh.svg?react';
|
|
4
|
+
import {
|
|
5
|
+
Button,
|
|
6
|
+
ConnectCTA,
|
|
7
|
+
SearchInput,
|
|
8
|
+
SelectionClearButton,
|
|
9
|
+
DeleteActionButton,
|
|
10
|
+
Tooltip,
|
|
11
|
+
TooltipContent,
|
|
12
|
+
TooltipProvider,
|
|
13
|
+
TooltipTrigger,
|
|
14
|
+
ConfirmDialog,
|
|
15
|
+
} from '@/components';
|
|
16
|
+
import { UsersDataGrid, UserFormDialog } from '@/features/auth/components';
|
|
17
|
+
import { SortColumn } from 'react-data-grid';
|
|
18
|
+
import { UserSchema } from '@insforge/shared-schemas';
|
|
19
|
+
import { useToast } from '@/lib/hooks/useToast';
|
|
20
|
+
import { useUsers } from '@/features/auth/hooks/useUsers';
|
|
21
|
+
import {
|
|
22
|
+
DataUpdatePayload,
|
|
23
|
+
DataUpdateResourceType,
|
|
24
|
+
ServerEvents,
|
|
25
|
+
SocketMessage,
|
|
26
|
+
useSocket,
|
|
27
|
+
} from '@/lib/contexts/SocketContext';
|
|
28
|
+
|
|
29
|
+
export default function UsersPage() {
|
|
30
|
+
const [searchQuery, setSearchQuery] = useState('');
|
|
31
|
+
const [addDialogOpen, setAddDialogOpen] = useState(false);
|
|
32
|
+
const [confirmDeleteOpen, setConfirmDeleteOpen] = useState(false);
|
|
33
|
+
const [selectedRows, setSelectedRows] = useState<Set<string>>(new Set());
|
|
34
|
+
const [isRefreshing, setIsRefreshing] = useState(false);
|
|
35
|
+
const [sortColumns, setSortColumns] = useState<SortColumn[]>([]);
|
|
36
|
+
|
|
37
|
+
const { socket, isConnected } = useSocket();
|
|
38
|
+
|
|
39
|
+
const { showToast } = useToast();
|
|
40
|
+
|
|
41
|
+
// Default page size of 20 records per page
|
|
42
|
+
const pageSize = 20;
|
|
43
|
+
const {
|
|
44
|
+
users,
|
|
45
|
+
totalUsers,
|
|
46
|
+
isLoading,
|
|
47
|
+
currentPage,
|
|
48
|
+
setCurrentPage,
|
|
49
|
+
totalPages,
|
|
50
|
+
refetch,
|
|
51
|
+
deleteUsers,
|
|
52
|
+
} = useUsers({ searchQuery, pageSize });
|
|
53
|
+
|
|
54
|
+
// Listen for refresh events
|
|
55
|
+
useEffect(() => {
|
|
56
|
+
const handleRefreshEvent = () => {
|
|
57
|
+
// Reset sorting columns
|
|
58
|
+
setSortColumns([]);
|
|
59
|
+
// Reset selected rows
|
|
60
|
+
setSelectedRows(new Set());
|
|
61
|
+
// Refetch data
|
|
62
|
+
void refetch();
|
|
63
|
+
};
|
|
64
|
+
window.addEventListener('refreshUsers', handleRefreshEvent);
|
|
65
|
+
return () => window.removeEventListener('refreshUsers', handleRefreshEvent);
|
|
66
|
+
}, [refetch]);
|
|
67
|
+
|
|
68
|
+
useEffect(() => {
|
|
69
|
+
if (!socket || !isConnected) {
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
const handleDataUpdate = (message: SocketMessage<DataUpdatePayload>) => {
|
|
74
|
+
if (message.payload?.resource === DataUpdateResourceType.USERS) {
|
|
75
|
+
// Refetch data
|
|
76
|
+
void refetch();
|
|
77
|
+
}
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
socket.on(ServerEvents.DATA_UPDATE, handleDataUpdate);
|
|
81
|
+
|
|
82
|
+
return () => {
|
|
83
|
+
socket.off(ServerEvents.DATA_UPDATE, handleDataUpdate);
|
|
84
|
+
};
|
|
85
|
+
}, [socket, isConnected, refetch]);
|
|
86
|
+
|
|
87
|
+
// Clear selection when page changes or search changes
|
|
88
|
+
useEffect(() => {
|
|
89
|
+
setSelectedRows(new Set());
|
|
90
|
+
}, [currentPage, searchQuery]);
|
|
91
|
+
|
|
92
|
+
// Apply sorting to users data
|
|
93
|
+
const sortedUsers = useMemo(() => {
|
|
94
|
+
if (!sortColumns.length) {
|
|
95
|
+
return users;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
return [...users].sort((a, b) => {
|
|
99
|
+
for (const sort of sortColumns) {
|
|
100
|
+
const { columnKey, direction } = sort;
|
|
101
|
+
let aVal = a[columnKey as keyof UserSchema];
|
|
102
|
+
let bVal = b[columnKey as keyof UserSchema];
|
|
103
|
+
|
|
104
|
+
// Handle null/undefined values
|
|
105
|
+
if ((aVal === null || aVal === undefined) && (bVal === null || bVal === undefined)) {
|
|
106
|
+
continue;
|
|
107
|
+
}
|
|
108
|
+
if (aVal === null || aVal === undefined) {
|
|
109
|
+
return direction === 'ASC' ? -1 : 1;
|
|
110
|
+
}
|
|
111
|
+
if (bVal === null || bVal === undefined) {
|
|
112
|
+
return direction === 'ASC' ? 1 : -1;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
// Convert to comparable values
|
|
116
|
+
if (typeof aVal === 'string') {
|
|
117
|
+
aVal = aVal.toLowerCase();
|
|
118
|
+
}
|
|
119
|
+
if (typeof bVal === 'string') {
|
|
120
|
+
bVal = bVal.toLowerCase();
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
if (aVal < bVal) {
|
|
124
|
+
return direction === 'ASC' ? -1 : 1;
|
|
125
|
+
}
|
|
126
|
+
if (aVal > bVal) {
|
|
127
|
+
return direction === 'ASC' ? 1 : -1;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
return 0;
|
|
131
|
+
});
|
|
132
|
+
}, [users, sortColumns]);
|
|
133
|
+
|
|
134
|
+
const handleBulkDelete = async () => {
|
|
135
|
+
if (selectedRows.size === 0) {
|
|
136
|
+
return;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
try {
|
|
140
|
+
const userIds = Array.from(selectedRows);
|
|
141
|
+
await deleteUsers(userIds);
|
|
142
|
+
void refetch();
|
|
143
|
+
setSelectedRows(new Set());
|
|
144
|
+
showToast(
|
|
145
|
+
`${userIds.length} user${userIds.length > 1 ? 's' : ''} deleted successfully`,
|
|
146
|
+
'success'
|
|
147
|
+
);
|
|
148
|
+
} catch (error) {
|
|
149
|
+
showToast(error instanceof Error ? error.message : 'Failed to delete users', 'error');
|
|
150
|
+
}
|
|
151
|
+
};
|
|
152
|
+
|
|
153
|
+
const handleRefresh = async () => {
|
|
154
|
+
setIsRefreshing(true);
|
|
155
|
+
try {
|
|
156
|
+
setSelectedRows(new Set());
|
|
157
|
+
setSearchQuery('');
|
|
158
|
+
await refetch();
|
|
159
|
+
} finally {
|
|
160
|
+
setIsRefreshing(false);
|
|
161
|
+
}
|
|
162
|
+
};
|
|
163
|
+
|
|
164
|
+
const emptyState = (
|
|
165
|
+
<div className="text-sm text-black dark:text-white">
|
|
166
|
+
{searchQuery ? 'No users match your search criteria' : 'No users found'}. <ConnectCTA />
|
|
167
|
+
</div>
|
|
168
|
+
);
|
|
169
|
+
|
|
170
|
+
return (
|
|
171
|
+
<div className="h-full bg-slate-50 dark:bg-neutral-800 flex flex-col overflow-hidden">
|
|
172
|
+
<div className="flex-1 flex flex-col overflow-y-auto">
|
|
173
|
+
{/* Page Header with Title and Actions */}
|
|
174
|
+
<div className="pl-4 pr-1.5 py-1.5 h-12 dark:bg-neutral-800">
|
|
175
|
+
<div className="flex items-center justify-between">
|
|
176
|
+
<div className="flex items-center gap-3">
|
|
177
|
+
<h1 className="text-base font-bold text-black dark:text-white">Users</h1>
|
|
178
|
+
|
|
179
|
+
{/* Separator */}
|
|
180
|
+
<div className="h-6 w-px bg-gray-200 dark:bg-neutral-700" />
|
|
181
|
+
|
|
182
|
+
{/* Refresh button */}
|
|
183
|
+
<TooltipProvider>
|
|
184
|
+
<Tooltip>
|
|
185
|
+
<TooltipTrigger asChild>
|
|
186
|
+
<Button
|
|
187
|
+
variant="ghost"
|
|
188
|
+
size="icon"
|
|
189
|
+
className="p-1 h-9 w-9"
|
|
190
|
+
onClick={() => void handleRefresh()}
|
|
191
|
+
disabled={isRefreshing}
|
|
192
|
+
>
|
|
193
|
+
<RefreshIcon className="h-5 w-5 text-zinc-400 dark:text-neutral-400" />
|
|
194
|
+
</Button>
|
|
195
|
+
</TooltipTrigger>
|
|
196
|
+
<TooltipContent side="bottom" align="center">
|
|
197
|
+
<p>{isRefreshing ? 'Refreshing...' : 'Refresh'}</p>
|
|
198
|
+
</TooltipContent>
|
|
199
|
+
</Tooltip>
|
|
200
|
+
</TooltipProvider>
|
|
201
|
+
</div>
|
|
202
|
+
</div>
|
|
203
|
+
</div>
|
|
204
|
+
|
|
205
|
+
{/* Search Bar and Actions */}
|
|
206
|
+
<div className="pt-2 pb-4 px-3 dark:bg-neutral-800">
|
|
207
|
+
<div className="flex items-center justify-between">
|
|
208
|
+
{selectedRows.size > 0 ? (
|
|
209
|
+
<div className="flex items-center gap-3">
|
|
210
|
+
<SelectionClearButton
|
|
211
|
+
selectedCount={selectedRows.size}
|
|
212
|
+
itemType="user"
|
|
213
|
+
onClear={() => setSelectedRows(new Set())}
|
|
214
|
+
/>
|
|
215
|
+
<DeleteActionButton
|
|
216
|
+
selectedCount={selectedRows.size}
|
|
217
|
+
itemType="user"
|
|
218
|
+
onDelete={() => setConfirmDeleteOpen(true)}
|
|
219
|
+
/>
|
|
220
|
+
</div>
|
|
221
|
+
) : (
|
|
222
|
+
<SearchInput
|
|
223
|
+
value={searchQuery}
|
|
224
|
+
onChange={setSearchQuery}
|
|
225
|
+
placeholder="Search user"
|
|
226
|
+
className="flex-1 max-w-80 dark:bg-neutral-800 dark:text-white dark:border-neutral-700"
|
|
227
|
+
debounceTime={300}
|
|
228
|
+
/>
|
|
229
|
+
)}
|
|
230
|
+
<div className="flex items-center gap-2 ml-4">
|
|
231
|
+
{selectedRows.size === 0 && (
|
|
232
|
+
<Button
|
|
233
|
+
className="h-10 px-4 font-medium dark:bg-emerald-300 dark:text-black"
|
|
234
|
+
onClick={() => setAddDialogOpen(true)}
|
|
235
|
+
>
|
|
236
|
+
<UserPlus className="h-4 w-4 mr-2" />
|
|
237
|
+
Add User
|
|
238
|
+
</Button>
|
|
239
|
+
)}
|
|
240
|
+
</div>
|
|
241
|
+
</div>
|
|
242
|
+
</div>
|
|
243
|
+
|
|
244
|
+
{/* Main Content */}
|
|
245
|
+
<div className="relative flex-1 flex flex-col overflow-hidden">
|
|
246
|
+
<div className="flex-1 flex flex-col overflow-hidden">
|
|
247
|
+
<UsersDataGrid
|
|
248
|
+
data={sortedUsers}
|
|
249
|
+
loading={isLoading}
|
|
250
|
+
isRefreshing={isRefreshing}
|
|
251
|
+
selectedRows={selectedRows}
|
|
252
|
+
onSelectedRowsChange={setSelectedRows}
|
|
253
|
+
sortColumns={sortColumns}
|
|
254
|
+
onSortColumnsChange={setSortColumns}
|
|
255
|
+
currentPage={currentPage}
|
|
256
|
+
totalPages={totalPages}
|
|
257
|
+
pageSize={pageSize}
|
|
258
|
+
totalRecords={totalUsers}
|
|
259
|
+
onPageChange={setCurrentPage}
|
|
260
|
+
emptyState={emptyState}
|
|
261
|
+
/>
|
|
262
|
+
</div>
|
|
263
|
+
</div>
|
|
264
|
+
</div>
|
|
265
|
+
|
|
266
|
+
<UserFormDialog open={addDialogOpen} onOpenChange={setAddDialogOpen} />
|
|
267
|
+
|
|
268
|
+
<ConfirmDialog
|
|
269
|
+
open={confirmDeleteOpen}
|
|
270
|
+
onOpenChange={setConfirmDeleteOpen}
|
|
271
|
+
title={`Delete ${selectedRows.size} ${selectedRows.size === 1 ? 'User' : 'Users'}`}
|
|
272
|
+
description={
|
|
273
|
+
<span>
|
|
274
|
+
Are you sure to <strong>permanently delete {selectedRows.size}</strong>{' '}
|
|
275
|
+
{selectedRows.size === 1 ? 'user' : 'users'}? This action cannot be undone.
|
|
276
|
+
</span>
|
|
277
|
+
}
|
|
278
|
+
confirmText="Delete"
|
|
279
|
+
cancelText="Cancel"
|
|
280
|
+
destructive
|
|
281
|
+
onConfirm={handleBulkDelete}
|
|
282
|
+
/>
|
|
283
|
+
</div>
|
|
284
|
+
);
|
|
285
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { apiClient } from '@/lib/api/client';
|
|
2
|
+
|
|
3
|
+
export class AnonTokenService {
|
|
4
|
+
async generateAnonToken(): Promise<{ accessToken: string; message: string }> {
|
|
5
|
+
return apiClient.request('/auth/tokens/anon', {
|
|
6
|
+
method: 'POST',
|
|
7
|
+
});
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export const anonTokenService = new AnonTokenService();
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { apiClient } from '@/lib/api/client';
|
|
2
|
+
import { AuthConfigSchema, UpdateAuthConfigRequest } from '@insforge/shared-schemas';
|
|
3
|
+
|
|
4
|
+
export class AuthConfigService {
|
|
5
|
+
// Get authentication configuration (admin only)
|
|
6
|
+
async getConfig(): Promise<AuthConfigSchema> {
|
|
7
|
+
return apiClient.request('/auth/config');
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
// Update authentication configuration
|
|
11
|
+
async updateConfig(config: UpdateAuthConfigRequest): Promise<AuthConfigSchema> {
|
|
12
|
+
return apiClient.request('/auth/config', {
|
|
13
|
+
method: 'PUT',
|
|
14
|
+
body: JSON.stringify(config),
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export const authConfigService = new AuthConfigService();
|
|
@@ -16,7 +16,7 @@ export class OAuthConfigService {
|
|
|
16
16
|
async getConfigByProvider(
|
|
17
17
|
provider: string
|
|
18
18
|
): Promise<OAuthConfigSchema & { clientSecret?: string }> {
|
|
19
|
-
return apiClient.request(`/auth/oauth
|
|
19
|
+
return apiClient.request(`/auth/oauth/${provider}/config`);
|
|
20
20
|
}
|
|
21
21
|
|
|
22
22
|
// Create new OAuth configuration
|
|
@@ -32,7 +32,7 @@ export class OAuthConfigService {
|
|
|
32
32
|
provider: string,
|
|
33
33
|
config: UpdateOAuthConfigRequest
|
|
34
34
|
): Promise<OAuthConfigSchema> {
|
|
35
|
-
return apiClient.request(`/auth/oauth
|
|
35
|
+
return apiClient.request(`/auth/oauth/${provider}/config`, {
|
|
36
36
|
method: 'PUT',
|
|
37
37
|
body: JSON.stringify(config),
|
|
38
38
|
});
|
|
@@ -40,10 +40,10 @@ export class OAuthConfigService {
|
|
|
40
40
|
|
|
41
41
|
// Delete OAuth configuration
|
|
42
42
|
async deleteConfig(provider: string): Promise<{ success: boolean; message: string }> {
|
|
43
|
-
return apiClient.request(`/auth/oauth
|
|
43
|
+
return apiClient.request(`/auth/oauth/${provider}/config`, {
|
|
44
44
|
method: 'DELETE',
|
|
45
45
|
});
|
|
46
46
|
}
|
|
47
47
|
}
|
|
48
48
|
|
|
49
|
-
export const
|
|
49
|
+
export const oAuthConfigService = new OAuthConfigService();
|
|
@@ -1,52 +1,7 @@
|
|
|
1
1
|
import { apiClient } from '@/lib/api/client';
|
|
2
2
|
import { UserSchema } from '@insforge/shared-schemas';
|
|
3
3
|
|
|
4
|
-
export class
|
|
5
|
-
async loginWithPassword(email: string, password: string) {
|
|
6
|
-
const data = await apiClient.request('/auth/admin/sessions', {
|
|
7
|
-
method: 'POST',
|
|
8
|
-
body: JSON.stringify({ email, password }),
|
|
9
|
-
});
|
|
10
|
-
|
|
11
|
-
// Set token in apiClient
|
|
12
|
-
if (data.accessToken) {
|
|
13
|
-
apiClient.setToken(data.accessToken);
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
// Return unified format
|
|
17
|
-
return {
|
|
18
|
-
accessToken: data.accessToken,
|
|
19
|
-
user: data.user,
|
|
20
|
-
};
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
async loginWithAuthorizationCode(code: string) {
|
|
24
|
-
const data = await apiClient.request('/auth/admin/sessions/exchange', {
|
|
25
|
-
method: 'POST',
|
|
26
|
-
body: JSON.stringify({ code }),
|
|
27
|
-
});
|
|
28
|
-
|
|
29
|
-
// Set token in apiClient
|
|
30
|
-
if (data.accessToken) {
|
|
31
|
-
apiClient.setToken(data.accessToken);
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
// Return unified format
|
|
35
|
-
return {
|
|
36
|
-
accessToken: data.accessToken,
|
|
37
|
-
user: data.user,
|
|
38
|
-
};
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
async getCurrentUser() {
|
|
42
|
-
const response = await apiClient.request('/auth/sessions/current');
|
|
43
|
-
return response.user;
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
logout() {
|
|
47
|
-
apiClient.clearToken();
|
|
48
|
-
}
|
|
49
|
-
|
|
4
|
+
export class UserService {
|
|
50
5
|
/**
|
|
51
6
|
* Get users list
|
|
52
7
|
* @param queryParams - Query parameters for pagination
|
|
@@ -86,6 +41,11 @@ export class AuthService {
|
|
|
86
41
|
return await apiClient.request(`/auth/users/${id}`);
|
|
87
42
|
}
|
|
88
43
|
|
|
44
|
+
async getCurrentUser() {
|
|
45
|
+
const response = await apiClient.request('/auth/sessions/current');
|
|
46
|
+
return response.user;
|
|
47
|
+
}
|
|
48
|
+
|
|
89
49
|
async register(email: string, password: string, name?: string) {
|
|
90
50
|
const response = await apiClient.request('/auth/users', {
|
|
91
51
|
method: 'POST',
|
|
@@ -101,12 +61,6 @@ export class AuthService {
|
|
|
101
61
|
body: JSON.stringify({ userIds }),
|
|
102
62
|
});
|
|
103
63
|
}
|
|
104
|
-
|
|
105
|
-
async generateAnonToken(): Promise<{ accessToken: string; message: string }> {
|
|
106
|
-
return apiClient.request('/auth/tokens/anon', {
|
|
107
|
-
method: 'POST',
|
|
108
|
-
});
|
|
109
|
-
}
|
|
110
64
|
}
|
|
111
65
|
|
|
112
|
-
export const
|
|
66
|
+
export const userService = new UserService();
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { useState } from 'react';
|
|
2
|
+
import { X } from 'lucide-react';
|
|
3
|
+
|
|
4
|
+
export function ConnectionSuccessBanner() {
|
|
5
|
+
const [isVisible, setIsVisible] = useState(true);
|
|
6
|
+
|
|
7
|
+
const handleClose = () => {
|
|
8
|
+
setIsVisible(false);
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
if (!isVisible) {
|
|
12
|
+
return null;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
return (
|
|
16
|
+
<div className="relative w-full bg-zinc-50 dark:bg-[#333333] border-l-3 border-neutral-600 dark:border-emerald-300 rounded-[8px] py-6 px-8">
|
|
17
|
+
<div className="flex flex-col items-start gap-3">
|
|
18
|
+
<p className="text-xl font-semibold text-zinc-950 dark:text-white">
|
|
19
|
+
Connected successfully!
|
|
20
|
+
</p>
|
|
21
|
+
<p className="text-sm text-neutral-600 dark:text-neutral-100">
|
|
22
|
+
InsForge is running in the background — now head to your coding agent and create real
|
|
23
|
+
products.
|
|
24
|
+
</p>
|
|
25
|
+
</div>
|
|
26
|
+
<button
|
|
27
|
+
onClick={handleClose}
|
|
28
|
+
className="flex-shrink-0 absolute right-6 top-0 bottom-0"
|
|
29
|
+
aria-label="Close banner"
|
|
30
|
+
>
|
|
31
|
+
<X className="w-5 h-5 text-neutral-600 dark:text-neutral-400" />
|
|
32
|
+
</button>
|
|
33
|
+
</div>
|
|
34
|
+
);
|
|
35
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { ChevronRight, LayoutGrid } from 'lucide-react';
|
|
2
|
+
|
|
3
|
+
interface PromptCardProps {
|
|
4
|
+
title: string;
|
|
5
|
+
onClick?: () => void;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export function PromptCard({ title, onClick }: PromptCardProps) {
|
|
9
|
+
return (
|
|
10
|
+
<button
|
|
11
|
+
onClick={onClick}
|
|
12
|
+
className="bg-white dark:bg-[#363636] border border-gray-200 dark:border-[#414141] rounded px-6 py-4 flex items-center gap-3 hover:bg-gray-50 hover:border-gray-300 dark:hover:bg-neutral-700 dark:hover:border-[#525252] transition-all group"
|
|
13
|
+
>
|
|
14
|
+
<LayoutGrid className="w-6 h-6 text-zinc-700 dark:text-emerald-400 shrink-0" />
|
|
15
|
+
<p className="flex-1 text-base text-gray-900 dark:text-white font-normal leading-6 text-left truncate">
|
|
16
|
+
{title}
|
|
17
|
+
</p>
|
|
18
|
+
<ChevronRight className="w-5 h-5 text-gray-400 dark:text-neutral-400 shrink-0 group-hover:translate-x-0.5 transition-transform" />
|
|
19
|
+
</button>
|
|
20
|
+
);
|
|
21
|
+
}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import { Button, CopyButton, Dialog, DialogContent } from '@/components';
|
|
2
|
+
import { CheckCircle, Lock, Database, HardDrive, Code2, Box } from 'lucide-react';
|
|
3
|
+
import type { PromptTemplate } from '../prompts';
|
|
4
|
+
|
|
5
|
+
interface PromptDialogProps {
|
|
6
|
+
open: boolean;
|
|
7
|
+
onOpenChange: (open: boolean) => void;
|
|
8
|
+
promptTemplate: PromptTemplate | null;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
const featureIcons: Record<string, typeof Lock> = {
|
|
12
|
+
Authentication: Lock,
|
|
13
|
+
Database: Database,
|
|
14
|
+
Storage: HardDrive,
|
|
15
|
+
Functions: Code2,
|
|
16
|
+
'AI Integration': Box,
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
export function PromptDialog({ open, onOpenChange, promptTemplate }: PromptDialogProps) {
|
|
20
|
+
if (!promptTemplate) {
|
|
21
|
+
return null;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
return (
|
|
25
|
+
<Dialog open={open} onOpenChange={onOpenChange}>
|
|
26
|
+
<DialogContent className="max-w-2xl max-h-[90vh] p-0 bg-white dark:bg-neutral-800 border border-gray-200 dark:border-neutral-700 overflow-y-auto">
|
|
27
|
+
{/* Content area with border bottom */}
|
|
28
|
+
<div className="flex flex-col gap-10 p-6 border-b border-gray-200 dark:border-neutral-700">
|
|
29
|
+
{/* Header and Prompt Section */}
|
|
30
|
+
<div className="flex flex-col gap-6">
|
|
31
|
+
{/* Title */}
|
|
32
|
+
<div className="flex flex-col gap-3">
|
|
33
|
+
<h2 className="text-2xl font-semibold text-gray-900 dark:text-white tracking-[-0.144px] leading-8">
|
|
34
|
+
{promptTemplate.title}
|
|
35
|
+
</h2>
|
|
36
|
+
</div>
|
|
37
|
+
|
|
38
|
+
{/* Prompt Box */}
|
|
39
|
+
<div className="flex flex-col gap-3">
|
|
40
|
+
<p className="text-sm text-gray-500 dark:text-neutral-400 leading-6">
|
|
41
|
+
{promptTemplate.description}
|
|
42
|
+
</p>
|
|
43
|
+
<div className="bg-gray-50 dark:bg-neutral-900 rounded p-3 h-60 overflow-y-auto relative">
|
|
44
|
+
{/* Badge only */}
|
|
45
|
+
<div className="flex items-center justify-between mb-2">
|
|
46
|
+
<div className="bg-gray-200 dark:bg-neutral-700 rounded px-2 py-0 inline-flex items-center justify-center">
|
|
47
|
+
<span className="text-xs text-gray-900 dark:text-neutral-50 leading-5">
|
|
48
|
+
Prompt
|
|
49
|
+
</span>
|
|
50
|
+
</div>
|
|
51
|
+
</div>
|
|
52
|
+
{/* Prompt Text */}
|
|
53
|
+
<p className="text-sm text-gray-900 dark:text-white leading-6 whitespace-pre-wrap">
|
|
54
|
+
{promptTemplate.prompt}
|
|
55
|
+
</p>
|
|
56
|
+
</div>
|
|
57
|
+
</div>
|
|
58
|
+
</div>
|
|
59
|
+
|
|
60
|
+
{/* Features Section */}
|
|
61
|
+
<div className="flex flex-col gap-3">
|
|
62
|
+
<p className="text-sm text-gray-500 dark:text-neutral-400 leading-6">
|
|
63
|
+
Features included:
|
|
64
|
+
</p>
|
|
65
|
+
<div className="flex flex-col gap-1">
|
|
66
|
+
{promptTemplate.features.map((feature, index) => {
|
|
67
|
+
const Icon = featureIcons[feature] || Box;
|
|
68
|
+
return (
|
|
69
|
+
<div key={index} className="flex items-center gap-3 h-9 px-2 py-0">
|
|
70
|
+
<CheckCircle className="w-5 h-5 text-emerald-500 shrink-0" />
|
|
71
|
+
<Icon className="w-5 h-5 text-gray-500 dark:text-neutral-400 shrink-0" />
|
|
72
|
+
<p className="text-sm text-gray-900 dark:text-white font-medium leading-6">
|
|
73
|
+
{feature}
|
|
74
|
+
</p>
|
|
75
|
+
</div>
|
|
76
|
+
);
|
|
77
|
+
})}
|
|
78
|
+
</div>
|
|
79
|
+
</div>
|
|
80
|
+
</div>
|
|
81
|
+
|
|
82
|
+
{/* Footer */}
|
|
83
|
+
<div className="flex items-center justify-end gap-2.5 p-3">
|
|
84
|
+
<Button
|
|
85
|
+
onClick={() => onOpenChange(false)}
|
|
86
|
+
variant="secondary"
|
|
87
|
+
className="h-8 px-3 text-sm font-medium bg-gray-200 text-gray-900 hover:bg-gray-300 dark:bg-neutral-700 dark:text-white dark:hover:bg-neutral-600"
|
|
88
|
+
>
|
|
89
|
+
Cancel
|
|
90
|
+
</Button>
|
|
91
|
+
<CopyButton
|
|
92
|
+
text={promptTemplate.prompt}
|
|
93
|
+
showText={true}
|
|
94
|
+
variant="primary"
|
|
95
|
+
className="h-8 px-3 text-sm font-medium"
|
|
96
|
+
copyText="Copy Prompt"
|
|
97
|
+
copiedText="Copied!"
|
|
98
|
+
/>
|
|
99
|
+
</div>
|
|
100
|
+
</DialogContent>
|
|
101
|
+
</Dialog>
|
|
102
|
+
);
|
|
103
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { Card, CardContent, Skeleton } from '@/components';
|
|
2
|
+
import { LucideIcon } from 'lucide-react';
|
|
3
|
+
|
|
4
|
+
interface StatsCardProps {
|
|
5
|
+
icon: LucideIcon;
|
|
6
|
+
title: string;
|
|
7
|
+
value: string | number;
|
|
8
|
+
unit: string;
|
|
9
|
+
description: string;
|
|
10
|
+
isLoading?: boolean;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export function StatsCard({
|
|
14
|
+
icon: Icon,
|
|
15
|
+
title,
|
|
16
|
+
value,
|
|
17
|
+
unit,
|
|
18
|
+
description,
|
|
19
|
+
isLoading,
|
|
20
|
+
}: StatsCardProps) {
|
|
21
|
+
return (
|
|
22
|
+
<Card className="flex-1 bg-white dark:bg-[#333333] rounded-lg border border-gray-200 dark:border-neutral-700 shadow-[0px_1px_3px_0px_rgba(0,0,0,0.1)] h-full">
|
|
23
|
+
<CardContent className="px-8 py-6 h-full flex flex-col gap-6">
|
|
24
|
+
<div className="flex items-center gap-2 h-7">
|
|
25
|
+
<Icon className="w-5 h-5 text-gray-700 dark:text-neutral-400" />
|
|
26
|
+
<span className="text-base font-normal text-gray-900 dark:text-white">{title}</span>
|
|
27
|
+
</div>
|
|
28
|
+
|
|
29
|
+
<div className="flex flex-col gap-2">
|
|
30
|
+
{isLoading ? (
|
|
31
|
+
<Skeleton className="h-8 w-24 bg-gray-200 dark:bg-neutral-700" />
|
|
32
|
+
) : (
|
|
33
|
+
<p className="text-2xl font-normal text-gray-900 dark:text-white tracking-[-0.144px] leading-8">
|
|
34
|
+
{value}{' '}
|
|
35
|
+
<span className="text-sm font-normal text-gray-500 dark:text-neutral-400 leading-6">
|
|
36
|
+
{unit}
|
|
37
|
+
</span>
|
|
38
|
+
</p>
|
|
39
|
+
)}
|
|
40
|
+
|
|
41
|
+
{isLoading ? (
|
|
42
|
+
<Skeleton className="h-6 w-32 bg-gray-200 dark:bg-neutral-700" />
|
|
43
|
+
) : (
|
|
44
|
+
<p className="text-base text-gray-500 dark:text-neutral-400 leading-6">{description}</p>
|
|
45
|
+
)}
|
|
46
|
+
</div>
|
|
47
|
+
</CardContent>
|
|
48
|
+
</Card>
|
|
49
|
+
);
|
|
50
|
+
}
|