Skip to content

Conversation

@ymc9
Copy link
Member

@ymc9 ymc9 commented Sep 10, 2025

Summary by CodeRabbit

  • New Features
    • More informative NotFoundError messages including model context and optional details, especially for failed nested relation connects.
  • Bug Fixes
    • Corrected handling of unary NOT in policy expressions for more accurate evaluation.
    • Clarified validation message when comparing models (“comparison between models is not supported”).
  • Tests
    • Added comprehensive policy tests for reference equality and language tests for expression validation; removed an obsolete test.
  • Chores
    • Streamlined development dependencies and improved plugin model discovery in test utilities.

Copilot AI review requested due to automatic review settings September 10, 2025 04:17
@coderabbitai
Copy link

coderabbitai bot commented Sep 10, 2025

Note

Other AI code review bot(s) detected

CodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review.

Caution

Review failed

The pull request is closed.

Walkthrough

The PR updates devDependencies, tweaks a validation error message, enhances test utilities and adds new language tests, changes NotFoundError to accept optional details and updates its call site, adjusts unary NOT transformation in policy code, and replaces a runtime policy test with two more comprehensive ones.

Changes

Cohort / File(s) Summary
Dev tooling
packages/language/package.json
Reorganized devDependencies; added glob, @types/tmp, and @zenstackhq/common-helpers; deduplicated tmp-related entries. No runtime dependency changes.
Language validation message
packages/language/src/validators/expression-validator.ts
Updated error text for model–model comparisons from “comparison between model-typed fields are not supported” to “comparison between models is not supported”.
Language test utilities and suites
packages/language/test/utils.ts, packages/language/test/expression-validation.test.ts
Test utils now pass plugin models to loadDocument, add glob-based plugin discovery, and strengthen error assertions. Added tests covering model comparison, auth comparisons, and type compatibility.
Runtime error handling
packages/runtime/src/client/errors.ts, packages/runtime/src/client/crud/operations/base.ts
NotFoundError now supports an optional details parameter; call site updated to include relation model and descriptive message for failed nested connect.
Policy expression transformation
packages/runtime/src/plugins/policy/expression-transformer.ts
Unary ! now emits a logical-not operation instead of transforming to operand != true.
Runtime policy tests
packages/runtime/test/policy/auth-equality.test.ts, packages/runtime/test/policy/ref-equality.test.ts
Added new tests for reference equality/inequality across models and auth; removed the older reference-equality test file.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Poem

A rabbit taps keys with a whisker’s delight,
Flips a “not” to true logic’s light,
Errors now speak with a little more lore,
Tests hop farther than they did before.
Models won’t mingle where they shouldn’t compare—
Carrots for clarity, shipped with care! 🥕✨


📜 Recent review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 6ba1480 and fd0f8ce.

📒 Files selected for processing (1)
  • packages/language/test/expression-validation.test.ts (1 hunks)
✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/ref-equality

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

Comment @coderabbitai help to get the list of available commands and usage tips.

@claude
Copy link

claude bot commented Sep 10, 2025

Claude finished @ymc9's task —— View job


PR Review: feat(policy): support comparing auth() with auth model

Todo List:

  • Read and analyze all changed files
  • Review language validator changes
  • Review runtime policy transformer changes
  • Examine test coverage and quality
  • Check for potential bugs and security issues
  • Provide comprehensive feedback

Summary

This PR adds support for comparing auth() with auth model instances in policy expressions. It's a well-implemented feature that allows more natural policy expressions like auth() == user instead of requiring field-by-field comparisons.

Review Feedback

Code Quality & Best Practices

Strong Points:

  • Clean separation of concerns: Language validation logic is properly separated from runtime transformation
  • Consistent error handling: Good use of custom error types (QueryError) with descriptive messages
  • Comprehensive test coverage: Both language validation tests and runtime policy tests
  • Type safety: Proper TypeScript usage with invariant checks

Language Validator Changes (packages/language/src/validators/expression-validator.ts)

The changes are minimal but important:

  • Line 194-201: Enhanced comparison validation to allow auth model comparisons
  • Line 217-225: Maintains existing restrictions on general model comparisons
  • Good approach: Only allows auth comparisons when both operands are auth-related models

Runtime Policy Transformer (packages/runtime/src/plugins/policy/expression-transformer.ts)

Well-implemented transformation logic:

  • Lines 252-297: transformAuthBinary method properly handles auth comparisons
  • Lines 284-291: Correctly transforms auth comparisons to ID field comparisons using ExpressionUtils.member
  • Lines 272-277: Proper validation that auth type must be a model for comparisons
  • Lines 291-295: Handles both == and != operators correctly

Test Coverage

Excellent test suite:

  • Language tests: Validates that auth comparisons are allowed while regular model comparisons are still forbidden
  • Runtime tests: Comprehensive testing of create/update operations with composite keys
  • Edge cases: Tests both equality and inequality comparisons
  • Real scenarios: Tests with realistic User/Post relationship patterns

⚠️ Minor Issues

  1. Error message consistency (packages/runtime/src/client/errors.ts):

    • The changes on lines 27-29 appear to be formatting-only
    • Consider adding a specific error type for auth comparison issues
  2. Base operation changes (packages/runtime/src/client/crud/operations/base.ts):

    • Line 106 change looks like import organization
    • Changes appear minimal and safe

🔒 Security Considerations

Security looks good:

  • No new attack vectors introduced
  • Auth comparisons are properly validated at both language and runtime levels
  • ID field comparison approach is secure and performant
  • Proper error handling prevents information leakage

Performance Considerations

Efficient implementation:

  • Auth comparisons are transformed to ID field comparisons at query build time
  • No runtime overhead for auth resolution
  • Reuses existing field comparison infrastructure

📝 Documentation & Maintainability

Suggestions:

  • Consider adding inline comments explaining the ID field expansion logic in transformAuthBinary
  • The test file rename (ref-equality.test.tsauth-equality.test.ts) better reflects the feature

Verdict

This is a high-quality implementation that adds a useful feature while maintaining code quality and security. The changes are minimal, well-tested, and follow existing patterns in the codebase.

Recommended for approval


Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

This PR implements support for comparing auth() with auth model types in policy expressions. The changes enable equality/inequality comparisons between the auth() function and model instances within access control policies.

  • Refactored unary expression handling to use logical NOT instead of binary comparison
  • Updated error messages for better clarity and specificity
  • Added comprehensive test coverage for auth equality comparisons

Reviewed Changes

Copilot reviewed 9 out of 10 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
packages/runtime/test/policy/auth-equality.test.ts Added new test file with comprehensive auth equality/inequality test cases
packages/runtime/src/plugins/policy/expression-transformer.ts Simplified unary expression transformation to use logical NOT
packages/runtime/src/client/errors.ts Enhanced NotFoundError constructor with optional details parameter
packages/runtime/src/client/crud/operations/base.ts Updated error message for relation connection failures
packages/language/test/utils.ts Improved test utilities with better error handling and plugin model loading
packages/language/test/expression-validationt.test.ts Added validation tests for model comparison expressions
packages/language/src/validators/expression-validator.ts Updated error message for model comparison validation
packages/language/package.json Reordered dependencies alphabetically
Files not reviewed (1)
  • pnpm-lock.yaml: Language not supported

Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.

Copy link

@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 (6)
packages/language/src/validators/expression-validator.ts (1)

195-201: Prefer strict reference comparison for model types

Use !== instead of != when comparing leftType and rightType (both objects) to avoid abstract equality semantics.

packages/runtime/src/plugins/policy/expression-transformer.ts (1)

198-206: Minor clarity: document '^' vs '!' collection semantics

Current logic implements: '^' = none (count == 0), '!' = every (negated predicate then count == 0). A short comment would prevent future confusion.

Also applies to: 239-244

packages/runtime/src/client/crud/operations/base.ts (1)

570-574: Great: richer NotFoundError for connect failures

Passing relation context improves debuggability for nested connects. Consider gradually adding similar details to other NotFoundError throws in this file for consistency.

packages/runtime/test/policy/auth-equality.test.ts (1)

63-108: Nice negative coverage for inequality

Validates auth()!=this/author policy behavior. Consider adding a tiny case for auth() == null acceptance/rejection semantics in the future.

packages/language/test/expression-validationt.test.ts (1)

1-101: File name likely has a stray 't'

Suggest renaming to expression-validation.test.ts for consistency with suite names and discoverability.

packages/language/test/utils.ts (1)

1-3: ESM-safe __dirname, glob usage, and UUID generation

  • In ESM, prefer fileURLToPath(import.meta.url) over __dirname.
  • Use globSync for clarity with glob@11.
  • Avoid relying on global crypto; import randomUUID explicitly.

Apply this diff:

-import { glob } from 'glob';
-import fs from 'node:fs';
+import { globSync } from 'glob';
+import fs from 'node:fs';
+import { randomUUID } from 'node:crypto';
+import { fileURLToPath } from 'node:url';
 import os from 'node:os';
 import path from 'node:path';
 import { expect } from 'vitest';
 import { loadDocument } from '../src';
+const __dirname = path.dirname(fileURLToPath(import.meta.url));
@@
-    const tempFile = path.join(os.tmpdir(), `zenstack-schema-${crypto.randomUUID()}.zmodel`);
+    const tempFile = path.join(os.tmpdir(), `zenstack-schema-${randomUUID()}.zmodel`);
@@
-    const tempFile = path.join(os.tmpdir(), `zenstack-schema-${crypto.randomUUID()}.zmodel`);
+    const tempFile = path.join(os.tmpdir(), `zenstack-schema-${randomUUID()}.zmodel`);
@@
-function getPluginModels() {
-    return glob.sync(path.resolve(__dirname, '../../runtime/src/plugins/**/plugin.zmodel'));
-}
+function getPluginModels() {
+    return globSync(path.resolve(__dirname, '../../runtime/src/plugins/**/plugin.zmodel'));
+}

Also applies to: 41-43

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 67d35d5 and 6ba1480.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (9)
  • packages/language/package.json (1 hunks)
  • packages/language/src/validators/expression-validator.ts (1 hunks)
  • packages/language/test/expression-validationt.test.ts (1 hunks)
  • packages/language/test/utils.ts (2 hunks)
  • packages/runtime/src/client/crud/operations/base.ts (1 hunks)
  • packages/runtime/src/client/errors.ts (1 hunks)
  • packages/runtime/src/plugins/policy/expression-transformer.ts (1 hunks)
  • packages/runtime/test/policy/auth-equality.test.ts (1 hunks)
  • packages/runtime/test/policy/ref-equality.test.ts (0 hunks)
💤 Files with no reviewable changes (1)
  • packages/runtime/test/policy/ref-equality.test.ts
🧰 Additional context used
📓 Path-based instructions (1)
{packages,samples,tests}/**

📄 CodeRabbit inference engine (CLAUDE.md)

Place packages only under packages/, samples/, or tests/

Files:

  • packages/language/src/validators/expression-validator.ts
  • packages/runtime/src/client/errors.ts
  • packages/runtime/src/plugins/policy/expression-transformer.ts
  • packages/language/test/expression-validationt.test.ts
  • packages/runtime/src/client/crud/operations/base.ts
  • packages/runtime/test/policy/auth-equality.test.ts
  • packages/language/package.json
  • packages/language/test/utils.ts
🧬 Code graph analysis (6)
packages/language/src/validators/expression-validator.ts (2)
packages/language/src/utils.ts (1)
  • isDataFieldReference (138-140)
packages/language/src/generated/ast.ts (1)
  • isThisExpr (721-723)
packages/runtime/src/plugins/policy/expression-transformer.ts (1)
packages/runtime/src/plugins/policy/utils.ts (1)
  • logicalNot (88-95)
packages/language/test/expression-validationt.test.ts (1)
packages/language/test/utils.ts (2)
  • loadSchemaWithError (22-40)
  • loadSchema (9-20)
packages/runtime/src/client/crud/operations/base.ts (1)
packages/runtime/src/client/errors.ts (1)
  • NotFoundError (27-31)
packages/runtime/test/policy/auth-equality.test.ts (1)
packages/runtime/test/policy/utils.ts (1)
  • createPolicyTestClient (14-25)
packages/language/test/utils.ts (1)
packages/language/src/index.ts (1)
  • loadDocument (21-132)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: build-test (20.x)
🔇 Additional comments (6)
packages/language/src/validators/expression-validator.ts (1)

210-216: Error wording change is good; matches tests

Switching to "comparison between models is not supported" is clearer and aligns with new tests.

packages/runtime/src/plugins/policy/expression-transformer.ts (2)

303-309: Unary "!" rewrite via logicalNot is correct

This produces proper SQL NOT (...) with precedence handled by utils (paren-wrapping And/Or).


252-296: Auth reference equality looks solid (composite IDs included)

Building equality on all auth model id fields, with != handled via logical NOT, covers composite keys and matches policy behavior.

packages/language/package.json (1)

61-70: Dev deps update looks good

Adding glob and consolidating tmp/types supports new test utils. No issues spotted.

packages/runtime/src/client/errors.ts (1)

28-30: Optional details on NotFoundError is a useful improvement

Message composition is clear and backward-compatible.

packages/runtime/test/policy/auth-equality.test.ts (1)

4-61: Covers equality paths well

Happy path and policy rejections for auth()==this/author are validated, including connect with composite IDs.

@ymc9 ymc9 merged commit 4ef27c7 into dev Sep 10, 2025
3 of 4 checks passed
@claude
Copy link

claude bot commented Sep 10, 2025

Claude finished @ymc9's task —— View job


PR Review: feat(policy): support comparing auth() with auth model

Todo List:

  • Read and analyze all changed files
  • Review language validator changes
  • Review runtime policy transformer changes
  • Examine test coverage and quality
  • Check for potential bugs and security issues
  • Provide comprehensive feedback

Summary

This PR adds support for comparing auth() with auth model instances in policy expressions. It's a well-implemented feature that allows more natural policy expressions like auth() == user instead of requiring field-by-field comparisons.

Review Feedback

Code Quality & Best Practices

Strong Points:

  • Clean separation of concerns: Language validation logic is properly separated from runtime transformation
  • Consistent error handling: Good use of custom error types (QueryError) with descriptive messages
  • Comprehensive test coverage: Both language validation tests and runtime policy tests
  • Type safety: Proper TypeScript usage with invariant checks

Language Validator Changes (packages/language/src/validators/expression-validator.ts)

The changes are minimal but important:

  • Line 194-201: Enhanced comparison validation to allow auth model comparisons
  • Line 217-225: Maintains existing restrictions on general model comparisons
  • Good approach: Only allows auth comparisons when both operands are auth-related models

Runtime Policy Transformer (packages/runtime/src/plugins/policy/expression-transformer.ts)

Well-implemented transformation logic:

  • Lines 252-297: transformAuthBinary method properly handles auth comparisons
  • Lines 284-291: Correctly transforms auth comparisons to ID field comparisons using ExpressionUtils.member
  • Lines 272-277: Proper validation that auth type must be a model for comparisons
  • Lines 291-295: Handles both == and != operators correctly

Test Coverage

Excellent test suite:

  • Language tests: Validates that auth comparisons are allowed while regular model comparisons are still forbidden
  • Runtime tests: Comprehensive testing of create/update operations with composite keys
  • Edge cases: Tests both equality and inequality comparisons
  • Real scenarios: Tests with realistic User/Post relationship patterns

⚠️ Minor Issues

  1. Error message consistency (packages/runtime/src/client/errors.ts):

    • The changes on lines 27-29 appear to be formatting-only
    • Consider adding a specific error type for auth comparison issues
  2. Base operation changes (packages/runtime/src/client/crud/operations/base.ts):

    • Line 106 change looks like import organization
    • Changes appear minimal and safe

🔒 Security Considerations

Security looks good:

  • No new attack vectors introduced
  • Auth comparisons are properly validated at both language and runtime levels
  • ID field comparison approach is secure and performant
  • Proper error handling prevents information leakage

Performance Considerations

Efficient implementation:

  • Auth comparisons are transformed to ID field comparisons at query build time
  • No runtime overhead for auth resolution
  • Reuses existing field comparison infrastructure

📝 Documentation & Maintainability

Suggestions:

  • Consider adding inline comments explaining the ID field expansion logic in transformAuthBinary
  • The test file rename (ref-equality.test.tsauth-equality.test.ts) better reflects the feature

Verdict

This is a high-quality implementation that adds a useful feature while maintaining code quality and security. The changes are minimal, well-tested, and follow existing patterns in the codebase.

Recommended for approval


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