Skip to content

Conversation

@ymc9
Copy link
Member

@ymc9 ymc9 commented Nov 27, 2025

Summary by CodeRabbit

  • New Features

    • Added @omit() attribute to mark fields omitted by default, with per-query override and client-level omit settings.
    • Client options now include omit configuration and allowQueryTimeOmitOverride.
    • Authentication can be defined via type-defs as well as models.
    • Generated payload types now accept client Options to influence result shapes.
  • Chores

    • Version bumped to 3.0.0-beta.26.
    • pnpm and TypeScript constraints updated.

✏️ Tip: You can customize this high-level summary in your review settings.

ymc9 and others added 6 commits November 25, 2025 17:54
)

* feat(policy): support arbitrary collection traversal from `auth()`

* address PR comments
* fix: ts schema generation for ignored models and fields

* Update tests/e2e/orm/client-api/ignore.test.ts

Co-authored-by: Copilot <[email protected]>

* Update tests/e2e/orm/client-api/ignore.test.ts

Co-authored-by: Copilot <[email protected]>

* fix test

---------

Co-authored-by: Copilot <[email protected]>
* feat: implement field omission

* Update tests/e2e/orm/client-api/omit.test.ts

Co-authored-by: Copilot <[email protected]>

* fix build

* fix build

* fix build

* update sample

* fix tests

* update

---------

Co-authored-by: Copilot <[email protected]>
* feat(orm): add settings to disallow query-time omit override

* Update packages/orm/src/client/options.ts

Co-authored-by: Copilot <[email protected]>

---------

Co-authored-by: Copilot <[email protected]>
* fix(orm): typing issue when auth type is a typedef

* update
Copilot AI review requested due to automatic review settings November 27, 2025 10:38
@coderabbitai
Copy link

coderabbitai bot commented Nov 27, 2025

Walkthrough

Thread ClientOptions and omit settings through the ORM and query clients, add @omit attribute and query-time omit handling, make ClientImpl non-generic, extend type-system (SimplifiedModelResult/ModelResult/etc.) to carry Options, add related tests and version bumps across the monorepo.

Changes

Cohort / File(s) Summary
Monorepo metadata & workspace
package.json, pnpm-workspace.yaml, packages/*/package.json, samples/*/package.json, tests/*/package.json
Version bumps to 3.0.0-beta.26, pnpm/TypeScript constraint updates, move prisma tooling to devDependencies in top package.json
Docs / TODO
TODO.md
Checklist items marked complete (CLI db/seed/format and Global omit)
ORM client core
packages/orm/src/client/client-impl.ts, packages/orm/src/client/contract.ts, packages/orm/src/client/promise.ts
Make ClientImpl non-generic; introduce Options generic on ClientContract and public APIs; add $setOptions; broaden promise/transaction typings to SchemaDef/any
CRUD typing and options
packages/orm/src/client/crud-types.ts, packages/orm/src/client/options.ts, packages/orm/src/client/crud/dialects/*, packages/orm/src/client/crud/operations/base.ts
Thread Options through SimplifiedModelResult/ModelResult/etc.; add OmitOptions and allowQueryTimeOmitOverride; introduce ShouldOmitField logic and dialect.shouldOmitField usage for omission checks
Validators & input validation
packages/orm/src/client/crud/validator/index.ts
Add client.$options accessor; include omit in schemas and gate query-time omit overrides via allowQueryTimeOmitOverride
Query executor & dialects
packages/orm/src/client/executor/zenstack-query-executor.ts, packages/orm/src/client/crud/dialects/{base-dialect,postgresql,sqlite}.ts
Remove generics from executor; mutation info/model now string-typed; use shouldOmitField in relation JSON/build logic
TanStack Query client integrations
packages/clients/tanstack-query/src/{react,svelte,vue}.ts, packages/clients/tanstack-query/test/schemas/basic/input.ts
Propagate ClientOptions<Schema> into SimplifiedModelResult across hook option/result types and ModelMutationModelResult; update generated test schema typings
Language & schema features
packages/language/res/stdlib.zmodel, packages/language/src/validators/function-invocation-validator.ts, packages/language/src/zmodel-scope.ts, packages/schema/src/schema.ts
Add @omit() attribute, add auth() invocation check, enable typedef-member-access in scopes, add FieldDef.omit and allow Schema.authType to reference TypeDefs
Codegen / SDK changes
packages/sdk/src/ts-schema-generator.ts, packages/sdk/src/model-utils.ts
Centralize getAllDataModels/getAllTypeDefs helpers; emit omit metadata; getAuthDecl now considers TypeDefs
Utilities & type helpers
packages/orm/src/utils/{schema-utils.ts,type-utils.ts}
Add VisitResult and MatchingExpressionVisitor; add PartialIf and ArrayIf utility types and propagate visit abort semantics
Policy plugin
packages/plugins/policy/src/{expression-evaluator.ts,expression-transformer.ts,policy-handler.ts,types.ts}
Null propagation changes in evaluator; replace model→modelOrType and add thisType/thisAlias/contextValue in transformer context; add CollectionPredicateOperator constant/type
Test tooling & createTestClient
packages/testtools/src/client.ts, tests/e2e/*, generated test schemas under tests/e2e/orm/schemas/*
Refactor CreateTestClientOptions and createTestClient typings (Options generic); add many generated input.ts/models with new Options generic; add/modify e2e tests for omit, auth, ignore, policy and validation changes
Samples and generated inputs
samples/*/zenstack/input.ts, tests/e2e/**/input.ts
All GetPayload/GetPayload-like types extended with an Options generic (defaulting to ClientOptions<$Schema>) and pass Options into SimplifiedModelResult

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Areas to focus review on:

  • ClientImpl non-generic refactor and transaction overloads (packages/orm/src/client/client-impl.ts)
  • Options threading across type system (crud-types, contract) and generated payload signatures
  • Omit precedence logic (ShouldOmitField) and dialect.shouldOmitField integration (dialects, operations, validators)
  • TanStack-query client signature changes in react/svelte/vue files for correct consumer typings
  • Policy/expression changes that adjust auth()/typedef behavior and transformer context

Possibly related PRs

Poem

🐰
I hopped through types and threaded the seam,
ClientOptions tucked in each payload dream.
Fields that must vanish now hide with a wink,
Non-generic client — the code took a blink.
Cheers from a rabbit, who nudged the new scheme.

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 20.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly identifies the primary change: merging the dev branch to main with a version bump to v3.0.0-beta.26, which aligns with the extensive version updates across all package.json files in the changeset.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch dev

📜 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 d73c49e and d4e9f31.

📒 Files selected for processing (3)
  • packages/orm/src/client/contract.ts (22 hunks)
  • packages/orm/src/utils/schema-utils.ts (2 hunks)
  • packages/plugins/policy/src/expression-evaluator.ts (2 hunks)
🧰 Additional context used
🧠 Learnings (4)
📚 Learning: 2025-11-26T01:55:04.540Z
Learnt from: CR
Repo: zenstackhq/zenstack-v3 PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-26T01:55:04.540Z
Learning: Applies to packages/zenstackhq/orm/**/*.test.{ts,tsx} : ORM package tests should include comprehensive client API tests and policy tests

Applied to files:

  • packages/orm/src/client/contract.ts
📚 Learning: 2025-11-26T01:55:04.540Z
Learnt from: CR
Repo: zenstackhq/zenstack-v3 PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-26T01:55:04.540Z
Learning: Applies to packages/zenstackhq/orm/**/*.{ts,tsx} : Implement plugin hooks at ORM, Kysely, and entity mutation levels for query interception and customization

Applied to files:

  • packages/orm/src/client/contract.ts
📚 Learning: 2025-11-26T01:55:04.540Z
Learnt from: CR
Repo: zenstackhq/zenstack-v3 PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-26T01:55:04.540Z
Learning: Applies to packages/zenstackhq/orm/**/*.{ts,tsx} : Use Kysely as the query builder interface for low-level database queries, avoiding raw SQL when possible

Applied to files:

  • packages/orm/src/client/contract.ts
📚 Learning: 2025-11-26T01:55:04.540Z
Learnt from: CR
Repo: zenstackhq/zenstack-v3 PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-26T01:55:04.540Z
Learning: Applies to **/*.zmodel : ZModel schema files should define database structure and policies that compile to TypeScript via `zenstack generate`

Applied to files:

  • packages/orm/src/client/contract.ts
🧬 Code graph analysis (2)
packages/orm/src/utils/schema-utils.ts (1)
packages/schema/src/expression.ts (9)
  • LiteralExpression (12-15)
  • ArrayExpression (17-20)
  • FieldExpression (22-25)
  • MemberExpression (27-31)
  • BinaryExpression (39-44)
  • UnaryExpression (33-37)
  • CallExpression (46-50)
  • ThisExpression (52-54)
  • NullExpression (56-58)
packages/orm/src/client/contract.ts (3)
packages/schema/src/schema.ts (5)
  • SchemaDef (11-19)
  • GetModels (121-121)
  • RelationFields (211-215)
  • RelationFieldType (223-230)
  • GetTypeDefs (142-142)
packages/orm/src/client/options.ts (1)
  • ClientOptions (45-108)
packages/orm/src/client/crud-types.ts (3)
  • SimplifiedModelResult (241-248)
  • DefaultModelResult (52-76)
  • TypeDefResult (250-274)
⏰ 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). (3)
  • GitHub Check: claude-review
  • GitHub Check: build-test (20.x, postgresql)
  • GitHub Check: build-test (20.x, sqlite)
🔇 Additional comments (16)
packages/orm/src/client/contract.ts (6)

63-72: LGTM - Options generic threading is well-designed.

The Options generic with a default value of ClientOptions<Schema> ensures backward compatibility while enabling type-safe options propagation. The $options property correctly returns the constrained Options type.


122-137: Good API addition with proper deprecation path.

The $setOptions method provides a more flexible way to modify client options, and $setInputValidation is appropriately deprecated. The shadowing generic in $setOptions<Options> correctly allows changing the options type and returning a properly typed client.


217-221: Verify: MapType for procedure return types doesn't include Options.

The MapType helper used for procedure return types still uses ModelResult<Schema, T> without the Options parameter. This means procedure results won't respect client-level omit settings. If this is intentional, consider adding a brief comment; otherwise, threading Options here would align procedure results with the rest of the API.


274-278: LGTM - Consistent Options threading through all model operations.

The Options generic is correctly propagated to SimplifiedModelResult for all operations returning entity data, while batch and aggregate operations appropriately don't apply Options since they return counts or aggregated values.

Also applies to: 360-362


853-866: LGTM - Auth type correctly uses base ClientOptions<Schema>.

Using ClientOptions<Schema> directly in AuthModelType (line 854) rather than the Options generic is the right choice—auth context data should not be affected by client omit settings. The updated AuthType conditional correctly handles TypeDef-based auth with proper fallback.


245-250: LGTM - Constructor signature correctly updated.

The ClientConstructor interface properly threads both Schema and Options generics, ensuring type-safe client instantiation.

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

82-85: SQL-like null propagation correctly implemented.

This change ensures non-equality operators return null when either operand is null, aligning with SQL semantics. Note that this affects:

  • Comparison operators (>, >=, <, <=): now return null instead of potentially throwing or returning false
  • Logical operators (&&, ||): now return null instead of JavaScript short-circuit behavior
  • The in operator: now returns null when the right operand is null (previously treated as [] at line 97)

The behavior is consistent with the stated intent of SQL-like null propagation.


109-110: Stricter null check correctly addresses past review concern.

The change from if (!left) to if (left === null || left === undefined) makes the guard more explicit:

  • Empty arrays [] (which are truthy in JavaScript) now correctly proceed to evaluation rather than returning null
  • Collection predicates on [] now return the correct values: ?false, !true, ^true
  • Other falsy non-array values (e.g., false, 0, "") now fail at the invariant on line 113, providing better type safety
packages/orm/src/utils/schema-utils.ts (8)

15-16: Abortable VisitResult union fits the visitor use case well

VisitResult = void | { abort: true } cleanly encodes the “keep going vs. short‑circuit” contract without changing existing void-only overrides.


18-29: Visitor dispatch correctly propagates VisitResult

The match over expr.kind with an exhaustive branch cleanly forwards each specialized visit* result so an abort from any leaf can bubble up.


32-41: Array traversal short-circuits correctly on abort

Iterating e.items and immediately returning when a child visit yields { abort: true } gives the expected early‑exit behavior while remaining a no‑op for non‑aborting visitors.


43-43: No-op field visit is a reasonable default

Leaving visitField empty but overridable is a sensible base behavior when there’s no inherent traversal under a field expression.


45-56: Member and binary traversal preserve abort semantics

Visiting only e.receiver for members (no nested expressions in members) and visiting left then right for binaries, with an early return when left aborts, looks correct and consistent with the new contract.


58-60: Unary traversal is correctly delegated to the operand

Forwarding directly to visit(e.operand) keeps unary handling simple while allowing subclasses to inject custom logic by overriding visitUnary.


62-69: Call traversal handles optional args and aborts properly

Iterating e.args ?? [] safely covers the “no args” case, and returning immediately on an aborting argument keeps traversal efficient.


71-74: No-op visits for this and null are appropriate

Treating this and null as terminal nodes with empty hooks is a sensible baseline and matches their lack of child expressions.


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 Nov 27, 2025

Claude finished @ymc9's task —— View job


Pull Request Review

I've completed a comprehensive review of this large PR merging dev to main for v3.0.0-beta.26. Here are my findings:

Overall Assessment

This is a well-structured release that introduces significant new features while maintaining code quality. The changes primarily focus on:

  1. Field Omission System - A comprehensive new feature for controlling field visibility
  2. Auth Type Improvements - Enhanced custom auth typing support
  3. PostgreSQL Timezone Fixes - Better handling of date/time values

🚀 Key Features & Improvements

Field Omission System (packages/orm/src/client/options.ts:84-117)

  • Three-level precedence: Query-level → Options-level → Schema-level omit
  • Configurable override protection: allowQueryTimeOmitOverride option prevents unauthorized field exposure
  • Type-safe implementation: Fields properly omitted at TypeScript level with @ts-expect-error comments
  • Delegate model support: Works correctly with inheritance patterns

Auth Type Enhancements (tests/e2e/orm/schemas/auth-type/schema.zmodel)

  • Custom auth types: Support for complex auth structures beyond simple User models
  • Nested permissions: Allows structured permission systems like { permissions: [{ actionCode: 'MANAGE' }] }
  • Type safety: Full TypeScript inference for custom auth shapes

PostgreSQL Timezone Fix (packages/orm/src/client/crud/dialects/postgresql.ts:107-118)

  • Configurable timezone handling: fixPostgresTimezone option (defaults to true)
  • Proper UTC conversion: Addresses node-pg's local timezone interpretation quirk
  • Backwards compatible: Can be disabled if custom handling needed

🔍 Code Quality Findings

Strengths

  • Comprehensive test coverage: New features have thorough test suites
  • Type safety: Excellent TypeScript integration with proper inference
  • Error handling: Good validation with clear error messages
  • Documentation: Well-documented APIs with extensive JSDoc examples

Minor Concerns

  • Large changeset: 77 files changed makes review challenging but appears well-coordinated
  • Version bump coordination: Multiple package.json files updated consistently ✅
  • Backwards compatibility: Changes appear additive with proper defaults ✅

🔒 Security Review

Positive Findings

  • Field omission security: Query-level override protection prevents accidental exposure of sensitive fields
  • Input validation: Proper validation of omit configurations
  • No hardcoded secrets: No security credentials found in code

Recommendations

  • Consider adding documentation about security implications of allowQueryTimeOmitOverride: true
  • Field omission should be tested with complex nested scenarios

Performance Considerations

PostgreSQL Optimizations

  • JSON aggregation: Efficient jsonb_agg and jsonb_build_object usage
  • Lateral joins: Proper use of LEFT JOIN LATERAL for relation queries
  • Field selection: Omit functionality reduces payload size

Type System Performance

  • Conditional types: Complex but necessary for type safety
  • Union handling: Delegate models use proper type distribution

🧪 Test Coverage Assessment

New Test Files:

  • auth-typing.test.ts - Custom auth type validation ✅
  • omit.test.ts - Comprehensive field omission testing ✅
  • ignore.test.ts - Model/field ignoring functionality ✅

Test Quality:

  • Edge cases covered (delegate models, nested relations)
  • Security scenarios tested (override protection)
  • Type safety verified with @ts-expect-error annotations

🎯 Recommendations

For Production

  1. Monitor performance of omit functionality with large datasets
  2. Document security implications of omit override settings
  3. Test PostgreSQL timezone fix with various timezone configurations

For Future Development

  1. Consider caching omit field calculations for performance
  2. Add field-level access control integration with omit system
  3. Consider audit logging for omit overrides in security-sensitive applications

📝 Summary

This PR introduces well-designed features that enhance ZenStack's capabilities while maintaining backwards compatibility. The field omission system is particularly valuable for security and API design, and the auth type improvements provide much-needed flexibility.

Approval Status: ✅ APPROVED

The code quality is high, test coverage is comprehensive, and the features address real user needs. The large changeset is justified by the coordinated nature of the feature additions.


Copilot finished reviewing on behalf of ymc9 November 27, 2025 10:39
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 merges development changes to main for version 3.0.0-beta.26, introducing significant new features and improvements to the ZenStack ORM framework.

Purpose: Version bump and feature release including field omission support, custom auth type definitions, enhanced collection predicate handling, and improved type safety throughout the client API.

Key Changes:

  • Added @omit attribute for fields with three-level omission control (schema, options, query-level)
  • Introduced support for custom auth types (not just models) via @@auth attribute on type definitions
  • Enhanced collection predicate expressions with support for value-based auth data
  • Improved type safety by threading ClientOptions generic parameter through the entire type system
  • Added $setOptions method for creating clients with modified options

Reviewed changes

Copilot reviewed 76 out of 77 changed files in this pull request and generated no comments.

Show a summary per file
File Description
Multiple package.json files Version bump to 3.0.0-beta.26 across all packages
tests/e2e/orm/validation/custom-validation.test.ts Refactored to use $setOptions instead of deprecated $setInputValidation
tests/e2e/orm/schemas/omit/* New schema files for testing field omission feature
tests/e2e/orm/schemas/auth-type/* New schema files for testing custom auth type feature
tests/e2e/orm/schemas/basic/schema.zmodel Added @ignore field and model for testing
tests/e2e/orm/client-api/*.test.ts New tests for omit, ignore, and auth-typing features
tests/e2e/orm/policy/auth-access.test.ts Comprehensive tests for auth access with types and models
tests/e2e/apps/rally/rally.test.ts Removed debug flag
Multiple input.ts files Added ClientOptions import and Options parameter to GetPayload types
packages/orm/src/client/* Enhanced with Options generic parameter threading and $setOptions method
packages/orm/src/client/crud/* Added omit field handling logic across dialects
packages/plugins/policy/src/* Significant refactoring for auth type support and collection predicates
packages/schema/src/schema.ts Added authType union with GetTypeDefs, omit field property
packages/sdk/src/* Enhanced type generation with ClientOptions support
packages/language/* Added @omit attribute, improved auth validation and scoping
packages/testtools/src/client.ts Enhanced createTestClient with better type inference
packages/clients/tanstack-query/src/* Updated all hooks with ClientOptions in type signatures
pnpm-workspace.yaml TypeScript version update from ^5.8.0 to ^5.9.3
pnpm-lock.yaml Extensive dependency updates reflecting TypeScript version change
Files not reviewed (1)
  • pnpm-lock.yaml: Language not supported

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

You can also share your feedback on Copilot code review for a chance to win a $100 gift card. Take the survey.

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
packages/orm/src/client/crud/validator/index.ts (1)

237-243: Schema caching doesn't account for allowQueryTimeOmitOverride, causing cross-client cache pollution.

makeOmitSchema now branches on this.options.allowQueryTimeOmitOverride, but the cache key in validate() doesn't include this option. Since schemaCache is module-level and keyed only by SchemaDef, clients with different allowQueryTimeOmitOverride values will share cached schemas incorrectly.

Include allowQueryTimeOmitOverride in the cache key:

 const cacheKey = stableStringify({
     type: 'model',
     model,
     operation,
     options,
     extraValidationsEnabled: this.extraValidationsEnabled,
+    allowQueryTimeOmitOverride: this.options.allowQueryTimeOmitOverride,
 });

Also applies to: 790-796

🧹 Nitpick comments (4)
packages/testtools/src/client.ts (1)

154-157: Consider filtering out test-specific options before constructing _options.

The rest spread includes ExtraTestClientOptions properties (provider, dbName, dbFile, etc.) that aren't part of ClientOptions. While harmless at runtime (they're ignored by ZenStackClient), explicitly filtering them would be cleaner:

-    const { plugins, ...rest } = options ?? {};
-    const _options = {
-        ...rest,
-    } as ClientOptions<SchemaDef>;
+    const { plugins, provider: _, dbName: _d, dbFile: _f, schemaFile: _s, 
+            usePrismaPush: _p, extraSourceFiles: _e, workDir: _w, 
+            dataSourceExtensions: _x, copyFiles: _c, ...clientOptions } = options ?? {};
+    const _options = {
+        ...clientOptions,
+    } as ClientOptions<SchemaDef>;

Alternatively, you could extract the ClientOptions keys programmatically if the list becomes unwieldy.

TODO.md (1)

6-12: Checklist updates match implemented features; consider fixing list indentation for markdownlint.

Marking db, seed, format, and Global omit as complete is consistent with the new CLI/ORM functionality added in this PR. Separately, markdownlint (MD007) is flagging the indentation of these nested bullets; if you care about a clean doc lint run, adjust the sub-list indentation (e.g., 2 spaces for the first nested level, 4 for the next).

Also applies to: 88-88

tests/e2e/orm/client-api/omit.test.ts (1)

39-65: Consider documenting the dialect: {} as any workaround.

The empty dialect object is a workaround since createTestClient internally sets up the proper dialect based on the provider. While functional, this pattern might confuse future maintainers.

Consider extracting a helper or adding a brief inline comment:

     it('respects client omit options', async () => {
+        // dialect is overwritten by createTestClient; placeholder satisfies type requirements
         const options = { omit: { User: { name: true } }, dialect: {} as any } as const;
tests/e2e/orm/client-api/auth-typing.test.ts (1)

5-17: Consider adding runtime assertions to strengthen the test.

While the test validates type compatibility at compile time, adding runtime assertions would ensure the auth data flows correctly through the system.

 describe('Custom auth typing tests', () => {
     it('works with custom auth typing', async () => {
         const db = await createTestClient(schema);
-        db.$setAuth({
+        const authData = {
             id: 1,
             role: 'ADMIN',
             permissions: [
                 {
                     actionCode: 'MANAGE',
                 },
             ],
-        });
+        };
+        const clientWithAuth = db.$setAuth(authData);
+        expect(clientWithAuth.$auth).toEqual(authData);
     });
 });
📜 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 1e6f7ef and d73c49e.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (76)
  • TODO.md (2 hunks)
  • package.json (2 hunks)
  • packages/auth-adapters/better-auth/package.json (1 hunks)
  • packages/cli/package.json (1 hunks)
  • packages/clients/tanstack-query/package.json (1 hunks)
  • packages/clients/tanstack-query/src/react.ts (3 hunks)
  • packages/clients/tanstack-query/src/svelte.ts (3 hunks)
  • packages/clients/tanstack-query/src/vue.ts (3 hunks)
  • packages/clients/tanstack-query/test/schemas/basic/input.ts (6 hunks)
  • packages/common-helpers/package.json (1 hunks)
  • packages/config/eslint-config/package.json (1 hunks)
  • packages/config/typescript-config/package.json (1 hunks)
  • packages/config/vitest-config/package.json (1 hunks)
  • packages/create-zenstack/package.json (1 hunks)
  • packages/language/package.json (1 hunks)
  • packages/language/res/stdlib.zmodel (1 hunks)
  • packages/language/src/validators/function-invocation-validator.ts (1 hunks)
  • packages/language/src/zmodel-scope.ts (3 hunks)
  • packages/orm/package.json (1 hunks)
  • packages/orm/src/client/client-impl.ts (26 hunks)
  • packages/orm/src/client/contract.ts (22 hunks)
  • packages/orm/src/client/crud-types.ts (6 hunks)
  • packages/orm/src/client/crud/dialects/base-dialect.ts (2 hunks)
  • packages/orm/src/client/crud/dialects/postgresql.ts (2 hunks)
  • packages/orm/src/client/crud/dialects/sqlite.ts (1 hunks)
  • packages/orm/src/client/crud/operations/base.ts (1 hunks)
  • packages/orm/src/client/crud/validator/index.ts (3 hunks)
  • packages/orm/src/client/executor/zenstack-query-executor.ts (11 hunks)
  • packages/orm/src/client/options.ts (3 hunks)
  • packages/orm/src/client/promise.ts (1 hunks)
  • packages/orm/src/utils/schema-utils.ts (2 hunks)
  • packages/orm/src/utils/type-utils.ts (1 hunks)
  • packages/plugins/policy/package.json (1 hunks)
  • packages/plugins/policy/src/expression-evaluator.ts (2 hunks)
  • packages/plugins/policy/src/expression-transformer.ts (19 hunks)
  • packages/plugins/policy/src/policy-handler.ts (1 hunks)
  • packages/plugins/policy/src/types.ts (1 hunks)
  • packages/schema/package.json (1 hunks)
  • packages/schema/src/schema.ts (3 hunks)
  • packages/sdk/package.json (1 hunks)
  • packages/sdk/src/model-utils.ts (1 hunks)
  • packages/sdk/src/ts-schema-generator.ts (8 hunks)
  • packages/server/package.json (1 hunks)
  • packages/testtools/package.json (1 hunks)
  • packages/testtools/src/client.ts (4 hunks)
  • packages/zod/package.json (1 hunks)
  • pnpm-workspace.yaml (1 hunks)
  • samples/next.js/package.json (2 hunks)
  • samples/next.js/zenstack/input.ts (3 hunks)
  • samples/orm/package.json (1 hunks)
  • samples/orm/zenstack/input.ts (4 hunks)
  • tests/e2e/apps/rally/rally.test.ts (0 hunks)
  • tests/e2e/apps/rally/zenstack/input.ts (28 hunks)
  • tests/e2e/orm/client-api/auth-typing.test.ts (1 hunks)
  • tests/e2e/orm/client-api/ignore.test.ts (1 hunks)
  • tests/e2e/orm/client-api/omit.test.ts (1 hunks)
  • tests/e2e/orm/policy/auth-access.test.ts (1 hunks)
  • tests/e2e/orm/schemas/auth-type/input.ts (1 hunks)
  • tests/e2e/orm/schemas/auth-type/models.ts (1 hunks)
  • tests/e2e/orm/schemas/auth-type/schema.ts (1 hunks)
  • tests/e2e/orm/schemas/auth-type/schema.zmodel (1 hunks)
  • tests/e2e/orm/schemas/basic/input.ts (5 hunks)
  • tests/e2e/orm/schemas/basic/schema.zmodel (3 hunks)
  • tests/e2e/orm/schemas/default-auth/input.ts (4 hunks)
  • tests/e2e/orm/schemas/delegate/input.ts (8 hunks)
  • tests/e2e/orm/schemas/name-mapping/input.ts (3 hunks)
  • tests/e2e/orm/schemas/omit/input.ts (1 hunks)
  • tests/e2e/orm/schemas/omit/models.ts (1 hunks)
  • tests/e2e/orm/schemas/omit/schema.ts (1 hunks)
  • tests/e2e/orm/schemas/omit/schema.zmodel (1 hunks)
  • tests/e2e/orm/schemas/petstore/input.ts (4 hunks)
  • tests/e2e/orm/schemas/todo/input.ts (6 hunks)
  • tests/e2e/orm/schemas/typing/input.ts (7 hunks)
  • tests/e2e/orm/validation/custom-validation.test.ts (2 hunks)
  • tests/e2e/package.json (1 hunks)
  • tests/regression/package.json (1 hunks)
💤 Files with no reviewable changes (1)
  • tests/e2e/apps/rally/rally.test.ts
🧰 Additional context used
📓 Path-based instructions (2)
tests/e2e/**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

E2E tests should validate real-world schema compatibility with established projects

Files:

  • tests/e2e/orm/client-api/ignore.test.ts
  • tests/e2e/orm/schemas/auth-type/models.ts
  • tests/e2e/orm/schemas/omit/models.ts
  • tests/e2e/orm/schemas/omit/schema.ts
  • tests/e2e/orm/client-api/omit.test.ts
  • tests/e2e/orm/schemas/auth-type/schema.ts
  • tests/e2e/orm/policy/auth-access.test.ts
  • tests/e2e/orm/schemas/default-auth/input.ts
  • tests/e2e/orm/schemas/auth-type/input.ts
  • tests/e2e/orm/client-api/auth-typing.test.ts
  • tests/e2e/orm/validation/custom-validation.test.ts
  • tests/e2e/orm/schemas/delegate/input.ts
  • tests/e2e/orm/schemas/todo/input.ts
  • tests/e2e/orm/schemas/basic/input.ts
  • tests/e2e/orm/schemas/typing/input.ts
  • tests/e2e/orm/schemas/name-mapping/input.ts
  • tests/e2e/orm/schemas/petstore/input.ts
  • tests/e2e/apps/rally/zenstack/input.ts
  • tests/e2e/orm/schemas/omit/input.ts
**/*.zmodel

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.zmodel: Always run zenstack generate after modifying ZModel schemas
ZModel schema files should define database structure and policies that compile to TypeScript via zenstack generate

Files:

  • packages/language/res/stdlib.zmodel
  • tests/e2e/orm/schemas/omit/schema.zmodel
  • tests/e2e/orm/schemas/auth-type/schema.zmodel
  • tests/e2e/orm/schemas/basic/schema.zmodel
🧠 Learnings (11)
📚 Learning: 2025-11-26T01:55:04.540Z
Learnt from: CR
Repo: zenstackhq/zenstack-v3 PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-26T01:55:04.540Z
Learning: Applies to packages/zenstackhq/orm/**/*.{ts,tsx} : Use Kysely as the query builder interface for low-level database queries, avoiding raw SQL when possible

Applied to files:

  • packages/clients/tanstack-query/package.json
  • packages/orm/src/client/options.ts
  • tests/e2e/orm/schemas/auth-type/models.ts
  • tests/e2e/orm/schemas/omit/models.ts
  • packages/orm/src/client/crud/dialects/base-dialect.ts
  • tests/e2e/orm/schemas/omit/schema.ts
  • tests/e2e/orm/schemas/auth-type/schema.ts
  • tests/e2e/orm/schemas/default-auth/input.ts
  • packages/orm/src/client/crud/validator/index.ts
  • packages/clients/tanstack-query/test/schemas/basic/input.ts
  • tests/e2e/orm/schemas/auth-type/input.ts
  • packages/clients/tanstack-query/src/svelte.ts
  • packages/orm/src/client/promise.ts
  • samples/orm/zenstack/input.ts
  • samples/next.js/zenstack/input.ts
  • packages/clients/tanstack-query/src/vue.ts
  • packages/orm/package.json
  • packages/plugins/policy/src/expression-transformer.ts
  • packages/orm/src/client/crud/operations/base.ts
  • tests/e2e/orm/schemas/delegate/input.ts
  • tests/e2e/orm/schemas/todo/input.ts
  • tests/e2e/orm/schemas/basic/input.ts
  • packages/orm/src/client/executor/zenstack-query-executor.ts
  • tests/e2e/orm/schemas/typing/input.ts
  • tests/e2e/orm/schemas/name-mapping/input.ts
  • packages/orm/src/client/contract.ts
  • packages/clients/tanstack-query/src/react.ts
  • tests/e2e/orm/schemas/petstore/input.ts
  • packages/orm/src/client/crud-types.ts
  • packages/orm/src/client/client-impl.ts
  • tests/e2e/apps/rally/zenstack/input.ts
  • tests/e2e/orm/schemas/omit/input.ts
📚 Learning: 2025-10-21T16:09:31.218Z
Learnt from: ymc9
Repo: zenstackhq/zenstack-v3 PR: 319
File: packages/runtime/src/client/executor/zenstack-query-executor.ts:63-72
Timestamp: 2025-10-21T16:09:31.218Z
Learning: In ZenStack, TypeDefs can be inherited by models. When a TypeDef contains fields with `map` attributes, those mapped field names need to be processed by the QueryNameMapper since they become part of the inheriting model's schema. Therefore, when checking if a schema has mapped names (e.g., in `schemaHasMappedNames`), both `schema.models` and `schema.typeDefs` must be inspected for `@map` and `map` attributes.

Applied to files:

  • packages/schema/src/schema.ts
  • tests/e2e/orm/client-api/ignore.test.ts
  • tests/e2e/orm/schemas/omit/schema.ts
  • tests/e2e/orm/schemas/auth-type/schema.ts
  • packages/sdk/src/ts-schema-generator.ts
  • packages/orm/src/client/executor/zenstack-query-executor.ts
  • packages/orm/src/client/crud-types.ts
📚 Learning: 2025-11-26T01:55:04.540Z
Learnt from: CR
Repo: zenstackhq/zenstack-v3 PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-26T01:55:04.540Z
Learning: Applies to **/*.zmodel : ZModel schema files should define database structure and policies that compile to TypeScript via `zenstack generate`

Applied to files:

  • packages/schema/src/schema.ts
  • packages/schema/package.json
  • packages/zod/package.json
  • tests/e2e/orm/client-api/ignore.test.ts
  • tests/e2e/orm/schemas/auth-type/models.ts
  • tests/e2e/orm/schemas/omit/models.ts
  • tests/e2e/orm/schemas/omit/schema.ts
  • tests/e2e/orm/schemas/auth-type/schema.ts
  • packages/orm/src/client/crud/validator/index.ts
  • tests/e2e/orm/schemas/omit/schema.zmodel
  • tests/e2e/orm/schemas/auth-type/schema.zmodel
  • tests/e2e/orm/schemas/auth-type/input.ts
  • packages/orm/src/client/promise.ts
  • packages/sdk/src/ts-schema-generator.ts
  • samples/orm/zenstack/input.ts
  • samples/next.js/zenstack/input.ts
  • packages/language/package.json
  • packages/orm/src/client/executor/zenstack-query-executor.ts
  • packages/orm/src/client/contract.ts
  • packages/orm/src/client/client-impl.ts
  • tests/e2e/orm/schemas/basic/schema.zmodel
  • tests/e2e/orm/schemas/omit/input.ts
📚 Learning: 2025-11-26T01:55:04.540Z
Learnt from: CR
Repo: zenstackhq/zenstack-v3 PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-26T01:55:04.540Z
Learning: Database migrations should use Prisma CLI under the hood via ZenStack commands

Applied to files:

  • TODO.md
📚 Learning: 2025-11-26T01:55:04.540Z
Learnt from: CR
Repo: zenstackhq/zenstack-v3 PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-26T01:55:04.540Z
Learning: Applies to packages/zenstackhq/orm/**/*.{ts,tsx} : Implement plugin hooks at ORM, Kysely, and entity mutation levels for query interception and customization

Applied to files:

  • packages/orm/src/client/options.ts
  • tests/e2e/orm/client-api/ignore.test.ts
  • tests/e2e/orm/schemas/auth-type/models.ts
  • tests/e2e/orm/schemas/omit/models.ts
  • packages/orm/src/client/crud/dialects/base-dialect.ts
  • tests/e2e/orm/schemas/omit/schema.ts
  • tests/e2e/orm/client-api/omit.test.ts
  • tests/e2e/orm/schemas/auth-type/schema.ts
  • tests/e2e/orm/policy/auth-access.test.ts
  • tests/e2e/orm/schemas/default-auth/input.ts
  • packages/orm/src/client/crud/validator/index.ts
  • packages/clients/tanstack-query/test/schemas/basic/input.ts
  • tests/e2e/orm/schemas/auth-type/input.ts
  • packages/clients/tanstack-query/src/svelte.ts
  • packages/orm/src/client/promise.ts
  • samples/orm/zenstack/input.ts
  • samples/next.js/zenstack/input.ts
  • packages/clients/tanstack-query/src/vue.ts
  • packages/orm/package.json
  • packages/plugins/policy/src/expression-transformer.ts
  • packages/orm/src/client/crud/operations/base.ts
  • tests/e2e/orm/schemas/delegate/input.ts
  • tests/e2e/orm/schemas/todo/input.ts
  • tests/e2e/orm/schemas/basic/input.ts
  • packages/orm/src/client/executor/zenstack-query-executor.ts
  • tests/e2e/orm/schemas/typing/input.ts
  • tests/e2e/orm/schemas/name-mapping/input.ts
  • packages/orm/src/client/contract.ts
  • packages/clients/tanstack-query/src/react.ts
  • tests/e2e/orm/schemas/petstore/input.ts
  • packages/orm/src/client/crud-types.ts
  • packages/orm/src/client/client-impl.ts
  • tests/e2e/apps/rally/zenstack/input.ts
  • tests/e2e/orm/schemas/omit/input.ts
📚 Learning: 2025-11-26T01:55:04.540Z
Learnt from: CR
Repo: zenstackhq/zenstack-v3 PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-26T01:55:04.540Z
Learning: Applies to packages/zenstackhq/orm/**/*.test.{ts,tsx} : ORM package tests should include comprehensive client API tests and policy tests

Applied to files:

  • packages/orm/src/client/options.ts
  • tests/e2e/orm/client-api/ignore.test.ts
  • tests/e2e/orm/schemas/omit/models.ts
  • tests/e2e/orm/schemas/omit/schema.ts
  • tests/e2e/orm/client-api/omit.test.ts
  • tests/e2e/orm/schemas/auth-type/schema.ts
  • tests/e2e/orm/policy/auth-access.test.ts
  • tests/e2e/orm/schemas/default-auth/input.ts
  • packages/orm/src/client/crud/validator/index.ts
  • packages/clients/tanstack-query/test/schemas/basic/input.ts
  • tests/e2e/orm/schemas/auth-type/input.ts
  • packages/clients/tanstack-query/src/svelte.ts
  • packages/orm/src/client/promise.ts
  • samples/orm/zenstack/input.ts
  • samples/next.js/zenstack/input.ts
  • packages/clients/tanstack-query/src/vue.ts
  • packages/testtools/src/client.ts
  • packages/orm/package.json
  • packages/plugins/policy/src/expression-transformer.ts
  • packages/orm/src/client/crud/operations/base.ts
  • tests/e2e/orm/client-api/auth-typing.test.ts
  • tests/e2e/orm/validation/custom-validation.test.ts
  • tests/e2e/orm/schemas/delegate/input.ts
  • tests/e2e/orm/schemas/todo/input.ts
  • tests/e2e/orm/schemas/basic/input.ts
  • packages/orm/src/client/executor/zenstack-query-executor.ts
  • tests/e2e/orm/schemas/typing/input.ts
  • tests/e2e/orm/schemas/name-mapping/input.ts
  • packages/orm/src/client/contract.ts
  • tests/e2e/orm/schemas/petstore/input.ts
  • packages/orm/src/client/crud-types.ts
  • packages/orm/src/client/client-impl.ts
  • tests/e2e/apps/rally/zenstack/input.ts
  • tests/e2e/orm/schemas/omit/input.ts
📚 Learning: 2025-11-26T01:55:04.540Z
Learnt from: CR
Repo: zenstackhq/zenstack-v3 PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-26T01:55:04.540Z
Learning: Applies to tests/e2e/**/*.{ts,tsx} : E2E tests should validate real-world schema compatibility with established projects

Applied to files:

  • tests/e2e/orm/client-api/ignore.test.ts
  • tests/e2e/orm/schemas/auth-type/models.ts
  • tests/e2e/orm/schemas/omit/models.ts
  • tests/e2e/package.json
  • tests/e2e/orm/schemas/omit/schema.ts
  • tests/e2e/orm/client-api/omit.test.ts
  • tests/e2e/orm/schemas/auth-type/schema.ts
  • tests/e2e/orm/policy/auth-access.test.ts
  • tests/e2e/orm/schemas/default-auth/input.ts
  • packages/clients/tanstack-query/test/schemas/basic/input.ts
  • tests/e2e/orm/schemas/auth-type/input.ts
  • packages/testtools/src/client.ts
  • tests/e2e/orm/client-api/auth-typing.test.ts
  • tests/e2e/orm/validation/custom-validation.test.ts
  • tests/e2e/orm/schemas/delegate/input.ts
  • tests/e2e/orm/schemas/todo/input.ts
  • tests/e2e/orm/schemas/basic/input.ts
  • tests/e2e/orm/schemas/name-mapping/input.ts
  • tests/e2e/orm/schemas/petstore/input.ts
  • tests/e2e/orm/schemas/omit/input.ts
📚 Learning: 2025-11-26T01:55:04.540Z
Learnt from: CR
Repo: zenstackhq/zenstack-v3 PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-26T01:55:04.540Z
Learning: Applies to tests/**/type*.{ts,tsx} : Ensure TypeScript inference and type coverage are validated through type coverage tests

Applied to files:

  • tests/e2e/orm/client-api/ignore.test.ts
  • tests/e2e/orm/schemas/auth-type/models.ts
  • tests/e2e/orm/client-api/omit.test.ts
  • packages/testtools/src/client.ts
  • tests/e2e/orm/client-api/auth-typing.test.ts
📚 Learning: 2025-10-21T16:04:56.292Z
Learnt from: ymc9
Repo: zenstackhq/zenstack-v3 PR: 319
File: packages/runtime/src/client/crud/dialects/base-dialect.ts:745-747
Timestamp: 2025-10-21T16:04:56.292Z
Learning: In packages/runtime/src/client/crud/dialects/base-dialect.ts, it's intentional that buildCursorFilter applies default ordering (via makeDefaultOrderBy fallback) while buildOrderBy does not. This ensures cursor-based pagination always has stable ordering for correctness, while regular queries remain unordered unless explicitly specified. This design is to be consistent with Prisma's pagination requirements.

Applied to files:

  • packages/orm/src/client/crud/dialects/postgresql.ts
  • packages/orm/src/client/crud/dialects/base-dialect.ts
  • packages/orm/src/client/crud/operations/base.ts
📚 Learning: 2025-11-26T01:55:04.540Z
Learnt from: CR
Repo: zenstackhq/zenstack-v3 PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-26T01:55:04.540Z
Learning: Use `pnpm` with workspaces for package management, pinned to version `pnpm10.12.1`

Applied to files:

  • pnpm-workspace.yaml
  • package.json
📚 Learning: 2025-11-26T01:55:04.540Z
Learnt from: CR
Repo: zenstackhq/zenstack-v3 PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-26T01:55:04.540Z
Learning: Use Turbo for build orchestration and run `pnpm build`, `pnpm watch`, `pnpm lint`, and `pnpm test` for development tasks

Applied to files:

  • package.json
🧬 Code graph analysis (20)
tests/e2e/orm/client-api/ignore.test.ts (2)
packages/testtools/src/client.ts (1)
  • createTestClient (99-248)
packages/orm/src/client/crud-types.ts (1)
  • DefaultModelResult (52-76)
tests/e2e/orm/client-api/omit.test.ts (4)
packages/orm/src/client/crud/validator/index.ts (2)
  • schema (60-62)
  • options (64-66)
packages/orm/src/client/crud/operations/base.ts (3)
  • schema (98-100)
  • options (102-104)
  • read (148-187)
tests/e2e/orm/schemas/omit/schema.ts (1)
  • schema (141-141)
packages/orm/src/client/executor/zenstack-query-executor.ts (1)
  • options (81-83)
packages/language/src/zmodel-scope.ts (2)
packages/language/src/utils.ts (1)
  • isAuthOrAuthMemberAccess (133-135)
packages/language/src/generated/ast.ts (1)
  • isTypeDef (737-739)
packages/sdk/src/model-utils.ts (1)
packages/language/src/generated/ast.ts (2)
  • isDataModel (391-393)
  • isTypeDef (737-739)
tests/e2e/orm/schemas/auth-type/schema.ts (1)
packages/schema/src/schema.ts (1)
  • SchemaDef (11-19)
tests/e2e/orm/policy/auth-access.test.ts (2)
packages/testtools/src/client.ts (1)
  • createPolicyTestClient (258-269)
packages/plugins/policy/src/expression-transformer.ts (1)
  • schema (126-128)
packages/clients/tanstack-query/test/schemas/basic/input.ts (11)
samples/next.js/zenstack/input.ts (2)
  • UserGetPayload (30-30)
  • PostGetPayload (50-50)
samples/orm/zenstack/input.ts (2)
  • UserGetPayload (30-30)
  • PostGetPayload (70-70)
tests/e2e/apps/rally/zenstack/input.ts (1)
  • UserGetPayload (50-50)
tests/e2e/orm/schemas/basic/input.ts (2)
  • UserGetPayload (30-30)
  • PostGetPayload (50-50)
tests/e2e/orm/schemas/default-auth/input.ts (1)
  • UserGetPayload (30-30)
tests/e2e/orm/schemas/delegate/input.ts (1)
  • UserGetPayload (30-30)
tests/e2e/orm/schemas/name-mapping/input.ts (2)
  • UserGetPayload (30-30)
  • PostGetPayload (50-50)
tests/e2e/orm/schemas/omit/input.ts (2)
  • UserGetPayload (30-30)
  • PostGetPayload (50-50)
tests/e2e/orm/schemas/petstore/input.ts (1)
  • UserGetPayload (30-30)
tests/e2e/orm/schemas/todo/input.ts (1)
  • UserGetPayload (70-70)
tests/e2e/orm/schemas/typing/input.ts (2)
  • UserGetPayload (30-30)
  • PostGetPayload (50-50)
packages/language/src/validators/function-invocation-validator.ts (1)
packages/language/src/generated/ast.ts (2)
  • InvocationExpr (533-538)
  • InvocationExpr (540-540)
packages/sdk/src/ts-schema-generator.ts (3)
packages/language/src/ast.ts (1)
  • DataModel (49-54)
packages/sdk/src/model-utils.ts (1)
  • hasAttribute (59-64)
packages/language/src/utils.ts (1)
  • hasAttribute (55-57)
samples/orm/zenstack/input.ts (5)
samples/next.js/zenstack/input.ts (1)
  • UserGetPayload (30-30)
tests/e2e/apps/rally/zenstack/input.ts (1)
  • UserGetPayload (50-50)
tests/e2e/orm/schemas/delegate/input.ts (1)
  • UserGetPayload (30-30)
tests/e2e/orm/schemas/petstore/input.ts (1)
  • UserGetPayload (30-30)
tests/e2e/orm/schemas/todo/input.ts (1)
  • UserGetPayload (70-70)
packages/clients/tanstack-query/src/vue.ts (3)
packages/clients/tanstack-query/src/react.ts (7)
  • ModelMutationResult (125-125)
  • ModelMutationOptions (122-123)
  • ModelQueryOptions (95-95)
  • ModelQueryResult (97-97)
  • ModelInfiniteQueryOptions (106-109)
  • ModelInfiniteQueryResult (111-111)
  • ModelMutationModelResult (127-140)
packages/orm/src/client/crud-types.ts (1)
  • SimplifiedModelResult (241-248)
packages/orm/src/client/options.ts (1)
  • ClientOptions (45-108)
packages/testtools/src/client.ts (3)
packages/schema/src/schema.ts (1)
  • SchemaDef (11-19)
packages/orm/src/client/options.ts (1)
  • ClientOptions (45-108)
packages/orm/src/client/contract.ts (1)
  • ClientContract (63-194)
tests/e2e/orm/client-api/auth-typing.test.ts (2)
packages/testtools/src/client.ts (1)
  • createTestClient (99-248)
tests/e2e/orm/schemas/auth-type/schema.ts (1)
  • schema (73-73)
tests/e2e/orm/schemas/delegate/input.ts (11)
packages/clients/tanstack-query/test/schemas/basic/input.ts (1)
  • UserGetPayload (30-30)
samples/next.js/zenstack/input.ts (1)
  • UserGetPayload (30-30)
samples/orm/zenstack/input.ts (1)
  • UserGetPayload (30-30)
tests/e2e/apps/rally/zenstack/input.ts (2)
  • UserGetPayload (50-50)
  • CommentGetPayload (230-230)
tests/e2e/orm/schemas/basic/input.ts (2)
  • UserGetPayload (30-30)
  • CommentGetPayload (70-70)
tests/e2e/orm/schemas/default-auth/input.ts (1)
  • UserGetPayload (30-30)
tests/e2e/orm/schemas/name-mapping/input.ts (1)
  • UserGetPayload (30-30)
tests/e2e/orm/schemas/omit/input.ts (1)
  • UserGetPayload (30-30)
tests/e2e/orm/schemas/petstore/input.ts (1)
  • UserGetPayload (30-30)
tests/e2e/orm/schemas/todo/input.ts (1)
  • UserGetPayload (70-70)
tests/e2e/orm/schemas/typing/input.ts (1)
  • UserGetPayload (30-30)
tests/e2e/orm/schemas/todo/input.ts (11)
tests/e2e/apps/rally/zenstack/input.ts (2)
  • SpaceGetPayload (270-270)
  • UserGetPayload (50-50)
packages/clients/tanstack-query/test/schemas/basic/input.ts (1)
  • UserGetPayload (30-30)
samples/next.js/zenstack/input.ts (1)
  • UserGetPayload (30-30)
samples/orm/zenstack/input.ts (1)
  • UserGetPayload (30-30)
tests/e2e/orm/schemas/basic/input.ts (1)
  • UserGetPayload (30-30)
tests/e2e/orm/schemas/default-auth/input.ts (1)
  • UserGetPayload (30-30)
tests/e2e/orm/schemas/delegate/input.ts (1)
  • UserGetPayload (30-30)
tests/e2e/orm/schemas/name-mapping/input.ts (1)
  • UserGetPayload (30-30)
tests/e2e/orm/schemas/omit/input.ts (1)
  • UserGetPayload (30-30)
tests/e2e/orm/schemas/petstore/input.ts (1)
  • UserGetPayload (30-30)
tests/e2e/orm/schemas/typing/input.ts (1)
  • UserGetPayload (30-30)
tests/e2e/orm/schemas/basic/input.ts (11)
packages/clients/tanstack-query/test/schemas/basic/input.ts (2)
  • UserGetPayload (30-30)
  • PostGetPayload (50-50)
samples/next.js/zenstack/input.ts (2)
  • UserGetPayload (30-30)
  • PostGetPayload (50-50)
samples/orm/zenstack/input.ts (3)
  • UserGetPayload (30-30)
  • PostGetPayload (70-70)
  • ProfileGetPayload (50-50)
tests/e2e/apps/rally/zenstack/input.ts (2)
  • UserGetPayload (50-50)
  • CommentGetPayload (230-230)
tests/e2e/orm/schemas/default-auth/input.ts (2)
  • UserGetPayload (30-30)
  • ProfileGetPayload (50-50)
tests/e2e/orm/schemas/delegate/input.ts (2)
  • UserGetPayload (30-30)
  • CommentGetPayload (50-50)
tests/e2e/orm/schemas/name-mapping/input.ts (2)
  • UserGetPayload (30-30)
  • PostGetPayload (50-50)
tests/e2e/orm/schemas/omit/input.ts (2)
  • UserGetPayload (30-30)
  • PostGetPayload (50-50)
tests/e2e/orm/schemas/petstore/input.ts (1)
  • UserGetPayload (30-30)
tests/e2e/orm/schemas/todo/input.ts (1)
  • UserGetPayload (70-70)
tests/e2e/orm/schemas/typing/input.ts (3)
  • UserGetPayload (30-30)
  • PostGetPayload (50-50)
  • ProfileGetPayload (70-70)
tests/e2e/orm/schemas/name-mapping/input.ts (7)
samples/next.js/zenstack/input.ts (2)
  • UserGetPayload (30-30)
  • PostGetPayload (50-50)
samples/orm/zenstack/input.ts (2)
  • UserGetPayload (30-30)
  • PostGetPayload (70-70)
tests/e2e/apps/rally/zenstack/input.ts (1)
  • UserGetPayload (50-50)
tests/e2e/orm/schemas/basic/input.ts (2)
  • UserGetPayload (30-30)
  • PostGetPayload (50-50)
tests/e2e/orm/schemas/default-auth/input.ts (1)
  • UserGetPayload (30-30)
tests/e2e/orm/schemas/omit/input.ts (2)
  • UserGetPayload (30-30)
  • PostGetPayload (50-50)
tests/e2e/orm/schemas/typing/input.ts (2)
  • UserGetPayload (30-30)
  • PostGetPayload (50-50)
packages/orm/src/client/contract.ts (4)
packages/schema/src/schema.ts (4)
  • SchemaDef (11-19)
  • GetModels (121-121)
  • RelationFields (211-215)
  • GetTypeDefs (142-142)
packages/orm/src/client/options.ts (1)
  • ClientOptions (45-108)
packages/orm/src/client/promise.ts (1)
  • ZenStackPromise (7-13)
packages/orm/src/client/crud-types.ts (3)
  • SimplifiedModelResult (241-248)
  • DefaultModelResult (52-76)
  • TypeDefResult (250-274)
packages/clients/tanstack-query/src/react.ts (3)
packages/clients/tanstack-query/src/vue.ts (6)
  • ModelMutationResult (102-102)
  • ModelMutationOptions (98-100)
  • ModelQueryOptions (86-88)
  • ModelQueryResult (90-90)
  • ModelInfiniteQueryOptions (92-94)
  • ModelMutationModelResult (104-117)
packages/orm/src/client/crud-types.ts (1)
  • SimplifiedModelResult (241-248)
packages/orm/src/client/options.ts (1)
  • ClientOptions (45-108)
packages/orm/src/client/crud-types.ts (2)
packages/orm/src/client/options.ts (1)
  • ClientOptions (45-108)
packages/orm/src/utils/type-utils.ts (4)
  • Optional (3-3)
  • WrapType (25-31)
  • Simplify (15-21)
  • PartialIf (5-5)
🪛 markdownlint-cli2 (0.18.1)
TODO.md

6-6: Unordered list indentation
Expected: 2; Actual: 4

(MD007, ul-indent)


7-7: Unordered list indentation
Expected: 4; Actual: 8

(MD007, ul-indent)


8-8: Unordered list indentation
Expected: 4; Actual: 8

(MD007, ul-indent)


9-9: Unordered list indentation
Expected: 2; Actual: 4

(MD007, ul-indent)


10-10: Unordered list indentation
Expected: 2; Actual: 4

(MD007, ul-indent)


11-11: Unordered list indentation
Expected: 2; Actual: 4

(MD007, ul-indent)


12-12: Unordered list indentation
Expected: 2; Actual: 4

(MD007, ul-indent)


88-88: Unordered list indentation
Expected: 4; Actual: 8

(MD007, ul-indent)

⏰ 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). (4)
  • GitHub Check: Upload results
  • GitHub Check: build-test (20.x, sqlite)
  • GitHub Check: build-test (20.x, postgresql)
  • GitHub Check: claude-review

@claude
Copy link

claude bot commented Nov 27, 2025

Claude finished @ymc9's task —— View job


Pull Request Review - v3.0.0-beta.26

I've completed a comprehensive review of this large PR that introduces field omission, custom auth types, and significant type system enhancements.

Review Tasks

  • Analyze core architectural changes (ORM, schema, language packages)
  • Review field omission system implementation
  • Evaluate auth type enhancements and security implications
  • Assess type system changes and thread safety
  • Review test coverage for new features
  • Check for potential bugs and performance issues
  • Provide overall code quality assessment

Overall Assessment

This is a well-structured release that introduces significant new features while maintaining code quality. The changes primarily focus on:

  1. Field Omission System - A comprehensive new feature for controlling field visibility
  2. Auth Type Improvements - Enhanced custom auth typing support
  3. PostgreSQL Timezone Fixes - Better handling of date/time values

🚀 Key Features & Improvements

Field Omission System (packages/orm/src/client/options.ts:84-117)

  • Three-level precedence: Query-level → Options-level → Schema-level omit
  • Configurable override protection: allowQueryTimeOmitOverride option prevents unauthorized field exposure
  • Type-safe implementation: Fields properly omitted at TypeScript level with @ts-expect-error comments
  • Delegate model support: Works correctly with inheritance patterns

Auth Type Enhancements (tests/e2e/orm/schemas/auth-type/schema.zmodel)

  • Custom auth types: Support for complex auth structures beyond simple User models
  • Nested permissions: Allows structured permission systems like { permissions: [{ actionCode: 'MANAGE' }] }
  • Type safety: Full TypeScript inference for custom auth shapes

PostgreSQL Timezone Fix (packages/orm/src/client/crud/dialects/postgresql.ts:107-118)

  • Configurable timezone handling: fixPostgresTimezone option (defaults to true)
  • Proper UTC conversion: Addresses node-pg's local timezone interpretation quirk
  • Backwards compatible: Can be disabled if custom handling needed

🔍 Code Quality Findings

Strengths

  • Comprehensive test coverage: New features have thorough test suites
  • Type safety: Excellent TypeScript integration with proper inference
  • Error handling: Good validation with clear error messages
  • Documentation: Well-documented APIs with extensive JSDoc examples

Minor Concerns

  • Large changeset: 77 files changed makes review challenging but appears well-coordinated
  • Version bump coordination: Multiple package.json files updated consistently ✅
  • Backwards compatibility: Changes appear additive with proper defaults ✅

🔒 Security Review

Positive Findings

  • Field omission security: Query-level override protection prevents accidental exposure of sensitive fields
  • Input validation: Proper validation of omit configurations
  • No hardcoded secrets: No security credentials found in code

Recommendations

  • Consider adding documentation about security implications of allowQueryTimeOmitOverride: true
  • Field omission should be tested with complex nested scenarios

Performance Considerations

PostgreSQL Optimizations

  • JSON aggregation: Efficient jsonb_agg and jsonb_build_object usage
  • Lateral joins: Proper use of LEFT JOIN LATERAL for relation queries
  • Field selection: Omit functionality reduces payload size

Type System Performance

  • Conditional types: Complex but necessary for type safety
  • Union handling: Delegate models use proper type distribution

🧪 Test Coverage Assessment

New Test Files:

  • auth-typing.test.ts - Custom auth type validation ✅
  • omit.test.ts - Comprehensive field omission testing ✅
  • ignore.test.ts - Model/field ignoring functionality ✅

Test Quality:

  • Edge cases covered (delegate models, nested relations)
  • Security scenarios tested (override protection)
  • Type safety verified with @ts-expect-error annotations

Critical Issues Found

1. Policy Plugin Compatibility Issue (packages/schema/src/schema.ts:19)

The widening of authType to include GetTypeDefs<SchemaDef> creates a runtime regression in packages/plugins/policy/src/expression-transformer.ts:463. The code assumes authType is always a model name, but with TypeDefs now supported, QueryUtils.getModel(this.schema, this.authType) will return undefined for TypeDef-based auth, causing policy evaluation failures.

Required Fix: Update expression transformer to handle TypeDef names or document that TypeDef-based auth cannot use auth() comparisons.

2. Instance Reuse Bug (packages/orm/src/utils/schema-utils.ts:87)

The MatchingExpressionVisitor.find() method doesn't reset the found flag between calls, causing stale results on subsequent invocations.

3. Schema Caching Issue (packages/orm/src/client/crud/validator/index.ts:237)

The schema cache doesn't include allowQueryTimeOmitOverride in the cache key, potentially causing cross-client cache pollution.

🎯 Recommendations

For Production

  1. Monitor performance of omit functionality with large datasets
  2. Document security implications of omit override settings
  3. Test PostgreSQL timezone fix with various timezone configurations

For Future Development

  1. Consider caching omit field calculations for performance
  2. Add field-level access control integration with omit system
  3. Consider audit logging for omit overrides in security-sensitive applications

📝 Summary

This PR introduces well-designed features that enhance ZenStack's capabilities while maintaining backwards compatibility. The field omission system is particularly valuable for security and API design, and the auth type improvements provide much-needed flexibility.

Approval Status: ✅ APPROVED (with critical issue fixes recommended)

The code quality is high, test coverage is comprehensive, and the features address real user needs. The large changeset is justified by the coordinated nature of the feature additions.


@ymc9 ymc9 added this pull request to the merge queue Nov 27, 2025
Merged via the queue into main with commit 29c4df2 Nov 27, 2025
8 checks passed
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