insforge 1.2.10 → 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/.claude-plugin/marketplace.json +20 -20
- package/.dockerignore +60 -60
- package/.env.example +83 -77
- package/.github/ISSUE_TEMPLATE/bug_report.yml +36 -36
- package/.github/ISSUE_TEMPLATE/config.yml +11 -11
- package/.github/ISSUE_TEMPLATE/feature_request.yml +26 -26
- package/.github/PULL_REQUEST_TEMPLATE.md +7 -7
- package/.github/copilot-instructions.md +146 -146
- package/.github/workflows/build-image.yml +65 -65
- package/.github/workflows/ci-premerge-check.yml +23 -23
- package/.github/workflows/e2e.yml +63 -63
- package/.github/workflows/lint-and-format.yml +32 -32
- package/.prettierignore +64 -64
- package/CHANGELOG.md +46 -44
- package/CLAUDE_PLUGIN.md +104 -104
- package/CODE_OF_CONDUCT.md +128 -128
- package/CONTRIBUTING.md +125 -125
- package/Dockerfile +30 -30
- package/GITHUB_OAUTH_SETUP.md +49 -49
- package/GOOGLE_OAUTH_SETUP.md +148 -148
- package/LICENSE +201 -201
- package/README.md +182 -182
- package/assets/Dark.svg +23 -23
- package/auth/package.json +30 -28
- package/auth/src/lib/broadcastService.ts +4 -4
- package/auth/src/lib/insforge.ts +8 -0
- package/auth/src/main.tsx +2 -4
- package/auth/src/pages/SignInPage.tsx +5 -2
- package/auth/src/pages/SignUpPage.tsx +5 -2
- package/auth/src/pages/VerifyEmailPage.tsx +18 -0
- package/auth/tsconfig.json +33 -32
- package/auth/tsconfig.node.json +11 -11
- package/backend/package.json +82 -75
- 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 +720 -570
- package/backend/src/api/routes/auth/oauth.routes.ts +478 -448
- package/backend/src/api/routes/database/advance.routes.ts +37 -16
- package/backend/src/api/routes/database/index.routes.ts +80 -1
- package/backend/src/api/routes/database/records.routes.ts +48 -184
- package/backend/src/api/routes/database/rpc.routes.ts +69 -0
- package/backend/src/api/routes/database/tables.routes.ts +0 -14
- package/backend/src/api/routes/deployments/index.routes.ts +192 -0
- package/backend/src/api/routes/docs/index.routes.ts +76 -76
- package/backend/src/api/routes/email/index.routes.ts +35 -0
- package/backend/src/api/routes/functions/index.routes.ts +21 -15
- package/backend/src/api/routes/metadata/index.routes.ts +38 -0
- package/backend/src/api/routes/realtime/channels.routes.ts +81 -0
- package/backend/src/api/routes/realtime/index.routes.ts +12 -0
- package/backend/src/api/routes/realtime/messages.routes.ts +48 -0
- package/backend/src/api/routes/realtime/permissions.routes.ts +19 -0
- package/backend/src/api/routes/storage/index.routes.ts +18 -12
- package/backend/src/api/routes/usage/index.routes.ts +6 -4
- package/backend/src/api/routes/webhooks/index.routes.ts +109 -0
- package/backend/src/infra/database/database.manager.ts +14 -11
- package/backend/src/infra/database/migrations/000_create-base-tables.sql +141 -141
- package/backend/src/infra/database/migrations/001_create-helper-functions.sql +40 -40
- package/backend/src/infra/database/migrations/002_rename-auth-tables.sql +29 -29
- package/backend/src/infra/database/migrations/003_create-users-table.sql +55 -55
- package/backend/src/infra/database/migrations/004_add-reload-postgrest-func.sql +23 -23
- package/backend/src/infra/database/migrations/005_enable-project-admin-modify-users.sql +29 -29
- package/backend/src/infra/database/migrations/006_modify-ai-usage-table.sql +24 -24
- package/backend/src/infra/database/migrations/007_drop-metadata-table.sql +1 -1
- package/backend/src/infra/database/migrations/008_add-system-tables.sql +76 -76
- package/backend/src/infra/database/migrations/009_add-function-secrets.sql +23 -23
- package/backend/src/infra/database/migrations/010_modify-ai-config-modalities.sql +93 -93
- package/backend/src/infra/database/migrations/011_refactor-secrets-table.sql +15 -15
- package/backend/src/infra/database/migrations/012_add-storage-uploaded-by.sql +7 -7
- package/backend/src/infra/database/migrations/013_create-auth-schema-functions.sql +44 -44
- package/backend/src/infra/database/migrations/014_add-updated-at-trigger-user-table.sql +7 -7
- package/backend/src/infra/database/migrations/015_create-auth-config-and-email-otp-tables.sql +59 -59
- package/backend/src/infra/database/migrations/016_update-auth-config-and-email-otp.sql +24 -24
- package/backend/src/infra/database/migrations/017_create-realtime-schema.sql +233 -0
- 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/realtime/realtime.manager.ts +246 -0
- package/backend/src/infra/realtime/webhook-sender.ts +82 -0
- package/backend/src/infra/security/token.manager.ts +216 -125
- package/backend/src/infra/socket/socket.manager.ts +198 -64
- package/backend/src/providers/ai/openrouter.provider.ts +24 -12
- 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/providers/email/base.provider.ts +4 -7
- package/backend/src/providers/email/cloud.provider.ts +84 -0
- package/backend/src/providers/oauth/apple.provider.ts +266 -0
- package/backend/src/providers/oauth/index.ts +1 -0
- package/backend/src/server.ts +329 -284
- 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/image-generation.service.ts +3 -3
- 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 +148 -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 -94
- package/backend/src/services/database/database.service.ts +127 -0
- 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/email/email.service.ts +5 -7
- package/backend/src/services/functions/function.service.ts +61 -41
- package/backend/src/services/logs/audit.service.ts +10 -10
- package/backend/src/services/realtime/index.ts +3 -0
- package/backend/src/services/realtime/realtime-auth.service.ts +104 -0
- package/backend/src/services/realtime/realtime-channel.service.ts +237 -0
- package/backend/src/services/realtime/realtime-message.service.ts +260 -0
- 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 +16 -1
- package/backend/src/types/database.ts +2 -0
- package/backend/src/types/deployments.ts +33 -0
- package/backend/src/types/realtime.ts +18 -0
- package/backend/src/types/socket.ts +7 -31
- package/backend/src/types/storage.ts +1 -1
- package/backend/src/types/webhooks.ts +45 -0
- package/backend/src/utils/cookies.ts +34 -0
- package/backend/src/utils/environment.ts +0 -14
- package/backend/src/utils/s3-config-loader.ts +64 -0
- package/backend/src/utils/seed.ts +79 -43
- package/backend/src/utils/sql-parser.ts +216 -0
- package/backend/src/utils/utils.ts +114 -114
- package/backend/src/utils/validations.ts +10 -10
- package/backend/tests/README.md +133 -133
- package/backend/tests/cleanup-all-test-data.sh +230 -230
- package/backend/tests/cloud/test-s3-multitenant.sh +131 -131
- package/backend/tests/local/comprehensive-curl-tests.sh +155 -155
- package/backend/tests/local/test-ai-config.sh +129 -129
- package/backend/tests/local/test-ai-usage.sh +80 -80
- package/backend/tests/local/test-auth-router.sh +143 -143
- package/backend/tests/local/test-database-router.sh +222 -222
- package/backend/tests/local/test-e2e.sh +240 -240
- package/backend/tests/local/test-fk-errors.sh +96 -96
- package/backend/tests/local/test-functions.sh +123 -123
- package/backend/tests/local/test-id-field.sh +200 -200
- package/backend/tests/local/test-logs.sh +132 -132
- package/backend/tests/local/test-public-bucket.sh +264 -264
- package/backend/tests/local/test-rpc.sh +141 -0
- package/backend/tests/local/test-secrets.sh +249 -249
- package/backend/tests/local/test-serverless-functions.sh.disabled +325 -325
- package/backend/tests/local/test-traditional-rest.sh +208 -208
- package/backend/tests/manual/README.md +50 -50
- package/backend/tests/manual/create-large-table-simple.sql +10 -10
- package/backend/tests/manual/seed-large-table.sql +100 -100
- package/backend/tests/manual/setup-large-table-extras.sql +33 -33
- package/backend/tests/manual/test-ai-model-plugins.sh +258 -0
- package/backend/tests/manual/test-bulk-upsert.sh +409 -409
- package/backend/tests/manual/test-database-advance.sh +296 -296
- package/backend/tests/manual/test-postgrest-stability.sh +191 -191
- package/backend/tests/manual/test-rawsql-export-import.sh +411 -411
- package/backend/tests/manual/test-rawsql-modes.sh +244 -244
- package/backend/tests/manual/test-universal-storage.sh +263 -263
- package/backend/tests/manual/test-users.sql +17 -17
- package/backend/tests/run-all-tests.sh +139 -139
- package/backend/tests/setup.ts +0 -0
- package/backend/tests/test-config.sh +338 -338
- package/backend/tests/unit/analyze-query.test.ts +697 -0
- package/backend/tests/unit/database-advance.test.ts +326 -0
- package/backend/tests/unit/helpers.test.ts +2 -2
- package/backend/tsconfig.json +22 -22
- package/claude-plugin/.claude-plugin/plugin.json +24 -24
- package/claude-plugin/README.md +133 -133
- package/claude-plugin/skills/insforge-schema-patterns/SKILL.md +273 -270
- package/docker-compose.prod.yml +204 -200
- package/docker-compose.yml +232 -228
- package/docker-init/db/db-init.sql +97 -97
- package/docker-init/db/jwt.sql +5 -5
- package/docker-init/db/postgresql.conf +16 -16
- package/docker-init/logs/vector.yml +236 -236
- package/docs/README.md +44 -44
- package/docs/agent-docs/deployment.md +79 -0
- package/docs/agent-docs/real-time.md +269 -0
- package/docs/changelog.mdx +212 -67
- package/docs/core-concepts/ai/architecture.mdx +350 -372
- package/docs/core-concepts/ai/sdk.mdx +238 -213
- package/docs/core-concepts/authentication/architecture.mdx +276 -278
- package/docs/core-concepts/authentication/sdk.mdx +710 -414
- package/docs/core-concepts/authentication/ui-components/customization.mdx +733 -529
- package/docs/core-concepts/authentication/ui-components/nextjs.mdx +247 -221
- package/docs/core-concepts/authentication/ui-components/react-router.mdx +183 -184
- package/docs/core-concepts/authentication/ui-components/react.mdx +136 -129
- package/docs/core-concepts/database/architecture.mdx +292 -255
- package/docs/core-concepts/database/pgvector.mdx +138 -0
- package/docs/core-concepts/database/sdk.mdx +382 -382
- package/docs/core-concepts/deployments/architecture.mdx +152 -0
- package/docs/core-concepts/email/architecture.mdx +103 -0
- package/docs/core-concepts/email/sdk.mdx +53 -0
- package/docs/core-concepts/functions/architecture.mdx +105 -105
- package/docs/core-concepts/functions/sdk.mdx +183 -184
- package/docs/core-concepts/realtime/architecture.mdx +446 -0
- package/docs/core-concepts/realtime/sdk.mdx +409 -0
- package/docs/core-concepts/storage/architecture.mdx +243 -243
- package/docs/core-concepts/storage/sdk.mdx +253 -253
- package/docs/deployment/README.md +94 -94
- package/docs/deployment/deploy-to-aws-ec2.md +564 -564
- package/docs/deployment/deploy-to-azure-virtual-machines.md +312 -312
- package/docs/deployment/deploy-to-google-cloud-compute-engine.md +613 -613
- package/docs/deployment/deploy-to-render.md +441 -441
- package/docs/deprecated/insforge-auth-api.md +214 -214
- package/docs/deprecated/insforge-auth-sdk.md +99 -99
- package/docs/deprecated/insforge-db-api.md +358 -358
- package/docs/deprecated/insforge-db-sdk.md +139 -139
- package/docs/deprecated/insforge-debug-sdk.md +156 -156
- package/docs/deprecated/insforge-debug.md +64 -64
- package/docs/deprecated/insforge-instructions.md +123 -123
- package/docs/deprecated/insforge-project.md +117 -117
- package/docs/deprecated/insforge-storage-api.md +278 -278
- package/docs/deprecated/insforge-storage-sdk.md +158 -158
- package/docs/docs.json +240 -210
- package/docs/examples/framework-guides/nextjs.mdx +131 -131
- package/docs/examples/framework-guides/nuxt.mdx +165 -165
- package/docs/examples/framework-guides/react.mdx +165 -165
- package/docs/examples/framework-guides/svelte.mdx +153 -153
- package/docs/examples/framework-guides/vue.mdx +159 -159
- package/docs/examples/overview.mdx +67 -67
- package/docs/favicon.png +0 -0
- package/docs/favicon.svg +4 -19
- package/docs/images/changelog/dec-2025/ai-integration.png +0 -0
- package/docs/images/changelog/dec-2025/ai-models.webp +0 -0
- package/docs/images/changelog/dec-2025/alipay-payment.webp +0 -0
- package/docs/images/changelog/dec-2025/apple-login.jpg +0 -0
- package/docs/images/changelog/dec-2025/apple-oauth.mp4 +0 -0
- package/docs/images/changelog/dec-2025/mcp-installer.png +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/realtime-module.jpg +0 -0
- package/docs/images/changelog/dec-2025/realtime2.png +0 -0
- package/docs/images/icons/ai.svg +4 -4
- package/docs/images/logos/nextjs.svg +4 -4
- package/docs/images/logos/nuxt.svg +4 -4
- package/docs/images/logos/react.svg +5 -5
- package/docs/images/logos/svelte.svg +4 -4
- package/docs/images/logos/vue.svg +5 -5
- 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 +93 -88
- package/docs/introduction.mdx +46 -45
- package/docs/logo/dark.svg +22 -22
- package/docs/logo/light.svg +20 -20
- package/docs/mcp-setup.mdx +332 -0
- package/docs/oauth-server.mdx +563 -0
- package/docs/partnership.mdx +720 -646
- package/docs/quickstart.mdx +82 -82
- package/docs/showcase.mdx +52 -52
- package/docs/snippets/sdk-installation.mdx +21 -21
- package/docs/snippets/service-icons.mdx +27 -27
- package/docs/vscode-extension.mdx +74 -0
- package/eslint.config.js +1 -0
- package/examples/oauth/frontend-oauth-example.html +250 -250
- package/examples/response-examples.md +443 -443
- package/frontend/components.json +17 -17
- package/frontend/package.json +69 -69
- package/frontend/src/App.tsx +8 -3
- package/frontend/src/assets/icons/checkbox_checked.svg +6 -6
- package/frontend/src/assets/icons/checkbox_undetermined.svg +6 -6
- package/frontend/src/assets/icons/checked.svg +3 -3
- package/frontend/src/assets/icons/connected.svg +3 -3
- package/frontend/src/assets/icons/error.svg +3 -3
- package/frontend/src/assets/icons/loader.svg +9 -9
- package/frontend/src/assets/icons/pencil.svg +4 -4
- package/frontend/src/assets/icons/refresh.svg +4 -4
- package/frontend/src/assets/icons/step_active.svg +3 -3
- package/frontend/src/assets/icons/step_inactive.svg +11 -11
- package/frontend/src/assets/icons/warning.svg +3 -3
- package/frontend/src/assets/logos/antigravity.svg +1 -0
- package/frontend/src/assets/logos/apple.svg +3 -3
- package/frontend/src/assets/logos/claude_code.svg +3 -3
- package/frontend/src/assets/logos/cline.svg +6 -6
- package/frontend/src/assets/logos/copilot.svg +10 -0
- package/frontend/src/assets/logos/cursor.svg +20 -20
- package/frontend/src/assets/logos/deepseek.svg +139 -0
- package/frontend/src/assets/logos/discord.svg +8 -8
- package/frontend/src/assets/logos/facebook.svg +3 -3
- package/frontend/src/assets/logos/gemini.svg +19 -19
- package/frontend/src/assets/logos/github.svg +5 -5
- package/frontend/src/assets/logos/google.svg +13 -13
- package/frontend/src/assets/logos/grok.svg +10 -10
- package/frontend/src/assets/logos/insforge_dark.svg +15 -15
- package/frontend/src/assets/logos/insforge_light.svg +15 -15
- package/frontend/src/assets/logos/instagram.svg +1 -1
- package/frontend/src/assets/logos/kiro.svg +9 -0
- package/frontend/src/assets/logos/linkedin.svg +3 -3
- package/frontend/src/assets/logos/openai.svg +10 -10
- package/frontend/src/assets/logos/qoder.svg +4 -0
- package/frontend/src/assets/logos/qwen.svg +15 -0
- package/frontend/src/assets/logos/roo_code.svg +9 -9
- package/frontend/src/assets/logos/spotify.svg +16 -16
- package/frontend/src/assets/logos/tiktok.svg +5 -5
- package/frontend/src/assets/logos/trae.svg +3 -3
- package/frontend/src/assets/logos/windsurf.svg +10 -10
- package/frontend/src/assets/logos/x.svg +3 -3
- 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 +13 -37
- 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/{page → pages}/AIPage.tsx +166 -166
- package/frontend/src/features/auth/components/AuthPreview.tsx +96 -96
- package/frontend/src/features/auth/components/OAuthConfigDialog.tsx +1 -0
- package/frontend/src/features/auth/components/UsersDataGrid.tsx +61 -31
- package/frontend/src/features/auth/components/index.ts +5 -5
- package/frontend/src/features/auth/helpers.tsx +8 -0
- package/frontend/src/features/auth/{page → pages}/AuthMethodsPage.tsx +275 -275
- package/frontend/src/features/auth/{page → pages}/UsersPage.tsx +0 -28
- package/frontend/src/features/dashboard/{page → 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/SQLModal.tsx +75 -0
- package/frontend/src/features/database/components/TableForm.tsx +0 -4
- 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/useDatabase.ts +66 -0
- package/frontend/src/features/database/hooks/useRawSQL.ts +3 -2
- package/frontend/src/features/database/hooks/useTables.ts +30 -28
- package/frontend/src/features/database/index.ts +1 -0
- package/frontend/src/features/database/{page → pages}/FunctionsPage.tsx +29 -42
- package/frontend/src/features/database/{page → pages}/IndexesPage.tsx +34 -51
- package/frontend/src/features/database/{page → pages}/PoliciesPage.tsx +42 -58
- package/frontend/src/features/database/{page → pages}/SQLEditorPage.tsx +2 -2
- package/frontend/src/features/database/{page → pages}/TablesPage.tsx +0 -42
- package/frontend/src/features/database/{page → pages}/TriggersPage.tsx +34 -51
- package/frontend/src/features/database/services/advance.service.ts +1 -41
- package/frontend/src/features/database/services/database.service.ts +55 -0
- package/frontend/src/features/database/services/record.service.ts +4 -20
- package/frontend/src/features/database/services/table.service.ts +1 -10
- 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/{page → pages}/FunctionsPage.tsx +21 -44
- package/frontend/src/features/functions/{page → pages}/SecretsPage.tsx +118 -116
- 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/{page → 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/hooks/useMcpUsage.ts +13 -66
- package/frontend/src/features/logs/{page → 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/realtime/components/ChannelRow.tsx +83 -0
- package/frontend/src/features/realtime/components/EditChannelModal.tsx +246 -0
- package/frontend/src/features/realtime/components/MessageRow.tsx +85 -0
- package/frontend/src/features/realtime/components/RealtimeEmptyState.tsx +30 -0
- package/frontend/src/features/realtime/hooks/useRealtime.ts +218 -0
- package/frontend/src/features/realtime/index.ts +11 -0
- package/frontend/src/features/realtime/pages/RealtimeChannelsPage.tsx +172 -0
- package/frontend/src/features/realtime/pages/RealtimeMessagesPage.tsx +211 -0
- package/frontend/src/features/realtime/pages/RealtimePermissionsPage.tsx +191 -0
- package/frontend/src/features/realtime/services/realtime.service.ts +107 -0
- package/frontend/src/features/settings/pages/SettingsPage.tsx +349 -0
- package/frontend/src/features/storage/{page → pages}/StoragePage.tsx +1 -29
- package/frontend/src/features/visualizer/components/AuthNode.tsx +4 -4
- package/frontend/src/features/visualizer/components/SchemaVisualizer.tsx +24 -11
- package/frontend/src/features/visualizer/{page → pages}/VisualizerPage.tsx +11 -36
- package/frontend/src/index.css +249 -249
- package/frontend/src/lib/contexts/ModalContext.tsx +35 -0
- package/frontend/src/lib/contexts/SocketContext.tsx +119 -75
- 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 -84
- package/frontend/src/lib/services/metadata.service.ts +20 -3
- package/frontend/src/lib/utils/cloudMessaging.ts +1 -1
- package/frontend/src/lib/utils/menuItems.ts +223 -183
- package/frontend/src/lib/utils/utils.ts +196 -183
- package/frontend/tsconfig.json +25 -25
- package/frontend/tsconfig.node.json +9 -9
- package/functions/deno.json +24 -24
- package/functions/server.ts +6 -6
- package/functions/worker-template.js +1 -1
- package/i18n/README.ar.md +130 -130
- package/i18n/README.de.md +130 -130
- package/i18n/README.es.md +154 -154
- package/i18n/README.fr.md +134 -134
- package/i18n/README.hi.md +129 -129
- package/i18n/README.ja.md +174 -174
- package/i18n/README.ko.md +136 -136
- package/i18n/README.pt-BR.md +131 -131
- package/i18n/README.ru.md +129 -129
- package/i18n/README.zh-CN.md +133 -133
- package/openapi/ai.yaml +825 -715
- package/openapi/auth.yaml +1324 -1244
- package/openapi/email.yaml +158 -0
- package/openapi/functions.yaml +475 -475
- package/openapi/health.yaml +29 -29
- package/openapi/logs.yaml +221 -223
- package/openapi/metadata.yaml +175 -177
- package/openapi/realtime.yaml +699 -0
- package/openapi/records.yaml +381 -381
- package/openapi/secrets.yaml +370 -370
- package/openapi/storage.yaml +875 -875
- package/openapi/tables.yaml +462 -463
- package/package.json +97 -97
- package/shared-schemas/package.json +31 -31
- package/shared-schemas/src/ai-api.schema.ts +251 -143
- package/shared-schemas/src/ai.schema.ts +8 -4
- package/shared-schemas/src/auth-api.schema.ts +380 -339
- package/shared-schemas/src/auth.schema.ts +18 -11
- package/shared-schemas/src/cloud-events.schema.ts +26 -0
- package/shared-schemas/src/database-api.schema.ts +32 -1
- package/shared-schemas/src/database.schema.ts +39 -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 +32 -0
- package/shared-schemas/src/email-api.schema.ts +30 -0
- 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 -14
- package/shared-schemas/src/metadata.schema.ts +39 -4
- package/shared-schemas/src/realtime-api.schema.ts +111 -0
- package/shared-schemas/src/realtime.schema.ts +143 -0
- package/shared-schemas/src/secrets-api.schema.ts +44 -0
- package/shared-schemas/src/secrets.schema.ts +15 -0
- package/shared-schemas/tsconfig.json +21 -21
- package/tsconfig.json +7 -7
- package/zeabur/README.md +26 -13
- package/zeabur/template.yml +1001 -1032
- package/.cursor/rules/cursor-rules.mdc +0 -94
- package/backend/src/types/profile.ts +0 -55
- package/frontend/src/components/ProjectInfoModal.tsx +0 -128
- package/frontend/src/features/database/hooks/useFullMetadata.ts +0 -18
- package/test-gemini.sh +0 -35
- package/test-usage-admin.sh +0 -57
- package/test-usage.sh +0 -50
- /package/frontend/src/features/auth/{page → pages}/ConfigurationPage.tsx +0 -0
- /package/frontend/src/features/database/{page → pages}/TemplatesPage.tsx +0 -0
- /package/frontend/src/features/login/{page → pages}/LoginPage.tsx +0 -0
- /package/frontend/src/features/logs/{page → pages}/AuditsPage.tsx +0 -0
- /package/frontend/src/features/logs/{page → pages}/MCPLogsPage.tsx +0 -0
|
@@ -0,0 +1,233 @@
|
|
|
1
|
+
-- Migration 017: Create Realtime Schema
|
|
2
|
+
--
|
|
3
|
+
-- Creates the realtime schema with:
|
|
4
|
+
-- 1. channels table - Channel definitions with webhook configuration
|
|
5
|
+
-- 2. messages table - All realtime messages with delivery statistics
|
|
6
|
+
-- 3. publish() function - Called by developer triggers to publish events
|
|
7
|
+
--
|
|
8
|
+
-- Permission Model (Supabase pattern):
|
|
9
|
+
-- - SELECT on channels = 'subscribe' permission (subscribe to channel)
|
|
10
|
+
-- - INSERT on messages = 'publish' permission (publish to channel)
|
|
11
|
+
-- Developers define RLS policies on channels/messages table to control access.
|
|
12
|
+
|
|
13
|
+
-- ============================================================================
|
|
14
|
+
-- CREATE SCHEMA
|
|
15
|
+
-- ============================================================================
|
|
16
|
+
|
|
17
|
+
CREATE SCHEMA IF NOT EXISTS realtime;
|
|
18
|
+
|
|
19
|
+
-- ============================================================================
|
|
20
|
+
-- CHANNELS TABLE
|
|
21
|
+
-- ============================================================================
|
|
22
|
+
-- Stores channel definitions with delivery configuration.
|
|
23
|
+
-- RLS policies control subscribe permissions.
|
|
24
|
+
-- - SELECT policy = 'subscribe' permission (can subscribe to channel)
|
|
25
|
+
-- Channel names use : as separator and % for wildcards (LIKE pattern).
|
|
26
|
+
-- Examples: "orders", "order:%", "chat:%:messages"
|
|
27
|
+
|
|
28
|
+
CREATE TABLE IF NOT EXISTS realtime.channels (
|
|
29
|
+
id UUID DEFAULT gen_random_uuid() PRIMARY KEY,
|
|
30
|
+
|
|
31
|
+
-- Channel name pattern (e.g., "orders", "order:%", "chat:%:messages")
|
|
32
|
+
-- Convention: use : as separator, % for wildcards (LIKE pattern)
|
|
33
|
+
pattern TEXT UNIQUE NOT NULL,
|
|
34
|
+
|
|
35
|
+
-- Human-readable description
|
|
36
|
+
description TEXT,
|
|
37
|
+
|
|
38
|
+
-- Webhook URLs to POST events to (NULL or empty array = no webhooks)
|
|
39
|
+
webhook_urls TEXT[],
|
|
40
|
+
|
|
41
|
+
-- Whether this channel is active
|
|
42
|
+
enabled BOOLEAN DEFAULT TRUE NOT NULL,
|
|
43
|
+
|
|
44
|
+
created_at TIMESTAMPTZ DEFAULT NOW(),
|
|
45
|
+
updated_at TIMESTAMPTZ DEFAULT NOW()
|
|
46
|
+
);
|
|
47
|
+
|
|
48
|
+
-- ============================================================================
|
|
49
|
+
-- MESSAGES TABLE
|
|
50
|
+
-- ============================================================================
|
|
51
|
+
-- Stores all realtime messages published through the system.
|
|
52
|
+
-- RLS policies on this table control publish permissions:
|
|
53
|
+
-- - INSERT policy = 'publish' permission (can publish to channel)
|
|
54
|
+
|
|
55
|
+
CREATE TABLE IF NOT EXISTS realtime.messages (
|
|
56
|
+
id UUID DEFAULT gen_random_uuid() PRIMARY KEY,
|
|
57
|
+
|
|
58
|
+
-- Event metadata
|
|
59
|
+
event_name TEXT NOT NULL,
|
|
60
|
+
|
|
61
|
+
-- Channel reference (SET NULL on delete to preserve history)
|
|
62
|
+
channel_id UUID REFERENCES realtime.channels(id) ON DELETE SET NULL,
|
|
63
|
+
channel_name TEXT NOT NULL, -- Denormalized for query convenience after channel deletion
|
|
64
|
+
|
|
65
|
+
-- Event payload (stored for audit/replay purposes)
|
|
66
|
+
payload JSONB DEFAULT '{}'::jsonb NOT NULL,
|
|
67
|
+
|
|
68
|
+
-- Sender information
|
|
69
|
+
-- 'system' = triggered by database trigger (via publish() function)
|
|
70
|
+
-- 'user' = published by client via WebSocket
|
|
71
|
+
sender_type TEXT DEFAULT 'system' NOT NULL CHECK (sender_type IN ('system', 'user')),
|
|
72
|
+
sender_id UUID, -- User ID for 'user' type, NULL for 'system' type
|
|
73
|
+
|
|
74
|
+
-- Delivery statistics for WebSocket
|
|
75
|
+
ws_audience_count INTEGER DEFAULT 0 NOT NULL, -- How many clients were subscribed
|
|
76
|
+
|
|
77
|
+
-- Delivery statistics for Webhooks
|
|
78
|
+
wh_audience_count INTEGER DEFAULT 0 NOT NULL, -- How many webhook URLs configured
|
|
79
|
+
wh_delivered_count INTEGER DEFAULT 0 NOT NULL, -- How many succeeded (2xx response)
|
|
80
|
+
|
|
81
|
+
created_at TIMESTAMPTZ DEFAULT NOW()
|
|
82
|
+
);
|
|
83
|
+
|
|
84
|
+
-- ============================================================================
|
|
85
|
+
-- INDEXES
|
|
86
|
+
-- ============================================================================
|
|
87
|
+
|
|
88
|
+
CREATE INDEX IF NOT EXISTS idx_realtime_channels_pattern ON realtime.channels(pattern);
|
|
89
|
+
CREATE INDEX IF NOT EXISTS idx_realtime_channels_enabled ON realtime.channels(enabled);
|
|
90
|
+
CREATE INDEX IF NOT EXISTS idx_realtime_messages_channel_id ON realtime.messages(channel_id);
|
|
91
|
+
CREATE INDEX IF NOT EXISTS idx_realtime_messages_channel_name ON realtime.messages(channel_name);
|
|
92
|
+
CREATE INDEX IF NOT EXISTS idx_realtime_messages_created_at ON realtime.messages(created_at DESC);
|
|
93
|
+
CREATE INDEX IF NOT EXISTS idx_realtime_messages_event_name ON realtime.messages(event_name);
|
|
94
|
+
CREATE INDEX IF NOT EXISTS idx_realtime_messages_sender ON realtime.messages(sender_type, sender_id);
|
|
95
|
+
|
|
96
|
+
-- ============================================================================
|
|
97
|
+
-- UPDATED_AT TRIGGER
|
|
98
|
+
-- ============================================================================
|
|
99
|
+
|
|
100
|
+
CREATE OR REPLACE FUNCTION realtime.update_updated_at()
|
|
101
|
+
RETURNS TRIGGER AS $$
|
|
102
|
+
BEGIN
|
|
103
|
+
NEW.updated_at = NOW();
|
|
104
|
+
RETURN NEW;
|
|
105
|
+
END;
|
|
106
|
+
$$ LANGUAGE plpgsql;
|
|
107
|
+
|
|
108
|
+
DROP TRIGGER IF EXISTS trg_channels_updated_at ON realtime.channels;
|
|
109
|
+
CREATE TRIGGER trg_channels_updated_at
|
|
110
|
+
BEFORE UPDATE ON realtime.channels
|
|
111
|
+
FOR EACH ROW EXECUTE FUNCTION realtime.update_updated_at();
|
|
112
|
+
|
|
113
|
+
-- ============================================================================
|
|
114
|
+
-- ROW LEVEL SECURITY (DISABLED BY DEFAULT)
|
|
115
|
+
-- ============================================================================
|
|
116
|
+
-- RLS is disabled by default for the best developer experience.
|
|
117
|
+
-- Channels and messages are open to all authenticated/anon users out of the box.
|
|
118
|
+
--
|
|
119
|
+
-- To enable access control, developers can:
|
|
120
|
+
-- 1. Enable RLS: ALTER TABLE realtime.channels ENABLE ROW LEVEL SECURITY;
|
|
121
|
+
-- 2. Add policies using the helper function realtime.channel_name()
|
|
122
|
+
--
|
|
123
|
+
-- See documentation for policy examples.
|
|
124
|
+
|
|
125
|
+
-- ============================================================================
|
|
126
|
+
-- HELPER FUNCTIONS FOR RLS POLICIES
|
|
127
|
+
-- ============================================================================
|
|
128
|
+
|
|
129
|
+
-- Returns the channel name being accessed (set by backend during permission checks)
|
|
130
|
+
-- Developers use this in policies instead of writing current_setting directly
|
|
131
|
+
CREATE OR REPLACE FUNCTION realtime.channel_name()
|
|
132
|
+
RETURNS TEXT AS $$
|
|
133
|
+
SELECT current_setting('realtime.channel_name', true);
|
|
134
|
+
$$ LANGUAGE SQL STABLE;
|
|
135
|
+
|
|
136
|
+
-- ============================================================================
|
|
137
|
+
-- PUBLISH FUNCTION
|
|
138
|
+
-- ============================================================================
|
|
139
|
+
-- Called by developer triggers to publish events to channels.
|
|
140
|
+
-- This function can only be executed by the backend (SECURITY DEFINER).
|
|
141
|
+
--
|
|
142
|
+
-- Usage in a trigger:
|
|
143
|
+
-- PERFORM realtime.publish(
|
|
144
|
+
-- 'order:' || NEW.id::text, -- channel name (resolved instance)
|
|
145
|
+
-- 'order_updated', -- event name
|
|
146
|
+
-- jsonb_build_object('id', NEW.id, 'status', NEW.status) -- payload
|
|
147
|
+
-- );
|
|
148
|
+
|
|
149
|
+
CREATE OR REPLACE FUNCTION realtime.publish(
|
|
150
|
+
p_channel_name TEXT,
|
|
151
|
+
p_event_name TEXT,
|
|
152
|
+
p_payload JSONB
|
|
153
|
+
)
|
|
154
|
+
RETURNS UUID AS $$
|
|
155
|
+
DECLARE
|
|
156
|
+
v_channel_id UUID;
|
|
157
|
+
v_message_id UUID;
|
|
158
|
+
BEGIN
|
|
159
|
+
-- Find matching channel: exact match first, then wildcard pattern match
|
|
160
|
+
-- For wildcard patterns like "order:%", check if p_channel_name LIKE pattern
|
|
161
|
+
SELECT id INTO v_channel_id
|
|
162
|
+
FROM realtime.channels
|
|
163
|
+
WHERE enabled = TRUE
|
|
164
|
+
AND (pattern = p_channel_name OR p_channel_name LIKE pattern)
|
|
165
|
+
ORDER BY pattern = p_channel_name DESC
|
|
166
|
+
LIMIT 1;
|
|
167
|
+
|
|
168
|
+
-- If no channel found, raise a warning and return NULL
|
|
169
|
+
IF v_channel_id IS NULL THEN
|
|
170
|
+
RAISE WARNING 'Realtime: No matching channel found for "%"', p_channel_name;
|
|
171
|
+
RETURN NULL;
|
|
172
|
+
END IF;
|
|
173
|
+
|
|
174
|
+
-- Insert message record (system-triggered, so sender_type = 'system')
|
|
175
|
+
INSERT INTO realtime.messages (
|
|
176
|
+
event_name,
|
|
177
|
+
channel_id,
|
|
178
|
+
channel_name,
|
|
179
|
+
payload,
|
|
180
|
+
sender_type
|
|
181
|
+
) VALUES (
|
|
182
|
+
p_event_name,
|
|
183
|
+
v_channel_id,
|
|
184
|
+
p_channel_name,
|
|
185
|
+
p_payload,
|
|
186
|
+
'system'
|
|
187
|
+
)
|
|
188
|
+
RETURNING id INTO v_message_id;
|
|
189
|
+
|
|
190
|
+
RETURN v_message_id;
|
|
191
|
+
END;
|
|
192
|
+
$$ LANGUAGE plpgsql SECURITY DEFINER;
|
|
193
|
+
|
|
194
|
+
-- Revoke execute from public, only backend can call this
|
|
195
|
+
REVOKE ALL ON FUNCTION realtime.publish FROM PUBLIC;
|
|
196
|
+
|
|
197
|
+
-- ============================================================================
|
|
198
|
+
-- TRIGGER FOR PG_NOTIFY
|
|
199
|
+
-- ============================================================================
|
|
200
|
+
-- Trigger function that sends pg_notify for every new message (both system and client).
|
|
201
|
+
|
|
202
|
+
CREATE OR REPLACE FUNCTION realtime.notify_on_message_insert()
|
|
203
|
+
RETURNS TRIGGER AS $$
|
|
204
|
+
BEGIN
|
|
205
|
+
-- Send only message_id to bypass pg_notify 8KB payload limit
|
|
206
|
+
-- Backend will fetch full message from DB
|
|
207
|
+
PERFORM pg_notify('realtime_message', NEW.id::text);
|
|
208
|
+
RETURN NEW;
|
|
209
|
+
END;
|
|
210
|
+
$$ LANGUAGE plpgsql;
|
|
211
|
+
|
|
212
|
+
-- Create trigger on messages table
|
|
213
|
+
DROP TRIGGER IF EXISTS trg_message_notify ON realtime.messages;
|
|
214
|
+
CREATE TRIGGER trg_message_notify
|
|
215
|
+
AFTER INSERT ON realtime.messages
|
|
216
|
+
FOR EACH ROW
|
|
217
|
+
EXECUTE FUNCTION realtime.notify_on_message_insert();
|
|
218
|
+
|
|
219
|
+
-- ============================================================================
|
|
220
|
+
-- GRANTS
|
|
221
|
+
-- ============================================================================
|
|
222
|
+
|
|
223
|
+
-- Grant schema access to both authenticated and anonymous users
|
|
224
|
+
GRANT USAGE ON SCHEMA realtime TO authenticated, anon;
|
|
225
|
+
|
|
226
|
+
-- Grant SELECT on channels table (allows subscribe)
|
|
227
|
+
GRANT SELECT ON realtime.channels TO authenticated, anon;
|
|
228
|
+
|
|
229
|
+
-- Grant INSERT on messages table (allows publish)
|
|
230
|
+
GRANT INSERT ON realtime.messages TO authenticated, anon;
|
|
231
|
+
|
|
232
|
+
-- Grant execution permission on helper function (used when RLS is enabled)
|
|
233
|
+
GRANT EXECUTE ON FUNCTION realtime.channel_name() TO authenticated, anon;
|
|
@@ -0,0 +1,441 @@
|
|
|
1
|
+
-- Migration: 018 - Create system and auth schemas, move and rename system tables
|
|
2
|
+
-- This migration creates dedicated schemas for internal system and auth tables,
|
|
3
|
+
-- moves tables into them, and removes the underscore prefix from table names.
|
|
4
|
+
|
|
5
|
+
-- ============================================================================
|
|
6
|
+
-- PART 1: SYSTEM SCHEMA (secrets, audit_logs, mcp_usage)
|
|
7
|
+
-- Note: migrations table is handled by bootstrap/bootstrap-migrations.js before this runs
|
|
8
|
+
-- ============================================================================
|
|
9
|
+
|
|
10
|
+
-- 1.1 Create the system schema (may already exist from bootstrap)
|
|
11
|
+
CREATE SCHEMA IF NOT EXISTS system;
|
|
12
|
+
|
|
13
|
+
-- 1.2 Move _secrets table to system schema and rename to 'secrets'
|
|
14
|
+
-- First, drop the foreign key constraint from _oauth_configs that references _secrets
|
|
15
|
+
ALTER TABLE public._oauth_configs
|
|
16
|
+
DROP CONSTRAINT IF EXISTS _oauth_configs_secret_id_fkey;
|
|
17
|
+
|
|
18
|
+
-- Move and rename the _secrets table to system.secrets
|
|
19
|
+
ALTER TABLE public._secrets SET SCHEMA system;
|
|
20
|
+
ALTER TABLE system._secrets RENAME TO secrets;
|
|
21
|
+
|
|
22
|
+
-- Note: We'll recreate the FK constraint after moving _oauth_configs to auth schema
|
|
23
|
+
|
|
24
|
+
-- 1.3 Move _audit_logs table to system schema and rename to 'audit_logs'
|
|
25
|
+
ALTER TABLE public._audit_logs SET SCHEMA system;
|
|
26
|
+
ALTER TABLE system._audit_logs RENAME TO audit_logs;
|
|
27
|
+
|
|
28
|
+
-- 1.4 Move _mcp_usage table to system schema and rename to 'mcp_usage'
|
|
29
|
+
ALTER TABLE public._mcp_usage SET SCHEMA system;
|
|
30
|
+
ALTER TABLE system._mcp_usage RENAME TO mcp_usage;
|
|
31
|
+
|
|
32
|
+
-- Note: system schema is internal and should NOT be exposed to PUBLIC.
|
|
33
|
+
-- Access is controlled through the application's database connection.
|
|
34
|
+
|
|
35
|
+
-- ============================================================================
|
|
36
|
+
-- PART 2: AUTH SCHEMA (users, user_providers, configs, oauth_configs, email_otps)
|
|
37
|
+
-- ============================================================================
|
|
38
|
+
|
|
39
|
+
-- 2.1 Create the auth schema
|
|
40
|
+
CREATE SCHEMA IF NOT EXISTS auth;
|
|
41
|
+
|
|
42
|
+
-- 2.2 Drop all foreign key constraints that reference tables being moved
|
|
43
|
+
-- FK: _account_providers.user_id -> _accounts(id)
|
|
44
|
+
ALTER TABLE public._account_providers
|
|
45
|
+
DROP CONSTRAINT IF EXISTS _account_providers_user_id_fkey;
|
|
46
|
+
|
|
47
|
+
-- FK: users.id -> _accounts(id) (public users table references _accounts)
|
|
48
|
+
ALTER TABLE public.users
|
|
49
|
+
DROP CONSTRAINT IF EXISTS users_id_fkey;
|
|
50
|
+
|
|
51
|
+
-- FK: _storage.uploaded_by -> _accounts(id)
|
|
52
|
+
ALTER TABLE public._storage
|
|
53
|
+
DROP CONSTRAINT IF EXISTS _storage_uploaded_by_fkey;
|
|
54
|
+
|
|
55
|
+
-- 2.3 Move _accounts table to auth schema and rename to 'users'
|
|
56
|
+
ALTER TABLE public._accounts SET SCHEMA auth;
|
|
57
|
+
ALTER TABLE auth._accounts RENAME TO users;
|
|
58
|
+
|
|
59
|
+
-- 2.4 Move _account_providers table to auth schema and rename to 'user_providers'
|
|
60
|
+
ALTER TABLE public._account_providers SET SCHEMA auth;
|
|
61
|
+
ALTER TABLE auth._account_providers RENAME TO user_providers;
|
|
62
|
+
|
|
63
|
+
-- 2.5 Recreate FK: auth.user_providers.user_id -> auth.users(id)
|
|
64
|
+
ALTER TABLE auth.user_providers
|
|
65
|
+
ADD CONSTRAINT user_providers_user_id_fkey
|
|
66
|
+
FOREIGN KEY (user_id) REFERENCES auth.users(id) ON DELETE CASCADE;
|
|
67
|
+
|
|
68
|
+
-- 2.6 Add profile and metadata JSONB columns to auth.users BEFORE migrating data
|
|
69
|
+
-- profile: stores user profile data (name, avatar_url, bio, etc.)
|
|
70
|
+
-- metadata: reserved for system use (device ID, login IP, etc.)
|
|
71
|
+
ALTER TABLE auth.users ADD COLUMN IF NOT EXISTS profile JSONB DEFAULT '{}'::jsonb;
|
|
72
|
+
ALTER TABLE auth.users ADD COLUMN IF NOT EXISTS metadata JSONB DEFAULT '{}'::jsonb;
|
|
73
|
+
|
|
74
|
+
-- 2.7 Migrate data from public.users into auth.users.profile
|
|
75
|
+
-- Priority for name: public.users.nickname first, then auth.users.name as fallback
|
|
76
|
+
-- Also migrate: avatar_url, bio, birthday from public.users
|
|
77
|
+
UPDATE auth.users AS au
|
|
78
|
+
SET profile = jsonb_strip_nulls(jsonb_build_object(
|
|
79
|
+
'name', COALESCE(pu.nickname, au.name),
|
|
80
|
+
'avatar_url', pu.avatar_url,
|
|
81
|
+
'bio', pu.bio,
|
|
82
|
+
'birthday', pu.birthday
|
|
83
|
+
))
|
|
84
|
+
FROM public.users AS pu
|
|
85
|
+
WHERE au.id = pu.id;
|
|
86
|
+
|
|
87
|
+
-- 2.8 For users without a public.users row, migrate auth.users.name to profile
|
|
88
|
+
UPDATE auth.users
|
|
89
|
+
SET profile = jsonb_build_object('name', name)
|
|
90
|
+
WHERE name IS NOT NULL
|
|
91
|
+
AND (profile IS NULL OR profile = '{}'::jsonb)
|
|
92
|
+
AND id NOT IN (SELECT id FROM public.users);
|
|
93
|
+
|
|
94
|
+
-- 2.9 Update all foreign key constraints that reference public.users to use auth.users instead
|
|
95
|
+
-- This handles any custom tables developers may have created that reference public.users
|
|
96
|
+
DO $$
|
|
97
|
+
DECLARE
|
|
98
|
+
fk_record RECORD;
|
|
99
|
+
drop_sql TEXT;
|
|
100
|
+
create_sql TEXT;
|
|
101
|
+
BEGIN
|
|
102
|
+
-- Find all foreign keys that reference public.users
|
|
103
|
+
FOR fk_record IN
|
|
104
|
+
SELECT
|
|
105
|
+
tc.table_schema,
|
|
106
|
+
tc.table_name,
|
|
107
|
+
tc.constraint_name,
|
|
108
|
+
kcu.column_name,
|
|
109
|
+
rc.delete_rule,
|
|
110
|
+
rc.update_rule
|
|
111
|
+
FROM information_schema.table_constraints tc
|
|
112
|
+
JOIN information_schema.key_column_usage kcu
|
|
113
|
+
ON tc.constraint_name = kcu.constraint_name
|
|
114
|
+
AND tc.table_schema = kcu.table_schema
|
|
115
|
+
JOIN information_schema.referential_constraints rc
|
|
116
|
+
ON tc.constraint_name = rc.constraint_name
|
|
117
|
+
AND tc.table_schema = rc.constraint_schema
|
|
118
|
+
JOIN information_schema.constraint_column_usage ccu
|
|
119
|
+
ON rc.unique_constraint_name = ccu.constraint_name
|
|
120
|
+
AND rc.unique_constraint_schema = ccu.constraint_schema
|
|
121
|
+
WHERE tc.constraint_type = 'FOREIGN KEY'
|
|
122
|
+
AND ccu.table_schema = 'public'
|
|
123
|
+
AND ccu.table_name = 'users'
|
|
124
|
+
LOOP
|
|
125
|
+
-- Drop the old foreign key
|
|
126
|
+
drop_sql := format(
|
|
127
|
+
'ALTER TABLE %I.%I DROP CONSTRAINT IF EXISTS %I',
|
|
128
|
+
fk_record.table_schema,
|
|
129
|
+
fk_record.table_name,
|
|
130
|
+
fk_record.constraint_name
|
|
131
|
+
);
|
|
132
|
+
EXECUTE drop_sql;
|
|
133
|
+
|
|
134
|
+
-- Recreate with reference to auth.users
|
|
135
|
+
create_sql := format(
|
|
136
|
+
'ALTER TABLE %I.%I ADD CONSTRAINT %I FOREIGN KEY (%I) REFERENCES auth.users(id) ON DELETE %s ON UPDATE %s',
|
|
137
|
+
fk_record.table_schema,
|
|
138
|
+
fk_record.table_name,
|
|
139
|
+
fk_record.constraint_name,
|
|
140
|
+
fk_record.column_name,
|
|
141
|
+
fk_record.delete_rule,
|
|
142
|
+
fk_record.update_rule
|
|
143
|
+
);
|
|
144
|
+
EXECUTE create_sql;
|
|
145
|
+
|
|
146
|
+
RAISE NOTICE 'Updated FK constraint % on %.% to reference auth.users',
|
|
147
|
+
fk_record.constraint_name, fk_record.table_schema, fk_record.table_name;
|
|
148
|
+
END LOOP;
|
|
149
|
+
END $$;
|
|
150
|
+
|
|
151
|
+
-- 2.10 Drop public.users table (profile data now stored in auth.users.profile)
|
|
152
|
+
-- First drop RLS policies
|
|
153
|
+
DROP POLICY IF EXISTS "Enable read access for all users" ON public.users;
|
|
154
|
+
DROP POLICY IF EXISTS "Disable delete for users" ON public.users;
|
|
155
|
+
DROP POLICY IF EXISTS "Enable update for users based on user_id" ON public.users;
|
|
156
|
+
-- Drop the table (CASCADE will handle any remaining dependencies)
|
|
157
|
+
DROP TABLE IF EXISTS public.users CASCADE;
|
|
158
|
+
|
|
159
|
+
-- 2.11 Drop the name column from auth.users (data already migrated to profile)
|
|
160
|
+
ALTER TABLE auth.users DROP COLUMN IF EXISTS name;
|
|
161
|
+
|
|
162
|
+
-- Note: _storage.uploaded_by FK is handled in Part 4 when moving to storage schema
|
|
163
|
+
|
|
164
|
+
-- 2.12 Add is_project_admin and is_anonymous columns to auth.users
|
|
165
|
+
ALTER TABLE auth.users ADD COLUMN IF NOT EXISTS is_project_admin BOOLEAN NOT NULL DEFAULT false;
|
|
166
|
+
ALTER TABLE auth.users ADD COLUMN IF NOT EXISTS is_anonymous BOOLEAN NOT NULL DEFAULT false;
|
|
167
|
+
|
|
168
|
+
-- 2.13 Move _auth_configs table to auth schema and rename to 'configs'
|
|
169
|
+
ALTER TABLE public._auth_configs SET SCHEMA auth;
|
|
170
|
+
ALTER TABLE auth._auth_configs RENAME TO configs;
|
|
171
|
+
|
|
172
|
+
-- 2.14 Move _oauth_configs table to auth schema and rename to 'oauth_configs'
|
|
173
|
+
ALTER TABLE public._oauth_configs SET SCHEMA auth;
|
|
174
|
+
ALTER TABLE auth._oauth_configs RENAME TO oauth_configs;
|
|
175
|
+
|
|
176
|
+
-- 2.15 Recreate FK: auth.oauth_configs.secret_id -> system.secrets(id)
|
|
177
|
+
ALTER TABLE auth.oauth_configs
|
|
178
|
+
ADD CONSTRAINT oauth_configs_secret_id_fkey
|
|
179
|
+
FOREIGN KEY (secret_id) REFERENCES system.secrets(id) ON DELETE RESTRICT;
|
|
180
|
+
|
|
181
|
+
-- 2.16 Move _email_otps table to auth schema and rename to 'email_otps'
|
|
182
|
+
ALTER TABLE public._email_otps SET SCHEMA auth;
|
|
183
|
+
ALTER TABLE auth._email_otps RENAME TO email_otps;
|
|
184
|
+
|
|
185
|
+
-- Note: auth schema is internal and should NOT be exposed to PUBLIC.
|
|
186
|
+
-- However, we grant limited access to auth.users for public profile info.
|
|
187
|
+
|
|
188
|
+
-- 2.17 Grant limited public access to auth.users (only safe columns)
|
|
189
|
+
GRANT USAGE ON SCHEMA auth TO PUBLIC;
|
|
190
|
+
|
|
191
|
+
-- Grant SELECT on specific columns only (public profile info)
|
|
192
|
+
GRANT SELECT (id, profile, created_at) ON auth.users TO PUBLIC;
|
|
193
|
+
|
|
194
|
+
-- Grant UPDATE on profile column only (users can update their own profile)
|
|
195
|
+
GRANT UPDATE (profile) ON auth.users TO PUBLIC;
|
|
196
|
+
|
|
197
|
+
-- 2.18 Enable RLS on auth.users for row-level access control
|
|
198
|
+
-- Note: auth.uid() function already exists from migration 013
|
|
199
|
+
ALTER TABLE auth.users ENABLE ROW LEVEL SECURITY;
|
|
200
|
+
|
|
201
|
+
-- Policy: Everyone can SELECT public columns (id, profile, created_at)
|
|
202
|
+
-- Column-level GRANT above already restricts which columns can be read
|
|
203
|
+
CREATE POLICY "Public can view user profiles" ON auth.users
|
|
204
|
+
FOR SELECT
|
|
205
|
+
USING (true);
|
|
206
|
+
|
|
207
|
+
-- Policy: Users can only UPDATE their own row
|
|
208
|
+
CREATE POLICY "Users can update own profile" ON auth.users
|
|
209
|
+
FOR UPDATE
|
|
210
|
+
USING (id = auth.uid())
|
|
211
|
+
WITH CHECK (id = auth.uid());
|
|
212
|
+
|
|
213
|
+
-- 2.19 Drop obsolete public schema helper functions (migrated to auth schema)
|
|
214
|
+
-- NOTE: CASCADE intentionally used to force migration from public.uid() to auth.uid()
|
|
215
|
+
-- Any dependent objects (policies, views, functions, defaults) will be dropped.
|
|
216
|
+
-- Users must recreate them using auth.uid(), auth.role(), auth.email() instead.
|
|
217
|
+
DROP FUNCTION IF EXISTS public.uid() CASCADE;
|
|
218
|
+
DROP FUNCTION IF EXISTS public.role() CASCADE;
|
|
219
|
+
DROP FUNCTION IF EXISTS public.email() CASCADE;
|
|
220
|
+
|
|
221
|
+
-- ============================================================================
|
|
222
|
+
-- PART 3: AI SCHEMA (configs, usage)
|
|
223
|
+
-- ============================================================================
|
|
224
|
+
|
|
225
|
+
-- 3.1 Create the ai schema
|
|
226
|
+
CREATE SCHEMA IF NOT EXISTS ai;
|
|
227
|
+
|
|
228
|
+
-- 3.2 Drop FK constraint from _ai_usage to _ai_configs before moving
|
|
229
|
+
ALTER TABLE public._ai_usage
|
|
230
|
+
DROP CONSTRAINT IF EXISTS _ai_usage_config_id_fkey;
|
|
231
|
+
|
|
232
|
+
-- 3.3 Move _ai_configs table to ai schema and rename to 'configs'
|
|
233
|
+
ALTER TABLE public._ai_configs SET SCHEMA ai;
|
|
234
|
+
ALTER TABLE ai._ai_configs RENAME TO configs;
|
|
235
|
+
|
|
236
|
+
-- 3.4 Move _ai_usage table to ai schema and rename to 'usage'
|
|
237
|
+
ALTER TABLE public._ai_usage SET SCHEMA ai;
|
|
238
|
+
ALTER TABLE ai._ai_usage RENAME TO usage;
|
|
239
|
+
|
|
240
|
+
-- 3.5 Recreate FK: ai.usage.config_id -> ai.configs(id)
|
|
241
|
+
ALTER TABLE ai.usage
|
|
242
|
+
ADD CONSTRAINT usage_config_id_fkey
|
|
243
|
+
FOREIGN KEY (config_id) REFERENCES ai.configs(id) ON DELETE NO ACTION;
|
|
244
|
+
|
|
245
|
+
-- Note: ai schema is internal and should NOT be exposed to PUBLIC.
|
|
246
|
+
-- Access is controlled through the application's database connection.
|
|
247
|
+
|
|
248
|
+
-- ============================================================================
|
|
249
|
+
-- PART 4: STORAGE SCHEMA (buckets, objects)
|
|
250
|
+
-- ============================================================================
|
|
251
|
+
|
|
252
|
+
-- 4.1 Create the storage schema
|
|
253
|
+
CREATE SCHEMA IF NOT EXISTS storage;
|
|
254
|
+
|
|
255
|
+
-- 4.2 Drop FK constraints from _storage before moving
|
|
256
|
+
ALTER TABLE public._storage
|
|
257
|
+
DROP CONSTRAINT IF EXISTS _storage_bucket_fkey;
|
|
258
|
+
|
|
259
|
+
ALTER TABLE public._storage
|
|
260
|
+
DROP CONSTRAINT IF EXISTS _storage_uploaded_by_fkey;
|
|
261
|
+
|
|
262
|
+
-- 4.3 Move _storage_buckets table to storage schema and rename to 'buckets'
|
|
263
|
+
ALTER TABLE public._storage_buckets SET SCHEMA storage;
|
|
264
|
+
ALTER TABLE storage._storage_buckets RENAME TO buckets;
|
|
265
|
+
|
|
266
|
+
-- 4.4 Move _storage table to storage schema and rename to 'objects'
|
|
267
|
+
ALTER TABLE public._storage SET SCHEMA storage;
|
|
268
|
+
ALTER TABLE storage._storage RENAME TO objects;
|
|
269
|
+
|
|
270
|
+
-- 4.5 Recreate FK: storage.objects.bucket -> storage.buckets(name)
|
|
271
|
+
ALTER TABLE storage.objects
|
|
272
|
+
ADD CONSTRAINT objects_bucket_fkey
|
|
273
|
+
FOREIGN KEY (bucket) REFERENCES storage.buckets(name) ON DELETE CASCADE;
|
|
274
|
+
|
|
275
|
+
-- 4.6 Recreate FK: storage.objects.uploaded_by -> auth.users(id)
|
|
276
|
+
ALTER TABLE storage.objects
|
|
277
|
+
ADD CONSTRAINT objects_uploaded_by_fkey
|
|
278
|
+
FOREIGN KEY (uploaded_by) REFERENCES auth.users(id) ON DELETE SET NULL;
|
|
279
|
+
|
|
280
|
+
-- Note: storage schema is internal and should NOT be exposed to PUBLIC.
|
|
281
|
+
-- Access is controlled through the application's database connection.
|
|
282
|
+
|
|
283
|
+
-- ============================================================================
|
|
284
|
+
-- PART 5: FUNCTIONS SCHEMA (definitions)
|
|
285
|
+
-- ============================================================================
|
|
286
|
+
|
|
287
|
+
-- 5.1 Create the functions schema
|
|
288
|
+
CREATE SCHEMA IF NOT EXISTS functions;
|
|
289
|
+
|
|
290
|
+
-- 5.2 Move _functions table to functions schema and rename to 'definitions'
|
|
291
|
+
ALTER TABLE public._functions SET SCHEMA functions;
|
|
292
|
+
ALTER TABLE functions._functions RENAME TO definitions;
|
|
293
|
+
|
|
294
|
+
-- Note: functions schema is internal and should NOT be exposed to PUBLIC.
|
|
295
|
+
-- Access is controlled through the application's database connection.
|
|
296
|
+
|
|
297
|
+
-- ============================================================================
|
|
298
|
+
-- PART 6: UTILITY FUNCTIONS CLEANUP
|
|
299
|
+
-- ============================================================================
|
|
300
|
+
|
|
301
|
+
-- 6.1 Create system.update_updated_at() function (replaces public.update_updated_at_column)
|
|
302
|
+
CREATE OR REPLACE FUNCTION system.update_updated_at()
|
|
303
|
+
RETURNS trigger AS $$
|
|
304
|
+
BEGIN
|
|
305
|
+
NEW.updated_at = NOW();
|
|
306
|
+
RETURN NEW;
|
|
307
|
+
END;
|
|
308
|
+
$$ LANGUAGE plpgsql;
|
|
309
|
+
|
|
310
|
+
-- 6.2 Update all triggers to use system.update_updated_at() and rename (remove double underscore)
|
|
311
|
+
|
|
312
|
+
-- system.secrets: update__secrets_updated_at -> update_secrets_updated_at
|
|
313
|
+
DROP TRIGGER IF EXISTS update__secrets_updated_at ON system.secrets;
|
|
314
|
+
CREATE TRIGGER update_secrets_updated_at
|
|
315
|
+
BEFORE UPDATE ON system.secrets
|
|
316
|
+
FOR EACH ROW EXECUTE FUNCTION system.update_updated_at();
|
|
317
|
+
|
|
318
|
+
-- system.audit_logs: update__audit_logs_updated_at -> update_audit_logs_updated_at
|
|
319
|
+
DROP TRIGGER IF EXISTS update__audit_logs_updated_at ON system.audit_logs;
|
|
320
|
+
CREATE TRIGGER update_audit_logs_updated_at
|
|
321
|
+
BEFORE UPDATE ON system.audit_logs
|
|
322
|
+
FOR EACH ROW EXECUTE FUNCTION system.update_updated_at();
|
|
323
|
+
|
|
324
|
+
-- auth.configs: update__auth_configs_updated_at -> update_configs_updated_at
|
|
325
|
+
DROP TRIGGER IF EXISTS update__auth_configs_updated_at ON auth.configs;
|
|
326
|
+
CREATE TRIGGER update_configs_updated_at
|
|
327
|
+
BEFORE UPDATE ON auth.configs
|
|
328
|
+
FOR EACH ROW EXECUTE FUNCTION system.update_updated_at();
|
|
329
|
+
|
|
330
|
+
-- auth.oauth_configs: update__oauth_configs_updated_at -> update_oauth_configs_updated_at
|
|
331
|
+
DROP TRIGGER IF EXISTS update__oauth_configs_updated_at ON auth.oauth_configs;
|
|
332
|
+
CREATE TRIGGER update_oauth_configs_updated_at
|
|
333
|
+
BEFORE UPDATE ON auth.oauth_configs
|
|
334
|
+
FOR EACH ROW EXECUTE FUNCTION system.update_updated_at();
|
|
335
|
+
|
|
336
|
+
-- auth.email_otps: update__email_otps_updated_at -> update_email_otps_updated_at
|
|
337
|
+
DROP TRIGGER IF EXISTS update__email_otps_updated_at ON auth.email_otps;
|
|
338
|
+
CREATE TRIGGER update_email_otps_updated_at
|
|
339
|
+
BEFORE UPDATE ON auth.email_otps
|
|
340
|
+
FOR EACH ROW EXECUTE FUNCTION system.update_updated_at();
|
|
341
|
+
|
|
342
|
+
-- functions.definitions: update__edge_functions_updated_at -> update_definitions_updated_at
|
|
343
|
+
DROP TRIGGER IF EXISTS update__edge_functions_updated_at ON functions.definitions;
|
|
344
|
+
CREATE TRIGGER update_definitions_updated_at
|
|
345
|
+
BEFORE UPDATE ON functions.definitions
|
|
346
|
+
FOR EACH ROW EXECUTE FUNCTION system.update_updated_at();
|
|
347
|
+
|
|
348
|
+
-- realtime.channels: trg_channels_updated_at -> update_channels_updated_at
|
|
349
|
+
DROP TRIGGER IF EXISTS trg_channels_updated_at ON realtime.channels;
|
|
350
|
+
CREATE TRIGGER update_channels_updated_at
|
|
351
|
+
BEFORE UPDATE ON realtime.channels
|
|
352
|
+
FOR EACH ROW EXECUTE FUNCTION system.update_updated_at();
|
|
353
|
+
|
|
354
|
+
-- 6.3 Move reload_postgrest_schema to system schema
|
|
355
|
+
-- Recreate in system schema (ALTER FUNCTION SET SCHEMA doesn't work well with search_path)
|
|
356
|
+
CREATE OR REPLACE FUNCTION system.reload_postgrest_schema()
|
|
357
|
+
RETURNS void AS $$
|
|
358
|
+
BEGIN
|
|
359
|
+
NOTIFY pgrst, 'reload schema';
|
|
360
|
+
RAISE NOTICE 'PostgREST schema reload notification sent';
|
|
361
|
+
END
|
|
362
|
+
$$ LANGUAGE plpgsql;
|
|
363
|
+
|
|
364
|
+
-- 6.4 Move event trigger functions to system schema
|
|
365
|
+
-- These functions auto-create project_admin_policy when RLS is enabled on tables
|
|
366
|
+
|
|
367
|
+
-- First, drop the event triggers (they reference the old functions)
|
|
368
|
+
DROP EVENT TRIGGER IF EXISTS create_policies_on_table_create;
|
|
369
|
+
DROP EVENT TRIGGER IF EXISTS create_policies_on_rls_enable;
|
|
370
|
+
|
|
371
|
+
-- Recreate functions in system schema
|
|
372
|
+
CREATE OR REPLACE FUNCTION system.create_default_policies()
|
|
373
|
+
RETURNS event_trigger AS $$
|
|
374
|
+
DECLARE
|
|
375
|
+
obj record;
|
|
376
|
+
table_schema text;
|
|
377
|
+
table_name text;
|
|
378
|
+
has_rls boolean;
|
|
379
|
+
BEGIN
|
|
380
|
+
FOR obj IN SELECT * FROM pg_event_trigger_ddl_commands() WHERE command_tag = 'CREATE TABLE'
|
|
381
|
+
LOOP
|
|
382
|
+
SELECT INTO table_schema, table_name
|
|
383
|
+
split_part(obj.object_identity, '.', 1),
|
|
384
|
+
trim(both '"' from split_part(obj.object_identity, '.', 2));
|
|
385
|
+
SELECT INTO has_rls
|
|
386
|
+
rowsecurity
|
|
387
|
+
FROM pg_tables
|
|
388
|
+
WHERE schemaname = table_schema
|
|
389
|
+
AND tablename = table_name;
|
|
390
|
+
IF has_rls THEN
|
|
391
|
+
EXECUTE format('CREATE POLICY "project_admin_policy" ON %s FOR ALL TO project_admin USING (true) WITH CHECK (true)', obj.object_identity);
|
|
392
|
+
END IF;
|
|
393
|
+
END LOOP;
|
|
394
|
+
END;
|
|
395
|
+
$$ LANGUAGE plpgsql;
|
|
396
|
+
|
|
397
|
+
CREATE OR REPLACE FUNCTION system.create_policies_after_rls()
|
|
398
|
+
RETURNS event_trigger AS $$
|
|
399
|
+
DECLARE
|
|
400
|
+
obj record;
|
|
401
|
+
table_schema text;
|
|
402
|
+
table_name text;
|
|
403
|
+
BEGIN
|
|
404
|
+
FOR obj IN SELECT * FROM pg_event_trigger_ddl_commands() WHERE command_tag = 'ALTER TABLE'
|
|
405
|
+
LOOP
|
|
406
|
+
SELECT INTO table_schema, table_name
|
|
407
|
+
split_part(obj.object_identity, '.', 1),
|
|
408
|
+
trim(both '"' from split_part(obj.object_identity, '.', 2));
|
|
409
|
+
IF EXISTS (
|
|
410
|
+
SELECT 1 FROM pg_tables
|
|
411
|
+
WHERE schemaname = table_schema
|
|
412
|
+
AND tablename = table_name
|
|
413
|
+
AND rowsecurity = true
|
|
414
|
+
) AND NOT EXISTS (
|
|
415
|
+
SELECT 1 FROM pg_policies
|
|
416
|
+
WHERE schemaname = table_schema
|
|
417
|
+
AND tablename = table_name
|
|
418
|
+
) THEN
|
|
419
|
+
EXECUTE format('CREATE POLICY "project_admin_policy" ON %s FOR ALL TO project_admin USING (true) WITH CHECK (true)', obj.object_identity);
|
|
420
|
+
END IF;
|
|
421
|
+
END LOOP;
|
|
422
|
+
END;
|
|
423
|
+
$$ LANGUAGE plpgsql;
|
|
424
|
+
|
|
425
|
+
-- Recreate event triggers pointing to system schema functions
|
|
426
|
+
CREATE EVENT TRIGGER create_policies_on_table_create
|
|
427
|
+
ON ddl_command_end
|
|
428
|
+
WHEN TAG IN ('CREATE TABLE')
|
|
429
|
+
EXECUTE FUNCTION system.create_default_policies();
|
|
430
|
+
|
|
431
|
+
CREATE EVENT TRIGGER create_policies_on_rls_enable
|
|
432
|
+
ON ddl_command_end
|
|
433
|
+
WHEN TAG IN ('ALTER TABLE')
|
|
434
|
+
EXECUTE FUNCTION system.create_policies_after_rls();
|
|
435
|
+
|
|
436
|
+
-- 6.5 Drop obsolete functions
|
|
437
|
+
DROP FUNCTION IF EXISTS public.create_default_policies() CASCADE;
|
|
438
|
+
DROP FUNCTION IF EXISTS public.create_policies_after_rls() CASCADE;
|
|
439
|
+
DROP FUNCTION IF EXISTS public.reload_postgrest_schema() CASCADE;
|
|
440
|
+
DROP FUNCTION IF EXISTS public.update_updated_at_column() CASCADE;
|
|
441
|
+
DROP FUNCTION IF EXISTS realtime.update_updated_at() CASCADE;
|