feat(deployment): gate GPU preset and card for trial users on the configure screen - #3409
Conversation
ed51d3b to
a0750b4
Compare
📝 WalkthroughWalkthroughChangesThis PR adds trial-based GPU model restrictions, blocked-option indicators, unlock controls, and credits-sheet wiring across GPU cards, presets, and hardware configuration. It also expands locked-state coverage, adds supporting hook and policy tests, and types existing manifest test mocks. GPU trial gating
Manifest test dependency mocks
Estimated code review effort: 4 (Complex) | ~45 minutes Possibly related PRs
Suggested labels: Suggested reviewers: ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Comment |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #3409 +/- ##
==========================================
- Coverage 71.98% 70.95% -1.03%
==========================================
Files 1153 1065 -88
Lines 29228 26921 -2307
Branches 7207 6762 -445
==========================================
- Hits 21041 19103 -1938
+ Misses 7191 6854 -337
+ Partials 996 964 -32
*This pull request uses carry forward flags. Click here to find out more.
🚀 New features to boost your workflow:
|
|
Caution Review failedAn error occurred during the review process. Please try again later. ✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
7d1683c to
5ed56ae
Compare
5ed56ae to
e9cd09f
Compare
Trial users can still pick allowed GPUs, but models on the managed-wallet trial blocklist lock in the Presets and GPU cards with an unlock CTA (and tooltip) that opens the add-credits sheet. isTrialBlockedGpuModel is shared with applyTrialGpuPolicy so the UI locks exactly what the SDL strips. The GPU card also mirrors the sibling hardware cards: an off-state message when disabled and read-only controls while the pane is locked.
e9cd09f to
fc6390e
Compare
There was a problem hiding this comment.
🧹 Nitpick comments (1)
apps/deploy-web/src/components/deployments/ConfigureDeployment/ConfigurationPane/HardwareSection/HardwareSection.spec.tsx (1)
43-51: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick winExercise the positive gating branch.
These assertions only verify that callbacks exist; the following tests cover only
falsecases. A regression that always returnsfalsewould still pass. Assert that the predicate returnstruefor a blocked model when the trial restriction is active and the pane is unlocked.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@apps/deploy-web/src/components/deployments/ConfigureDeployment/ConfigurationPane/HardwareSection/HardwareSection.spec.tsx` around lines 43 - 51, The test does not verify that the gating predicate blocks restricted models. In the “passes an isBlockedModel predicate and unlock handler to the GPU cards” test, capture the props passed to PresetsCard and GpuCard, invoke each isBlockedModel with a blocked model while useTrialGate reports isRestricted true and the pane is unlocked, and assert both return true.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Nitpick comments:
In
`@apps/deploy-web/src/components/deployments/ConfigureDeployment/ConfigurationPane/HardwareSection/HardwareSection.spec.tsx`:
- Around line 43-51: The test does not verify that the gating predicate blocks
restricted models. In the “passes an isBlockedModel predicate and unlock handler
to the GPU cards” test, capture the props passed to PresetsCard and GpuCard,
invoke each isBlockedModel with a blocked model while useTrialGate reports
isRestricted true and the pane is unlocked, and assert both return true.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 651e7016-012d-49ad-9526-4a98895e0ddd
📒 Files selected for processing (14)
apps/deploy-web/src/components/deployments/ConfigureDeployment/ConfigurationPane/GpuCard/GpuCard.gated.spec.tsxapps/deploy-web/src/components/deployments/ConfigureDeployment/ConfigurationPane/GpuCard/GpuCard.spec.tsxapps/deploy-web/src/components/deployments/ConfigureDeployment/ConfigurationPane/GpuCard/GpuCard.tsxapps/deploy-web/src/components/deployments/ConfigureDeployment/ConfigurationPane/HardwareSection/HardwareSection.spec.tsxapps/deploy-web/src/components/deployments/ConfigureDeployment/ConfigurationPane/HardwareSection/HardwareSection.tsxapps/deploy-web/src/components/deployments/ConfigureDeployment/ConfigurationPane/HardwareSection/useTrialGate/useTrialGate.spec.tsapps/deploy-web/src/components/deployments/ConfigureDeployment/ConfigurationPane/HardwareSection/useTrialGate/useTrialGate.tsapps/deploy-web/src/components/deployments/ConfigureDeployment/ConfigurationPane/PresetsCard/PresetsCard.spec.tsxapps/deploy-web/src/components/deployments/ConfigureDeployment/ConfigurationPane/PresetsCard/PresetsCard.tsxapps/deploy-web/src/components/deployments/ConfigureDeployment/ConfigurationPane/UnlockGpusButton/UnlockGpusButton.tsxapps/deploy-web/src/components/deployments/ManifestUpdate/ManifestUpdate.spec.tsxapps/deploy-web/src/components/onboarding/OnboardingContainer/OnboardingContainer.spec.tsxapps/deploy-web/src/utils/deploymentData/v1beta3.spec.tsapps/deploy-web/src/utils/deploymentData/v1beta3.ts
✅ Files skipped from review due to trivial changes (2)
- apps/deploy-web/src/components/deployments/ConfigureDeployment/ConfigurationPane/HardwareSection/useTrialGate/useTrialGate.ts
- apps/deploy-web/src/components/deployments/ConfigureDeployment/ConfigurationPane/GpuCard/GpuCard.spec.tsx
Why
Managed-wallet trials don't allow every GPU:
applyTrialGpuPolicystrips models on the trial blocklist (NEXT_PUBLIC_MANAGED_WALLET_TRIAL_BLOCKED_GPU_MODELS— H100/A100/RTX 4090/… while e.g. T4 is allowed) from the SDL at deploy time. On the configure screen that limit was invisible: a trial user could pick a blocklisted GPU preset or model and only find out it was silently dropped when the deployment ran. This surfaces the same policy in the UI at the point of selection — blocked GPUs lock with an unlock CTA, allowed GPUs stay usable — matching how the onboarding picker gates its top-tier-GPU template.Fixes CON-638
What
isTrialBlockedGpuModel(vendor, model)predicate inv1beta3.tsis the single source of truth;applyTrialGpuPolicynow uses it, so the UI locks exactly what the SDL strips (they can't drift).useTrialGatereturns{ isRestricted, isWalletReady }—isRestricted = isTrialing || !isWalletReady(readiness read ashasManagedWallet, a pure context read, sinceDeploymentFlowProvideralready provisions the trial here). It only says whether the trial restriction is in force; what it blocks is the consumer's call.HardwareSectionderivesisBlockedModel = isRestricted && !locked && isTrialBlockedGpuModel(...)and threads it (plusonUnlock) to the hardware cards; it owns a singleAddCreditsSheet.UnlockGpusButtonrenders the CTA plus a tooltip explaining why. All unlock CTAs open the existingAddCreditsSheet; adding credits ends the trial, so the locks lift reactively.v1beta3module type, so two specs that mock the whole module (ManifestUpdate,OnboardingContainer) were updated accordingly.Tests
v1beta3.spec(isTrialBlockedGpuModel): matches a listed vendor/model case-insensitively; allows unlisted models; never blocks a missing vendor/model or an empty blocklist.useTrialGate.spec: restricted while trialing; restricted while the wallet isn't ready; not restricted for a ready, non-trial wallet; readiness fromhasManagedWallet.PresetsCard.spec: a blocked GPU preset locks while allowed presets stay selectable; an allowed preset still applies while some GPUs are blocked; the unlock CTA callsonUnlock; no CTA when nothing is blocked.GpuCard.gated.spec(isolated file — avoids the sibling file's jsdom Radix-leak tail): a blocked model option locks while allowed ones stay selectable; the unlock CTA callsonUnlock; no CTA when nothing is blocked.GpuCard.specalso asserts every GPU input is disabled while locked.HardwareSection.spec: passesisBlockedModel/onUnlockto the cards; blocks nothing while the pane is locked or the restriction isn't in force; a card's unlock request opens theAddCreditsSheet.Screen.Recording.2026-07-10.at.18.50.43.mov
Summary by CodeRabbit
New Features
Bug Fixes
Tests