Skip to content

Conversation

@jsbroks
Copy link
Member

@jsbroks jsbroks commented Mar 30, 2025

Summary by CodeRabbit

  • New Features

    • Introduced a background processing component to handle and evaluate release events.
    • Expanded event channels with the addition of ReleaseEvaluate for enhanced event handling.
    • Added new validation schemas for various condition types, improving deployment and environment evaluations.
  • Refactor/Improvements

    • Upgraded validation schemas and condition building for more robust data matching.
    • Enhanced type safety for deployment and environment conditions, streamlining the validation process.
    • Consolidated module exports for easier access to policy-related functionalities.
  • Chores

    • Added a new dependency to bolster rule validation capabilities.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Mar 30, 2025

Walkthrough

This pull request introduces a new release evaluation worker that processes ReleaseEvaluateEvent jobs using BullMQ. It refines the type definitions for policy selectors in the database schema and adds new functions to match and retrieve applicable policies. Additionally, several new Zod schemas and TypeScript types are defined for validating deployment, environment, and condition objects. Updates to SQL condition-building logic across deployment and environment modules improve query construction. Lastly, dependency and export changes enhance the module interfaces in both the rule engine and validators packages.

Changes

File(s) Change Summary
apps/event-worker/src/.../evaluate/index.ts Added createReleaseEvaluateWorker() to process ReleaseEvaluateEvent jobs using BullMQ with context creation, policy retrieval, and evaluation.
packages/db/src/schema/policy.ts Updated deploymentSelector and environmentSelector fields with stricter type annotations and modified insert schemas accordingly.
packages/rule-engine/{package.json,src/db/get-applicable-policies.ts,src/db/index.ts} Added new dependency "ts-is-present", introduced functions matchPolicyTargetForResource and getApplicablePolicies, and exported them via index.ts.
packages/validators/src/events/index.ts Extended Channel enum with ReleaseEvaluate and defined the releaseEvaluateEvent schema and its inferred type.
packages/db/src/{common.ts,schema/deployment.ts,schema/environment.ts} Enhanced SQL column operators, introduced new type definitions, and updated condition-building functions for deployment and environment matching.
packages/validators/src/deployments/conditions/{comparison-condition.ts, deployment-condition.ts, slug-condition.ts, index.ts} Added new Zod schemas and TypeScript types for validating various deployment conditions including comparison, deployment, and slug conditions.
packages/validators/src/conditions/{id-condition.ts, name-condition.ts, system-condition.ts, index.ts} Added new Zod schemas and types for IdCondition, NameCondition, and SystemCondition, and updated exports.
packages/validators/src/environments/{comparison-condition.ts, directory-condition.ts, environment-condition.ts, index.ts} Introduced new Zod schemas and types for environment conditions including comparison, directory, and composite environment conditions with aggregated exports.
packages/validators/package.json Added export entries for the new ./environments module with both type definitions and default JavaScript implementations.

Sequence Diagram(s)

sequenceDiagram
    participant W as ReleaseEvaluateWorker
    participant DB as Database (createCtx)
    participant P as Policy Engine (getApplicablePolicies)
    participant E as Evaluator (evaluate)

    W->>DB: createCtx(job.data)
    alt Context is null
       DB-->>W: null
       W->>W: Log error and exit job
    else Context exists
       DB-->>W: context data with workspaceId
       W->>P: getApplicablePolicies(workspaceId, repo)
       P-->>W: list of policies
       W->>E: evaluate(policies, context)
       E-->>W: evaluation result
       W->>Console: Log evaluation result
    end
Loading

Possibly related PRs

  • fix: Reuse filter endpoints for deployment resource drawer #239: The changes in the main PR, specifically the introduction of the createReleaseEvaluateWorker function that processes ReleaseEvaluateEvent jobs, are related to the modifications in the retrieved PR, which involves filtering job conditions based on deployment and environment selectors.
  • fix: Remove semver and regex release filter #160: The changes in the main PR, which introduce a new worker function for processing ReleaseEvaluateEvent jobs and evaluating policies, are related to the modifications in the retrieved PR that involve handling release conditions and filters, particularly through the introduction of a releaseFilter in the schema and its integration into various components.

Poem

Oh, the hops of code today,
A worker born in fields of BullMQ play.
Schemas and types, neatly revised,
Policies and conditions now harmonized.
With every line, we joyfully tweak—
A rabbit’s celebration in every peek! 🐇✨

✨ Finishing Touches
  • 📝 Generate Docstrings

🪧 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.
    • Generate unit testing code for this file.
    • 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 generate unit testing code for this file.
    • @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 generate unit testing code.
    • @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.

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 resolve resolve all the CodeRabbit review comments.
  • @coderabbitai plan to trigger planning for file edits and PR creation.
  • @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: 1

🧹 Nitpick comments (1)
packages/rule-engine/src/db/get-applicable-policies.ts (1)

93-127: Optimize repeated queries for large policy sets.
When workspaces have many policies, iterating through each policy and invoking matchPolicyTargetForResource for every target may become expensive. Consider caching or performing a combined query that filters out non-matching environments/deployments before iterating, avoiding multiple repeated lookups.

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between efac018 and ab63535.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (7)
  • apps/event-worker/src/releases/evaluate/index.ts (1 hunks)
  • packages/db/src/schema/policy.ts (2 hunks)
  • packages/rule-engine/package.json (1 hunks)
  • packages/rule-engine/src/db/get-applicable-policies.ts (1 hunks)
  • packages/rule-engine/src/db/index.ts (1 hunks)
  • packages/rule-engine/src/types.ts (4 hunks)
  • packages/validators/src/events/index.ts (2 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.

  • packages/rule-engine/src/db/index.ts
  • apps/event-worker/src/releases/evaluate/index.ts
  • packages/validators/src/events/index.ts
  • packages/db/src/schema/policy.ts
  • packages/rule-engine/src/types.ts
  • packages/rule-engine/src/db/get-applicable-policies.ts
🧬 Code Definitions (1)
packages/rule-engine/src/db/get-applicable-policies.ts (2)
packages/rule-engine/src/types.ts (1)
  • ReleaseRepository (70-74)
packages/db/src/schema/policy.ts (2)
  • PolicyTarget (225-225)
  • policy (22-38)
⏰ Context from checks skipped due to timeout of 90000ms (3)
  • GitHub Check: Lint
  • GitHub Check: Typecheck
  • GitHub Check: build (linux/amd64)
🔇 Additional comments (11)
packages/rule-engine/package.json (1)

33-33: Dependency addition looks good

The addition of "ts-is-present" with the "catalog:" version specifier is consistent with other dependencies in the package. This utility will likely help with type checking in policy evaluation logic.

packages/rule-engine/src/db/index.ts (1)

2-2: Export addition looks good

The export statement correctly exposes the policy-related functionalities from the get-applicable-policies.js file, maintaining consistency with existing export patterns.

apps/event-worker/src/releases/evaluate/index.ts (1)

1-8: Imports look good

All necessary imports are present for the worker implementation, including the event type, database connections, and rule engine utilities.

packages/validators/src/events/index.ts (2)

9-9: Enum addition looks good

The ReleaseEvaluate enum value follows the existing naming pattern and provides a clear identifier for the new event channel.


23-28: Event definition is well-structured

The releaseEvaluateEvent definition and corresponding type export correctly define the structure of release evaluation events using the Zod schema, consistent with other event definitions in the file.

packages/rule-engine/src/db/get-applicable-policies.ts (1)

29-91: Consider explicitly handling both-null scenario for selectors.
Currently, if both deploymentSelector and environmentSelector are null, the function returns null. If the intended behavior is that a policy with neither selector applies universally, you may want to add an explicit check for that scenario. Otherwise, the current behavior is correct if you intend to skip policies in such a case.

packages/db/src/schema/policy.ts (1)

45-50: Typed JSONB fields look good.
Applying explicit types (DeploymentCondition | null, EnvironmentCondition | null) to deploymentSelector and environmentSelector is a solid approach for stricter type validation.

packages/rule-engine/src/types.ts (4)

2-3: Stricter typing for deployment and resource conditions is clear.
The addition of DeploymentVersionCondition and ResourceCondition imports provides more clarity and safety when parsing or handling these selectors.


22-23: Improved type definition for deployment selectors.
Using ResourceCondition and DeploymentVersionCondition in Deployment clarifies how each property is expected to be structured and validated.


34-34: Applying ResourceCondition to environments.
Defining resourceSelector in Environment with an explicit type fosters consistency across models.


69-74: New ReleaseRepository type is well-structured.
Defining deploymentId, environmentId, and resourceId as strings aligns perfectly with usage in the policy-matching code.

Comment on lines +10 to +28
export const createReleaseEvaluateWorker = () =>
new Worker<ReleaseEvaluateEvent>(Channel.ReleaseEvaluate, async (job) => {
job.log(
`Evaluating release for deployment ${job.data.deploymentId} and resource ${job.data.resourceId}`,
);

const ctx = await createCtx(db, job.data);
if (ctx == null) {
job.log(
`Resource ${job.data.resourceId} not found for deployment ${job.data.deploymentId} and environment ${job.data.environmentId}`,
);
return;
}

const { workspaceId } = ctx.resource;
const policy = await getApplicablePolicies(db, workspaceId, job.data);
const result = await evaluate(policy, [], ctx);
console.log(result);
});
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

Add error handling to worker implementation

The worker function is well-structured, but lacks explicit error handling for the database operations and policy evaluation. A try/catch block would make the worker more resilient against unexpected errors.

Also, consider using a structured logger instead of console.log for the evaluation result.

 export const createReleaseEvaluateWorker = () =>
   new Worker<ReleaseEvaluateEvent>(Channel.ReleaseEvaluate, async (job) => {
     job.log(
       `Evaluating release for deployment ${job.data.deploymentId} and resource ${job.data.resourceId}`,
     );
 
+    try {
       const ctx = await createCtx(db, job.data);
       if (ctx == null) {
         job.log(
           `Resource ${job.data.resourceId} not found for deployment ${job.data.deploymentId} and environment ${job.data.environmentId}`,
         );
         return;
       }
 
       const { workspaceId } = ctx.resource;
       const policy = await getApplicablePolicies(db, workspaceId, job.data);
       const result = await evaluate(policy, [], ctx);
-      console.log(result);
+      job.log(`Evaluation result: ${JSON.stringify(result)}`);
+    } catch (error) {
+      job.log(`Error during release evaluation: ${error instanceof Error ? error.message : String(error)}`);
+      throw error; // Rethrow to let BullMQ handle the job failure
+    }
   });
📝 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
export const createReleaseEvaluateWorker = () =>
new Worker<ReleaseEvaluateEvent>(Channel.ReleaseEvaluate, async (job) => {
job.log(
`Evaluating release for deployment ${job.data.deploymentId} and resource ${job.data.resourceId}`,
);
const ctx = await createCtx(db, job.data);
if (ctx == null) {
job.log(
`Resource ${job.data.resourceId} not found for deployment ${job.data.deploymentId} and environment ${job.data.environmentId}`,
);
return;
}
const { workspaceId } = ctx.resource;
const policy = await getApplicablePolicies(db, workspaceId, job.data);
const result = await evaluate(policy, [], ctx);
console.log(result);
});
export const createReleaseEvaluateWorker = () =>
new Worker<ReleaseEvaluateEvent>(Channel.ReleaseEvaluate, async (job) => {
job.log(
`Evaluating release for deployment ${job.data.deploymentId} and resource ${job.data.resourceId}`,
);
try {
const ctx = await createCtx(db, job.data);
if (ctx == null) {
job.log(
`Resource ${job.data.resourceId} not found for deployment ${job.data.deploymentId} and environment ${job.data.environmentId}`,
);
return;
}
const { workspaceId } = ctx.resource;
const policy = await getApplicablePolicies(db, workspaceId, job.data);
const result = await evaluate(policy, [], ctx);
job.log(`Evaluation result: ${JSON.stringify(result)}`);
} catch (error) {
job.log(`Error during release evaluation: ${error instanceof Error ? error.message : String(error)}`);
throw error; // Rethrow to let BullMQ handle the job failure
}
});

jsbroks and others added 2 commits March 30, 2025 14:57
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: 0

🧹 Nitpick comments (5)
packages/validators/src/deployments/conditions/deployment-condition.ts (1)

14-19: Consider enumerating allowed types in doc comments.
Ensure that future maintainers easily understand which condition types are part of the DeploymentCondition union by adding short doc comments.

packages/rule-engine/src/db/get-applicable-policies.ts (2)

29-91: Add specialized tests for partial matches.
The matchPolicyTargetForResource function handles various selector combinations (deployment/environment). Consider adding test cases ensuring correct behavior when only one of the selectors is present or null.


108-128: Optimize for large policy sets.
Iterating over every policy can cause performance bottlenecks in workspaces with a high policy count. Evaluate whether indexing or more targeted queries can filter out non-matching policies earlier.

packages/db/src/common.ts (1)

54-65: Well-structured column operator mapping
This record neatly encapsulates SQL operators for columns. Consider adding case-sensitive operators or others (like “In” or numeric comparisons) to handle more advanced filtering scenarios.

packages/db/src/schema/deployment.ts (1)

121-135: Robust condition-building function
The logic correctly maps each condition type to an SQL expression. Consider adding a fallback or explicit error if a new or unknown condition type is encountered to prevent silent failures.

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between ab63535 and 2b987ea.

📒 Files selected for processing (12)
  • packages/db/src/common.ts (3 hunks)
  • packages/db/src/schema/deployment.ts (3 hunks)
  • packages/db/src/schema/policy.ts (2 hunks)
  • packages/rule-engine/src/db/get-applicable-policies.ts (1 hunks)
  • packages/validators/src/deployments/conditions/comparison-condition.ts (1 hunks)
  • packages/validators/src/deployments/conditions/deployment-condition.ts (1 hunks)
  • packages/validators/src/deployments/conditions/id-condition.ts (1 hunks)
  • packages/validators/src/deployments/conditions/index.ts (1 hunks)
  • packages/validators/src/deployments/conditions/name-condition.ts (1 hunks)
  • packages/validators/src/deployments/conditions/slug-condition.ts (1 hunks)
  • packages/validators/src/deployments/conditions/system-condition.ts (1 hunks)
  • packages/validators/src/deployments/index.ts (1 hunks)
✅ Files skipped from review due to trivial changes (1)
  • packages/validators/src/deployments/conditions/index.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/db/src/schema/policy.ts
🧰 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.

  • packages/validators/src/deployments/index.ts
  • packages/validators/src/deployments/conditions/system-condition.ts
  • packages/validators/src/deployments/conditions/name-condition.ts
  • packages/validators/src/deployments/conditions/slug-condition.ts
  • packages/validators/src/deployments/conditions/id-condition.ts
  • packages/rule-engine/src/db/get-applicable-policies.ts
  • packages/validators/src/deployments/conditions/deployment-condition.ts
  • packages/validators/src/deployments/conditions/comparison-condition.ts
  • packages/db/src/common.ts
  • packages/db/src/schema/deployment.ts
🧬 Code Definitions (4)
packages/rule-engine/src/db/get-applicable-policies.ts (3)
packages/db/src/common.ts (2)
  • Tx (22-22)
  • takeFirstOrNull (15-20)
packages/rule-engine/src/types.ts (1)
  • ReleaseRepository (70-74)
packages/db/src/schema/policy.ts (2)
  • PolicyTarget (223-223)
  • policy (20-36)
packages/validators/src/deployments/conditions/deployment-condition.ts (5)
packages/validators/src/deployments/conditions/comparison-condition.ts (2)
  • ComparisonCondition (23-30)
  • comparisonCondition (12-21)
packages/validators/src/deployments/conditions/name-condition.ts (1)
  • nameCondition (5-9)
packages/validators/src/deployments/conditions/slug-condition.ts (1)
  • slugCondition (5-9)
packages/validators/src/deployments/conditions/system-condition.ts (1)
  • systemCondition (3-7)
packages/validators/src/deployments/conditions/id-condition.ts (1)
  • idCondition (3-7)
packages/validators/src/deployments/conditions/comparison-condition.ts (4)
packages/validators/src/deployments/conditions/name-condition.ts (2)
  • nameCondition (5-9)
  • NameCondition (11-11)
packages/validators/src/deployments/conditions/slug-condition.ts (2)
  • slugCondition (5-9)
  • SlugCondition (11-11)
packages/validators/src/deployments/conditions/system-condition.ts (2)
  • systemCondition (3-7)
  • SystemCondition (9-9)
packages/validators/src/deployments/conditions/id-condition.ts (2)
  • idCondition (3-7)
  • IdCondition (9-9)
packages/db/src/schema/deployment.ts (2)
packages/validators/src/deployments/conditions/deployment-condition.ts (1)
  • DeploymentCondition (14-19)
packages/db/src/common.ts (1)
  • ColumnOperatorFn (54-65)
⏰ Context from checks skipped due to timeout of 90000ms (3)
  • GitHub Check: Typecheck
  • GitHub Check: Lint
  • GitHub Check: build (linux/amd64)
🔇 Additional comments (17)
packages/validators/src/deployments/index.ts (1)

21-22: Appropriate module re-export

The addition properly exports all condition-related schemas and types, making them accessible through this module. This follows the established pattern in the file and is a clean way to organize related validation schemas.

packages/validators/src/deployments/conditions/system-condition.ts (1)

1-9: Well-structured validation schema

The schema correctly defines a system condition with appropriate constraints. The pattern of defining a Zod schema and exporting a derived TypeScript type is a good practice for ensuring type safety throughout the application.

packages/validators/src/deployments/conditions/name-condition.ts (1)

1-11: Well-defined validation schema with appropriate operator flexibility

The schema correctly defines a name condition and imports columnOperator to support multiple comparison operators, unlike other condition types that use fixed literals. This provides appropriate flexibility for name-based conditions while maintaining type safety.

packages/validators/src/deployments/conditions/id-condition.ts (1)

1-9: Properly implemented ID condition schema

The schema correctly defines an ID condition with appropriate constraints. The implementation is consistent with other condition schemas and follows the established pattern of pairing Zod schemas with derived TypeScript types.

packages/validators/src/deployments/conditions/slug-condition.ts (2)

11-11: Export statement looks good.
The SlugCondition export aids in strongly typed usage of this schema across the codebase.


5-9:

❓ Verification inconclusive

Ensure consistent testing coverage.
Consider adding unit tests specifically for the slugCondition object to make sure the operator and value fields are validated correctly against various input scenarios.

Would you like to verify the test coverage using a command to locate relevant test files referencing slugCondition?


🏁 Script executed:

#!/bin/bash
# Searching for tests that reference slugCondition
fd --type f --extension ts --exec rg 'slugCondition' {}

Length of output: 358


Coverage Concern for slugCondition

The search results only returned references within production code rather than dedicated unit tests. Please add specific unit tests for the slugCondition object to ensure that both the operator and value fields are validated correctly across different input scenarios.

  • Verify that tests are added in the appropriate test directory.
  • Ensure that edge cases (invalid/valid input combinations) are thoroughly covered.
packages/validators/src/deployments/conditions/deployment-condition.ts (1)

21-29: Schema design is aligned with best practices.
Using z.lazy properly prevents circular reference issues. The union of condition schemas is both elegant and extensible.

packages/validators/src/deployments/conditions/comparison-condition.ts (2)

12-21: Validate nested conditions coverage.
The conditions array can contain multiple types. Confirm that your test cases cover complex nested structures (AND/OR logic) to ensure correctness.


23-30: Type definition mirrors the schema accurately.
This strongly typed approach reduces potential schema drift.

packages/db/src/common.ts (4)

3-3: Appropriate usage of drizzle-orm imports
These expanded imports (eq, getTableColumns, ilike, sql) are valid for building and composing queries. No concerns here.


5-5: Correct import for column operator handling
Bringing in ColumnOperator from @ctrlplane/validators/conditions aligns well with the new operator-based logic.


24-28: Improved type safety for table columns
Defining ColumnKey and ColumnType ensures better clarity and correctness when working with table columns.


32-32: Refined type parameter promotes clarity
Using Q extends ColumnKey<T> in buildConflictUpdateColumns consistently enforces valid column keys, eliminating potential mismatches.

packages/db/src/schema/deployment.ts (4)

1-4: Updated imports for condition-based logic
Importing DeploymentCondition from the correct validators package and the new drizzle-orm operators is consistent with the revised query-building functionality.


16-16: Comparison operator imported successfully
Including ComparisonOperator sets up the framework for handling compound conditions in deployment filtering.


22-22: ColumnOperatorFn usage recognized
This import from ../common.js will integrate seamlessly with the new deployment condition logic.


137-142: Graceful handling of null or empty conditions
Returning undefined for null or empty conditions is a clean approach, letting callers bypass condition logic when needed.

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: 0

🧹 Nitpick comments (1)
packages/db/src/schema/environment.ts (1)

289-361: Metadata condition builder covers common cases thoroughly.

All operators (Null, StartsWith, EndsWith, Contains, and equality) are handled, and queries appear safely parameterized through drizzle-orm.

Consider adding a more descriptive error message in throw Error("invalid metadata conditions"); to help indicate which operator or scenario was unsupported.

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 2b987ea and cca94c9.

📒 Files selected for processing (13)
  • packages/db/src/schema/environment.ts (3 hunks)
  • packages/validators/package.json (1 hunks)
  • packages/validators/src/conditions/id-condition.ts (1 hunks)
  • packages/validators/src/conditions/index.ts (1 hunks)
  • packages/validators/src/conditions/name-condition.ts (1 hunks)
  • packages/validators/src/conditions/system-condition.ts (1 hunks)
  • packages/validators/src/deployments/conditions/comparison-condition.ts (1 hunks)
  • packages/validators/src/deployments/conditions/deployment-condition.ts (1 hunks)
  • packages/validators/src/deployments/conditions/index.ts (1 hunks)
  • packages/validators/src/environments/comparison-condition.ts (1 hunks)
  • packages/validators/src/environments/directory-condition.ts (1 hunks)
  • packages/validators/src/environments/environment-condition.ts (1 hunks)
  • packages/validators/src/environments/index.ts (1 hunks)
✅ Files skipped from review due to trivial changes (1)
  • packages/validators/src/environments/index.ts
🚧 Files skipped from review as they are similar to previous changes (3)
  • packages/validators/src/deployments/conditions/index.ts
  • packages/validators/src/deployments/conditions/deployment-condition.ts
  • packages/validators/src/deployments/conditions/comparison-condition.ts
🧰 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.

  • packages/validators/src/conditions/id-condition.ts
  • packages/validators/src/conditions/index.ts
  • packages/validators/src/environments/directory-condition.ts
  • packages/validators/src/environments/environment-condition.ts
  • packages/validators/src/conditions/system-condition.ts
  • packages/validators/src/environments/comparison-condition.ts
  • packages/validators/src/conditions/name-condition.ts
  • packages/db/src/schema/environment.ts
🧬 Code Definitions (4)
packages/validators/src/environments/directory-condition.ts (1)
packages/validators/src/conditions/index.ts (1)
  • columnOperator (15-15)
packages/validators/src/environments/environment-condition.ts (5)
packages/validators/src/deployments/conditions/comparison-condition.ts (2)
  • ComparisonCondition (23-30)
  • comparisonCondition (12-21)
packages/validators/src/conditions/name-condition.ts (2)
  • NameCondition (11-11)
  • nameCondition (5-9)
packages/validators/src/conditions/system-condition.ts (2)
  • SystemCondition (9-9)
  • systemCondition (3-7)
packages/validators/src/environments/directory-condition.ts (2)
  • DirectoryCondition (11-11)
  • directoryCondition (5-9)
packages/validators/src/conditions/id-condition.ts (2)
  • IdCondition (9-9)
  • idCondition (3-7)
packages/validators/src/environments/comparison-condition.ts (4)
packages/validators/src/conditions/name-condition.ts (2)
  • nameCondition (5-9)
  • NameCondition (11-11)
packages/validators/src/environments/directory-condition.ts (2)
  • directoryCondition (5-9)
  • DirectoryCondition (11-11)
packages/validators/src/conditions/system-condition.ts (2)
  • systemCondition (3-7)
  • SystemCondition (9-9)
packages/validators/src/conditions/id-condition.ts (2)
  • idCondition (3-7)
  • IdCondition (9-9)
packages/validators/src/conditions/name-condition.ts (1)
packages/validators/src/conditions/index.ts (1)
  • columnOperator (15-15)
⏰ Context from checks skipped due to timeout of 90000ms (2)
  • GitHub Check: Lint
  • GitHub Check: build (linux/amd64)
🔇 Additional comments (19)
packages/validators/package.json (1)

55-57: New "environments" Export Added

This new export block for "./environments" correctly exposes both the TypeScript definitions (./src/environments/index.ts) and the compiled JavaScript implementation (./dist/environments/index.js). This change enhances the module interface in line with the PR objectives by making additional functionality available to package consumers.

Please verify that the corresponding files exist at the specified paths and that they integrate well with other parts of the system.

packages/validators/src/conditions/name-condition.ts (1)

1-11: Looks good - well-structured schema definition.

The implementation follows a clean pattern for condition schema definition with appropriate validations for each field. The use of columnOperator from the shared index file maintains consistency with other condition types.

packages/validators/src/conditions/id-condition.ts (1)

1-9: Looks good - straightforward ID condition schema.

The implementation constrains the operator to only "equals", which is appropriate for ID conditions that typically only need exact matching. This differs from the approach in name-condition.ts but seems intentional and well-reasoned.

packages/validators/src/conditions/system-condition.ts (1)

1-9: Looks good - clean system condition implementation.

The implementation follows the same pattern as id-condition.ts, restricting the operator to only "equals" which makes sense for system identification. The schema structure is clear and appropriately constrained.

packages/validators/src/conditions/index.ts (1)

5-6: Good additions to the index exports.

These exports properly integrate the new condition types into the module's public API, following the established pattern of re-exporting from individual files.

packages/validators/src/environments/directory-condition.ts (3)

1-4: No issues with imports.

The imports are straightforward and appropriate for the new condition schema.


5-9: Schema definition looks good.

The directoryCondition schema correctly enforces a type literal of "directory", uses columnOperator, and requires a string value.


11-11: No concerns with type inference.

Exporting DirectoryCondition using z.infer matches the schema properly.

packages/validators/src/environments/environment-condition.ts (3)

1-15: Imports and type references are consistent.

No issues found with the organization of type imports and references for the sub-condition schemas.


16-22: Union type is well-defined.

Having EnvironmentCondition as a union of supported condition types cleanly captures each variant of environment conditions.


24-34: Zod lazy union is appropriate.

Defining the environmentCondition schema using z.lazy is a good design for recursive or union-based validations. Looks great.

packages/validators/src/environments/comparison-condition.ts (3)

1-13: No issues with imports.

Imports for condition types and Zod are straightforward and neatly organized.


14-29: Lazy-loaded schema is implemented correctly.

The comparisonCondition schema leverages z.lazy and a union of various condition schemas effectively. Good use of optional not with a default of false.


31-42: Strong alignment between schema and type.

The ComparisonCondition type matches the Zod schema nicely, ensuring clarity and consistency.

packages/db/src/schema/environment.ts (5)

1-2: New type imports are appropriate.

Using MetadataCondition and EnvironmentCondition references is aligned with the updated validators.


6-6: No issues with added imports.

The additional imports for drizzle-orm functions (like and, eq, etc.) appear correct and standard for query construction.


22-25: Imports for operators look correct.

The introduction of ComparisonOperator and MetadataOperator from @ctrlplane/validators/conditions is consistent with the new condition logic.


362-390: Composite condition building is well-structured.

  1. Each condition type is correctly transformed into SQL constraints.
  2. The handling of empty conditions returning FALSE is a logical approach for comparisonCondition.

394-398:

✅ Verification successful

Behaves as expected when condition is null or empty.

Returning undefined if condition is empty or null means no WHERE clause, thereby matching all environments. Confirm that this behavior is intentional.

Would you like to verify that this default (“match all”) logic is correct in contexts where no condition is provided?


🏁 Script executed:

#!/bin/bash
# Explanation: Search usage of environmentMatchSelector calls that may pass an undefined or empty condition.

# We'll look for references to environmentMatchSelector:
rg -A 5 "environmentMatchSelector"

Length of output: 992


Match-All Filter Logic Verified
The implementation in packages/db/src/schema/environment.ts correctly returns undefined when condition is null or empty, ensuring that no additional WHERE clause is added (i.e., all environments are matched). Our search confirms that this behavior is consistently and intentionally relied upon—in particular, the usage in packages/rule-engine/src/db/get-applicable-policies.ts indicates that an undefined condition is expected and handled appropriately.

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: 0

🧹 Nitpick comments (2)
packages/rule-engine/src/db/get-applicable-policies.ts (2)

10-92: Confirm handling of multiple query results and unused resourceId.

  1. takeFirstOrNull returns null if more than one matching row is found. Please verify if this strict "single row or nothing" approach matches your expected policy logic, or if you might prefer to select the first matching row instead.
  2. The function signature accepts a resourceId (part of ReleaseRepository) but does not utilize it in the matching logic. Confirm that this omission is intentional and that you do not need resource-level matching.

93-128: Consider performance optimizations and matched-target reporting.

  1. Iterating through every policy and retrieving matches with Promise.all could become costly for large workspaces. If performance becomes an issue, consider partial queries or caching.
  2. Currently, if any target matches, this code returns the entire policy without indicating which target matched. If you need insight into specific matches, store or return the matched target(s) for downstream usage.
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between cca94c9 and 509603f.

📒 Files selected for processing (2)
  • packages/db/src/schema/policy.ts (4 hunks)
  • packages/rule-engine/src/db/get-applicable-policies.ts (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/db/src/schema/policy.ts
🧰 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.

  • packages/rule-engine/src/db/get-applicable-policies.ts
🧬 Code Definitions (1)
packages/rule-engine/src/db/get-applicable-policies.ts (3)
packages/db/src/common.ts (2)
  • Tx (22-22)
  • takeFirstOrNull (15-20)
packages/rule-engine/src/types.ts (1)
  • ReleaseRepository (70-74)
packages/db/src/schema/policy.ts (2)
  • PolicyTarget (228-228)
  • policy (23-39)
⏰ Context from checks skipped due to timeout of 90000ms (3)
  • GitHub Check: Typecheck
  • GitHub Check: build (linux/amd64)
  • GitHub Check: Lint
🔇 Additional comments (1)
packages/rule-engine/src/db/get-applicable-policies.ts (1)

1-9: Imports and initial setup look good.

No immediate issues identified in these lines. The imports are consistent with the usage throughout the file, and type references appear to be correctly organized.

@jsbroks jsbroks merged commit 1563998 into main Mar 31, 2025
9 of 11 checks passed
@jsbroks jsbroks deleted the policy-selectors branch March 31, 2025 03:05
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.

3 participants