insforge 1.3.0 → 1.4.8
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/CHANGELOG.md +2 -0
- package/auth/package.json +5 -3
- package/auth/src/lib/broadcastService.ts +115 -117
- package/auth/src/lib/insforge.ts +8 -0
- package/auth/src/main.tsx +2 -4
- package/auth/src/pages/SignInPage.tsx +60 -60
- package/auth/src/pages/SignUpPage.tsx +60 -60
- package/auth/src/pages/VerifyEmailPage.tsx +18 -0
- package/auth/tsconfig.json +2 -1
- package/backend/package.json +10 -6
- package/backend/src/api/middlewares/rate-limiters.ts +127 -127
- package/backend/src/api/routes/ai/index.routes.ts +475 -468
- package/backend/src/api/routes/auth/index.routes.ts +85 -32
- package/backend/src/api/routes/auth/oauth.routes.ts +11 -6
- package/backend/src/api/routes/database/index.routes.ts +2 -0
- package/backend/src/api/routes/database/records.routes.ts +39 -175
- package/backend/src/api/routes/database/rpc.routes.ts +69 -0
- package/backend/src/api/routes/deployments/index.routes.ts +192 -0
- package/backend/src/api/routes/docs/index.routes.ts +3 -2
- package/backend/src/api/routes/email/index.routes.ts +35 -35
- package/backend/src/api/routes/functions/index.routes.ts +3 -3
- package/backend/src/api/routes/metadata/index.routes.ts +26 -0
- package/backend/src/api/routes/webhooks/index.routes.ts +109 -0
- package/backend/src/infra/database/database.manager.ts +0 -10
- package/backend/src/infra/database/migrations/018_schema-rework.sql +441 -0
- package/backend/src/infra/database/migrations/019_create-deployments-table.sql +36 -0
- package/backend/src/infra/database/migrations/020_add-audio-modality.sql +11 -0
- package/backend/src/infra/database/migrations/bootstrap/bootstrap-migrations.js +103 -0
- package/backend/src/infra/security/token.manager.ts +1 -4
- package/backend/src/providers/ai/openrouter.provider.ts +12 -3
- package/backend/src/providers/database/base.provider.ts +39 -0
- package/backend/src/providers/database/cloud.provider.ts +159 -0
- package/backend/src/providers/deployments/vercel.provider.ts +516 -0
- package/backend/src/server.ts +19 -7
- package/backend/src/services/ai/ai-config.service.ts +6 -6
- package/backend/src/services/ai/ai-model.service.ts +60 -60
- package/backend/src/services/ai/ai-usage.service.ts +7 -7
- package/backend/src/services/ai/chat-completion.service.ts +415 -220
- package/backend/src/services/ai/helpers.ts +64 -64
- package/backend/src/services/ai/index.ts +13 -13
- package/backend/src/services/auth/auth-config.service.ts +4 -4
- package/backend/src/services/auth/auth-otp.service.ts +6 -6
- package/backend/src/services/auth/auth.service.ts +134 -74
- package/backend/src/services/auth/index.ts +4 -4
- package/backend/src/services/auth/oauth-config.service.ts +12 -12
- package/backend/src/services/database/database-advance.service.ts +19 -55
- package/backend/src/services/database/database-table.service.ts +38 -85
- package/backend/src/services/database/postgrest-proxy.service.ts +165 -0
- package/backend/src/services/deployments/deployment.service.ts +693 -0
- package/backend/src/services/functions/function.service.ts +61 -41
- package/backend/src/services/logs/audit.service.ts +10 -10
- package/backend/src/services/secrets/secret.service.ts +101 -27
- package/backend/src/services/storage/storage.service.ts +30 -30
- package/backend/src/services/usage/usage.service.ts +6 -6
- package/backend/src/types/ai.ts +8 -0
- package/backend/src/types/auth.ts +5 -1
- package/backend/src/types/database.ts +2 -0
- package/backend/src/types/deployments.ts +33 -0
- package/backend/src/types/storage.ts +1 -1
- package/backend/src/types/webhooks.ts +45 -0
- package/backend/src/utils/cookies.ts +34 -35
- package/backend/src/utils/environment.ts +0 -14
- package/backend/src/utils/s3-config-loader.ts +64 -64
- package/backend/src/utils/seed.ts +334 -301
- package/backend/src/utils/sql-parser.ts +126 -0
- package/backend/src/utils/utils.ts +114 -114
- package/backend/src/utils/validations.ts +10 -10
- package/backend/tests/local/test-rpc.sh +141 -0
- package/backend/tests/local/test-secrets.sh +1 -1
- package/backend/tests/manual/test-ai-model-plugins.sh +258 -0
- package/backend/tests/manual/test-rawsql-modes.sh +24 -24
- package/backend/tests/unit/database-advance.test.ts +326 -0
- package/backend/tests/unit/helpers.test.ts +2 -2
- package/claude-plugin/skills/insforge-schema-patterns/SKILL.md +13 -10
- package/docker-compose.prod.yml +1 -1
- package/docker-compose.yml +1 -1
- package/docs/agent-docs/deployment.md +79 -0
- package/docs/changelog.mdx +165 -72
- package/docs/core-concepts/ai/architecture.mdx +1 -23
- package/docs/core-concepts/ai/sdk.mdx +26 -1
- package/docs/core-concepts/authentication/architecture.mdx +6 -8
- package/docs/core-concepts/authentication/sdk.mdx +387 -91
- package/docs/core-concepts/authentication/ui-components/customization.mdx +460 -256
- package/docs/core-concepts/authentication/ui-components/nextjs.mdx +50 -24
- package/docs/core-concepts/authentication/ui-components/react-router.mdx +18 -19
- package/docs/core-concepts/authentication/ui-components/react.mdx +26 -19
- package/docs/core-concepts/database/architecture.mdx +58 -21
- package/docs/core-concepts/database/pgvector.mdx +138 -0
- package/docs/core-concepts/database/sdk.mdx +17 -17
- package/docs/core-concepts/deployments/architecture.mdx +152 -0
- package/docs/core-concepts/email/architecture.mdx +4 -2
- package/docs/core-concepts/functions/architecture.mdx +1 -1
- package/docs/core-concepts/functions/sdk.mdx +0 -1
- package/docs/core-concepts/realtime/architecture.mdx +1 -1
- package/docs/core-concepts/storage/architecture.mdx +1 -1
- package/docs/core-concepts/storage/sdk.mdx +25 -25
- package/docs/docs.json +14 -6
- package/docs/favicon.png +0 -0
- package/docs/favicon.svg +3 -18
- package/docs/images/changelog/dec-2025/apple-oauth.mp4 +0 -0
- package/docs/images/changelog/dec-2025/moreModels.png +0 -0
- package/docs/images/changelog/dec-2025/multi-region.webp +0 -0
- package/docs/images/changelog/dec-2025/postgres-connection.webp +0 -0
- package/docs/images/changelog/dec-2025/realtime2.png +0 -0
- package/docs/images/mcp-setup/CC-MCP-1.mp4 +0 -0
- package/docs/images/mcp-setup/CC-MCP-2.mp4 +0 -0
- package/docs/images/mcp-setup/Cursor-MCP-1.mp4 +0 -0
- package/docs/images/mcp-setup/Cursor-MCP-2.mp4 +0 -0
- package/docs/images/mcp-setup/Cursor-MCP-3.mp4 +0 -0
- package/docs/images/mcp-setup/claude-code-connect.png +0 -0
- package/docs/images/mcp-setup/cline-1.png +0 -0
- package/docs/images/mcp-setup/cline-2.png +0 -0
- package/docs/images/mcp-setup/cline-3.png +0 -0
- package/docs/images/mcp-setup/connect-project.png +0 -0
- package/docs/images/mcp-setup/copilot-1.png +0 -0
- package/docs/images/mcp-setup/copilot-2.png +0 -0
- package/docs/images/mcp-setup/copilot-3.png +0 -0
- package/docs/images/mcp-setup/mcp-json-1.png +0 -0
- package/docs/images/mcp-setup/mcp-json-2.png +0 -0
- package/docs/images/mcp-setup/qoder-1.png +0 -0
- package/docs/images/mcp-setup/qoder-2.png +0 -0
- package/docs/images/mcp-setup/roocode-1.png +0 -0
- package/docs/images/mcp-setup/roocode-2.png +0 -0
- package/docs/images/mcp-setup/trae-1.png +0 -0
- package/docs/images/mcp-setup/trae-2.png +0 -0
- package/docs/images/mcp-setup/trae-3.png +0 -0
- package/docs/images/mcp-setup/trae-4.png +0 -0
- package/docs/images/mcp-setup/trae-5.png +0 -0
- package/docs/images/mcp-setup/windsurf-1.png +0 -0
- package/docs/images/mcp-setup/windsurf-2.png +0 -0
- package/docs/insforge-instructions-sdk.md +7 -3
- package/docs/introduction.mdx +9 -8
- package/docs/mcp-setup.mdx +332 -0
- package/docs/oauth-server.mdx +563 -0
- package/docs/partnership.mdx +79 -10
- package/docs/quickstart.mdx +1 -1
- package/docs/vscode-extension.mdx +74 -0
- package/eslint.config.js +1 -0
- package/examples/response-examples.md +1 -1
- package/frontend/package.json +1 -1
- package/frontend/src/App.tsx +8 -3
- package/frontend/src/assets/logos/antigravity.svg +1 -0
- package/frontend/src/assets/logos/copilot.svg +10 -0
- package/frontend/src/assets/logos/deepseek.svg +139 -0
- package/frontend/src/assets/logos/kiro.svg +9 -0
- package/frontend/src/assets/logos/qoder.svg +4 -0
- package/frontend/src/assets/logos/qwen.svg +15 -0
- package/frontend/src/components/CodeBlock.tsx +2 -2
- package/frontend/src/components/ConnectCTA.tsx +3 -2
- package/frontend/src/components/datagrid/DataGrid.tsx +90 -62
- package/frontend/src/components/datagrid/datagridTypes.tsx +2 -1
- package/frontend/src/components/datagrid/index.ts +1 -1
- package/frontend/src/components/index.ts +0 -1
- package/frontend/src/components/layout/AppHeader.tsx +4 -27
- package/frontend/src/components/layout/AppSidebar.tsx +85 -100
- package/frontend/src/components/layout/Layout.tsx +34 -32
- package/frontend/src/components/layout/PrimaryMenu.tsx +12 -4
- package/frontend/src/components/radix/Select.tsx +151 -151
- package/frontend/src/features/ai/components/AIConfigCard.tsx +200 -200
- package/frontend/src/features/ai/components/AIEmptyState.tsx +23 -23
- package/frontend/src/features/ai/components/ModalityFilterSidebar.tsx +102 -101
- package/frontend/src/features/ai/components/ModelSelectionDialog.tsx +135 -135
- package/frontend/src/features/ai/components/ModelSelectionGrid.tsx +51 -51
- package/frontend/src/features/ai/components/SystemPromptDialog.tsx +118 -118
- package/frontend/src/features/ai/components/index.ts +6 -6
- package/frontend/src/features/ai/helpers.ts +147 -141
- package/frontend/src/features/ai/pages/AIPage.tsx +166 -166
- package/frontend/src/features/auth/components/AuthPreview.tsx +96 -96
- package/frontend/src/features/auth/components/UsersDataGrid.tsx +55 -31
- package/frontend/src/features/auth/components/index.ts +5 -5
- package/frontend/src/features/auth/pages/AuthMethodsPage.tsx +275 -275
- package/frontend/src/features/dashboard/pages/DashboardPage.tsx +1 -1
- package/frontend/src/features/database/components/DatabaseDataGrid.tsx +0 -2
- package/frontend/src/features/database/components/ForeignKeyCell.tsx +38 -11
- package/frontend/src/features/database/components/ForeignKeyPopover.tsx +18 -8
- package/frontend/src/features/database/components/LinkRecordModal.tsx +61 -13
- package/frontend/src/features/database/components/RecordFormField.tsx +1 -1
- package/frontend/src/features/database/components/TableSidebar.tsx +0 -3
- package/frontend/src/features/database/components/TablesEmptyState.tsx +1 -1
- package/frontend/src/features/database/components/TemplatePreview.tsx +1 -2
- package/frontend/src/features/database/constants.ts +16 -28
- package/frontend/src/features/database/hooks/useCSVImport.ts +3 -2
- package/frontend/src/features/database/hooks/useRawSQL.ts +3 -2
- package/frontend/src/features/database/hooks/useTables.ts +5 -7
- package/frontend/src/features/database/pages/FunctionsPage.tsx +0 -5
- package/frontend/src/features/database/pages/IndexesPage.tsx +0 -5
- package/frontend/src/features/database/pages/PoliciesPage.tsx +0 -5
- package/frontend/src/features/database/pages/SQLEditorPage.tsx +2 -2
- package/frontend/src/features/database/pages/TriggersPage.tsx +0 -5
- package/frontend/src/features/database/services/advance.service.ts +1 -15
- package/frontend/src/features/database/services/record.service.ts +4 -20
- package/frontend/src/features/database/services/table.service.ts +1 -4
- package/frontend/src/features/database/templates/ai-chatbot.ts +6 -6
- package/frontend/src/features/database/templates/ecommerce-platform.ts +2 -2
- package/frontend/src/features/database/templates/instagram-clone.ts +10 -10
- package/frontend/src/features/database/templates/notion-clone.ts +8 -8
- package/frontend/src/features/database/templates/reddit-clone.ts +10 -10
- package/frontend/src/features/deployments/components/DeploymentRow.tsx +93 -0
- package/frontend/src/features/deployments/components/DeploymentsEmptyState.tsx +15 -0
- package/frontend/src/features/deployments/hooks/useDeployments.ts +157 -0
- package/frontend/src/features/deployments/pages/DeploymentsPage.tsx +318 -0
- package/frontend/src/features/deployments/services/deployments.service.ts +63 -0
- package/frontend/src/features/functions/components/FunctionRow.tsx +72 -72
- package/frontend/src/features/functions/components/FunctionsSidebar.tsx +56 -56
- package/frontend/src/features/functions/components/SecretRow.tsx +3 -3
- package/frontend/src/features/functions/components/index.ts +5 -5
- package/frontend/src/features/functions/hooks/useFunctions.ts +5 -4
- package/frontend/src/features/functions/hooks/useSecrets.ts +6 -9
- package/frontend/src/features/functions/pages/SecretsPage.tsx +118 -118
- package/frontend/src/features/functions/services/function.service.ts +8 -25
- package/frontend/src/features/functions/services/secret.service.ts +23 -41
- package/frontend/src/features/login/pages/CloudLoginPage.tsx +125 -118
- package/frontend/src/features/logs/components/LogDetailPanel.tsx +41 -0
- package/frontend/src/features/logs/components/LogsDataGrid.tsx +32 -1
- package/frontend/src/features/logs/components/index.ts +1 -0
- package/frontend/src/features/logs/pages/LogsPage.tsx +36 -6
- package/frontend/src/features/onboard/components/ApiCredentialsSection.tsx +59 -0
- package/frontend/src/features/onboard/components/ConnectionStringSection.tsx +180 -0
- package/frontend/src/features/onboard/components/McpConnectionSection.tsx +159 -0
- package/frontend/src/features/onboard/components/OnboardingController.tsx +68 -0
- package/frontend/src/features/onboard/components/OnboardingModal.tsx +121 -267
- package/frontend/src/features/onboard/components/ShowPasswordButton.tsx +21 -0
- package/frontend/src/features/onboard/components/index.ts +9 -4
- package/frontend/src/features/onboard/components/mcp/CursorDeeplinkGenerator.tsx +1 -1
- package/frontend/src/features/onboard/components/mcp/QoderDeeplinkGenerator.tsx +36 -0
- package/frontend/src/features/onboard/components/mcp/helpers.tsx +123 -98
- package/frontend/src/features/onboard/components/mcp/index.ts +4 -3
- package/frontend/src/features/onboard/index.ts +17 -13
- package/frontend/src/features/settings/pages/SettingsPage.tsx +349 -0
- package/frontend/src/features/visualizer/components/AuthNode.tsx +4 -4
- package/frontend/src/features/visualizer/components/SchemaVisualizer.tsx +21 -8
- package/frontend/src/features/visualizer/pages/VisualizerPage.tsx +10 -1
- package/frontend/src/index.css +249 -249
- package/frontend/src/lib/contexts/ModalContext.tsx +35 -0
- package/frontend/src/lib/hooks/useMetadata.ts +45 -1
- package/frontend/src/lib/hooks/useModal.tsx +2 -0
- package/frontend/src/lib/routing/AppRoutes.tsx +103 -99
- package/frontend/src/lib/services/metadata.service.ts +20 -3
- package/frontend/src/lib/utils/menuItems.ts +223 -207
- package/frontend/src/lib/utils/utils.ts +196 -196
- package/functions/server.ts +315 -315
- package/functions/worker-template.js +1 -1
- package/openapi/ai.yaml +115 -5
- package/openapi/auth.yaml +97 -17
- package/openapi/logs.yaml +0 -2
- package/openapi/metadata.yaml +0 -2
- package/openapi/records.yaml +21 -21
- package/openapi/tables.yaml +1 -2
- package/package.json +1 -1
- package/shared-schemas/package.json +1 -1
- package/shared-schemas/src/ai-api.schema.ts +251 -143
- package/shared-schemas/src/ai.schema.ts +63 -63
- package/shared-schemas/src/auth-api.schema.ts +34 -6
- package/shared-schemas/src/auth.schema.ts +17 -10
- package/shared-schemas/src/cloud-events.schema.ts +26 -0
- package/shared-schemas/src/deployments-api.schema.ts +55 -0
- package/shared-schemas/src/deployments.schema.ts +30 -0
- package/shared-schemas/src/docs.schema.ts +8 -2
- package/shared-schemas/src/email-api.schema.ts +30 -30
- package/shared-schemas/src/functions-api.schema.ts +13 -4
- package/shared-schemas/src/functions.schema.ts +1 -1
- package/shared-schemas/src/index.ts +22 -18
- package/shared-schemas/src/metadata.schema.ts +30 -4
- package/shared-schemas/src/secrets-api.schema.ts +44 -0
- package/shared-schemas/src/secrets.schema.ts +15 -0
- package/zeabur/README.md +13 -0
- package/zeabur/template.yml +20 -51
- package/backend/src/types/profile.ts +0 -55
- package/frontend/src/components/ProjectInfoModal.tsx +0 -128
|
@@ -94,7 +94,7 @@ export const ecommercePlatformTemplate: DatabaseTemplate = {
|
|
|
94
94
|
isNullable: false,
|
|
95
95
|
isUnique: true,
|
|
96
96
|
foreignKey: {
|
|
97
|
-
referenceTable: 'users',
|
|
97
|
+
referenceTable: 'auth.users',
|
|
98
98
|
referenceColumn: 'id',
|
|
99
99
|
onDelete: 'CASCADE',
|
|
100
100
|
onUpdate: 'CASCADE',
|
|
@@ -340,7 +340,7 @@ CREATE TABLE products (
|
|
|
340
340
|
-- Customers table (extends users with customer-specific data)
|
|
341
341
|
CREATE TABLE customers (
|
|
342
342
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
343
|
-
user_id UUID UNIQUE NOT NULL REFERENCES users(id) ON UPDATE CASCADE ON DELETE CASCADE,
|
|
343
|
+
user_id UUID UNIQUE NOT NULL REFERENCES auth.users(id) ON UPDATE CASCADE ON DELETE CASCADE,
|
|
344
344
|
first_name VARCHAR(100) NOT NULL,
|
|
345
345
|
last_name VARCHAR(100) NOT NULL,
|
|
346
346
|
phone VARCHAR(50),
|
|
@@ -17,7 +17,7 @@ export const instagramCloneTemplate: DatabaseTemplate = {
|
|
|
17
17
|
isNullable: false,
|
|
18
18
|
isUnique: false,
|
|
19
19
|
foreignKey: {
|
|
20
|
-
referenceTable: 'users',
|
|
20
|
+
referenceTable: 'auth.users',
|
|
21
21
|
referenceColumn: 'id',
|
|
22
22
|
onDelete: 'CASCADE',
|
|
23
23
|
onUpdate: 'CASCADE',
|
|
@@ -70,7 +70,7 @@ export const instagramCloneTemplate: DatabaseTemplate = {
|
|
|
70
70
|
isNullable: false,
|
|
71
71
|
isUnique: false,
|
|
72
72
|
foreignKey: {
|
|
73
|
-
referenceTable: 'users',
|
|
73
|
+
referenceTable: 'auth.users',
|
|
74
74
|
referenceColumn: 'id',
|
|
75
75
|
onDelete: 'CASCADE',
|
|
76
76
|
onUpdate: 'CASCADE',
|
|
@@ -103,7 +103,7 @@ export const instagramCloneTemplate: DatabaseTemplate = {
|
|
|
103
103
|
isNullable: false,
|
|
104
104
|
isUnique: false,
|
|
105
105
|
foreignKey: {
|
|
106
|
-
referenceTable: 'users',
|
|
106
|
+
referenceTable: 'auth.users',
|
|
107
107
|
referenceColumn: 'id',
|
|
108
108
|
onDelete: 'CASCADE',
|
|
109
109
|
onUpdate: 'CASCADE',
|
|
@@ -142,7 +142,7 @@ export const instagramCloneTemplate: DatabaseTemplate = {
|
|
|
142
142
|
isNullable: false,
|
|
143
143
|
isUnique: false,
|
|
144
144
|
foreignKey: {
|
|
145
|
-
referenceTable: 'users',
|
|
145
|
+
referenceTable: 'auth.users',
|
|
146
146
|
referenceColumn: 'id',
|
|
147
147
|
onDelete: 'CASCADE',
|
|
148
148
|
onUpdate: 'CASCADE',
|
|
@@ -155,7 +155,7 @@ export const instagramCloneTemplate: DatabaseTemplate = {
|
|
|
155
155
|
isNullable: false,
|
|
156
156
|
isUnique: false,
|
|
157
157
|
foreignKey: {
|
|
158
|
-
referenceTable: 'users',
|
|
158
|
+
referenceTable: 'auth.users',
|
|
159
159
|
referenceColumn: 'id',
|
|
160
160
|
onDelete: 'CASCADE',
|
|
161
161
|
onUpdate: 'CASCADE',
|
|
@@ -176,7 +176,7 @@ export const instagramCloneTemplate: DatabaseTemplate = {
|
|
|
176
176
|
-- Posts table
|
|
177
177
|
CREATE TABLE posts (
|
|
178
178
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
179
|
-
user_id UUID NOT NULL REFERENCES users(id) ON UPDATE CASCADE ON DELETE CASCADE,
|
|
179
|
+
user_id UUID NOT NULL REFERENCES auth.users(id) ON UPDATE CASCADE ON DELETE CASCADE,
|
|
180
180
|
image_url VARCHAR(500) NOT NULL,
|
|
181
181
|
caption TEXT,
|
|
182
182
|
created_at TIMESTAMP DEFAULT NOW()
|
|
@@ -186,7 +186,7 @@ CREATE TABLE posts (
|
|
|
186
186
|
CREATE TABLE comments (
|
|
187
187
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
188
188
|
post_id UUID NOT NULL REFERENCES posts(id) ON UPDATE CASCADE ON DELETE CASCADE,
|
|
189
|
-
user_id UUID NOT NULL REFERENCES users(id) ON UPDATE CASCADE ON DELETE CASCADE,
|
|
189
|
+
user_id UUID NOT NULL REFERENCES auth.users(id) ON UPDATE CASCADE ON DELETE CASCADE,
|
|
190
190
|
content TEXT NOT NULL,
|
|
191
191
|
created_at TIMESTAMP DEFAULT NOW()
|
|
192
192
|
);
|
|
@@ -194,7 +194,7 @@ CREATE TABLE comments (
|
|
|
194
194
|
-- Likes table
|
|
195
195
|
CREATE TABLE likes (
|
|
196
196
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
197
|
-
user_id UUID NOT NULL REFERENCES users(id) ON UPDATE CASCADE ON DELETE CASCADE,
|
|
197
|
+
user_id UUID NOT NULL REFERENCES auth.users(id) ON UPDATE CASCADE ON DELETE CASCADE,
|
|
198
198
|
post_id UUID NOT NULL REFERENCES posts(id) ON UPDATE CASCADE ON DELETE CASCADE,
|
|
199
199
|
created_at TIMESTAMP DEFAULT NOW(),
|
|
200
200
|
UNIQUE(user_id, post_id)
|
|
@@ -203,8 +203,8 @@ CREATE TABLE likes (
|
|
|
203
203
|
-- Follows table
|
|
204
204
|
CREATE TABLE follows (
|
|
205
205
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
206
|
-
follower_id UUID NOT NULL REFERENCES users(id) ON UPDATE CASCADE ON DELETE CASCADE,
|
|
207
|
-
following_id UUID NOT NULL REFERENCES users(id) ON UPDATE CASCADE ON DELETE CASCADE,
|
|
206
|
+
follower_id UUID NOT NULL REFERENCES auth.users(id) ON UPDATE CASCADE ON DELETE CASCADE,
|
|
207
|
+
following_id UUID NOT NULL REFERENCES auth.users(id) ON UPDATE CASCADE ON DELETE CASCADE,
|
|
208
208
|
created_at TIMESTAMP DEFAULT NOW(),
|
|
209
209
|
UNIQUE(follower_id, following_id),
|
|
210
210
|
CHECK (follower_id != following_id)
|
|
@@ -24,7 +24,7 @@ export const notionCloneTemplate: DatabaseTemplate = {
|
|
|
24
24
|
isNullable: false,
|
|
25
25
|
isUnique: false,
|
|
26
26
|
foreignKey: {
|
|
27
|
-
referenceTable: 'users',
|
|
27
|
+
referenceTable: 'auth.users',
|
|
28
28
|
referenceColumn: 'id',
|
|
29
29
|
onDelete: 'CASCADE',
|
|
30
30
|
onUpdate: 'CASCADE',
|
|
@@ -90,7 +90,7 @@ export const notionCloneTemplate: DatabaseTemplate = {
|
|
|
90
90
|
isNullable: false,
|
|
91
91
|
isUnique: false,
|
|
92
92
|
foreignKey: {
|
|
93
|
-
referenceTable: 'users',
|
|
93
|
+
referenceTable: 'auth.users',
|
|
94
94
|
referenceColumn: 'id',
|
|
95
95
|
onDelete: 'CASCADE',
|
|
96
96
|
onUpdate: 'CASCADE',
|
|
@@ -178,7 +178,7 @@ export const notionCloneTemplate: DatabaseTemplate = {
|
|
|
178
178
|
isNullable: false,
|
|
179
179
|
isUnique: false,
|
|
180
180
|
foreignKey: {
|
|
181
|
-
referenceTable: 'users',
|
|
181
|
+
referenceTable: 'auth.users',
|
|
182
182
|
referenceColumn: 'id',
|
|
183
183
|
onDelete: 'CASCADE',
|
|
184
184
|
onUpdate: 'CASCADE',
|
|
@@ -224,7 +224,7 @@ export const notionCloneTemplate: DatabaseTemplate = {
|
|
|
224
224
|
isNullable: false,
|
|
225
225
|
isUnique: false,
|
|
226
226
|
foreignKey: {
|
|
227
|
-
referenceTable: 'users',
|
|
227
|
+
referenceTable: 'auth.users',
|
|
228
228
|
referenceColumn: 'id',
|
|
229
229
|
onDelete: 'CASCADE',
|
|
230
230
|
onUpdate: 'CASCADE',
|
|
@@ -275,7 +275,7 @@ export const notionCloneTemplate: DatabaseTemplate = {
|
|
|
275
275
|
CREATE TABLE workspaces (
|
|
276
276
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
277
277
|
name VARCHAR(200) NOT NULL,
|
|
278
|
-
owner_id UUID NOT NULL REFERENCES users(id) ON UPDATE CASCADE ON DELETE CASCADE,
|
|
278
|
+
owner_id UUID NOT NULL REFERENCES auth.users(id) ON UPDATE CASCADE ON DELETE CASCADE,
|
|
279
279
|
icon VARCHAR(100),
|
|
280
280
|
created_at TIMESTAMP DEFAULT NOW(),
|
|
281
281
|
updated_at TIMESTAMP DEFAULT NOW()
|
|
@@ -286,7 +286,7 @@ CREATE TABLE pages (
|
|
|
286
286
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
287
287
|
workspace_id UUID NOT NULL REFERENCES workspaces(id) ON UPDATE CASCADE ON DELETE CASCADE,
|
|
288
288
|
parent_page_id UUID REFERENCES pages(id) ON UPDATE CASCADE ON DELETE CASCADE,
|
|
289
|
-
creator_id UUID NOT NULL REFERENCES users(id) ON UPDATE CASCADE ON DELETE CASCADE,
|
|
289
|
+
creator_id UUID NOT NULL REFERENCES auth.users(id) ON UPDATE CASCADE ON DELETE CASCADE,
|
|
290
290
|
title VARCHAR(500) NOT NULL CHECK (LENGTH(TRIM(title)) > 0),
|
|
291
291
|
content TEXT,
|
|
292
292
|
icon VARCHAR(100),
|
|
@@ -301,7 +301,7 @@ CREATE TABLE pages (
|
|
|
301
301
|
CREATE TABLE page_shares (
|
|
302
302
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
303
303
|
page_id UUID NOT NULL REFERENCES pages(id) ON UPDATE CASCADE ON DELETE CASCADE,
|
|
304
|
-
user_id UUID NOT NULL REFERENCES users(id) ON UPDATE CASCADE ON DELETE CASCADE,
|
|
304
|
+
user_id UUID NOT NULL REFERENCES auth.users(id) ON UPDATE CASCADE ON DELETE CASCADE,
|
|
305
305
|
permission VARCHAR(20) NOT NULL CHECK (permission IN ('view', 'edit', 'admin')),
|
|
306
306
|
created_at TIMESTAMP DEFAULT NOW(),
|
|
307
307
|
UNIQUE(page_id, user_id)
|
|
@@ -311,7 +311,7 @@ CREATE TABLE page_shares (
|
|
|
311
311
|
CREATE TABLE attachments (
|
|
312
312
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
313
313
|
page_id UUID NOT NULL REFERENCES pages(id) ON UPDATE CASCADE ON DELETE CASCADE,
|
|
314
|
-
user_id UUID NOT NULL REFERENCES users(id) ON UPDATE CASCADE ON DELETE CASCADE,
|
|
314
|
+
user_id UUID NOT NULL REFERENCES auth.users(id) ON UPDATE CASCADE ON DELETE CASCADE,
|
|
315
315
|
file_name VARCHAR(255) NOT NULL,
|
|
316
316
|
file_url VARCHAR(500) NOT NULL,
|
|
317
317
|
file_size INTEGER,
|
|
@@ -38,7 +38,7 @@ export const redditCloneTemplate: DatabaseTemplate = {
|
|
|
38
38
|
isNullable: false,
|
|
39
39
|
isUnique: false,
|
|
40
40
|
foreignKey: {
|
|
41
|
-
referenceTable: 'users',
|
|
41
|
+
referenceTable: 'auth.users',
|
|
42
42
|
referenceColumn: 'id',
|
|
43
43
|
onDelete: 'CASCADE',
|
|
44
44
|
onUpdate: 'CASCADE',
|
|
@@ -91,7 +91,7 @@ export const redditCloneTemplate: DatabaseTemplate = {
|
|
|
91
91
|
isNullable: false,
|
|
92
92
|
isUnique: false,
|
|
93
93
|
foreignKey: {
|
|
94
|
-
referenceTable: 'users',
|
|
94
|
+
referenceTable: 'auth.users',
|
|
95
95
|
referenceColumn: 'id',
|
|
96
96
|
onDelete: 'CASCADE',
|
|
97
97
|
onUpdate: 'CASCADE',
|
|
@@ -172,7 +172,7 @@ export const redditCloneTemplate: DatabaseTemplate = {
|
|
|
172
172
|
isNullable: false,
|
|
173
173
|
isUnique: false,
|
|
174
174
|
foreignKey: {
|
|
175
|
-
referenceTable: 'users',
|
|
175
|
+
referenceTable: 'auth.users',
|
|
176
176
|
referenceColumn: 'id',
|
|
177
177
|
onDelete: 'CASCADE',
|
|
178
178
|
onUpdate: 'CASCADE',
|
|
@@ -232,7 +232,7 @@ export const redditCloneTemplate: DatabaseTemplate = {
|
|
|
232
232
|
isNullable: false,
|
|
233
233
|
isUnique: false,
|
|
234
234
|
foreignKey: {
|
|
235
|
-
referenceTable: 'users',
|
|
235
|
+
referenceTable: 'auth.users',
|
|
236
236
|
referenceColumn: 'id',
|
|
237
237
|
onDelete: 'CASCADE',
|
|
238
238
|
onUpdate: 'CASCADE',
|
|
@@ -304,7 +304,7 @@ export const redditCloneTemplate: DatabaseTemplate = {
|
|
|
304
304
|
isNullable: false,
|
|
305
305
|
isUnique: false,
|
|
306
306
|
foreignKey: {
|
|
307
|
-
referenceTable: 'users',
|
|
307
|
+
referenceTable: 'auth.users',
|
|
308
308
|
referenceColumn: 'id',
|
|
309
309
|
onDelete: 'CASCADE',
|
|
310
310
|
onUpdate: 'CASCADE',
|
|
@@ -336,7 +336,7 @@ CREATE TABLE communities (
|
|
|
336
336
|
name VARCHAR(100) UNIQUE NOT NULL CHECK (name ~ '^[a-zA-Z0-9_]+$'),
|
|
337
337
|
display_name VARCHAR(200) NOT NULL,
|
|
338
338
|
description TEXT,
|
|
339
|
-
creator_id UUID NOT NULL REFERENCES users(id) ON UPDATE CASCADE ON DELETE CASCADE,
|
|
339
|
+
creator_id UUID NOT NULL REFERENCES auth.users(id) ON UPDATE CASCADE ON DELETE CASCADE,
|
|
340
340
|
is_active BOOLEAN DEFAULT true,
|
|
341
341
|
created_at TIMESTAMP DEFAULT NOW(),
|
|
342
342
|
updated_at TIMESTAMP DEFAULT NOW()
|
|
@@ -346,7 +346,7 @@ CREATE TABLE communities (
|
|
|
346
346
|
CREATE TABLE posts (
|
|
347
347
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
348
348
|
community_id UUID NOT NULL REFERENCES communities(id) ON UPDATE CASCADE ON DELETE CASCADE,
|
|
349
|
-
user_id UUID NOT NULL REFERENCES users(id) ON UPDATE CASCADE ON DELETE CASCADE,
|
|
349
|
+
user_id UUID NOT NULL REFERENCES auth.users(id) ON UPDATE CASCADE ON DELETE CASCADE,
|
|
350
350
|
title VARCHAR(300) NOT NULL CHECK (LENGTH(TRIM(title)) > 0),
|
|
351
351
|
content TEXT,
|
|
352
352
|
link_url VARCHAR(500),
|
|
@@ -365,7 +365,7 @@ CREATE TABLE posts (
|
|
|
365
365
|
CREATE TABLE comments (
|
|
366
366
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
367
367
|
post_id UUID NOT NULL REFERENCES posts(id) ON UPDATE CASCADE ON DELETE CASCADE,
|
|
368
|
-
user_id UUID NOT NULL REFERENCES users(id) ON UPDATE CASCADE ON DELETE CASCADE,
|
|
368
|
+
user_id UUID NOT NULL REFERENCES auth.users(id) ON UPDATE CASCADE ON DELETE CASCADE,
|
|
369
369
|
parent_comment_id UUID REFERENCES comments(id) ON UPDATE CASCADE ON DELETE CASCADE,
|
|
370
370
|
content TEXT NOT NULL CHECK (LENGTH(TRIM(content)) > 0),
|
|
371
371
|
is_active BOOLEAN DEFAULT true,
|
|
@@ -376,7 +376,7 @@ CREATE TABLE comments (
|
|
|
376
376
|
-- Votes table (for both posts and comments)
|
|
377
377
|
CREATE TABLE votes (
|
|
378
378
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
379
|
-
user_id UUID NOT NULL REFERENCES users(id) ON UPDATE CASCADE ON DELETE CASCADE,
|
|
379
|
+
user_id UUID NOT NULL REFERENCES auth.users(id) ON UPDATE CASCADE ON DELETE CASCADE,
|
|
380
380
|
post_id UUID REFERENCES posts(id) ON UPDATE CASCADE ON DELETE CASCADE,
|
|
381
381
|
comment_id UUID REFERENCES comments(id) ON UPDATE CASCADE ON DELETE CASCADE,
|
|
382
382
|
vote_type INTEGER NOT NULL CHECK (vote_type IN (-1, 1)),
|
|
@@ -393,7 +393,7 @@ CREATE TABLE votes (
|
|
|
393
393
|
CREATE TABLE community_members (
|
|
394
394
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
395
395
|
community_id UUID NOT NULL REFERENCES communities(id) ON UPDATE CASCADE ON DELETE CASCADE,
|
|
396
|
-
user_id UUID NOT NULL REFERENCES users(id) ON UPDATE CASCADE ON DELETE CASCADE,
|
|
396
|
+
user_id UUID NOT NULL REFERENCES auth.users(id) ON UPDATE CASCADE ON DELETE CASCADE,
|
|
397
397
|
role VARCHAR(20) NOT NULL DEFAULT 'member' CHECK (role IN ('member', 'moderator', 'admin')),
|
|
398
398
|
created_at TIMESTAMP DEFAULT NOW(),
|
|
399
399
|
UNIQUE(community_id, user_id)
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import { cn, formatTime } from '@/lib/utils/utils';
|
|
2
|
+
import type { DeploymentSchema } from '../services/deployments.service';
|
|
3
|
+
|
|
4
|
+
interface DeploymentRowProps {
|
|
5
|
+
deployment: DeploymentSchema;
|
|
6
|
+
onClick: () => void;
|
|
7
|
+
className?: string;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
const statusColors: Record<string, string> = {
|
|
11
|
+
WAITING: 'bg-yellow-600',
|
|
12
|
+
UPLOADING: 'bg-blue-600',
|
|
13
|
+
QUEUED: 'bg-purple-600',
|
|
14
|
+
BUILDING: 'bg-sky-600',
|
|
15
|
+
READY: 'bg-green-600',
|
|
16
|
+
ERROR: 'bg-red-600',
|
|
17
|
+
CANCELED: 'bg-gray-500',
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
export function DeploymentRow({ deployment, onClick, className }: DeploymentRowProps) {
|
|
21
|
+
const statusColor = statusColors[deployment.status] || 'bg-gray-500';
|
|
22
|
+
|
|
23
|
+
return (
|
|
24
|
+
<div
|
|
25
|
+
className={cn(
|
|
26
|
+
'group h-14 px-3 bg-white hover:bg-neutral-100 dark:bg-[#333333] dark:hover:bg-neutral-700 rounded-[8px] transition-all cursor-pointer',
|
|
27
|
+
className
|
|
28
|
+
)}
|
|
29
|
+
onClick={onClick}
|
|
30
|
+
>
|
|
31
|
+
<div className="grid grid-cols-12 h-full items-center">
|
|
32
|
+
{/* ID Column */}
|
|
33
|
+
<div className="col-span-3 min-w-0 px-3 py-1.5">
|
|
34
|
+
<p
|
|
35
|
+
className="text-sm text-zinc-950 dark:text-white truncate font-mono"
|
|
36
|
+
title={deployment.id}
|
|
37
|
+
>
|
|
38
|
+
{deployment.id}
|
|
39
|
+
</p>
|
|
40
|
+
</div>
|
|
41
|
+
|
|
42
|
+
{/* Status Column */}
|
|
43
|
+
<div className="col-span-2 px-3 py-1.5">
|
|
44
|
+
<span
|
|
45
|
+
className={cn(
|
|
46
|
+
'inline-flex items-center justify-center h-5 px-2 rounded-sm text-xs font-medium text-white',
|
|
47
|
+
statusColor
|
|
48
|
+
)}
|
|
49
|
+
>
|
|
50
|
+
{deployment.status}
|
|
51
|
+
</span>
|
|
52
|
+
</div>
|
|
53
|
+
|
|
54
|
+
{/* Provider Column */}
|
|
55
|
+
<div className="col-span-2 min-w-0 px-3 py-1.5">
|
|
56
|
+
<span className="text-sm text-muted-foreground dark:text-neutral-400 capitalize">
|
|
57
|
+
{deployment.provider}
|
|
58
|
+
</span>
|
|
59
|
+
</div>
|
|
60
|
+
|
|
61
|
+
{/* URL Column */}
|
|
62
|
+
<div className="col-span-3 min-w-0 px-3 py-1.5">
|
|
63
|
+
{deployment.url ? (
|
|
64
|
+
<a
|
|
65
|
+
href={
|
|
66
|
+
deployment.url.startsWith('http') ? deployment.url : `https://${deployment.url}`
|
|
67
|
+
}
|
|
68
|
+
target="_blank"
|
|
69
|
+
rel="noopener noreferrer"
|
|
70
|
+
className="text-sm text-blue-600 dark:text-blue-400 hover:underline truncate block"
|
|
71
|
+
onClick={(e) => e.stopPropagation()}
|
|
72
|
+
title={deployment.url}
|
|
73
|
+
>
|
|
74
|
+
{deployment.url}
|
|
75
|
+
</a>
|
|
76
|
+
) : (
|
|
77
|
+
<span className="text-sm text-muted-foreground dark:text-neutral-400">—</span>
|
|
78
|
+
)}
|
|
79
|
+
</div>
|
|
80
|
+
|
|
81
|
+
{/* Created Column */}
|
|
82
|
+
<div className="col-span-2 px-3 py-1.5">
|
|
83
|
+
<span
|
|
84
|
+
className="text-sm text-muted-foreground dark:text-neutral-400 truncate"
|
|
85
|
+
title={deployment.createdAt}
|
|
86
|
+
>
|
|
87
|
+
{formatTime(deployment.createdAt)}
|
|
88
|
+
</span>
|
|
89
|
+
</div>
|
|
90
|
+
</div>
|
|
91
|
+
</div>
|
|
92
|
+
);
|
|
93
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { Rocket } from 'lucide-react';
|
|
2
|
+
|
|
3
|
+
export default function DeploymentsEmptyState() {
|
|
4
|
+
return (
|
|
5
|
+
<div className="flex flex-col items-center justify-center py-8 text-center gap-3 rounded-[8px] bg-neutral-100 dark:bg-[#333333]">
|
|
6
|
+
<Rocket size={40} className="text-neutral-400 dark:text-neutral-600" />
|
|
7
|
+
<div className="flex flex-col items-center justify-center gap-1">
|
|
8
|
+
<p className="text-sm font-medium text-zinc-950 dark:text-white">No deployments yet</p>
|
|
9
|
+
<p className="text-neutral-500 dark:text-neutral-400 text-xs">
|
|
10
|
+
Deployments will appear here when you deploy your application
|
|
11
|
+
</p>
|
|
12
|
+
</div>
|
|
13
|
+
</div>
|
|
14
|
+
);
|
|
15
|
+
}
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
import { useState, useCallback } from 'react';
|
|
2
|
+
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
|
|
3
|
+
import { deploymentsService, type DeploymentSchema } from '../services/deployments.service';
|
|
4
|
+
import { useToast } from '@/lib/hooks/useToast';
|
|
5
|
+
import type { StartDeploymentRequest } from '@insforge/shared-schemas';
|
|
6
|
+
|
|
7
|
+
export function useDeployments() {
|
|
8
|
+
const queryClient = useQueryClient();
|
|
9
|
+
const { showToast } = useToast();
|
|
10
|
+
const [selectedDeployment, setSelectedDeployment] = useState<DeploymentSchema | null>(null);
|
|
11
|
+
|
|
12
|
+
// ============================================================================
|
|
13
|
+
// Pagination State
|
|
14
|
+
// ============================================================================
|
|
15
|
+
|
|
16
|
+
const [paginationParams, setPaginationParams] = useState({
|
|
17
|
+
limit: 50,
|
|
18
|
+
offset: 0,
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
// ============================================================================
|
|
22
|
+
// Deployments Query
|
|
23
|
+
// ============================================================================
|
|
24
|
+
|
|
25
|
+
const {
|
|
26
|
+
data: deploymentsData,
|
|
27
|
+
isLoading: isLoadingDeployments,
|
|
28
|
+
error: deploymentsError,
|
|
29
|
+
refetch: refetchDeployments,
|
|
30
|
+
} = useQuery({
|
|
31
|
+
queryKey: ['deployments', paginationParams],
|
|
32
|
+
queryFn: () =>
|
|
33
|
+
deploymentsService.listDeployments(paginationParams.limit, paginationParams.offset),
|
|
34
|
+
staleTime: 30 * 1000, // 30 seconds - deployments status can change
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
const deployments = deploymentsData?.data ?? [];
|
|
38
|
+
const totalDeployments = deploymentsData?.pagination?.total ?? 0;
|
|
39
|
+
|
|
40
|
+
// ============================================================================
|
|
41
|
+
// Mutations
|
|
42
|
+
// ============================================================================
|
|
43
|
+
|
|
44
|
+
const createDeploymentMutation = useMutation({
|
|
45
|
+
mutationFn: () => deploymentsService.createDeployment(),
|
|
46
|
+
onSuccess: () => {
|
|
47
|
+
void queryClient.invalidateQueries({ queryKey: ['deployments'] });
|
|
48
|
+
showToast('Deployment created successfully', 'success');
|
|
49
|
+
},
|
|
50
|
+
onError: (error: Error) => {
|
|
51
|
+
showToast(error.message || 'Failed to create deployment', 'error');
|
|
52
|
+
},
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
const startDeploymentMutation = useMutation({
|
|
56
|
+
mutationFn: ({ id, data }: { id: string; data?: StartDeploymentRequest }) =>
|
|
57
|
+
deploymentsService.startDeployment(id, data),
|
|
58
|
+
onSuccess: () => {
|
|
59
|
+
void queryClient.invalidateQueries({ queryKey: ['deployments'] });
|
|
60
|
+
showToast('Deployment started successfully', 'success');
|
|
61
|
+
},
|
|
62
|
+
onError: (error: Error) => {
|
|
63
|
+
showToast(error.message || 'Failed to start deployment', 'error');
|
|
64
|
+
},
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
const syncDeploymentMutation = useMutation({
|
|
68
|
+
mutationFn: (id: string) => deploymentsService.syncDeployment(id),
|
|
69
|
+
onSuccess: (updatedDeployment) => {
|
|
70
|
+
void queryClient.invalidateQueries({ queryKey: ['deployments'] });
|
|
71
|
+
// Update selected deployment if it's the one being synced
|
|
72
|
+
if (selectedDeployment?.id === updatedDeployment.id) {
|
|
73
|
+
setSelectedDeployment(updatedDeployment);
|
|
74
|
+
}
|
|
75
|
+
showToast('Deployment synced successfully', 'success');
|
|
76
|
+
},
|
|
77
|
+
onError: (error: Error) => {
|
|
78
|
+
showToast(error.message || 'Failed to sync deployment', 'error');
|
|
79
|
+
},
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
const cancelDeploymentMutation = useMutation({
|
|
83
|
+
mutationFn: (id: string) => deploymentsService.cancelDeployment(id),
|
|
84
|
+
onSuccess: (_, id) => {
|
|
85
|
+
void queryClient.invalidateQueries({ queryKey: ['deployments'] });
|
|
86
|
+
showToast('Deployment cancelled successfully', 'success');
|
|
87
|
+
if (selectedDeployment?.id === id) {
|
|
88
|
+
setSelectedDeployment(null);
|
|
89
|
+
}
|
|
90
|
+
},
|
|
91
|
+
onError: (error: Error) => {
|
|
92
|
+
showToast(error.message || 'Failed to cancel deployment', 'error');
|
|
93
|
+
},
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
// ============================================================================
|
|
97
|
+
// Actions
|
|
98
|
+
// ============================================================================
|
|
99
|
+
|
|
100
|
+
const selectDeployment = useCallback((deployment: DeploymentSchema | null) => {
|
|
101
|
+
setSelectedDeployment(deployment);
|
|
102
|
+
}, []);
|
|
103
|
+
|
|
104
|
+
const clearSelection = useCallback(() => {
|
|
105
|
+
setSelectedDeployment(null);
|
|
106
|
+
}, []);
|
|
107
|
+
|
|
108
|
+
const setPage = useCallback((page: number) => {
|
|
109
|
+
setPaginationParams((prev) => ({
|
|
110
|
+
...prev,
|
|
111
|
+
offset: (page - 1) * prev.limit,
|
|
112
|
+
}));
|
|
113
|
+
}, []);
|
|
114
|
+
|
|
115
|
+
// ============================================================================
|
|
116
|
+
// Computed Values
|
|
117
|
+
// ============================================================================
|
|
118
|
+
|
|
119
|
+
const deploymentsCount = deployments.length;
|
|
120
|
+
const pageSize = paginationParams.limit;
|
|
121
|
+
const currentPage = Math.floor(paginationParams.offset / pageSize) + 1;
|
|
122
|
+
const totalPages = Math.ceil(totalDeployments / pageSize) || 1;
|
|
123
|
+
|
|
124
|
+
return {
|
|
125
|
+
// Deployments
|
|
126
|
+
deployments,
|
|
127
|
+
deploymentsCount,
|
|
128
|
+
totalDeployments,
|
|
129
|
+
selectedDeployment,
|
|
130
|
+
isLoadingDeployments,
|
|
131
|
+
deploymentsError,
|
|
132
|
+
|
|
133
|
+
// Pagination
|
|
134
|
+
pageSize,
|
|
135
|
+
currentPage,
|
|
136
|
+
totalPages,
|
|
137
|
+
setPage,
|
|
138
|
+
|
|
139
|
+
// Loading states
|
|
140
|
+
isLoading: isLoadingDeployments,
|
|
141
|
+
|
|
142
|
+
// Mutations states
|
|
143
|
+
isCreating: createDeploymentMutation.isPending,
|
|
144
|
+
isStarting: startDeploymentMutation.isPending,
|
|
145
|
+
isSyncing: syncDeploymentMutation.isPending,
|
|
146
|
+
isCancelling: cancelDeploymentMutation.isPending,
|
|
147
|
+
|
|
148
|
+
// Actions
|
|
149
|
+
selectDeployment,
|
|
150
|
+
clearSelection,
|
|
151
|
+
createDeployment: createDeploymentMutation.mutateAsync,
|
|
152
|
+
startDeployment: startDeploymentMutation.mutate,
|
|
153
|
+
syncDeployment: syncDeploymentMutation.mutate,
|
|
154
|
+
cancelDeployment: cancelDeploymentMutation.mutate,
|
|
155
|
+
refetchDeployments,
|
|
156
|
+
};
|
|
157
|
+
}
|