Skip to content

feat: add managed warehouse provisioning UI and Django proxy#51712

Merged
EDsCODE merged 24 commits intomasterfrom
eric/warehouse-provisioning-ui
Apr 6, 2026
Merged

feat: add managed warehouse provisioning UI and Django proxy#51712
EDsCODE merged 24 commits intomasterfrom
eric/warehouse-provisioning-ui

Conversation

@EDsCODE
Copy link
Copy Markdown
Collaborator

@EDsCODE EDsCODE commented Mar 19, 2026

Problem

Teams need a managed data warehouse with dedicated Aurora, S3, and isolated compute. This PR adds the provisioning UI and Django proxy layer for the duckgres provisioning service.

Changes

Frontend:

  • Settings tab in Data Warehouse (gated behind data-managed-warehouse feature flag)
  • Database name input with debounced availability check
  • Provision/deprovision flows with confirmation dialogs
  • Show-once password pattern: password displayed in a dismissible warning banner immediately after provisioning, never shown again
  • Reset password button for lost credentials
  • Connection details (host, port, database, username) displayed when warehouse is ready
  • Kea logic with auto-polling during in-progress states

Backend:

  • Django proxy endpoints on DataWarehouseViewSet forwarding to duckgres provisioning service:
    • POST provision — start provisioning, returns root password (show-once)
    • POST deprovision — start deprovisioning
    • GET warehouse_status — current status + connection details when ready
    • GET check-database-name — database name availability check
    • POST reset-password — generate new root password (show-once)
  • @extend_schema annotations on all endpoints
  • Feature flag gate (data-managed-warehouse) on all endpoints
  • DUCKGRES_API_URL and DUCKGRES_INTERNAL_SECRET settings

Companion PR

How did you test this code?

  • Local QA: full provision→ready→deprovision flow from PostHog UI against local duckgres cluster
  • Verified Django proxy error handling (timeout, connection refused, auth failure)
  • 🤖 This PR was co-authored by an LLM agent. Manual QA was performed against a local duckgres instance.

Publish to changelog?

no

🤖 LLM context

Co-authored with Claude Code. Key design decisions:

  • Show-once password pattern (industry standard for managed DB services) — plaintext never stored server-side
  • Feature flag uses team.uuid + org/project groups matching the ducklake copy workflow pattern
  • Types simplified to match actual duckgres status API response shape

Frontend:
- SettingsTab with provision/deprovision buttons, status polling, and
  connection details display (host, port, database, username, psql command)
- warehouseProvisioningLogic (kea) with auto-polling during in-progress states
- API methods: provisionWarehouse, deprovisionWarehouse, warehouseStatus

Backend:
- Django proxy endpoints on DataWarehouseViewSet that forward to duckgres
  provisioning service (POST provision, POST deprovision, GET warehouse_status)
- DUCKGRES_PROVISIONING_URL and DUCKGRES_PROVISIONING_TOKEN settings

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Mar 19, 2026

Size Change: +3.83 kB (0%)

Total Size: 127 MB

ℹ️ View Unchanged
Filename Size Change
frontend/dist/368Hedgehogs 5.26 kB 0 B
frontend/dist/abap 14.2 kB 0 B
frontend/dist/Action 23.8 kB 0 B
frontend/dist/Actions 1.02 kB 0 B
frontend/dist/AdvancedActivityLogsScene 33.9 kB 0 B
frontend/dist/AgenticAuthorize 5.25 kB 0 B
frontend/dist/apex 3.95 kB 0 B
frontend/dist/ApprovalDetail 16.2 kB 0 B
frontend/dist/array.full.es5.js 326 kB 0 B
frontend/dist/array.full.js 421 kB 0 B
frontend/dist/array.js 177 kB 0 B
frontend/dist/AsyncMigrations 13.1 kB 0 B
frontend/dist/AuthorizationStatus 716 B 0 B
frontend/dist/azcli 846 B 0 B
frontend/dist/bat 1.84 kB 0 B
frontend/dist/BatchExportScene 60.3 kB 0 B
frontend/dist/bicep 2.55 kB 0 B
frontend/dist/Billing 493 B 0 B
frontend/dist/BillingSection 20.8 kB 0 B
frontend/dist/BoxPlot 4.99 kB 0 B
frontend/dist/browserAll-0QZMN1W2 37.4 kB 0 B
frontend/dist/ButtonPrimitives 562 B 0 B
frontend/dist/CalendarHeatMap 4.79 kB 0 B
frontend/dist/cameligo 2.18 kB 0 B
frontend/dist/changeRequestsLogic 544 B 0 B
frontend/dist/CLIAuthorize 11.3 kB 0 B
frontend/dist/CLILive 3.97 kB 0 B
frontend/dist/clojure 9.64 kB 0 B
frontend/dist/coffee 3.59 kB 0 B
frontend/dist/Cohort 23.2 kB 0 B
frontend/dist/CohortCalculationHistory 6.22 kB 0 B
frontend/dist/Cohorts 9.39 kB 0 B
frontend/dist/ConfirmOrganization 4.48 kB 0 B
frontend/dist/conversations.js 63.9 kB 0 B
frontend/dist/Coupons 720 B 0 B
frontend/dist/cpp 5.3 kB 0 B
frontend/dist/Create 829 B 0 B
frontend/dist/crisp-chat-integration.js 1.88 kB 0 B
frontend/dist/csharp 4.52 kB 0 B
frontend/dist/csp 1.42 kB 0 B
frontend/dist/css 4.51 kB 0 B
frontend/dist/cssMode 4.15 kB 0 B
frontend/dist/CustomCssScene 3.55 kB 0 B
frontend/dist/CustomerAnalyticsConfigurationScene 1.99 kB 0 B
frontend/dist/CustomerAnalyticsScene 26.1 kB 0 B
frontend/dist/CustomerJourneyBuilderScene 1.6 kB 0 B
frontend/dist/CustomerJourneyTemplatesScene 7.39 kB 0 B
frontend/dist/customizations.full.js 17.9 kB 0 B
frontend/dist/CyclotronJobInputAssignee 1.32 kB 0 B
frontend/dist/CyclotronJobInputTicketTags 711 B 0 B
frontend/dist/cypher 3.38 kB 0 B
frontend/dist/dart 4.25 kB 0 B
frontend/dist/Dashboard 1.04 kB 0 B
frontend/dist/Dashboards 20 kB 0 B
frontend/dist/DataManagementScene 646 B 0 B
frontend/dist/DataPipelinesNewScene 2.28 kB 0 B
frontend/dist/DataWarehouseScene 1.19 kB 0 B
frontend/dist/DataWarehouseSourceScene 634 B 0 B
frontend/dist/Deactivated 1.13 kB 0 B
frontend/dist/dead-clicks-autocapture.js 13.1 kB 0 B
frontend/dist/DeadLetterQueue 5.38 kB 0 B
frontend/dist/DebugScene 20 kB 0 B
frontend/dist/decompressionWorker 2.85 kB 0 B
frontend/dist/decompressionWorker.js 2.85 kB 0 B
frontend/dist/DefinitionEdit 7.11 kB 0 B
frontend/dist/DefinitionView 22.7 kB 0 B
frontend/dist/DestinationsScene 2.67 kB 0 B
frontend/dist/dist 575 B 0 B
frontend/dist/dockerfile 1.87 kB 0 B
frontend/dist/EarlyAccessFeature 719 B 0 B
frontend/dist/EarlyAccessFeatures 2.84 kB 0 B
frontend/dist/ecl 5.33 kB 0 B
frontend/dist/EditorScene 896 B 0 B
frontend/dist/elixir 10.3 kB 0 B
frontend/dist/elk.bundled 1.44 MB 0 B
frontend/dist/EmailMFAVerify 2.98 kB 0 B
frontend/dist/EndpointScene 37.5 kB 0 B
frontend/dist/EndpointsScene 22 kB 0 B
frontend/dist/ErrorTrackingConfigurationScene 2.2 kB 0 B
frontend/dist/ErrorTrackingIssueFingerprintsScene 6.98 kB 0 B
frontend/dist/ErrorTrackingIssueScene 81.9 kB 0 B
frontend/dist/ErrorTrackingScene 13.2 kB 0 B
frontend/dist/EvaluationTemplates 575 B 0 B
frontend/dist/EventsScene 2.46 kB 0 B
frontend/dist/exception-autocapture.js 11.8 kB 0 B
frontend/dist/Experiment 246 kB 0 B
frontend/dist/Experiments 17.1 kB 0 B
frontend/dist/exporter 20.7 MB +639 B (0%)
frontend/dist/exporter.js 20.7 MB +639 B (0%)
frontend/dist/ExportsScene 3.86 kB 0 B
frontend/dist/FeatureFlag 127 kB 0 B
frontend/dist/FeatureFlags 572 B 0 B
frontend/dist/FeatureFlagTemplatesScene 7.03 kB 0 B
frontend/dist/FlappyHog 5.78 kB 0 B
frontend/dist/flow9 1.8 kB 0 B
frontend/dist/freemarker2 16.7 kB 0 B
frontend/dist/fsharp 2.98 kB 0 B
frontend/dist/go 2.65 kB 0 B
frontend/dist/graphql 2.26 kB 0 B
frontend/dist/Group 14.3 kB 0 B
frontend/dist/Groups 3.93 kB 0 B
frontend/dist/GroupsNew 7.34 kB 0 B
frontend/dist/handlebars 7.34 kB 0 B
frontend/dist/hcl 3.59 kB 0 B
frontend/dist/HealthCategoryDetailScene 7.23 kB 0 B
frontend/dist/HealthScene 10.3 kB 0 B
frontend/dist/HeatmapNewScene 4.16 kB 0 B
frontend/dist/HeatmapRecordingScene 3.92 kB 0 B
frontend/dist/HeatmapScene 6.04 kB 0 B
frontend/dist/HeatmapsScene 3.88 kB 0 B
frontend/dist/hls 394 kB 0 B
frontend/dist/HogFunctionScene 58.8 kB 0 B
frontend/dist/HogRepl 7.37 kB 0 B
frontend/dist/html 5.58 kB 0 B
frontend/dist/htmlMode 4.62 kB 0 B
frontend/dist/image-blob-reduce.esm 49.4 kB 0 B
frontend/dist/InboxScene 59.1 kB 0 B
frontend/dist/index 306 kB 0 B
frontend/dist/index.js 306 kB 0 B
frontend/dist/ini 1.1 kB 0 B
frontend/dist/InsightOptions 5.41 kB 0 B
frontend/dist/InsightScene 28.8 kB 0 B
frontend/dist/IntegrationsRedirect 733 B 0 B
frontend/dist/intercom-integration.js 1.93 kB 0 B
frontend/dist/InviteSignup 14.4 kB 0 B
frontend/dist/java 3.22 kB 0 B
frontend/dist/javascript 985 B 0 B
frontend/dist/jsonMode 13.9 kB 0 B
frontend/dist/julia 7.22 kB 0 B
frontend/dist/kotlin 3.4 kB 0 B
frontend/dist/lazy 150 kB 0 B
frontend/dist/LegacyPluginScene 26.6 kB 0 B
frontend/dist/LemonTextAreaMarkdown 502 B 0 B
frontend/dist/less 3.9 kB 0 B
frontend/dist/lexon 2.44 kB 0 B
frontend/dist/lib 2.22 kB 0 B
frontend/dist/Link 468 B 0 B
frontend/dist/LinkScene 24.8 kB 0 B
frontend/dist/LinksScene 4.19 kB 0 B
frontend/dist/liquid 4.53 kB 0 B
frontend/dist/LiveDebugger 19.1 kB 0 B
frontend/dist/LiveEventsTable 2.98 kB 0 B
frontend/dist/LLMAnalyticsClusterScene 15.7 kB 0 B
frontend/dist/LLMAnalyticsClustersScene 43 kB 0 B
frontend/dist/LLMAnalyticsDatasetScene 19.7 kB 0 B
frontend/dist/LLMAnalyticsDatasetsScene 3.28 kB 0 B
frontend/dist/LLMAnalyticsEvaluation 40.7 kB 0 B
frontend/dist/LLMAnalyticsEvaluationsScene 29.5 kB 0 B
frontend/dist/LLMAnalyticsPlaygroundScene 36.3 kB 0 B
frontend/dist/LLMAnalyticsScene 116 kB 0 B
frontend/dist/LLMAnalyticsSessionScene 13.4 kB 0 B
frontend/dist/LLMAnalyticsTraceScene 127 kB 0 B
frontend/dist/LLMAnalyticsUsers 526 B 0 B
frontend/dist/LLMASessionFeedbackDisplay 4.83 kB 0 B
frontend/dist/LLMPromptScene 20.6 kB 0 B
frontend/dist/LLMPromptsScene 4.21 kB 0 B
frontend/dist/Login 8.57 kB 0 B
frontend/dist/Login2FA 4.2 kB 0 B
frontend/dist/logs.js 38.5 kB 0 B
frontend/dist/LogsScene 8.07 kB 0 B
frontend/dist/lua 2.11 kB 0 B
frontend/dist/m3 2.81 kB 0 B
frontend/dist/main 819 kB 0 B
frontend/dist/ManagedMigration 14 kB 0 B
frontend/dist/markdown 3.79 kB 0 B
frontend/dist/MarketingAnalyticsScene 24.7 kB 0 B
frontend/dist/MaterializedColumns 10.2 kB 0 B
frontend/dist/Max 835 B 0 B
frontend/dist/mdx 5.39 kB 0 B
frontend/dist/MessageTemplate 16.3 kB 0 B
frontend/dist/MetricsScene 828 B 0 B
frontend/dist/mips 2.58 kB 0 B
frontend/dist/ModelsScene 13.6 kB 0 B
frontend/dist/MonacoDiffEditor 403 B 0 B
frontend/dist/monacoEditorWorker 288 kB 0 B
frontend/dist/monacoEditorWorker.js 288 kB 0 B
frontend/dist/monacoJsonWorker 419 kB 0 B
frontend/dist/monacoJsonWorker.js 419 kB 0 B
frontend/dist/monacoTsWorker 7.02 MB 0 B
frontend/dist/monacoTsWorker.js 7.02 MB 0 B
frontend/dist/MoveToPostHogCloud 4.46 kB 0 B
frontend/dist/msdax 4.91 kB 0 B
frontend/dist/mysql 11.3 kB 0 B
frontend/dist/NavTabChat 4.68 kB 0 B
frontend/dist/NewSourceWizard 724 B 0 B
frontend/dist/NewTabScene 681 B 0 B
frontend/dist/NodeDetailScene 16.3 kB 0 B
frontend/dist/NotebookCanvasScene 3.06 kB 0 B
frontend/dist/NotebookPanel 5.08 kB 0 B
frontend/dist/NotebookScene 8.07 kB 0 B
frontend/dist/NotebooksScene 7.58 kB 0 B
frontend/dist/OAuthAuthorize 573 B 0 B
frontend/dist/objective-c 2.41 kB 0 B
frontend/dist/Onboarding 683 kB 0 B
frontend/dist/OnboardingCouponRedemption 1.2 kB 0 B
frontend/dist/pascal 2.99 kB 0 B
frontend/dist/pascaligo 2 kB 0 B
frontend/dist/passkeyLogic 484 B 0 B
frontend/dist/PasswordReset 4.32 kB 0 B
frontend/dist/PasswordResetComplete 2.94 kB 0 B
frontend/dist/perl 8.25 kB 0 B
frontend/dist/PersonScene 16 kB 0 B
frontend/dist/PersonsScene 4.73 kB 0 B
frontend/dist/pgsql 13.5 kB 0 B
frontend/dist/php 8.02 kB 0 B
frontend/dist/PipelineStatusScene 6.22 kB 0 B
frontend/dist/pla 1.67 kB 0 B
frontend/dist/posthog 250 kB 0 B
frontend/dist/postiats 7.86 kB 0 B
frontend/dist/powerquery 16.9 kB 0 B
frontend/dist/powershell 3.27 kB 0 B
frontend/dist/PreflightCheck 5.53 kB 0 B
frontend/dist/product-tours.js 115 kB 0 B
frontend/dist/ProductTour 274 kB 0 B
frontend/dist/ProductTours 4.7 kB 0 B
frontend/dist/ProjectHomepage 24.9 kB 0 B
frontend/dist/protobuf 9.05 kB 0 B
frontend/dist/pug 4.82 kB 0 B
frontend/dist/python 4.76 kB 0 B
frontend/dist/qsharp 3.19 kB 0 B
frontend/dist/r 3.12 kB 0 B
frontend/dist/razor 9.35 kB 0 B
frontend/dist/recorder-v2.js 111 kB 0 B
frontend/dist/recorder.js 111 kB 0 B
frontend/dist/redis 3.55 kB 0 B
frontend/dist/redshift 11.8 kB 0 B
frontend/dist/RegionMap 29.4 kB 0 B
frontend/dist/render-query 20.4 MB +639 B (0%)
frontend/dist/render-query.js 20.4 MB +639 B (0%)
frontend/dist/ResourceTransfer 9.17 kB 0 B
frontend/dist/restructuredtext 3.9 kB 0 B
frontend/dist/RevenueAnalyticsScene 25.6 kB 0 B
frontend/dist/ruby 8.5 kB 0 B
frontend/dist/rust 4.16 kB 0 B
frontend/dist/SavedInsights 664 B 0 B
frontend/dist/sb 1.82 kB 0 B
frontend/dist/scala 7.32 kB 0 B
frontend/dist/scheme 1.76 kB 0 B
frontend/dist/scss 6.41 kB 0 B
frontend/dist/SdkDoctorScene 9.42 kB 0 B
frontend/dist/SessionAttributionExplorerScene 6.6 kB 0 B
frontend/dist/SessionGroupSummariesTable 4.62 kB 0 B
frontend/dist/SessionGroupSummaryScene 17 kB 0 B
frontend/dist/SessionProfileScene 15.8 kB 0 B
frontend/dist/SessionRecordingDetail 1.73 kB 0 B
frontend/dist/SessionRecordingFilePlaybackScene 4.46 kB 0 B
frontend/dist/SessionRecordings 742 B 0 B
frontend/dist/SessionRecordingsKiosk 8.84 kB 0 B
frontend/dist/SessionRecordingsPlaylistScene 4.14 kB 0 B
frontend/dist/SessionRecordingsSettingsScene 1.9 kB 0 B
frontend/dist/SessionsScene 3.86 kB 0 B
frontend/dist/SettingsScene 2.98 kB 0 B
frontend/dist/SharedMetric 15.7 kB 0 B
frontend/dist/SharedMetrics 549 B 0 B
frontend/dist/shell 3.07 kB 0 B
frontend/dist/SignupContainer 24.5 kB 0 B
frontend/dist/Site 1.18 kB 0 B
frontend/dist/solidity 18.6 kB 0 B
frontend/dist/sophia 2.76 kB 0 B
frontend/dist/SourcesScene 5.96 kB 0 B
frontend/dist/sourceWizardLogic 662 B 0 B
frontend/dist/sparql 2.55 kB 0 B
frontend/dist/sql 10.3 kB 0 B
frontend/dist/SqlVariableEditScene 7.24 kB 0 B
frontend/dist/st 7.4 kB 0 B
frontend/dist/StartupProgram 21.2 kB 0 B
frontend/dist/SupportSettingsScene 40.7 kB 0 B
frontend/dist/SupportTicketScene 23 kB 0 B
frontend/dist/SupportTicketsScene 733 B 0 B
frontend/dist/Survey 746 B 0 B
frontend/dist/SurveyFormBuilder 1.54 kB 0 B
frontend/dist/Surveys 18.2 kB 0 B
frontend/dist/surveys.js 89.8 kB 0 B
frontend/dist/SurveyWizard 57.6 kB 0 B
frontend/dist/swift 5.26 kB 0 B
frontend/dist/SystemStatus 16.8 kB 0 B
frontend/dist/systemverilog 7.61 kB 0 B
frontend/dist/TaskDetailScene 20.1 kB 0 B
frontend/dist/TaskTracker 13.1 kB 0 B
frontend/dist/tcl 3.57 kB 0 B
frontend/dist/TextCardMarkdownEditor 11 kB 0 B
frontend/dist/toolbar 10.1 MB +639 B (+0.01%)
frontend/dist/toolbar.js 10.1 MB +639 B (+0.01%)
frontend/dist/ToolbarLaunch 2.52 kB 0 B
frontend/dist/tracing-headers.js 1.74 kB 0 B
frontend/dist/TracingScene 29.3 kB 0 B
frontend/dist/TransformationsScene 1.91 kB 0 B
frontend/dist/tsMode 24 kB 0 B
frontend/dist/twig 5.97 kB 0 B
frontend/dist/TwoFactorReset 3.98 kB 0 B
frontend/dist/typescript 240 B 0 B
frontend/dist/typespec 2.82 kB 0 B
frontend/dist/Unsubscribe 1.62 kB 0 B
frontend/dist/UserInterview 4.53 kB 0 B
frontend/dist/UserInterviews 2.01 kB 0 B
frontend/dist/vb 5.79 kB 0 B
frontend/dist/VercelConnect 4.95 kB 0 B
frontend/dist/VercelLinkError 1.91 kB 0 B
frontend/dist/VerifyEmail 4.48 kB 0 B
frontend/dist/vimMode 211 kB 0 B
frontend/dist/VisualReviewRunScene 18.6 kB 0 B
frontend/dist/VisualReviewRunsScene 6.16 kB 0 B
frontend/dist/VisualReviewSettingsScene 10.6 kB 0 B
frontend/dist/web-vitals.js 6.39 kB 0 B
frontend/dist/WebAnalyticsScene 5.77 kB 0 B
frontend/dist/WebGLRenderer-DYjOwNoG 60.3 kB 0 B
frontend/dist/WebGPURenderer-B_wkl_Ja 36.3 kB 0 B
frontend/dist/WebScriptsScene 2.54 kB 0 B
frontend/dist/webworkerAll-puPV1rBA 324 B 0 B
frontend/dist/wgsl 7.34 kB 0 B
frontend/dist/Wizard 4.45 kB 0 B
frontend/dist/WorkflowScene 101 kB 0 B
frontend/dist/WorkflowsScene 46.9 kB 0 B
frontend/dist/WorldMap 4.73 kB 0 B
frontend/dist/xml 2.98 kB 0 B
frontend/dist/yaml 4.6 kB 0 B

compressed-size-action

github-actions bot and others added 2 commits March 19, 2026 23:28
- Switch from Authorization: Bearer to X-Duckgres-Internal-Secret header
- Update API paths from /teams/ to /orgs/ to match duckgres rename
- Rename settings: DUCKGRES_PROVISIONING_URL → DUCKGRES_API_URL,
  DUCKGRES_PROVISIONING_TOKEN → DUCKGRES_INTERNAL_SECRET

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
EDsCODE and others added 5 commits March 24, 2026 09:34
The Duckling XRD no longer accepts an image field — the duckgres
Helm chart manages the container image separately.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…etails UI

Frontend:
- Database name field with debounced uniqueness check via kea logic
- Green check when available, red X otherwise (including API errors)
- Provision button disabled until name confirmed available
- Connection details use CodeSnippet with copy buttons in 2x2 grid
- Password field with show/hide toggle
- Remove component subcategories from status card
- Center CodeSnippet copy icon vertically (compact mode fix)

Backend:
- Add check_database_name endpoint proxying to duckgres
- Provision endpoint now accepts and requires database_name
- Fix warehouse_status path to /warehouse/status

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@EDsCODE EDsCODE changed the title Add managed warehouse provisioning UI and Django proxy feat: add managed warehouse provisioning UI and Django proxy Mar 31, 2026
@github-actions
Copy link
Copy Markdown
Contributor

MCP UI Apps size report

App JS CSS
debug 545.4 KB 23.6 KB
action 530.1 KB 23.6 KB
action-list 536.2 KB 23.6 KB
cohort 529.2 KB 23.6 KB
cohort-list 535.2 KB 23.6 KB
error-details 538.1 KB 23.6 KB
error-issue 529.8 KB 23.6 KB
error-issue-list 536.1 KB 23.6 KB
experiment 533.5 KB 23.6 KB
experiment-list 536.9 KB 23.6 KB
experiment-results 533.1 KB 23.6 KB
feature-flag 534.0 KB 23.6 KB
feature-flag-list 540.6 KB 23.6 KB
llm-costs 534.9 KB 23.6 KB
survey 530.8 KB 23.6 KB
survey-global-stats 532.4 KB 23.6 KB
survey-list 536.9 KB 23.6 KB
survey-stats 532.4 KB 23.6 KB
workflow 529.6 KB 23.6 KB
workflow-list 535.6 KB 23.6 KB
query-results 543.6 KB 23.6 KB

tests-posthog bot and others added 2 commits March 31, 2026 19:44
@socket-security
Copy link
Copy Markdown

socket-security bot commented Apr 3, 2026

No dependency changes detected. Learn more about Socket for GitHub.

👍 No dependency changes detected in pull request

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Apr 3, 2026

🎭 Playwright report · View test results →

⚠️ 2 flaky tests:

  • Inline editing insight title via compact card popover (chromium)
  • Materialize view pane (chromium)

These issues are not necessarily caused by your changes.
Annoyed by this comment? Help fix flakies and failures and it'll disappear!

@EDsCODE EDsCODE marked this pull request as ready for review April 3, 2026 19:47
@assign-reviewers-posthog assign-reviewers-posthog bot requested a review from a team April 3, 2026 19:47
@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps bot commented Apr 3, 2026

Comments Outside Diff (3)

  1. frontend/src/scenes/data-warehouse/scene/SettingsTab.tsx, line 333-342 (link)

    P1 Retry provisioning called with no databaseName

    The "Retry provisioning" button calls provisionWarehouse() without any argument. The action is defined as provisionWarehouse: (params: { databaseName: string }) => params, so when params is undefined, destructuring { databaseName } in the listener will throw a TypeError at runtime. Even if that is somehow swallowed, the API call passes undefined as database_name, and the backend immediately returns HTTP 400 because that field is required.

    For the retry path the backend still requires database_name. Either:

    1. Store the previously-used database name in the kea reducer and reuse it for retries, or
    2. Pass the current form value just as the initial provision does.
    Prompt To Fix With AI
    This is a comment left during a code review.
    Path: frontend/src/scenes/data-warehouse/scene/SettingsTab.tsx
    Line: 333-342
    
    Comment:
    **Retry provisioning called with no `databaseName`**
    
    The "Retry provisioning" button calls `provisionWarehouse()` without any argument. The action is defined as `provisionWarehouse: (params: { databaseName: string }) => params`, so when `params` is `undefined`, destructuring `{ databaseName }` in the listener will throw a `TypeError` at runtime. Even if that is somehow swallowed, the API call passes `undefined` as `database_name`, and the backend immediately returns `HTTP 400` because that field is required.
    
    For the retry path the backend still requires `database_name`. Either:
    1. Store the previously-used database name in the kea reducer and reuse it for retries, or
    2. Pass the current form value just as the initial provision does.
    
    
    
    How can I resolve this? If you propose a fix, please make it concise.
  2. products/data_warehouse/backend/api/data_warehouse.py, line 731-749 (link)

    P2 HTTP boilerplate duplicated from _provisioning_request

    check_database_name manually repeats the base_url / token / headers setup and the HTTP call that _provisioning_request already encapsulates. The only difference is that this endpoint lives at a different path (/api/v1/database-name/check) and is not team-scoped. A small refactor — for example, adding an optional flag to skip the org prefix, or extracting a lower-level _raw_provisioning_request helper — would eliminate the duplication and make error handling consistent.

    @action(methods=["GET"], detail=False, url_path="check-database-name")
    def check_database_name(self, request: Request, **kwargs) -> Response:
        """Check if a database name is available."""
        name = request.query_params.get("name")
        if not name:
            return Response({"error": "name query parameter is required"}, status=status.HTTP_400_BAD_REQUEST)
        return self._provisioning_request("GET", f"/database-name/check?name={name}", org_scoped=False)
    Prompt To Fix With AI
    This is a comment left during a code review.
    Path: products/data_warehouse/backend/api/data_warehouse.py
    Line: 731-749
    
    Comment:
    **HTTP boilerplate duplicated from `_provisioning_request`**
    
    `check_database_name` manually repeats the `base_url` / `token` / headers setup and the HTTP call that `_provisioning_request` already encapsulates. The only difference is that this endpoint lives at a different path (`/api/v1/database-name/check`) and is not team-scoped. A small refactor — for example, adding an optional flag to skip the org prefix, or extracting a lower-level `_raw_provisioning_request` helper — would eliminate the duplication and make error handling consistent.
    
    ```python
    @action(methods=["GET"], detail=False, url_path="check-database-name")
    def check_database_name(self, request: Request, **kwargs) -> Response:
        """Check if a database name is available."""
        name = request.query_params.get("name")
        if not name:
            return Response({"error": "name query parameter is required"}, status=status.HTTP_400_BAD_REQUEST)
        return self._provisioning_request("GET", f"/database-name/check?name={name}", org_scoped=False)
    ```
    
    How can I resolve this? If you propose a fix, please make it concise.

    Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

  3. frontend/src/scenes/data-warehouse/scene/warehouseProvisioningLogic.ts, line 546-552 (link)

    P2 Polling invariant not clearly guarded

    The pollStatus listener waits 10 s and then calls actions.loadWarehouseStatus(). The check if (!values.pollingActive) correctly short-circuits if stopPolling was dispatched during the wait. However, every new pollStatus dispatch (including the one fired by loadWarehouseStatusSuccess) resets pollingActive to true, so a stopPolling called concurrently could be immediately overwritten. Consider using kea's breakpoint pattern more explicitly, or at minimum add a comment explaining the intended invariant.

    Prompt To Fix With AI
    This is a comment left during a code review.
    Path: frontend/src/scenes/data-warehouse/scene/warehouseProvisioningLogic.ts
    Line: 546-552
    
    Comment:
    **Polling invariant not clearly guarded**
    
    The `pollStatus` listener waits 10 s and then calls `actions.loadWarehouseStatus()`. The check `if (!values.pollingActive)` correctly short-circuits if `stopPolling` was dispatched during the wait. However, every new `pollStatus` dispatch (including the one fired by `loadWarehouseStatusSuccess`) resets `pollingActive` to `true`, so a `stopPolling` called concurrently could be immediately overwritten. Consider using kea's `breakpoint` pattern more explicitly, or at minimum add a comment explaining the intended invariant.
    
    How can I resolve this? If you propose a fix, please make it concise.
Prompt To Fix All With AI
This is a comment left during a code review.
Path: frontend/src/scenes/data-warehouse/scene/SettingsTab.tsx
Line: 125-191

Comment:
**Hardcoded placeholder credentials shown to real users**

The `ConnectionDetails` component renders static hardcoded values — including a fake password `sk_phw_abc123def456` — even when the warehouse is genuinely in the `ready` state. Since `<ConnectionDetails />` is rendered whenever `isReady` is `true`, real users will see connection information that is incorrect and unusable.

The `DataWarehouseProvisioningStatus` type already exposes all the needed fields (`warehouse_database.endpoint`, `warehouse_database.port`, `warehouse_database.database_name`, `warehouse_database.username`). The component should be receiving the live status object and rendering those values instead of placeholders. If the password is not yet available from the provisioning API, that field alone can be omitted or shown as "not yet available" — but every other field should be real.

```tsx
function ConnectionDetails({ status }: { status: DataWarehouseProvisioningStatus }): JSX.Element {
    const host = status.warehouse_database.endpoint
    const port = String(status.warehouse_database.port)
    const dbName = status.warehouse_database.database_name
    const username = status.warehouse_database.username
    // ...
}
```

And at the call site:
```tsx
{isReady && <ConnectionDetails status={warehouseStatus!} />}
```

How can I resolve this? If you propose a fix, please make it concise.

---

This is a comment left during a code review.
Path: frontend/src/scenes/data-warehouse/scene/SettingsTab.tsx
Line: 333-342

Comment:
**Retry provisioning called with no `databaseName`**

The "Retry provisioning" button calls `provisionWarehouse()` without any argument. The action is defined as `provisionWarehouse: (params: { databaseName: string }) => params`, so when `params` is `undefined`, destructuring `{ databaseName }` in the listener will throw a `TypeError` at runtime. Even if that is somehow swallowed, the API call passes `undefined` as `database_name`, and the backend immediately returns `HTTP 400` because that field is required.

For the retry path the backend still requires `database_name`. Either:
1. Store the previously-used database name in the kea reducer and reuse it for retries, or
2. Pass the current form value just as the initial provision does.

```suggestion
                            onClick={() => provisionWarehouse({ databaseName })}
```

How can I resolve this? If you propose a fix, please make it concise.

---

This is a comment left during a code review.
Path: hedgebox-dummy/.next/app-build-manifest.json
Line: 1

Comment:
**Build artefacts committed to the repository**

All 19 files under `hedgebox-dummy/.next/` are compiled Next.js build output (manifests, webpack cache packs, `polyfills.js`, trace files, etc.). These should not be committed; they belong in `.gitignore`. Please add `hedgebox-dummy/.next/` to `.gitignore` and remove these files from the PR.

How can I resolve this? If you propose a fix, please make it concise.

---

This is a comment left during a code review.
Path: products/data_warehouse/backend/api/data_warehouse.py
Line: 731-749

Comment:
**HTTP boilerplate duplicated from `_provisioning_request`**

`check_database_name` manually repeats the `base_url` / `token` / headers setup and the HTTP call that `_provisioning_request` already encapsulates. The only difference is that this endpoint lives at a different path (`/api/v1/database-name/check`) and is not team-scoped. A small refactor — for example, adding an optional flag to skip the org prefix, or extracting a lower-level `_raw_provisioning_request` helper — would eliminate the duplication and make error handling consistent.

```python
@action(methods=["GET"], detail=False, url_path="check-database-name")
def check_database_name(self, request: Request, **kwargs) -> Response:
    """Check if a database name is available."""
    name = request.query_params.get("name")
    if not name:
        return Response({"error": "name query parameter is required"}, status=status.HTTP_400_BAD_REQUEST)
    return self._provisioning_request("GET", f"/database-name/check?name={name}", org_scoped=False)
```

How can I resolve this? If you propose a fix, please make it concise.

---

This is a comment left during a code review.
Path: frontend/src/scenes/data-warehouse/scene/warehouseProvisioningLogic.ts
Line: 546-552

Comment:
**Polling invariant not clearly guarded**

The `pollStatus` listener waits 10 s and then calls `actions.loadWarehouseStatus()`. The check `if (!values.pollingActive)` correctly short-circuits if `stopPolling` was dispatched during the wait. However, every new `pollStatus` dispatch (including the one fired by `loadWarehouseStatusSuccess`) resets `pollingActive` to `true`, so a `stopPolling` called concurrently could be immediately overwritten. Consider using kea's `breakpoint` pattern more explicitly, or at minimum add a comment explaining the intended invariant.

How can I resolve this? If you propose a fix, please make it concise.

Reviews (1): Last reviewed commit: "Merge branch 'master' into eric/warehous..." | Re-trigger Greptile

Comment on lines +125 to +191
<h2 className="mb-2">Managed Warehouse</h2>
<p className="text-muted mb-4">
Provision a dedicated data warehouse with Aurora, S3, and isolated compute for your team.
</p>
</div>

{warehouseStatusLoading && !warehouseStatus ? (
<div className="flex items-center gap-2">
<Spinner />
<span>Loading warehouse status...</span>
</div>
) : !hasWarehouse ? (
<div className="space-y-4">
<div>
<LemonLabel>Database name</LemonLabel>
<div className="flex items-center gap-2">
<LemonInput
value={databaseName}
onChange={setDatabaseName}
placeholder="my-warehouse"
fullWidth
/>
{databaseName &&
isValidDatabaseName &&
(databaseNameChecking ? (
<Spinner className="text-muted" />
) : databaseNameAvailable === true ? (
<IconCheck className="text-success text-xl" />
) : (
<IconX className="text-danger text-xl" />
))}
</div>
{databaseName &&
isValidDatabaseName &&
!databaseNameChecking &&
databaseNameAvailable !== true && (
<p className="text-danger text-xs mt-1">
{databaseNameAvailable === false
? 'This database name is already taken.'
: 'Unable to verify database name availability.'}
</p>
)}
{databaseName && !isValidDatabaseName && (
<p className="text-danger text-xs mt-1">
Must be 3-63 characters, start with a lowercase letter, and contain only lowercase
letters, numbers, hyphens, or underscores.
</p>
)}
{(!databaseName ||
(isValidDatabaseName && (databaseNameChecking || databaseNameAvailable === true))) && (
<p className="text-muted text-xs mt-1">
Unique name for your database. This is what you'll use in <code>dbname=</code> when
connecting.
</p>
)}
</div>
<LemonButton
type="primary"
loading={isProvisioning}
disabledReason={!canProvision ? 'Enter an available database name' : undefined}
onClick={() => {
LemonDialog.open({
title: 'Provision managed warehouse?',
description:
'This will create dedicated AWS resources (Aurora database, S3 bucket, IAM roles) for your team. This typically takes 5-15 minutes.',
primaryButton: {
children: 'Provision',
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Hardcoded placeholder credentials shown to real users

The ConnectionDetails component renders static hardcoded values — including a fake password sk_phw_abc123def456 — even when the warehouse is genuinely in the ready state. Since <ConnectionDetails /> is rendered whenever isReady is true, real users will see connection information that is incorrect and unusable.

The DataWarehouseProvisioningStatus type already exposes all the needed fields (warehouse_database.endpoint, warehouse_database.port, warehouse_database.database_name, warehouse_database.username). The component should be receiving the live status object and rendering those values instead of placeholders. If the password is not yet available from the provisioning API, that field alone can be omitted or shown as "not yet available" — but every other field should be real.

function ConnectionDetails({ status }: { status: DataWarehouseProvisioningStatus }): JSX.Element {
    const host = status.warehouse_database.endpoint
    const port = String(status.warehouse_database.port)
    const dbName = status.warehouse_database.database_name
    const username = status.warehouse_database.username
    // ...
}

And at the call site:

{isReady && <ConnectionDetails status={warehouseStatus!} />}
Prompt To Fix With AI
This is a comment left during a code review.
Path: frontend/src/scenes/data-warehouse/scene/SettingsTab.tsx
Line: 125-191

Comment:
**Hardcoded placeholder credentials shown to real users**

The `ConnectionDetails` component renders static hardcoded values — including a fake password `sk_phw_abc123def456` — even when the warehouse is genuinely in the `ready` state. Since `<ConnectionDetails />` is rendered whenever `isReady` is `true`, real users will see connection information that is incorrect and unusable.

The `DataWarehouseProvisioningStatus` type already exposes all the needed fields (`warehouse_database.endpoint`, `warehouse_database.port`, `warehouse_database.database_name`, `warehouse_database.username`). The component should be receiving the live status object and rendering those values instead of placeholders. If the password is not yet available from the provisioning API, that field alone can be omitted or shown as "not yet available" — but every other field should be real.

```tsx
function ConnectionDetails({ status }: { status: DataWarehouseProvisioningStatus }): JSX.Element {
    const host = status.warehouse_database.endpoint
    const port = String(status.warehouse_database.port)
    const dbName = status.warehouse_database.database_name
    const username = status.warehouse_database.username
    // ...
}
```

And at the call site:
```tsx
{isReady && <ConnectionDetails status={warehouseStatus!} />}
```

How can I resolve this? If you propose a fix, please make it concise.

@@ -0,0 +1,3 @@
{
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Build artefacts committed to the repository

All 19 files under hedgebox-dummy/.next/ are compiled Next.js build output (manifests, webpack cache packs, polyfills.js, trace files, etc.). These should not be committed; they belong in .gitignore. Please add hedgebox-dummy/.next/ to .gitignore and remove these files from the PR.

Prompt To Fix With AI
This is a comment left during a code review.
Path: hedgebox-dummy/.next/app-build-manifest.json
Line: 1

Comment:
**Build artefacts committed to the repository**

All 19 files under `hedgebox-dummy/.next/` are compiled Next.js build output (manifests, webpack cache packs, `polyfills.js`, trace files, etc.). These should not be committed; they belong in `.gitignore`. Please add `hedgebox-dummy/.next/` to `.gitignore` and remove these files from the PR.

How can I resolve this? If you propose a fix, please make it concise.

EDsCODE and others added 3 commits April 3, 2026 12:56
- Use withQueryString for check_database_name GET endpoint instead of passing data to get()
- Pass required databaseName param to provisionWarehouse on retry button

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Wire up real connection details from warehouseStatus.warehouse_database
  instead of hardcoded placeholders (including fake password)
- Remove accidentally committed hedgebox-dummy/.next/ build artifacts
- Add @extend_schema annotations to all 4 provisioning endpoints
- Gate endpoints and Settings tab behind data-managed-warehouse feature flag
  using team.uuid pattern matching ducklake copy workflows

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
display: flex;
gap: 0.5rem;
background: var(--color-bg-surface-primary) !important; // so that you can see button when over unwrapped text
transform: translateY(-50%);
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

text in this component has been off center

EDsCODE and others added 3 commits April 3, 2026 14:52
- Update DataWarehouseProvisioningStatus to match duckgres status API
  (flat connection object instead of nested infrastructure details)
- Add DataWarehouseProvisioningConnection type with password field
- ConnectionDetails component shows password with show/hide toggle
- Companion duckgres PR: PostHog/duckgres#390

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Provision response returns plaintext password (never stored server-side)
- Password shown in dismissible banner: "Save your password now"
- Connection details in status show host/port/db/username (no password)
- Reset password button generates new password, shown once
- Django proxy: add reset_password endpoint with @extend_schema
- Types: remove password from DataWarehouseProvisioningConnection

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@EDsCODE EDsCODE merged commit d57ec13 into master Apr 6, 2026
221 checks passed
@EDsCODE EDsCODE deleted the eric/warehouse-provisioning-ui branch April 6, 2026 01:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants