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
|
@@ -1,34 +1,35 @@
|
|
|
1
|
-
import { Lock, FormInput, Users } from 'lucide-react';
|
|
2
|
-
import
|
|
3
|
-
import GithubIcon from '@/assets/logos/github.svg';
|
|
1
|
+
import { Lock, FormInput, Users, Circle } from 'lucide-react';
|
|
2
|
+
import { Handle, Position } from '@xyflow/react';
|
|
4
3
|
import { AuthMetadataSchema } from '@insforge/shared-schemas';
|
|
5
4
|
import { cn } from '@/lib/utils/utils';
|
|
6
5
|
import { useOAuthConfig } from '@/features/auth/hooks/useOAuthConfig';
|
|
6
|
+
import { oauthProviders } from '@/features/auth/helpers';
|
|
7
7
|
|
|
8
8
|
interface AuthNodeProps {
|
|
9
9
|
data: {
|
|
10
10
|
authMetadata: AuthMetadataSchema;
|
|
11
11
|
userCount?: number;
|
|
12
|
+
isReferenced?: boolean; // Whether any tables have foreign keys to users.id
|
|
12
13
|
};
|
|
13
14
|
}
|
|
14
15
|
|
|
15
16
|
export function AuthNode({ data }: AuthNodeProps) {
|
|
16
|
-
const { authMetadata, userCount } = data;
|
|
17
|
+
const { authMetadata, userCount, isReferenced = false } = data;
|
|
17
18
|
const { isProviderConfigured } = useOAuthConfig();
|
|
18
19
|
|
|
19
|
-
const enabledCount = authMetadata.oauths.length;
|
|
20
|
+
const enabledCount = authMetadata.oauths.length + 1;
|
|
20
21
|
|
|
21
22
|
return (
|
|
22
|
-
<div className="bg-neutral-900 rounded-lg border border-[#363636] min-w-[280px]">
|
|
23
|
+
<div className="bg-white dark:bg-neutral-900 rounded-lg border border-gray-300 dark:border-[#363636] min-w-[280px] shadow-sm">
|
|
23
24
|
{/* Auth Header */}
|
|
24
|
-
<div className="flex items-center justify-between p-2 border-b border-neutral-800">
|
|
25
|
+
<div className="flex items-center justify-between p-2 border-b border-gray-200 dark:border-neutral-800">
|
|
25
26
|
<div className="flex items-center gap-2">
|
|
26
27
|
<div className="flex items-center justify-center w-11 h-11 bg-lime-300 rounded p-1.5">
|
|
27
28
|
<Lock className="w-5 h-5 text-neutral-900" />
|
|
28
29
|
</div>
|
|
29
30
|
<div className="flex-1">
|
|
30
|
-
<h3 className="text-sm font-medium text-white">Authentication</h3>
|
|
31
|
-
<p className="text-xs text-neutral-300">
|
|
31
|
+
<h3 className="text-sm font-medium text-zinc-950 dark:text-white">Authentication</h3>
|
|
32
|
+
<p className="text-xs text-zinc-600 dark:text-neutral-300">
|
|
32
33
|
{enabledCount} provider{enabledCount !== 1 ? 's' : ''} enabled
|
|
33
34
|
</p>
|
|
34
35
|
</div>
|
|
@@ -39,67 +40,82 @@ export function AuthNode({ data }: AuthNodeProps) {
|
|
|
39
40
|
</div>
|
|
40
41
|
|
|
41
42
|
{/* Auth Providers */}
|
|
42
|
-
<div className="p-2 space-y-2 border-b border-neutral-800">
|
|
43
|
+
<div className="p-2 space-y-2 border-b border-gray-200 dark:border-neutral-800">
|
|
43
44
|
{/* Email/Password */}
|
|
44
|
-
<div className="flex items-center justify-between p-2.5 bg-neutral-800 rounded">
|
|
45
|
+
<div className="flex items-center justify-between p-2.5 bg-gray-100 dark:bg-neutral-800 rounded">
|
|
45
46
|
<div className="flex items-center gap-2.5">
|
|
46
|
-
<FormInput className="w-5 h-5 text-neutral-300" />
|
|
47
|
-
<span className="text-sm text-neutral-300">Email/Password</span>
|
|
47
|
+
<FormInput className="w-5 h-5 text-zinc-700 dark:text-neutral-300" />
|
|
48
|
+
<span className="text-sm text-zinc-700 dark:text-neutral-300">Email/Password</span>
|
|
48
49
|
</div>
|
|
49
50
|
<div className="px-1.5 py-0.5 bg-lime-200 rounded flex items-center">
|
|
50
51
|
<span className="text-xs font-medium text-lime-900">Enabled</span>
|
|
51
52
|
</div>
|
|
52
53
|
</div>
|
|
53
54
|
|
|
54
|
-
{/*
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
<
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
className={cn(
|
|
82
|
-
'px-1.5 py-0.5 rounded flex items-center',
|
|
83
|
-
isProviderConfigured('github')
|
|
84
|
-
? 'bg-lime-200 text-lime-900'
|
|
85
|
-
: 'bg-neutral-700 text-neutral-300'
|
|
86
|
-
)}
|
|
87
|
-
>
|
|
88
|
-
<span className="text-xs font-medium">
|
|
89
|
-
{isProviderConfigured('github') ? 'Enabled' : 'Disabled'}
|
|
90
|
-
</span>
|
|
91
|
-
</div>
|
|
92
|
-
</div>
|
|
55
|
+
{/* OAuth Providers */}
|
|
56
|
+
{oauthProviders.map((provider) => {
|
|
57
|
+
const isEnabled = isProviderConfigured(provider.id);
|
|
58
|
+
return (
|
|
59
|
+
<div
|
|
60
|
+
key={provider.id}
|
|
61
|
+
className="flex items-center justify-between p-2.5 bg-gray-100 dark:bg-neutral-800 rounded"
|
|
62
|
+
>
|
|
63
|
+
<div className="flex items-center gap-2.5">
|
|
64
|
+
<div className="w-5 h-5 flex items-center justify-center [&>svg]:w-5 [&>svg]:h-5">
|
|
65
|
+
{provider.icon}
|
|
66
|
+
</div>
|
|
67
|
+
<span className="text-sm text-zinc-700 dark:text-neutral-300">{provider.name}</span>
|
|
68
|
+
</div>
|
|
69
|
+
<div
|
|
70
|
+
className={cn(
|
|
71
|
+
'px-1.5 py-0.5 rounded flex items-center',
|
|
72
|
+
isEnabled
|
|
73
|
+
? 'bg-lime-200 text-lime-900'
|
|
74
|
+
: 'bg-gray-200 dark:bg-neutral-700 text-gray-600 dark:text-neutral-300'
|
|
75
|
+
)}
|
|
76
|
+
>
|
|
77
|
+
<span className="text-xs font-medium">{isEnabled ? 'Enabled' : 'Disabled'}</span>
|
|
78
|
+
</div>
|
|
79
|
+
</div>
|
|
80
|
+
);
|
|
81
|
+
})}
|
|
93
82
|
</div>
|
|
94
83
|
|
|
95
84
|
{/* Users Section */}
|
|
96
|
-
<div className="flex items-center justify-between p-3 border-t border-neutral-700">
|
|
85
|
+
<div className="flex items-center justify-between p-3 border-t border-gray-300 dark:border-neutral-700 relative">
|
|
86
|
+
{/* Target handle for auth.id references - positioned at right bottom corner */}
|
|
87
|
+
<Handle
|
|
88
|
+
type="target"
|
|
89
|
+
position={Position.Right}
|
|
90
|
+
id="id-target"
|
|
91
|
+
className="!w-3 !h-3 !opacity-0 !border-0 !pointer-events-none"
|
|
92
|
+
style={{
|
|
93
|
+
right: 16,
|
|
94
|
+
bottom: 16,
|
|
95
|
+
top: 'auto',
|
|
96
|
+
transform: 'none',
|
|
97
|
+
pointerEvents: 'none',
|
|
98
|
+
}}
|
|
99
|
+
isConnectable={false}
|
|
100
|
+
/>
|
|
101
|
+
|
|
97
102
|
<div className="flex items-center gap-2.5">
|
|
98
|
-
<Users className="w-5 h-5 text-neutral-300" />
|
|
99
|
-
<span className="text-sm text-neutral-300">Users</span>
|
|
103
|
+
<Users className="w-5 h-5 text-zinc-700 dark:text-neutral-300" />
|
|
104
|
+
<span className="text-sm text-zinc-700 dark:text-neutral-300">Users</span>
|
|
105
|
+
<span className="text-xs text-zinc-500 dark:text-neutral-400">{userCount ?? 0}</span>
|
|
100
106
|
</div>
|
|
101
107
|
<div className="flex items-center">
|
|
102
|
-
{
|
|
108
|
+
{isReferenced ? (
|
|
109
|
+
<div className="w-5 h-5 flex items-center justify-center relative">
|
|
110
|
+
<Circle
|
|
111
|
+
className="w-5 h-5 text-zinc-950 dark:text-white fill-none stroke-current"
|
|
112
|
+
strokeWidth={1.5}
|
|
113
|
+
/>
|
|
114
|
+
<div className="w-2 h-2 bg-zinc-950 dark:bg-white rounded-full absolute" />
|
|
115
|
+
</div>
|
|
116
|
+
) : (
|
|
117
|
+
<Circle className="w-5 h-5 text-gray-400 dark:text-neutral-700 fill-gray-100 dark:fill-neutral-800 stroke-current" />
|
|
118
|
+
)}
|
|
103
119
|
</div>
|
|
104
120
|
</div>
|
|
105
121
|
</div>
|
|
@@ -11,16 +11,16 @@ export function BucketNode({ data }: BucketNodeProps) {
|
|
|
11
11
|
const { bucket } = data;
|
|
12
12
|
|
|
13
13
|
return (
|
|
14
|
-
<div className="bg-neutral-900 rounded-lg border border-[#363636] min-w-[320px]">
|
|
14
|
+
<div className="bg-white dark:bg-neutral-900 rounded-lg border border-gray-300 dark:border-[#363636] min-w-[320px] shadow-sm">
|
|
15
15
|
{/* Bucket Header */}
|
|
16
|
-
<div className="flex items-center justify-between p-2 border-b border-neutral-800">
|
|
16
|
+
<div className="flex items-center justify-between p-2 border-b border-gray-200 dark:border-neutral-800">
|
|
17
17
|
<div className="flex items-center gap-2">
|
|
18
18
|
<div className="flex items-center justify-center w-11 h-11 bg-blue-300 rounded p-1.5">
|
|
19
19
|
<HardDrive className="w-5 h-5 text-neutral-900" />
|
|
20
20
|
</div>
|
|
21
21
|
<div className="flex-1">
|
|
22
|
-
<h3 className="text-sm font-medium text-white">{bucket.name}</h3>
|
|
23
|
-
<p className="text-xs text-neutral-300">
|
|
22
|
+
<h3 className="text-sm font-medium text-zinc-950 dark:text-white">{bucket.name}</h3>
|
|
23
|
+
<p className="text-xs text-zinc-600 dark:text-neutral-300">
|
|
24
24
|
{bucket.objectCount ? `${bucket.objectCount} files` : '0 files'}
|
|
25
25
|
</p>
|
|
26
26
|
</div>
|
|
@@ -12,23 +12,32 @@ import {
|
|
|
12
12
|
ConnectionMode,
|
|
13
13
|
} from '@xyflow/react';
|
|
14
14
|
import '@xyflow/react/dist/style.css';
|
|
15
|
-
import { TableNode
|
|
15
|
+
import { TableNode } from './TableNode';
|
|
16
16
|
import { AuthNode } from './AuthNode';
|
|
17
17
|
import { BucketNode } from './BucketNode';
|
|
18
|
+
import { useTables } from '@/features/database/hooks/useTables';
|
|
19
|
+
import { useTheme } from '@/lib/contexts/ThemeContext';
|
|
18
20
|
import {
|
|
19
21
|
AppMetadataSchema,
|
|
20
22
|
StorageBucketSchema,
|
|
21
23
|
AuthMetadataSchema,
|
|
24
|
+
GetTableSchemaResponse,
|
|
22
25
|
} from '@insforge/shared-schemas';
|
|
23
26
|
|
|
24
27
|
interface SchemaVisualizerProps {
|
|
25
28
|
metadata: AppMetadataSchema;
|
|
26
29
|
userCount?: number;
|
|
30
|
+
// Optional external schemas for templates
|
|
31
|
+
externalSchemas?: GetTableSchemaResponse[];
|
|
32
|
+
// Control visibility of components
|
|
33
|
+
showControls?: boolean;
|
|
34
|
+
showMiniMap?: boolean;
|
|
27
35
|
}
|
|
28
36
|
|
|
29
37
|
type TableNodeData = {
|
|
30
|
-
table:
|
|
38
|
+
table: GetTableSchemaResponse;
|
|
31
39
|
referencedColumns: string[];
|
|
40
|
+
showRecordCount?: boolean;
|
|
32
41
|
};
|
|
33
42
|
|
|
34
43
|
type BucketNodeData = {
|
|
@@ -38,6 +47,7 @@ type BucketNodeData = {
|
|
|
38
47
|
type AuthNodeData = {
|
|
39
48
|
authMetadata: AuthMetadataSchema;
|
|
40
49
|
userCount?: number;
|
|
50
|
+
isReferenced?: boolean;
|
|
41
51
|
};
|
|
42
52
|
|
|
43
53
|
type CustomNodeData = TableNodeData | BucketNodeData | AuthNodeData;
|
|
@@ -119,7 +129,7 @@ const getLayoutedElements = (nodes: Node<CustomNodeData>[], edges: BuiltInEdge[]
|
|
|
119
129
|
|
|
120
130
|
// Position table nodes in a grid in the middle
|
|
121
131
|
let positionedTableNodes: Node<CustomNodeData>[] = [];
|
|
122
|
-
if (tableNodes.length
|
|
132
|
+
if (tableNodes.length) {
|
|
123
133
|
const cols = Math.ceil(Math.sqrt(tableNodes.length));
|
|
124
134
|
|
|
125
135
|
// Group tables by column for better height calculation
|
|
@@ -179,53 +189,20 @@ const getNodeColor = (node: Node<CustomNodeData>) => {
|
|
|
179
189
|
}
|
|
180
190
|
};
|
|
181
191
|
|
|
182
|
-
export function SchemaVisualizer({
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
tableData.indexes.forEach((index) => {
|
|
191
|
-
if (index.isPrimary) {
|
|
192
|
-
// Extract column names from index definition
|
|
193
|
-
const match = index.indexdef.match(/\(([^)]+)\)/);
|
|
194
|
-
if (match) {
|
|
195
|
-
match[1].split(',').forEach((col) => {
|
|
196
|
-
primaryKeyColumns.add(col.trim().replace(/"/g, ''));
|
|
197
|
-
});
|
|
198
|
-
}
|
|
199
|
-
}
|
|
200
|
-
});
|
|
201
|
-
|
|
202
|
-
// Transform columns from the new schema format
|
|
203
|
-
const columns = tableData.schema.map((col) => {
|
|
204
|
-
const column: VisualizerTableColumnSchema = {
|
|
205
|
-
columnName: col.columnName,
|
|
206
|
-
type: col.dataType.toLowerCase().substring(0, 4), // Truncate type to first 4 characters
|
|
207
|
-
isPrimaryKey: primaryKeyColumns.has(col.columnName),
|
|
208
|
-
};
|
|
209
|
-
|
|
210
|
-
// Find foreign key info for this column
|
|
211
|
-
const foreignKey = tableData.foreignKeys.find((fk) => fk.columnName === col.columnName);
|
|
212
|
-
if (foreignKey) {
|
|
213
|
-
column.foreignKey = {
|
|
214
|
-
referenceTable: foreignKey.foreignTableName,
|
|
215
|
-
referenceColumn: foreignKey.foreignColumnName,
|
|
216
|
-
};
|
|
217
|
-
}
|
|
192
|
+
export function SchemaVisualizer({
|
|
193
|
+
metadata,
|
|
194
|
+
userCount,
|
|
195
|
+
externalSchemas,
|
|
196
|
+
showControls = true,
|
|
197
|
+
showMiniMap = true,
|
|
198
|
+
}: SchemaVisualizerProps) {
|
|
199
|
+
const { resolvedTheme } = useTheme();
|
|
218
200
|
|
|
219
|
-
|
|
220
|
-
|
|
201
|
+
// Fetch all table schemas only if external schemas are not provided
|
|
202
|
+
const { allSchemas, isLoadingSchemas } = useTables();
|
|
221
203
|
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
columns,
|
|
225
|
-
recordCount: tableData.recordCount ?? 0, // Use actual record count from metadata
|
|
226
|
-
};
|
|
227
|
-
});
|
|
228
|
-
}, [metadata.database.tables]);
|
|
204
|
+
// Use external schemas if provided, otherwise use fetched schemas
|
|
205
|
+
const tables = externalSchemas || allSchemas;
|
|
229
206
|
|
|
230
207
|
const initialNodes = useMemo(() => {
|
|
231
208
|
// First, collect all referenced columns for each table
|
|
@@ -254,19 +231,32 @@ export function SchemaVisualizer({ metadata, userCount }: SchemaVisualizerProps)
|
|
|
254
231
|
data: {
|
|
255
232
|
table,
|
|
256
233
|
referencedColumns: referencedColumnsByTable[table.tableName] || [],
|
|
234
|
+
showRecordCount: !externalSchemas, // Hide record count when using external schemas (template preview)
|
|
257
235
|
},
|
|
258
236
|
}));
|
|
259
237
|
|
|
238
|
+
const nodes: Node<CustomNodeData>[] = [...tableNodes];
|
|
239
|
+
|
|
240
|
+
// Add bucket nodes
|
|
260
241
|
const bucketNodes: Node<BucketNodeData>[] = metadata.storage.buckets.map((bucket) => ({
|
|
261
242
|
id: `bucket-${bucket.name}`,
|
|
262
243
|
type: 'bucketNode',
|
|
263
244
|
position: { x: 0, y: 0 },
|
|
264
245
|
data: { bucket },
|
|
265
246
|
}));
|
|
247
|
+
nodes.push(...bucketNodes);
|
|
248
|
+
|
|
249
|
+
// Check if any tables reference users.id
|
|
250
|
+
const isUsersReferenced = tables.some((table) =>
|
|
251
|
+
table.columns.some(
|
|
252
|
+
(column) =>
|
|
253
|
+
column.foreignKey &&
|
|
254
|
+
column.foreignKey.referenceTable === 'users' &&
|
|
255
|
+
column.foreignKey.referenceColumn === 'id'
|
|
256
|
+
)
|
|
257
|
+
);
|
|
266
258
|
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
// Add authentication node if authData is provided
|
|
259
|
+
// Add authentication node
|
|
270
260
|
nodes.push({
|
|
271
261
|
id: 'authentication',
|
|
272
262
|
type: 'authNode',
|
|
@@ -274,41 +264,66 @@ export function SchemaVisualizer({ metadata, userCount }: SchemaVisualizerProps)
|
|
|
274
264
|
data: {
|
|
275
265
|
authMetadata: metadata.auth,
|
|
276
266
|
userCount,
|
|
267
|
+
isReferenced: isUsersReferenced,
|
|
277
268
|
},
|
|
278
269
|
});
|
|
279
270
|
|
|
280
271
|
return nodes;
|
|
281
|
-
}, [metadata,
|
|
272
|
+
}, [tables, metadata, externalSchemas, userCount]);
|
|
282
273
|
|
|
283
274
|
const initialEdges = useMemo(() => {
|
|
284
275
|
const edges: BuiltInEdge[] = [];
|
|
276
|
+
const edgeColor = resolvedTheme === 'dark' ? 'white' : '#18181b'; // zinc-950 for light mode
|
|
285
277
|
|
|
286
278
|
tables.forEach((table) => {
|
|
287
279
|
table.columns.forEach((column) => {
|
|
288
280
|
if (column.foreignKey) {
|
|
281
|
+
// Check if this is a reference to users.id
|
|
282
|
+
const isAuthReference =
|
|
283
|
+
column.foreignKey.referenceTable === 'users' &&
|
|
284
|
+
column.foreignKey.referenceColumn === 'id';
|
|
285
|
+
|
|
289
286
|
const edgeId = `${table.tableName}-${column.columnName}-${column.foreignKey.referenceTable}`;
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
287
|
+
|
|
288
|
+
if (isAuthReference) {
|
|
289
|
+
// Connect to the authentication node
|
|
290
|
+
edges.push({
|
|
291
|
+
id: edgeId,
|
|
292
|
+
source: table.tableName,
|
|
293
|
+
target: 'authentication',
|
|
294
|
+
sourceHandle: `${column.columnName}-source`,
|
|
295
|
+
targetHandle: 'id-target',
|
|
296
|
+
type: 'smoothstep',
|
|
297
|
+
animated: true,
|
|
298
|
+
style: { stroke: edgeColor, strokeWidth: 2, zIndex: 1000 },
|
|
299
|
+
zIndex: 1000,
|
|
300
|
+
pathOptions: {
|
|
301
|
+
offset: 40,
|
|
302
|
+
},
|
|
303
|
+
});
|
|
304
|
+
} else {
|
|
305
|
+
// Regular table-to-table edge
|
|
306
|
+
edges.push({
|
|
307
|
+
id: edgeId,
|
|
308
|
+
source: table.tableName,
|
|
309
|
+
target: column.foreignKey.referenceTable,
|
|
310
|
+
sourceHandle: `${column.columnName}-source`,
|
|
311
|
+
targetHandle: `${column.foreignKey.referenceColumn}-target`,
|
|
312
|
+
type: 'smoothstep',
|
|
313
|
+
animated: true,
|
|
314
|
+
style: { stroke: edgeColor, strokeWidth: 2, zIndex: 1000 },
|
|
315
|
+
zIndex: 1000,
|
|
316
|
+
pathOptions: {
|
|
317
|
+
offset: 40,
|
|
318
|
+
},
|
|
319
|
+
});
|
|
320
|
+
}
|
|
304
321
|
}
|
|
305
322
|
});
|
|
306
323
|
});
|
|
307
324
|
|
|
308
|
-
// Add authentication edges if authData exists
|
|
309
|
-
|
|
310
325
|
return edges;
|
|
311
|
-
}, [tables]);
|
|
326
|
+
}, [tables, resolvedTheme]);
|
|
312
327
|
|
|
313
328
|
const { nodes: layoutedNodes, edges: layoutedEdges } = useMemo(
|
|
314
329
|
() => getLayoutedElements(initialNodes, initialEdges),
|
|
@@ -319,15 +334,26 @@ export function SchemaVisualizer({ metadata, userCount }: SchemaVisualizerProps)
|
|
|
319
334
|
const [edges, setEdges, onEdgesChange] = useEdgesState(layoutedEdges);
|
|
320
335
|
|
|
321
336
|
useEffect(() => {
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
337
|
+
if (!isLoadingSchemas) {
|
|
338
|
+
setNodes(layoutedNodes);
|
|
339
|
+
setEdges(layoutedEdges);
|
|
340
|
+
}
|
|
341
|
+
}, [layoutedNodes, layoutedEdges, isLoadingSchemas, setNodes, setEdges]);
|
|
325
342
|
|
|
326
343
|
const onConnect = useCallback(
|
|
327
344
|
(params: Connection) => setEdges((eds) => addEdge(params, eds)),
|
|
328
345
|
[setEdges]
|
|
329
346
|
);
|
|
330
347
|
|
|
348
|
+
// Don't render ReactFlow until data is loaded (only if not using external schemas)
|
|
349
|
+
if (!externalSchemas && isLoadingSchemas) {
|
|
350
|
+
return (
|
|
351
|
+
<div className="w-full h-full flex items-center justify-center text-white">
|
|
352
|
+
Loading schemas...
|
|
353
|
+
</div>
|
|
354
|
+
);
|
|
355
|
+
}
|
|
356
|
+
|
|
331
357
|
return (
|
|
332
358
|
<div className="w-full h-full">
|
|
333
359
|
<ReactFlow
|
|
@@ -339,20 +365,22 @@ export function SchemaVisualizer({ metadata, userCount }: SchemaVisualizerProps)
|
|
|
339
365
|
nodeTypes={nodeTypes}
|
|
340
366
|
connectionMode={ConnectionMode.Loose}
|
|
341
367
|
fitView
|
|
342
|
-
fitViewOptions={{ padding: 1, maxZoom: 2, minZoom:
|
|
368
|
+
fitViewOptions={{ padding: 1, maxZoom: 2, minZoom: 0.8 }}
|
|
343
369
|
minZoom={0.1}
|
|
344
370
|
maxZoom={2}
|
|
345
371
|
proOptions={{ hideAttribution: true }}
|
|
346
372
|
elevateEdgesOnSelect={true}
|
|
347
|
-
colorMode=
|
|
373
|
+
colorMode={resolvedTheme === 'dark' ? 'dark' : 'light'}
|
|
348
374
|
className="!bg-transparent"
|
|
349
375
|
>
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
376
|
+
{showControls && (
|
|
377
|
+
<Controls
|
|
378
|
+
showInteractive={false}
|
|
379
|
+
className="!border !border-neutral-700 !shadow-lg"
|
|
380
|
+
fitViewOptions={{ padding: 1, duration: 300, maxZoom: 2, minZoom: 1 }}
|
|
381
|
+
/>
|
|
382
|
+
)}
|
|
383
|
+
{showMiniMap && <MiniMap nodeColor={(node: Node<CustomNodeData>) => getNodeColor(node)} />}
|
|
356
384
|
</ReactFlow>
|
|
357
385
|
</div>
|
|
358
386
|
);
|
|
@@ -1,32 +1,17 @@
|
|
|
1
1
|
import { Database, Circle, Key } from 'lucide-react';
|
|
2
2
|
import { Handle, Position } from '@xyflow/react';
|
|
3
|
-
|
|
4
|
-
// Define the table structure expected by this component
|
|
5
|
-
export interface VisualizerTableColumnSchema {
|
|
6
|
-
columnName: string;
|
|
7
|
-
type: string;
|
|
8
|
-
isPrimaryKey?: boolean;
|
|
9
|
-
foreignKey?: {
|
|
10
|
-
referenceTable: string;
|
|
11
|
-
referenceColumn: string;
|
|
12
|
-
};
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
export interface VisualizerTableSchema {
|
|
16
|
-
tableName: string;
|
|
17
|
-
columns: VisualizerTableColumnSchema[];
|
|
18
|
-
recordCount?: number;
|
|
19
|
-
}
|
|
3
|
+
import { TableSchema } from '@insforge/shared-schemas';
|
|
20
4
|
|
|
21
5
|
interface TableNodeProps {
|
|
22
6
|
data: {
|
|
23
|
-
table:
|
|
7
|
+
table: TableSchema;
|
|
24
8
|
referencedColumns?: string[]; // List of column names that are referenced by other tables
|
|
9
|
+
showRecordCount?: boolean; // Control whether to show record count
|
|
25
10
|
};
|
|
26
11
|
}
|
|
27
12
|
|
|
28
13
|
export function TableNode({ data }: TableNodeProps) {
|
|
29
|
-
const { table, referencedColumns = [] } = data;
|
|
14
|
+
const { table, referencedColumns = [], showRecordCount = true } = data;
|
|
30
15
|
|
|
31
16
|
const getColumnIcon = (isReferenced: boolean = false) => {
|
|
32
17
|
// If column is referenced by another table (has incoming connections)
|
|
@@ -35,35 +20,37 @@ export function TableNode({ data }: TableNodeProps) {
|
|
|
35
20
|
return (
|
|
36
21
|
<div className="w-4 h-4 flex items-center justify-center relative">
|
|
37
22
|
{/* Outer gray diamond */}
|
|
38
|
-
<div className="w-4 h-4 bg-neutral-800 border border-white absolute transform rotate-45" />
|
|
23
|
+
<div className="w-4 h-4 bg-gray-200 dark:bg-neutral-800 border border-zinc-950 dark:border-white absolute transform rotate-45" />
|
|
39
24
|
{/* Inner white diamond */}
|
|
40
|
-
<div className="w-2 h-2 bg-white absolute transform rotate-45" />
|
|
25
|
+
<div className="w-2 h-2 bg-zinc-950 dark:bg-white absolute transform rotate-45" />
|
|
41
26
|
</div>
|
|
42
27
|
);
|
|
43
28
|
}
|
|
44
29
|
return (
|
|
45
30
|
<div className="w-4 h-4 flex items-center justify-center relative">
|
|
46
31
|
{/* Outer gray diamond */}
|
|
47
|
-
<div className="w-4 h-4 bg-neutral-800 border border-neutral-700 absolute transform rotate-45" />
|
|
32
|
+
<div className="w-4 h-4 bg-gray-200 dark:bg-neutral-800 border border-gray-400 dark:border-neutral-700 absolute transform rotate-45" />
|
|
48
33
|
</div>
|
|
49
34
|
);
|
|
50
35
|
};
|
|
51
36
|
|
|
52
37
|
return (
|
|
53
|
-
<div className="bg-neutral-900 rounded-lg border border-[#363636] min-w-[320px]">
|
|
38
|
+
<div className="bg-white dark:bg-neutral-900 rounded-lg border border-gray-300 dark:border-[#363636] min-w-[320px] shadow-sm">
|
|
54
39
|
{/* Table Header */}
|
|
55
|
-
<div className="flex items-center justify-between p-2 border-b border-neutral-800">
|
|
40
|
+
<div className="flex items-center justify-between p-2 border-b border-gray-200 dark:border-neutral-800">
|
|
56
41
|
<div className="flex items-center gap-2">
|
|
57
42
|
<div className="flex items-center justify-center w-11 h-11 bg-teal-300 rounded p-1.5">
|
|
58
43
|
<Database className="w-5 h-5 text-neutral-900" />
|
|
59
44
|
</div>
|
|
60
45
|
<div className="flex-1">
|
|
61
|
-
<h3 className="text-sm font-medium text-white">{table.tableName}</h3>
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
46
|
+
<h3 className="text-sm font-medium text-zinc-950 dark:text-white">{table.tableName}</h3>
|
|
47
|
+
{showRecordCount && (
|
|
48
|
+
<p className="text-xs text-zinc-600 dark:text-neutral-300">
|
|
49
|
+
{table.recordCount !== undefined
|
|
50
|
+
? `${table.recordCount.toLocaleString()} data`
|
|
51
|
+
: '0 data'}
|
|
52
|
+
</p>
|
|
53
|
+
)}
|
|
67
54
|
</div>
|
|
68
55
|
</div>
|
|
69
56
|
{/* <div className="p-1.5">
|
|
@@ -76,7 +63,7 @@ export function TableNode({ data }: TableNodeProps) {
|
|
|
76
63
|
{table.columns.map((column) => (
|
|
77
64
|
<div
|
|
78
65
|
key={column.columnName}
|
|
79
|
-
className="flex items-center justify-between p-3 border-b border-neutral-800 relative"
|
|
66
|
+
className="flex items-center justify-between p-3 border-b border-gray-200 dark:border-neutral-800 relative"
|
|
80
67
|
>
|
|
81
68
|
{/* Source handle for foreign key columns - invisible and non-interactive */}
|
|
82
69
|
{column.foreignKey && (
|
|
@@ -114,35 +101,41 @@ export function TableNode({ data }: TableNodeProps) {
|
|
|
114
101
|
|
|
115
102
|
<div className="flex items-center gap-2.5 flex-1">
|
|
116
103
|
{getColumnIcon(referencedColumns.includes(column.columnName))}
|
|
117
|
-
<span className="text-sm text-neutral-300">
|
|
118
|
-
|
|
104
|
+
<span className="text-sm text-zinc-700 dark:text-neutral-300">
|
|
105
|
+
{column.columnName}
|
|
106
|
+
</span>
|
|
107
|
+
{column.isPrimaryKey && (
|
|
108
|
+
<Key className="w-3 h-3 text-zinc-500 dark:text-neutral-400" />
|
|
109
|
+
)}
|
|
119
110
|
</div>
|
|
120
111
|
<div className="flex items-center gap-2.5">
|
|
121
|
-
<div className="px-1.5 py-0.5 bg-neutral-800 rounded flex items-center">
|
|
122
|
-
<span className="text-xs font-medium text-neutral-300">
|
|
112
|
+
<div className="px-1.5 py-0.5 bg-gray-100 dark:bg-neutral-800 rounded flex items-center">
|
|
113
|
+
<span className="text-xs font-medium text-zinc-700 dark:text-neutral-300">
|
|
114
|
+
{column.type}
|
|
115
|
+
</span>
|
|
123
116
|
</div>
|
|
124
117
|
{/* Show white dot with outer circle for foreign key columns, gray circle for others */}
|
|
125
118
|
{column.foreignKey ? (
|
|
126
119
|
<div className="w-5 h-5 flex items-center justify-center relative">
|
|
127
120
|
<Circle
|
|
128
|
-
className="w-5 h-5 text-white fill-none stroke-current"
|
|
121
|
+
className="w-5 h-5 text-zinc-950 dark:text-white fill-none stroke-current"
|
|
129
122
|
strokeWidth={1.5}
|
|
130
123
|
/>
|
|
131
|
-
<div className="w-2 h-2 bg-white rounded-full absolute" />
|
|
124
|
+
<div className="w-2 h-2 bg-zinc-950 dark:bg-white rounded-full absolute" />
|
|
132
125
|
</div>
|
|
133
126
|
) : (
|
|
134
|
-
<Circle className="w-5 h-5 text-neutral-700 fill-neutral-800 stroke-current" />
|
|
127
|
+
<Circle className="w-5 h-5 text-gray-400 dark:text-neutral-700 fill-gray-100 dark:fill-neutral-800 stroke-current" />
|
|
135
128
|
)}
|
|
136
129
|
</div>
|
|
137
130
|
</div>
|
|
138
131
|
))}
|
|
139
132
|
|
|
140
133
|
{/* Empty state */}
|
|
141
|
-
{table.columns.length
|
|
134
|
+
{!table.columns.length && (
|
|
142
135
|
<div className="flex items-center justify-center p-6">
|
|
143
136
|
<div className="text-center">
|
|
144
|
-
<Database className="w-6 h-6 text-neutral-600 mx-auto mb-2" />
|
|
145
|
-
<p className="text-xs text-neutral-500">No columns defined</p>
|
|
137
|
+
<Database className="w-6 h-6 text-gray-400 dark:text-neutral-600 mx-auto mb-2" />
|
|
138
|
+
<p className="text-xs text-gray-500 dark:text-neutral-500">No columns defined</p>
|
|
146
139
|
</div>
|
|
147
140
|
</div>
|
|
148
141
|
)}
|