feat: add managed warehouse provisioning UI and Django proxy#51712
feat: add managed warehouse provisioning UI and Django proxy#51712
Conversation
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>
|
Size Change: +3.83 kB (0%) Total Size: 127 MB ℹ️ View Unchanged
|
- 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>
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>
MCP UI Apps size report
|
…isioning-ui # Conflicts: # products/data_warehouse/mcp/tools.yaml
|
No dependency changes detected. Learn more about Socket for GitHub. 👍 No dependency changes detected in pull request |
|
🎭 Playwright report · View test results →
These issues are not necessarily caused by your changes. |
|
| <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', |
There was a problem hiding this 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.
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 @@ | |||
| { | |||
There was a problem hiding this 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.
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.- 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%); |
There was a problem hiding this comment.
text in this component has been off center
- 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>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
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:
data-managed-warehousefeature flag)Backend:
POST provision— start provisioning, returns root password (show-once)POST deprovision— start deprovisioningGET warehouse_status— current status + connection details when readyGET check-database-name— database name availability checkPOST reset-password— generate new root password (show-once)@extend_schemaannotations on all endpointsdata-managed-warehouse) on all endpointsDUCKGRES_API_URLandDUCKGRES_INTERNAL_SECRETsettingsCompanion PR
How did you test this code?
Publish to changelog?
no
🤖 LLM context
Co-authored with Claude Code. Key design decisions:
team.uuid+ org/project groups matching the ducklake copy workflow pattern