Skip to content

Conversation

@adityachoudhari26
Copy link
Contributor

@adityachoudhari26 adityachoudhari26 commented Jun 20, 2025

Summary by CodeRabbit

  • New Features

    • Introduced "Rollouts" tabs in policy creation and editing interfaces for managing deployment rollout strategies.
    • Added interactive controls for selecting rollout type, time scale interval, and position growth factor.
    • Provided real-time rollout previews with visual charts to illustrate deployment timing.
    • Included a save button to submit rollout configurations.
  • Improvements

    • Relaxed validation constraints on rollout parameters for increased flexibility.
    • Enhanced policy tables and tabs to display and manage rollout-related rules and data.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jun 20, 2025

Walkthrough

This change introduces a new "environment-version-rollout" rule type to the policy management system. It adds UI components for configuring and previewing rollout strategies, updates policy creation and editing tabs to support rollouts, extends URL and API structures, and relaxes validation constraints for rollout parameters in the database schema.

Changes

File(s) Change Summary
.../(sidebar)/_components/PolicyTable.tsx, .../(sidebar)/_components/rule-themes.tsx Added "environment-version-rollout" rule type, updated rule type mappings, and icon/label/color assignments.
.../[policyId]/_components/PolicyTabs.tsx, .../[policyId]/_components/PolicyEditTabs.tsx, .../create/_components/PolicyContext.tsx, .../create/_components/PolicyCreationTabs.tsx Added "Rollouts" tab to policy tabs and creation flows, updated tab logic and type definitions.
.../urls.ts Added rollouts method to policy edit URL builder.
.../[policyId]/edit/rollouts/EditRollouts.tsx, .../[policyId]/edit/rollouts/page.tsx Introduced new rollout editing page and main component with layout and header.
.../[policyId]/edit/rollouts/_components/PositionGrowthFactor.tsx, .../create/_components/rollouts/PositionGrowthFactor.tsx Added input component for exponential rollout position growth factor.
.../[policyId]/edit/rollouts/_components/RolloutPreview.tsx, .../create/_components/rollouts/RolloutPreview.tsx Added chart preview components for rollout timing visualization.
.../[policyId]/edit/rollouts/_components/RolloutSubmit.tsx Added submit button for rollout form.
.../[policyId]/edit/rollouts/_components/RolloutTypeSelector.tsx, .../create/_components/rollouts/RolloutTypeSelector.tsx Added rollout type selector components for forms.
.../[policyId]/edit/rollouts/_components/TimeScaleInterval.tsx, .../create/_components/rollouts/TimeScaleInterval.tsx Added time scale interval input components with pretty formatting and parsing.
.../[policyId]/edit/rollouts/_components/equations.ts, .../create/_components/rollouts/equations.ts Added rollout offset calculation functions for different rollout strategies.
.../[policyId]/edit/PolicyFormContext.tsx Refactored promise handler formatting in form submission (no logic change).
.../create/_components/rollouts/Rollout.tsx Added main rollout configuration component for creation flow.
packages/api/src/router/policy/router.ts API now includes environmentVersionRollout relation in policy list queries.
packages/db/src/schema/rules/environment-version-rollout.ts Relaxed upper bound validation for rollout parameters; now only require positive values.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant UI (Policy Tabs)
    participant RolloutForm
    participant API
    participant DB

    User->>UI (Policy Tabs): Selects "Rollouts" tab
    UI (Policy Tabs)->>RolloutForm: Renders rollout configuration components
    User->>RolloutForm: Configures rollout type, interval, growth factor
    RolloutForm->>RolloutPreview: Updates chart preview based on input
    User->>RolloutForm: Submits rollout changes
    RolloutForm->>API: Sends rollout configuration
    API->>DB: Validates and stores rollout parameters
    DB-->>API: Confirms update
    API-->>RolloutForm: Responds with success/failure
Loading

Possibly related PRs

  • ctrlplanedev/ctrlplane#587: Introduced foundational database schema, API, and rule engine support for environment version rollout, which this PR extends with UI and validation features.

Suggested reviewers

  • jsbroks

Poem

In the garden of deploys, a new path unfurled,
Rollouts now bloom in the policy world.
With charts and forms, the timing’s just right—
Linear or exponential, rollouts take flight!
A bunny hops by, so proud and so spry,
“Gradual release,” it whispers, “give it a try!”
🐇✨


📜 Recent review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between d226496 and 6f71334.

📒 Files selected for processing (2)
  • apps/webservice/src/app/[workspaceSlug]/(app)/policies/[policyId]/edit/rollouts/_components/RolloutPreview.tsx (1 hunks)
  • apps/webservice/src/app/[workspaceSlug]/(app)/policies/create/_components/rollouts/RolloutPreview.tsx (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • apps/webservice/src/app/[workspaceSlug]/(app)/policies/create/_components/rollouts/RolloutPreview.tsx
  • apps/webservice/src/app/[workspaceSlug]/(app)/policies/[policyId]/edit/rollouts/_components/RolloutPreview.tsx
⏰ Context from checks skipped due to timeout of 90000ms (5)
  • GitHub Check: Typecheck
  • GitHub Check: build (linux/amd64)
  • GitHub Check: Lint
  • GitHub Check: build (linux/amd64)
  • GitHub Check: build (linux/amd64)
✨ Finishing Touches
  • 📝 Generate Docstrings

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

♻️ Duplicate comments (4)
apps/webservice/src/app/[workspaceSlug]/(app)/policies/create/_components/rollouts/PositionGrowthFactor.tsx (1)

12-38: Address code duplication with the edit version.

This component is nearly identical to apps/webservice/src/app/[workspaceSlug]/(app)/policies/[policyId]/edit/rollouts/_components/PositionGrowthFactor.tsx, differing only in the context hook import. This violates the DRY principle.

Consider the refactoring approach suggested in the edit version review to eliminate this duplication and maintain consistency between create and edit workflows.

apps/webservice/src/app/[workspaceSlug]/(app)/policies/[policyId]/edit/rollouts/_components/RolloutPreview.tsx (3)

23-23: Improve type safety for custom component props.

Same issue as in the create version - the any type should be replaced with a proper interface.


74-78: Verify hardcoded numReleaseTargets parameter.

Same issue as in the create version - hardcoded value of 10 may not match actual resource count.


95-95: Handle potential NaN values from number input.

Same input validation issue as in the create version.

🧹 Nitpick comments (6)
apps/webservice/src/app/[workspaceSlug]/(app)/policies/[policyId]/edit/rollouts/_components/PositionGrowthFactor.tsx (1)

12-38: Component implementation is correct, but consider addressing code duplication.

The component logic is well-structured with appropriate conditional rendering based on rollout type. However, this component appears to be nearly identical to the version in the create context, differing only in the imported context hook.

Consider extracting a shared component to reduce duplication:

+// shared/components/PositionGrowthFactor.tsx
+interface PositionGrowthFactorProps {
+  form: any; // or proper form type
+}
+
+export const PositionGrowthFactorBase: React.FC<PositionGrowthFactorProps> = ({ form }) => {
   const rolloutType = form.watch("environmentVersionRollout.rolloutType");
   const isExponential = rolloutType?.includes("exponential");
   
   if (!isExponential) return null;
   
   return (
     // ... existing JSX
   );
+};

+// In both edit and create contexts:
+export const PositionGrowthFactor: React.FC = () => {
+  const { form } = useContext(); // respective context
+  return <PositionGrowthFactorBase form={form} />;
+};
apps/webservice/src/app/[workspaceSlug]/(app)/policies/create/_components/rollouts/RolloutTypeSelector.tsx (1)

18-66: Well-implemented component with good UX patterns.

The component properly handles form state and includes helpful user guidance. The logic for clearing the entire environmentVersionRollout object when "no-rollout" is selected is a good UX pattern that prevents inconsistent form state.

Note: Based on the relevant code snippets, there appears to be a very similar RolloutTypeSelector in the edit context. Consider whether these could be consolidated to reduce duplication while maintaining their respective context integrations.

apps/webservice/src/app/[workspaceSlug]/(app)/policies/create/_components/rollouts/TimeScaleInterval.tsx (1)

17-52: Consider enhancing validation and error handling.

The custom hook implementation is well-structured with proper time conversion logic. However, consider these improvements:

  1. Remove unnecessary type assertion: ms() already returns number | undefined
  2. Add validation for negative/zero values: Time intervals should be positive
  3. Clear invalid form values: Currently invalid input remains in the form state
-    const msValue = ms(prettyValue) as number | undefined;
-    if (msValue == null || Number.isNaN(msValue)) {
+    const msValue = ms(prettyValue);
+    if (msValue == null || Number.isNaN(msValue) || msValue <= 0) {
       setPrettyString(prettyValue);
       toast.error("Invalid time scale interval");
+      // Clear invalid value from form
+      form.setValue("environmentVersionRollout.timeScaleInterval", undefined, {
+        shouldDirty: true,
+      });
       return;
     }
apps/webservice/src/app/[workspaceSlug]/(app)/policies/[policyId]/edit/rollouts/_components/TimeScaleInterval.tsx (2)

20-20: Remove debug console.log statement.

The console.log statement should be removed before production deployment as it's only for debugging purposes.

-  console.log("formErrors", formErrors);

35-40: Consider enhancing error handling specificity.

While the current error handling works, you might want to provide more specific error messages based on the type of invalid input (e.g., "negative values not allowed" vs "invalid format").

apps/webservice/src/app/[workspaceSlug]/(app)/policies/[policyId]/edit/rollouts/_components/RolloutPreview.tsx (1)

1-130: Consider extracting shared RolloutPreview logic to reduce duplication.

The create and edit versions of RolloutPreview are nearly identical except for the form context usage. Consider creating a shared base component or hook to eliminate this duplication.

// Potential shared hook approach:
const useRolloutPreviewData = (formHook: 'create' | 'edit') => {
  const { form } = formHook === 'create' ? usePolicyContext() : usePolicyFormContext();
  // ... shared logic
  return { environmentVersionRollout, chartData, ... };
};

Or create a shared component that accepts the form context as a prop.

📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between aebd8d8 and d226496.

📒 Files selected for processing (24)
  • apps/webservice/src/app/[workspaceSlug]/(app)/policies/(sidebar)/_components/PolicyTable.tsx (1 hunks)
  • apps/webservice/src/app/[workspaceSlug]/(app)/policies/(sidebar)/_components/rule-themes.tsx (5 hunks)
  • apps/webservice/src/app/[workspaceSlug]/(app)/policies/[policyId]/_components/PolicyTabs.tsx (5 hunks)
  • apps/webservice/src/app/[workspaceSlug]/(app)/policies/[policyId]/edit/_components/PolicyEditTabs.tsx (1 hunks)
  • apps/webservice/src/app/[workspaceSlug]/(app)/policies/[policyId]/edit/_components/PolicyFormContext.tsx (1 hunks)
  • apps/webservice/src/app/[workspaceSlug]/(app)/policies/[policyId]/edit/rollouts/EditRollouts.tsx (1 hunks)
  • apps/webservice/src/app/[workspaceSlug]/(app)/policies/[policyId]/edit/rollouts/_components/PositionGrowthFactor.tsx (1 hunks)
  • apps/webservice/src/app/[workspaceSlug]/(app)/policies/[policyId]/edit/rollouts/_components/RolloutPreview.tsx (1 hunks)
  • apps/webservice/src/app/[workspaceSlug]/(app)/policies/[policyId]/edit/rollouts/_components/RolloutSubmit.tsx (1 hunks)
  • apps/webservice/src/app/[workspaceSlug]/(app)/policies/[policyId]/edit/rollouts/_components/RolloutTypeSelector.tsx (1 hunks)
  • apps/webservice/src/app/[workspaceSlug]/(app)/policies/[policyId]/edit/rollouts/_components/TimeScaleInterval.tsx (1 hunks)
  • apps/webservice/src/app/[workspaceSlug]/(app)/policies/[policyId]/edit/rollouts/_components/equations.ts (1 hunks)
  • apps/webservice/src/app/[workspaceSlug]/(app)/policies/[policyId]/edit/rollouts/page.tsx (1 hunks)
  • apps/webservice/src/app/[workspaceSlug]/(app)/policies/create/_components/PolicyContext.tsx (1 hunks)
  • apps/webservice/src/app/[workspaceSlug]/(app)/policies/create/_components/PolicyCreationTabs.tsx (3 hunks)
  • apps/webservice/src/app/[workspaceSlug]/(app)/policies/create/_components/rollouts/PositionGrowthFactor.tsx (1 hunks)
  • apps/webservice/src/app/[workspaceSlug]/(app)/policies/create/_components/rollouts/Rollout.tsx (1 hunks)
  • apps/webservice/src/app/[workspaceSlug]/(app)/policies/create/_components/rollouts/RolloutPreview.tsx (1 hunks)
  • apps/webservice/src/app/[workspaceSlug]/(app)/policies/create/_components/rollouts/RolloutTypeSelector.tsx (1 hunks)
  • apps/webservice/src/app/[workspaceSlug]/(app)/policies/create/_components/rollouts/TimeScaleInterval.tsx (1 hunks)
  • apps/webservice/src/app/[workspaceSlug]/(app)/policies/create/_components/rollouts/equations.ts (1 hunks)
  • apps/webservice/src/app/urls.ts (1 hunks)
  • packages/api/src/router/policy/router.ts (1 hunks)
  • packages/db/src/schema/rules/environment-version-rollout.ts (1 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
`**/*.{ts,tsx}`: **Note on Error Handling:** Avoid strict enforcement of try/catch blocks. Code may use early returns, Promise chains (.then().catch()), or other patterns for error...

**/*.{ts,tsx}: Note on Error Handling:
Avoid strict enforcement of try/catch blocks. Code may use early returns, Promise chains (.then().catch()), or other patterns for error handling. These are acceptable as long as they maintain clarity and predictability.

  • apps/webservice/src/app/[workspaceSlug]/(app)/policies/(sidebar)/_components/PolicyTable.tsx
  • apps/webservice/src/app/[workspaceSlug]/(app)/policies/[policyId]/edit/_components/PolicyEditTabs.tsx
  • apps/webservice/src/app/[workspaceSlug]/(app)/policies/[policyId]/edit/_components/PolicyFormContext.tsx
  • packages/api/src/router/policy/router.ts
  • apps/webservice/src/app/[workspaceSlug]/(app)/policies/create/_components/PolicyContext.tsx
  • apps/webservice/src/app/[workspaceSlug]/(app)/policies/[policyId]/edit/rollouts/page.tsx
  • apps/webservice/src/app/[workspaceSlug]/(app)/policies/[policyId]/edit/rollouts/_components/RolloutSubmit.tsx
  • apps/webservice/src/app/[workspaceSlug]/(app)/policies/[policyId]/_components/PolicyTabs.tsx
  • apps/webservice/src/app/[workspaceSlug]/(app)/policies/create/_components/PolicyCreationTabs.tsx
  • packages/db/src/schema/rules/environment-version-rollout.ts
  • apps/webservice/src/app/[workspaceSlug]/(app)/policies/[policyId]/edit/rollouts/_components/PositionGrowthFactor.tsx
  • apps/webservice/src/app/[workspaceSlug]/(app)/policies/create/_components/rollouts/Rollout.tsx
  • apps/webservice/src/app/[workspaceSlug]/(app)/policies/[policyId]/edit/rollouts/EditRollouts.tsx
  • apps/webservice/src/app/[workspaceSlug]/(app)/policies/create/_components/rollouts/equations.ts
  • apps/webservice/src/app/urls.ts
  • apps/webservice/src/app/[workspaceSlug]/(app)/policies/create/_components/rollouts/RolloutTypeSelector.tsx
  • apps/webservice/src/app/[workspaceSlug]/(app)/policies/(sidebar)/_components/rule-themes.tsx
  • apps/webservice/src/app/[workspaceSlug]/(app)/policies/[policyId]/edit/rollouts/_components/equations.ts
  • apps/webservice/src/app/[workspaceSlug]/(app)/policies/[policyId]/edit/rollouts/_components/RolloutTypeSelector.tsx
  • apps/webservice/src/app/[workspaceSlug]/(app)/policies/create/_components/rollouts/RolloutPreview.tsx
  • apps/webservice/src/app/[workspaceSlug]/(app)/policies/create/_components/rollouts/TimeScaleInterval.tsx
  • apps/webservice/src/app/[workspaceSlug]/(app)/policies/[policyId]/edit/rollouts/_components/RolloutPreview.tsx
  • apps/webservice/src/app/[workspaceSlug]/(app)/policies/create/_components/rollouts/PositionGrowthFactor.tsx
  • apps/webservice/src/app/[workspaceSlug]/(app)/policies/[policyId]/edit/rollouts/_components/TimeScaleInterval.tsx
🧬 Code Graph Analysis (7)
apps/webservice/src/app/[workspaceSlug]/(app)/policies/[policyId]/edit/rollouts/page.tsx (1)
apps/webservice/src/app/[workspaceSlug]/(app)/policies/[policyId]/edit/rollouts/EditRollouts.tsx (1)
  • EditRollouts (20-33)
apps/webservice/src/app/[workspaceSlug]/(app)/policies/[policyId]/edit/rollouts/_components/RolloutSubmit.tsx (1)
apps/webservice/src/app/[workspaceSlug]/(app)/policies/[policyId]/edit/_components/PolicyFormContext.tsx (1)
  • usePolicyFormContext (37-44)
apps/webservice/src/app/[workspaceSlug]/(app)/policies/create/_components/PolicyCreationTabs.tsx (1)
apps/webservice/src/app/[workspaceSlug]/(app)/policies/create/_components/rollouts/Rollout.tsx (1)
  • Rollout (19-27)
apps/webservice/src/app/[workspaceSlug]/(app)/policies/create/_components/rollouts/RolloutTypeSelector.tsx (4)
apps/webservice/src/app/[workspaceSlug]/(app)/policies/[policyId]/edit/rollouts/_components/RolloutTypeSelector.tsx (1)
  • RolloutTypeSelector (18-66)
apps/webservice/src/app/[workspaceSlug]/(app)/policies/create/_components/PolicyContext.tsx (1)
  • usePolicyContext (61-63)
packages/ui/src/form.tsx (5)
  • FormField (220-220)
  • FormItem (215-215)
  • FormLabel (216-216)
  • FormDescription (218-218)
  • FormControl (217-217)
packages/ui/src/select.tsx (5)
  • Select (154-154)
  • SelectTrigger (157-157)
  • SelectValue (156-156)
  • SelectContent (158-158)
  • SelectItem (160-160)
apps/webservice/src/app/[workspaceSlug]/(app)/policies/[policyId]/edit/rollouts/_components/equations.ts (2)
apps/webservice/src/app/[workspaceSlug]/(app)/policies/create/_components/rollouts/equations.ts (1)
  • RolloutTypeToOffsetFunction (49-58)
apps/webservice/src/app/[workspaceSlug]/(app)/dashboards/[dashboardId]/_components/widgets/deployment-version-distribution/WidgetDeploymentVersionDistribution.tsx (1)
  • schema (16-19)
apps/webservice/src/app/[workspaceSlug]/(app)/policies/create/_components/rollouts/RolloutPreview.tsx (3)
apps/webservice/src/app/[workspaceSlug]/(app)/policies/create/_components/PolicyContext.tsx (1)
  • usePolicyContext (61-63)
apps/webservice/src/app/[workspaceSlug]/(app)/policies/create/_components/rollouts/equations.ts (1)
  • RolloutTypeToOffsetFunction (49-58)
packages/ui/src/input.tsx (1)
  • Input (24-24)
apps/webservice/src/app/[workspaceSlug]/(app)/policies/create/_components/rollouts/TimeScaleInterval.tsx (4)
apps/webservice/src/app/[workspaceSlug]/(app)/policies/create/_components/PolicyContext.tsx (1)
  • usePolicyContext (61-63)
apps/webservice/src/app/[workspaceSlug]/(app)/policies/[policyId]/edit/rollouts/_components/TimeScaleInterval.tsx (1)
  • TimeScaleInterval (56-86)
packages/ui/src/form.tsx (5)
  • FormField (220-220)
  • FormItem (215-215)
  • FormLabel (216-216)
  • FormDescription (218-218)
  • FormControl (217-217)
packages/ui/src/input.tsx (1)
  • Input (24-24)
⏰ Context from checks skipped due to timeout of 90000ms (6)
  • GitHub Check: build (linux/amd64)
  • GitHub Check: build (linux/amd64)
  • GitHub Check: build (linux/amd64)
  • GitHub Check: build (linux/amd64)
  • GitHub Check: Typecheck
  • GitHub Check: Lint
🔇 Additional comments (40)
apps/webservice/src/app/[workspaceSlug]/(app)/policies/[policyId]/edit/_components/PolicyEditTabs.tsx (1)

63-68: LGTM! Clean addition of rollouts tab.

The new rollouts tab follows the established pattern perfectly, with proper configuration structure and URL generation. The positioning at the end of the array is appropriate for this new feature.

apps/webservice/src/app/[workspaceSlug]/(app)/policies/create/_components/PolicyContext.tsx (1)

25-26: LGTM! Proper type extension for rollouts support.

The addition of "rollouts" to the PolicyTab union type is necessary and follows the established pattern for tab type definitions.

apps/webservice/src/app/[workspaceSlug]/(app)/policies/(sidebar)/_components/PolicyTable.tsx (1)

55-56: LGTM! Consistent rule type detection pattern.

The addition of the environment-version-rollout rule check follows the established pattern used for other rule types in the getRules function. The null check and array push logic is consistent with existing implementations.

apps/webservice/src/app/[workspaceSlug]/(app)/policies/[policyId]/edit/rollouts/page.tsx (1)

1-5: LGTM! Standard Next.js page component pattern.

The EditRolloutsPage component follows the proper Next.js page pattern with a clean, minimal wrapper that imports and renders the main EditRollouts component. The implementation is appropriate and follows React conventions.

apps/webservice/src/app/[workspaceSlug]/(app)/policies/[policyId]/edit/_components/PolicyFormContext.tsx (1)

88-100: LGTM! Clean formatting improvements.

The reformatting of the promise chain improves code readability while maintaining identical functional behavior. The async flow, error handling, and success handling remain unchanged.

packages/api/src/router/policy/router.ts (1)

62-62: LGTM! Consistent eager loading of rollout data.

The addition of environmentVersionRollout: true to the with clause properly enables eager loading of rollout data alongside other policy relations. This change is consistently applied across all policy query methods (list, byId, byResourceId), ensuring data consistency throughout the API.

apps/webservice/src/app/urls.ts (1)

64-64: LGTM! Consistent URL builder pattern.

The addition of the rollouts method follows the established pattern for URL building within the workspacePolicyEdit function. This properly enables navigation to rollout-specific pages in the policy editing workflow.

apps/webservice/src/app/[workspaceSlug]/(app)/policies/[policyId]/edit/rollouts/_components/RolloutSubmit.tsx (1)

5-17: LGTM! Well-structured submit button component.

The component properly:

  • Uses the form context to access form state
  • Implements correct disabled logic (when submitting or form is unchanged)
  • Follows React functional component best practices
  • Has appropriate styling and accessibility attributes

The disabled state logic form.formState.isSubmitting || !form.formState.isDirty correctly prevents submission during ongoing requests and when no changes have been made.

apps/webservice/src/app/[workspaceSlug]/(app)/policies/create/_components/PolicyCreationTabs.tsx (3)

17-17: LGTM! Proper import for rollout component.

The import statement correctly brings in the Rollout component from the rollouts directory.


51-56: LGTM! Consistent tab configuration.

The new rollout tab configuration follows the established pattern with:

  • Appropriate id: "rollouts" matching the switch case
  • Clear label and descriptive text
  • Consistent structure with other tab configurations

75-76: LGTM! Proper case handling for rollouts tab.

The switch statement correctly handles the "rollouts" case by returning the <Rollout /> component, maintaining consistency with other tab rendering logic.

apps/webservice/src/app/[workspaceSlug]/(app)/policies/create/_components/rollouts/Rollout.tsx (3)

1-1: LGTM! Proper client component directive.

The "use client" directive is correctly placed at the top of the file, indicating this component uses client-side React features.


10-17: LGTM! Well-structured header component.

The local Header component is appropriately defined as a functional component with:

  • Clear semantic HTML structure
  • Proper styling classes for typography and spacing
  • Descriptive content that matches the rollout functionality

19-27: LGTM! Excellent component composition.

The main Rollout component effectively uses composition to organize rollout-related functionality:

  • Logical ordering of components (header, type selector, time scale, growth factor, preview)
  • Clean layout with appropriate spacing (space-y-6)
  • Proper separation of concerns with each subcomponent handling specific rollout aspects
apps/webservice/src/app/[workspaceSlug]/(app)/policies/[policyId]/_components/PolicyTabs.tsx (5)

6-11: LGTM: Icon import follows established pattern.

The addition of IconCalendar is consistent with other tab icons and appropriate for rollout functionality.


33-33: LGTM: URL constant properly defined.

The rolloutsUrl constant follows the established pattern for other tabs.


44-44: LGTM: Tab detection logic updated correctly.

The rollouts pathname check is properly integrated into the getInitialTab function.


59-59: LGTM: Tab change routing implemented correctly.

The rollouts routing logic follows the established pattern for other tabs.


90-93: LGTM: Tab UI element follows established pattern.

The rollouts tab trigger is properly implemented with consistent styling and icon usage.

packages/db/src/schema/rules/environment-version-rollout.ts (1)

78-79: ```shell
#!/bin/bash

Retry searching for the validation fields without specifying an unrecognized file type

rg -A5 -B5 'positionGrowthFactor' -g '.ts'
rg -A5 -B5 'timeScaleInterval' -g '
.ts'


</details>
<details>
<summary>apps/webservice/src/app/[workspaceSlug]/(app)/policies/[policyId]/edit/rollouts/_components/RolloutTypeSelector.tsx (1)</summary>

`18-66`: **LGTM! Well-structured rollout type selector.**

The component correctly implements form integration with proper handling of the "no-rollout" case by clearing the entire `environmentVersionRollout` configuration. The disabled state during submission and clear option descriptions provide good user experience.

</details>
<details>
<summary>apps/webservice/src/app/[workspaceSlug]/(app)/policies/[policyId]/edit/rollouts/EditRollouts.tsx (1)</summary>

`1-33`: **LGTM! Clean layout and component composition.**

The component provides a well-structured layout for the rollout editing interface. The two-column grid with configuration controls on the left and preview on the right follows good UX patterns, and the component composition is clean and maintainable.

</details>
<details>
<summary>apps/webservice/src/app/[workspaceSlug]/(app)/policies/(sidebar)/_components/rule-themes.tsx (4)</summary>

`25-26`: **LGTM! Proper integration of new rule type.**

The new `"environment-version-rollout"` rule type is correctly added to the union type following the established naming convention.

---

`35-37`: **LGTM! Consistent icon theming.**

The IconCalendar with blue color scheme is appropriate for a rollout feature and maintains consistency with other time-related rules in the system.

---

`76-76`: **LGTM! Clear and descriptive label.**

The "Gradual Rollout" label clearly communicates the purpose of the environment version rollout rule to users.

---

`100-101`: **LGTM! Consistent color theming.**

The blue color scheme matches the icon and maintains visual consistency with other blue-themed rules like "deny-window".

</details>
<details>
<summary>apps/webservice/src/app/[workspaceSlug]/(app)/policies/create/_components/rollouts/TimeScaleInterval.tsx (1)</summary>

`54-84`: **LGTM! Clean component structure with proper form integration.**

The component correctly implements conditional rendering and form field integration. The use of the custom hook keeps the component clean and the form field setup follows established patterns.

</details>
<details>
<summary>apps/webservice/src/app/[workspaceSlug]/(app)/policies/create/_components/rollouts/equations.ts (4)</summary>

`3-9`: **LGTM! Clear type definitions for offset calculations.**

The type aliases clearly define the function signatures for deployment offset calculations, making the code self-documenting and type-safe.

---

`11-27`: **LGTM! Linear offset functions are mathematically correct.**

Both linear implementations are correct:
- Basic linear scales directly with position and time interval
- Normalized linear scales relative to total number of targets, ensuring predictable timing regardless of target count

---

`29-47`: **LGTM! Exponential offset functions are mathematically sound.**

The exponential decay formulas are correctly implemented:
- Basic exponential uses `1 - exp(-x/factor)` which approaches the time scale asymptotically
- Normalized exponential properly scales and bounds the curve to reach the time scale at the final target position

The mathematical properties ensure smooth rollout curves with faster initial deployments tapering off over time.

---

`49-58`: ```shell
#!/bin/bash
# Extract full ROLLOUT_TYPE_MAPPINGS object
rg -A10 -B2 "ROLLOUT_TYPE_MAPPINGS" packages/db/src/schema/rules/environment-version-rollout.ts
apps/webservice/src/app/[workspaceSlug]/(app)/policies/[policyId]/edit/rollouts/_components/equations.ts (5)

11-18: LGTM! Clean linear offset implementation.

The linear deployment offset function correctly implements a simple linear progression where offset increases proportionally with the time scale interval. Using underscores for unused parameters follows TypeScript conventions well.


20-27: LGTM! Proper normalization implementation.

The linear normalized function correctly scales the position by the total number of release targets, ensuring the rollout progression stays within bounds regardless of the target count.


29-36: LGTM! Exponential decay formula is mathematically sound.

The exponential offset function uses the standard exponential decay formula 1 - e^(-x/k), which provides the expected exponential rollout curve behavior where deployments start slow and accelerate.


38-47: LGTM! Complex but correct normalized exponential implementation.

The normalized exponential function properly scales both the input position and normalizes the output by the maximum possible value at numReleaseTargets. The mathematical derivation ensures consistent behavior across different target counts.


49-58: LGTM! Well-structured type mapping.

The RolloutTypeToOffsetFunction mapping provides a clean interface between the schema rollout types and their corresponding mathematical implementations. This design supports easy extension for additional rollout strategies.

apps/webservice/src/app/[workspaceSlug]/(app)/policies/[policyId]/edit/rollouts/_components/TimeScaleInterval.tsx (2)

17-54: LGTM! Well-designed time conversion hook.

The useReadableTimeScaleInterval hook provides a clean abstraction for converting between human-readable time strings and minute values. The validation and error handling with toast notifications provides good user feedback.


56-86: LGTM! Clean component implementation.

The component properly integrates with the form context and provides clear labeling and description for users. The conditional rendering based on rollout data availability is appropriate.

apps/webservice/src/app/[workspaceSlug]/(app)/policies/create/_components/rollouts/RolloutPreview.tsx (2)

62-129: LGTM! Well-structured rollout visualization component.

The component provides a clear and interactive rollout preview with proper chart formatting, tooltips, and user controls. The responsive design and pretty-printed time values enhance usability.


74-78: ```shell
#!/bin/bash

Find where usePolicyContext is defined and how environmentVersionRollout is sourced

rg -n "usePolicyContext" -A 10 -B 0 apps/webservice/src/app

Inspect usages and type or shape of environmentVersionRollout

rg -n "environmentVersionRollout" -C 5 apps/webservice/src/app


</details>

</blockquote></details>

</details>

<!-- This is an auto-generated comment by CodeRabbit for review status -->

import { usePolicyContext } from "../PolicyContext";
import { RolloutTypeToOffsetFunction } from "./equations";

const PrettyYAxisTick = (props: any) => {
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Improve type safety for custom component props.

The any type for props should be replaced with a more specific interface to ensure type safety.

-const PrettyYAxisTick = (props: any) => {
+interface YAxisTickProps {
+  payload: { value: string };
+  [key: string]: any;
+}
+
+const PrettyYAxisTick = (props: YAxisTickProps) => {
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const PrettyYAxisTick = (props: any) => {
interface YAxisTickProps {
payload: { value: string };
[key: string]: any;
}
const PrettyYAxisTick = (props: YAxisTickProps) => {
// ...existing implementation...
}
🤖 Prompt for AI Agents
In
apps/webservice/src/app/[workspaceSlug]/(app)/policies/create/_components/rollouts/RolloutPreview.tsx
at line 23, replace the use of the `any` type for the `props` parameter in the
`PrettyYAxisTick` component with a properly defined TypeScript interface that
matches the expected shape of the props. Define an interface describing the
specific properties and their types that `PrettyYAxisTick` expects, then use
that interface to type the `props` parameter to improve type safety.

@adityachoudhari26 adityachoudhari26 merged commit f5ff18f into main Jun 20, 2025
10 checks passed
@adityachoudhari26 adityachoudhari26 deleted the policy-rollouts-ui branch June 20, 2025 21:00
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