Skip to content

Conversation

@ymc9
Copy link
Member

@ymc9 ymc9 commented Aug 12, 2025

Summary by CodeRabbit

  • New Features

    • Added aggregation support across queries: use _count, _sum, _avg, _min, _max in filters, orderBy, groupBy, and having.
  • Bug Fixes

    • groupBy results are now correctly processed and grouped.
    • DateTime filters accept ISO datetime strings.
    • Clearer error for unsupported list types on sqlite.
  • Documentation

    • Clarified groupBy rules for orderBy and having with aggregations.
  • Chores

    • Bumped all packages to 3.0.0-alpha.20.
    • Updated better-sqlite3 and related type definitions.

github-actions bot and others added 3 commits August 12, 2025 18:17
Co-authored-by: ymc9 <104139426+ymc9@users.noreply.github.com>
* chore: single better-sqlite version for all packages

* update lock file

---------

Co-authored-by: ymc9 <104139426+ymc9@users.noreply.github.com>
…upBy` (#152)

* fix: support using aggregations inside `orderBy` and `having` of `groupBy`

* update

* update
Copilot AI review requested due to automatic review settings August 12, 2025 10:29
@coderabbitai
Copy link

coderabbitai bot commented Aug 12, 2025

Walkthrough

Version bumps across the monorepo. Runtime gains aggregation-aware querying: new constants, typings, validators, query utils, and dialect logic; groupBy processing adjusted and post-processed. Minor wording change in language validator. Tests expanded for groupBy and aggregations. Some dependencies updated (better-sqlite3, @types/better-sqlite3).

Changes

Cohort / File(s) Summary
Monorepo version bumps
package.json, packages/*/package.json, samples/blog/package.json, tests/e2e/package.json
Increment versions to 3.0.0-alpha.20 across packages; no functional changes.
Dependency updates (sqlite)
packages/cli/package.json, packages/testtools/package.json, samples/blog/package.json
Update better-sqlite3 to ^12.2.0 and @types/better-sqlite3 to ^7.6.13 where applicable.
Language validator tweak
packages/language/src/validators/datamodel-validator.ts
Adjust error text: “Array” → “List” for sqlite list-type validation.
Runtime constants
packages/runtime/src/client/constants.ts
Add LOGICAL_COMBINATORS and AGGREGATE_OPERATORS constants and type alias.
Client impl
packages/runtime/src/client/client-impl.ts
groupBy now enables post-processing via createPromise(..., true).
Contract docs
packages/runtime/src/client/contract.ts
Update groupBy JSDoc for orderBy/having to allow aggregation or by-field references; example adjusted.
Query typings (aggregations)
packages/runtime/src/client/crud-types.ts
Thread aggregation support across Where/Filters/OrderBy/Aggregate/GroupBy; add WithAggregations flag, new inputs/outputs, GroupByHaving.
CRUD dialect base
packages/runtime/src/client/crud/dialects/base.ts
Support aggregation in filters/orderBy; refactor logical combinators; update composite filter signature; integrate aggregate() helper.
GroupBy operation
packages/runtime/src/client/crud/operations/group-by.ts
Group by subquery refs ($sub.<field>); minor rename in having callback.
Validator (schemas)
packages/runtime/src/client/crud/validator.ts
Add aggregation-aware validation for filters/orderBy/having; new helper schemas; stricter int/date handling.
Query utilities
packages/runtime/src/client/query-utils.ts
Add exported aggregate() helper; remove exported extractFields (use imported utility).
Tests: groupBy and aggregations
packages/runtime/test/client-api/group-by.test.ts, packages/runtime/test/schemas/basic/*
Add posts grouping tests; expand aggregation tests (having/orderBy); add User.meta Json field in schema and zmodel.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Poem

A rabbit counts, then sums with glee,
Min and max beneath the tree.
Grouped by moon, ordered by star,
HAVING dreams that reach afar.
Lists not arrays, the burrow knows—
With steady paws, aggregation grows. 🐇✨

✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch dev

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

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • 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.
  • 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 the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Support

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

CodeRabbit Commands (Invoked using PR/Issue comments)

Type @coderabbitai help to get the list of available commands.

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.

Status, Documentation and Community

  • Visit our Status Page to check the current availability of CodeRabbit.
  • 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.

@claude
Copy link

claude bot commented Aug 12, 2025

Claude finished @ymc9's task —— View job


Code Review Analysis

Reviewing this PR that merges dev to main with aggregation support in groupBy operations and version updates.

Review Tasks:

  • Analyze core runtime changes (client-impl, crud-types, validator)
  • Review aggregation functionality in groupBy operations
  • Examine test coverage for new features
  • Check package.json version consistency
  • Assess potential bugs and security concerns
  • Evaluate performance implications

Review Summary

This is a substantial PR that adds aggregation support for orderBy and having clauses in groupBy operations. The main commit (2e95aa5) contains the core functionality, followed by version bumps and better-sqlite3 dependency consolidation.

Code Quality Assessment

✅ Strengths

  1. Comprehensive Type Safety: The TypeScript types in crud-types.ts properly constrain aggregation usage to appropriate field types and contexts
  2. Thorough Testing: Extensive test coverage in group-by.test.ts covers edge cases including aggregation validation, ordering, and filtering
  3. Proper Validation: Input validation correctly enforces that fields used in having and orderBy must be in the by clause or use aggregations
  4. Clean Architecture: The aggregation logic is well-separated between validation, SQL generation, and post-processing

⚠️ Areas of Concern

1. Complex Type System (packages/runtime/src/client/crud-types.ts:396-408)

The aggregation types are quite complex and could potentially cause TypeScript performance issues:

WithAggregation extends true
    ? {
          _count?: OrderBy<Schema, Model, false, false>;
          _min?: MinMaxInput<Schema, Model, SortOrder>;
          _max?: MinMaxInput<Schema, Model, SortOrder>;
      } & (NumericFields<Schema, Model> extends never
          ? {}
          : {
                _avg?: SumAvgInput<Schema, Model, SortOrder>;
                _sum?: SumAvgInput<Schema, Model, SortOrder>;
            })
    : {});

2. Aggregation Validation Logic (packages/runtime/src/client/crud/validator.ts:1269-1294)

The validation logic for aggregation-only fields in having is complex and may be brittle:

// 2. payload must only contain aggregations
if (!this.onlyAggregationFields(val)) {
    return false;
}

3. SQL Generation Complexity (packages/runtime/src/client/crud/dialects/base.ts:509-521)

The recursive aggregation handling in filters could lead to deeply nested SQL queries that may impact performance.

Security Analysis

✅ No Security Issues Found

  • All user input is properly validated through Zod schemas
  • SQL injection protection is maintained through Kysely's query builder
  • No exposure of sensitive data through aggregations

Performance Considerations

⚠️ Potential Performance Impact

  1. Complex Subqueries: The groupBy implementation uses nested subqueries which could be expensive on large datasets (packages/runtime/src/client/crud/operations/group-by.ts:15-45)

  2. Aggregation in Filters: Using aggregations in having clauses may require full table scans depending on indexing

  3. Type Compilation: The complex conditional types may increase TypeScript compilation time

Bug Risk Assessment

🔍 Minor Issues

  1. Edge Case Handling: The aggregation validation logic assumes specific object structures that might fail with unexpected input shapes

  2. Error Messages: Some validation errors could be more descriptive for complex aggregation scenarios

✅ Well-Handled Areas

  • Proper null handling in aggregations
  • Correct type coercion for numeric aggregations
  • Comprehensive input validation

Recommendations

  1. Consider Performance Testing: Test groupBy operations on larger datasets to ensure acceptable performance
  2. Type Optimization: Consider simplifying some of the conditional types or breaking them into smaller utilities
  3. Documentation: The aggregation features are complex - ensure good documentation for users
  4. Error Messages: Enhance error messages for aggregation validation failures

Version Consistency

All package.json files correctly bump from 3.0.0-alpha.19 to 3.0.0-alpha.20, with consistent dependency updates for better-sqlite3.

Overall Assessment

This is a high-quality implementation of a complex feature. The code demonstrates solid engineering practices with comprehensive testing and proper validation. The main concerns are around complexity and potential performance implications, but these are inherent to the sophisticated aggregation functionality being added.

Recommendation: Approve

The benefits of this functionality outweigh the complexity costs, and the implementation follows established patterns in the codebase.


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 upgrades the project from version 3.0.0-alpha.19 to 3.0.0-alpha.20, with key improvements to the GroupBy functionality and dependency updates.

  • Enhanced GroupBy operations with support for aggregations in having clauses and orderBy
  • Updated better-sqlite3 dependencies to version 12.2.0
  • Added comprehensive validation for aggregation operations in where clauses

Reviewed Changes

Copilot reviewed 29 out of 30 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
Multiple package.json files Version bump from 3.0.0-alpha.19 to 3.0.0-alpha.20
packages/runtime/src/client/crud/validator.ts Enhanced validation for aggregations in having clauses and primitive filters
packages/runtime/src/client/crud-types.ts Added aggregation support to filter types and improved GroupBy type definitions
packages/runtime/test/client-api/group-by.test.ts Comprehensive test coverage for new aggregation features
packages/runtime/src/client/crud/operations/group-by.ts Improved GroupBy SQL generation with proper column references
packages/runtime/src/client/crud/dialects/base.ts Added aggregation support in filters and orderBy operations
Files not reviewed (1)
  • pnpm-lock.yaml: Language not supported

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

🔭 Outside diff range comments (4)
packages/runtime/src/client/constants.ts (1)

26-31: Update PascalCase for AggregateOperator Type

To align with TS conventions and prevent value/type shadowing, rename the type from AGGREGATE_OPERATORS to AggregateOperator and update all its imports/usages accordingly.

Files to update:

  • packages/runtime/src/client/constants.ts
    • Change the type export.
  • packages/runtime/src/client/query-utils.ts
    • Import AggregateOperator instead of AGGREGATE_OPERATORS.
    • Update parameter op: AGGREGATE_OPERATORSop: AggregateOperator.
  • packages/runtime/src/client/crud/validator.ts
    • Import { AGGREGATE_OPERATORS, … }{ AGGREGATE_OPERATORS, … } (value) and type { AggregateOperator }.
    • Change withAggregations: Array<AGGREGATE_OPERATORS>Array<AggregateOperator>.
    • Update all casts and checks:
    key as AGGREGATE_OPERATORSkey as AggregateOperator
  • packages/runtime/src/client/crud/dialects/base.ts
    • Import type { AggregateOperator } in place of the type import.
    • Update casts: (field as AGGREGATE_OPERATORS)(field as AggregateOperator).

Example diff for constants.ts:

 export const AGGREGATE_OPERATORS = ['_count', '_sum', '_avg', '_min', '_max'] as const;
-export type AGGREGATE_OPERATORS = (typeof AGGREGATE_OPERATORS)[number];
+export type AggregateOperator = (typeof AGGREGATE_OPERATORS)[number];
packages/runtime/src/client/crud/dialects/base.ts (1)

737-749: Remove dead code: duplicate _count orderBy handling is unreachable

The earlier aggregation block handles all of ['_count','_avg','_sum','_min','_max'] and continues, so this special-case will never run. It’s confusing to keep around.

Apply this diff to remove the unreachable block:

-                switch (field) {
-                    case '_count': {
-                        invariant(value && typeof value === 'object', 'invalid orderBy value for field "_count"');
-                        for (const [k, v] of Object.entries<string>(value)) {
-                            invariant(v === 'asc' || v === 'desc', `invalid orderBy value for field "${field}"`);
-                            result = result.orderBy(
-                                (eb) => eb.fn.count(sql.ref(k)),
-                                sql.raw(this.negateSort(v, negated)),
-                            );
-                        }
-                        continue;
-                    }
-                    default:
-                        break;
-                }
+                // aggregate orderBy cases handled above
packages/runtime/src/client/crud/validator.ts (1)

713-719: Validation gap: restrict _avg/_sum orderBy to numeric fields

makeOrderBySchema currently allows all scalar fields under _avg/_sum. This disagrees with typing (SumAvgInput) and will accept invalid payloads at runtime.

Apply this refactor to enforce numeric-only keys for _avg/_sum while reusing the existing schema for _count/_min/_max:

-        if (WithAggregation) {
-            const aggregationFields = ['_count', '_avg', '_sum', '_min', '_max'];
-            for (const agg of aggregationFields) {
-                fields[agg] = z.lazy(() => this.makeOrderBySchema(model, true, false).optional());
-            }
-        }
+        if (WithAggregation) {
+            const nonRelationOrderBy = z.lazy(() => this.makeOrderBySchema(model, true, false).optional());
+            // unrestricted aggregations over all scalar fields
+            fields['_count'] = nonRelationOrderBy;
+            fields['_min'] = nonRelationOrderBy;
+            fields['_max'] = nonRelationOrderBy;
+
+            // restrict _avg/_sum to numeric scalar fields
+            const modelDef = requireModel(this.schema, model);
+            const sort = z.union([z.literal('asc'), z.literal('desc')]);
+            const numericFields = Object.keys(modelDef.fields).filter((f) => {
+                const def = requireField(this.schema, model, f);
+                return !def.relation && !def.array && NUMERIC_FIELD_TYPES.includes(def.type);
+            });
+            if (numericFields.length > 0) {
+                const numericOrderBy = z
+                    .strictObject(
+                        Object.fromEntries(numericFields.map((f) => [f, sort])) as Record<string, z.ZodType>,
+                    )
+                    .optional();
+                fields['_avg'] = numericOrderBy;
+                fields['_sum'] = numericOrderBy;
+            }
+        }
packages/runtime/src/client/crud-types.ts (1)

236-239: Type bug: AND/OR/NOT drop WithAggregations in recursive WhereInput

The recursive WhereInput uses the default WithAggregations=false, even when the outer WhereInput sets WithAggregations=true (e.g., GroupByHaving). This prevents aggregations under logical combinators at the type level.

Apply this fix:

-    AND?: OrArray<WhereInput<Schema, Model, ScalarOnly>>;
-    OR?: WhereInput<Schema, Model, ScalarOnly>[];
-    NOT?: OrArray<WhereInput<Schema, Model, ScalarOnly>>;
+    AND?: OrArray<WhereInput<Schema, Model, ScalarOnly, WithAggregations>>;
+    OR?: WhereInput<Schema, Model, ScalarOnly, WithAggregations>[];
+    NOT?: OrArray<WhereInput<Schema, Model, ScalarOnly, WithAggregations>>;
🧹 Nitpick comments (6)
packages/runtime/src/client/constants.ts (1)

21-25: Consider exporting a dedicated type alias for logical combinators

For readability and reuse in type signatures across the codebase, export a LogicalCombinator union type alongside the tuple.

Apply this diff:

 export const LOGICAL_COMBINATORS = ['AND', 'OR', 'NOT'] as const;
+export type LogicalCombinator = (typeof LOGICAL_COMBINATORS)[number];
packages/runtime/src/client/crud/operations/group-by.ts (1)

47-50: Pass groupBy expressions via spread for broader Kysely compatibility

Some Kysely versions have overloads that accept multiple arguments or a single array. Using spread avoids relying on the array overload and makes the intent explicit.

Apply this diff:

-const bys = typeof parsedArgs.by === 'string' ? [parsedArgs.by] : (parsedArgs.by as string[]);
-query = query.groupBy(bys.map((by) => sql.ref(`$sub.${by}`)));
+const bys = typeof parsedArgs.by === 'string' ? [parsedArgs.by] : (parsedArgs.by as string[]);
+query = query.groupBy(...bys.map((by) => sql.ref(`$sub.${by}`)));
packages/runtime/test/client-api/group-by.test.ts (1)

222-262: Strengthen orderBy-by-aggregation assertion to check ordering

Current assertion only checks presence. To verify ordering by _avg.age desc, assert the full ordered result.

Apply this diff:

-        await expect(
-            client.profile.groupBy({
-                by: ['bio'],
-                orderBy: {
-                    _avg: {
-                        age: 'desc',
-                    },
-                },
-            }),
-        ).resolves.toEqual(expect.arrayContaining([{ bio: 'bio2' }]));
+        await expect(
+            client.profile.groupBy({
+                by: ['bio'],
+                orderBy: {
+                    _avg: {
+                        age: 'desc',
+                    },
+                },
+            }),
+        ).resolves.toEqual([{ bio: 'bio2' }, { bio: 'bio1' }]);
packages/runtime/src/client/crud/dialects/base.ts (2)

724-735: OrderBy aggregation now unified via aggregate()

This refactor reduces bespoke logic and centralizes aggregator handling. One follow-up: consider removing the now-redundant special-case below for _count to avoid confusion.


664-680: Minor readability nit: avoid shadowing “conditions”

conditions is first an object, then spread as conditions.conditions. Consider renaming the variable to std or result to avoid confusion.

Apply this diff locally within the method:

-        const conditions = this.buildStandardFilter(
+        const std = this.buildStandardFilter(
             eb,
             'Bytes',
             payload,
             fieldRef,
             (value) => this.transformPrimitive(value, 'Bytes', false),
             (value) => this.buildBytesFilter(eb, fieldRef, value as BytesFilter<Schema, boolean, boolean>),
             true,
             ['equals', 'in', 'notIn', 'not'],
         );
-        return this.and(eb, ...conditions.conditions);
+        return this.and(eb, ...std.conditions);
packages/runtime/src/client/crud/validator.ts (1)

339-345: Intentional: negative take support

Switching take to z.int() (not constrained to nonnegative) enables negative take semantics for reversed pagination. If that’s intended, consider a short doc comment to avoid confusion.

Would you like me to add a brief comment near makeTakeSchema explaining the rationale?

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 0040e9d and 2e95aa5.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (29)
  • package.json (1 hunks)
  • packages/cli/package.json (2 hunks)
  • packages/common-helpers/package.json (1 hunks)
  • packages/create-zenstack/package.json (1 hunks)
  • packages/dialects/sql.js/package.json (1 hunks)
  • packages/eslint-config/package.json (1 hunks)
  • packages/ide/vscode/package.json (1 hunks)
  • packages/language/package.json (1 hunks)
  • packages/language/src/validators/datamodel-validator.ts (1 hunks)
  • packages/runtime/package.json (2 hunks)
  • packages/runtime/src/client/client-impl.ts (1 hunks)
  • packages/runtime/src/client/constants.ts (1 hunks)
  • packages/runtime/src/client/contract.ts (1 hunks)
  • packages/runtime/src/client/crud-types.ts (8 hunks)
  • packages/runtime/src/client/crud/dialects/base.ts (10 hunks)
  • packages/runtime/src/client/crud/operations/group-by.ts (1 hunks)
  • packages/runtime/src/client/crud/validator.ts (15 hunks)
  • packages/runtime/src/client/query-utils.ts (2 hunks)
  • packages/runtime/test/client-api/group-by.test.ts (6 hunks)
  • packages/runtime/test/schemas/basic/schema.ts (1 hunks)
  • packages/runtime/test/schemas/basic/schema.zmodel (1 hunks)
  • packages/sdk/package.json (1 hunks)
  • packages/tanstack-query/package.json (1 hunks)
  • packages/testtools/package.json (2 hunks)
  • packages/typescript-config/package.json (1 hunks)
  • packages/vitest-config/package.json (1 hunks)
  • packages/zod/package.json (1 hunks)
  • samples/blog/package.json (2 hunks)
  • tests/e2e/package.json (1 hunks)
🧰 Additional context used
📓 Path-based instructions (3)
**/schema.zmodel

📄 CodeRabbit Inference Engine (CLAUDE.md)

Always run zenstack generate after modifying ZModel schemas

Files:

  • packages/runtime/test/schemas/basic/schema.zmodel
{packages,samples,tests}/**

📄 CodeRabbit Inference Engine (CLAUDE.md)

Packages are located in packages/, samples/, and tests/

Files:

  • packages/runtime/test/schemas/basic/schema.zmodel
  • packages/language/src/validators/datamodel-validator.ts
  • packages/language/package.json
  • packages/dialects/sql.js/package.json
  • packages/typescript-config/package.json
  • packages/runtime/package.json
  • packages/zod/package.json
  • packages/create-zenstack/package.json
  • packages/eslint-config/package.json
  • samples/blog/package.json
  • packages/sdk/package.json
  • packages/common-helpers/package.json
  • packages/vitest-config/package.json
  • tests/e2e/package.json
  • packages/cli/package.json
  • packages/runtime/test/schemas/basic/schema.ts
  • packages/runtime/src/client/client-impl.ts
  • packages/tanstack-query/package.json
  • packages/runtime/src/client/constants.ts
  • packages/ide/vscode/package.json
  • packages/runtime/src/client/contract.ts
  • packages/testtools/package.json
  • packages/runtime/src/client/crud/operations/group-by.ts
  • packages/runtime/test/client-api/group-by.test.ts
  • packages/runtime/src/client/crud/validator.ts
  • packages/runtime/src/client/query-utils.ts
  • packages/runtime/src/client/crud/dialects/base.ts
  • packages/runtime/src/client/crud-types.ts
tests/e2e/**

📄 CodeRabbit Inference Engine (CLAUDE.md)

E2E tests are in tests/e2e/ directory

Files:

  • tests/e2e/package.json
🧠 Learnings (2)
📚 Learning: 2025-08-04T08:43:33.161Z
Learnt from: CR
PR: zenstackhq/zenstack-v3#0
File: CLAUDE.md:0-0
Timestamp: 2025-08-04T08:43:33.161Z
Learning: `zenstack generate` compiles ZModel to TypeScript schema (`schema.ts`)

Applied to files:

  • packages/language/package.json
📚 Learning: 2025-08-04T08:43:33.161Z
Learnt from: CR
PR: zenstackhq/zenstack-v3#0
File: CLAUDE.md:0-0
Timestamp: 2025-08-04T08:43:33.161Z
Learning: No runtime dependency on prisma/client

Applied to files:

  • samples/blog/package.json
🧬 Code Graph Analysis (8)
packages/language/src/validators/datamodel-validator.ts (2)
packages/runtime/src/client/crud/dialects/postgresql.ts (1)
  • provider (27-29)
packages/runtime/src/client/crud/dialects/sqlite.ts (1)
  • provider (27-29)
packages/runtime/src/client/client-impl.ts (1)
packages/runtime/src/client/crud/operations/group-by.ts (1)
  • GroupByOperationHandler (7-161)
packages/runtime/src/client/crud/operations/group-by.ts (1)
packages/runtime/src/helpers.ts (1)
  • sql (1-1)
packages/runtime/test/client-api/group-by.test.ts (1)
packages/runtime/test/client-api/utils.ts (1)
  • createPosts (23-32)
packages/runtime/src/client/crud/validator.ts (5)
packages/sdk/src/schema/schema.ts (3)
  • BuiltinType (84-94)
  • EnumDef (98-98)
  • GetModels (108-108)
packages/language/src/generated/ast.ts (1)
  • BuiltinType (101-101)
packages/runtime/src/utils/object-utils.ts (1)
  • extractFields (4-6)
packages/runtime/src/client/constants.ts (3)
  • AGGREGATE_OPERATORS (29-29)
  • AGGREGATE_OPERATORS (30-30)
  • LOGICAL_COMBINATORS (24-24)
packages/runtime/src/utils/enumerate.ts (1)
  • enumerate (9-17)
packages/runtime/src/client/query-utils.ts (2)
packages/sdk/src/schema/expression.ts (1)
  • Expression (1-10)
packages/runtime/src/client/constants.ts (2)
  • AGGREGATE_OPERATORS (29-29)
  • AGGREGATE_OPERATORS (30-30)
packages/runtime/src/client/crud/dialects/base.ts (3)
packages/runtime/src/client/constants.ts (3)
  • LOGICAL_COMBINATORS (24-24)
  • AGGREGATE_OPERATORS (29-29)
  • AGGREGATE_OPERATORS (30-30)
packages/runtime/src/client/query-utils.ts (1)
  • aggregate (321-333)
packages/runtime/src/client/crud-types.ts (4)
  • StringFilter (294-311)
  • BooleanFilter (357-368)
  • DateTimeFilter (331-340)
  • BytesFilter (342-355)
packages/runtime/src/client/crud-types.ts (2)
packages/sdk/src/schema/schema.ts (9)
  • GetModelFieldType (151-155)
  • ModelFieldIsOptional (217-221)
  • SchemaDef (10-18)
  • BuiltinType (84-94)
  • GetModels (108-108)
  • GetModelFields (132-135)
  • FieldIsArray (235-239)
  • FieldIsRelation (229-233)
  • NonRelationFields (190-194)
packages/runtime/src/utils/type-utils.ts (3)
  • NullableIf (5-5)
  • OrArray (48-48)
  • NonEmptyArray (50-50)
⏰ 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). (2)
  • GitHub Check: build-test (20.x)
  • GitHub Check: claude-review
🔇 Additional comments (35)
package.json (1)

3-3: Monorepo sync to 3.0.0-alpha.20 verified
No lingering alpha.19 references found; all package.json versions are at 3.0.0-alpha.20.

packages/zod/package.json (1)

3-3: LGTM: version bump

Aligned with the monorepo release; no API surface changes in this package.json.

packages/common-helpers/package.json (1)

3-3: LGTM: version bump

Consistent with the coordinated alpha.20 release; no other changes.

packages/create-zenstack/package.json (1)

3-3: LGTM: version bump

Matches the repo-wide version; no functional changes.

packages/tanstack-query/package.json (1)

3-3: LGTM: version bump

In sync with the monorepo; nothing else changed. Private package will be skipped by publish scripts as expected.

tests/e2e/package.json (2)

3-3: LGTM: version bump aligns with the monorepo release.
No functional impact; consistent with other packages moving to 3.0.0-alpha.20.


3-3: Monorepo version consistency confirmed
All package.json files share version 3.0.0-alpha.20, and every @zenstackhq/* dependency remains on workspace:*. Ready for publishing.

packages/eslint-config/package.json (1)

3-3: LGTM: metadata-only version bump.
Private package; no downstream risk. Matches the repo-wide alpha.20 release.

packages/sdk/package.json (1)

3-3: LGTM: SDK package version increment only.
Exports, deps, and scripts unchanged; safe metadata update.

packages/vitest-config/package.json (1)

4-4: LGTM: vitest-config version bump.
Config-only package; no functional changes introduced.

packages/typescript-config/package.json (1)

3-3: LGTM: typescript-config version bump.
No behavioral impact; aligns with monorepo release.

packages/dialects/sql.js/package.json (1)

3-3: Version bump looks good

Repo-wide alignment to 3.0.0-alpha.20 acknowledged. No API/manifest changes here.

samples/blog/package.json (2)

3-3: Sample app version bump is consistent

Version updated to 3.0.0-alpha.20, consistent with the workspace.


21-21: Consistent @types/better-sqlite3 versions confirmed

Running the provided script shows that all instances of @types/better-sqlite3 use ^7.6.13:

  • packages/cli/package.json: ^7.6.13
  • packages/runtime/package.json: ^7.6.13
  • samples/blog/package.json: ^7.6.13

No action required.

packages/language/package.json (1)

4-4: Language package version bump is straightforward

No functional or export changes here; just the version alignment.

packages/ide/vscode/package.json (1)

4-4: VS Code extension version updated — OK

Pre-release workflow remains the same; nothing else changed in the manifest.

packages/runtime/package.json (2)

3-3: Runtime package version bump aligns with repo

Nothing else changed in manifest contents. Good to go.


92-92: All better-sqlite3 versions are consistent across the workspace

After scanning every package.json that depends on better-sqlite3:

• packages/cli/package.json
– dependencies: better-sqlite3 ^12.2.0
– devDependencies: @types/better-sqlite3 ^7.6.13

• packages/runtime/package.json
– dependencies: better-sqlite3 ^12.2.0
– devDependencies: @types/better-sqlite3 ^7.6.13

• packages/testtools/package.json
– dependencies: better-sqlite3 ^12.2.0 (no types package)

• samples/blog/package.json
– dependencies: better-sqlite3 ^12.2.0
– dependencies: @types/better-sqlite3 ^7.6.13

All packages that declare better-sqlite3 use the same ^12.2.0 range, and all that include the types package use ^7.6.13. No mismatches detected—no changes required.

packages/language/src/validators/datamodel-validator.ts (1)

110-111: Message wording aligns with "list" terminology elsewhere — LGTM

The error message now consistently uses "List" (matching Line 100: "Optional lists are not supported"). The provider check ('sqlite') remains precise and consistent with runtime dialect providers.

packages/cli/package.json (1)

6-6: Monorepo versions and better-sqlite3 ranges are consistent

  • All @zenstackhq/* packages are at 3.0.0-alpha.20.
  • Every occurrence of better-sqlite3 in dependencies/devDependencies/peerDependencies is pinned to ^12.2.0.

Please manually verify that the prebuilt binaries for better-sqlite3 support all Node.js versions used in your CI pipelines and downstream consumers to avoid install/runtime issues.

packages/testtools/package.json (1)

3-3: Version/peer bump looks consistent with the coordinated release

The version aligns with the repo-wide bump, and peer better-sqlite3 moved to ^12.2.0, consistent with other packages. No further action from my side.

Also applies to: 40-40

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

755-757: Docs clarification for groupBy orderBy/having is accurate and helpful

Clarifying that orderBy/having can reference either aggregations or by-fields matches the new aggregation-aware validation and group-by flow. The example using an aggregated filter in having mirrors the implemented behavior.

Also applies to: 762-767

packages/runtime/test/schemas/basic/schema.zmodel (1)

27-27: LGTM: Optional Json meta field added to User

The addition looks correct and aligns with tests that may want to store arbitrary metadata.

Note: Per repo guidelines, “zenstack generate” must run after schema changes. The generated schema.ts in this PR reflects the update, so this appears handled.

packages/runtime/test/schemas/basic/schema.ts (1)

64-69: LGTM: Generated schema includes the new meta field

The generated file correctly mirrors the ZModel change with an optional Json field.

packages/runtime/src/client/crud/operations/group-by.ts (1)

56-58: LGTM: Having now built against subquery alias

Using the '$sub' alias here keeps having conditions consistent with grouped fields and aggregations sourced from the subquery.

packages/runtime/test/client-api/group-by.test.ts (5)

5-5: LGTM: Imports extended with createPosts

Pulling in createPosts improves reusability and keeps seeding logic consistent across tests.


36-36: LGTM: Post grouping coverage added

Seeding posts for author '1' and asserting grouping by published with _count exercises the new aggregation paths on an additional model.

Also applies to: 98-109


71-71: LGTM: Use of arrayContaining makes ordering/limits assertions resilient

This avoids over-constraining results when skip/take and ordering interact.


146-157: LGTM: Expanded aggregation coverage with deterministic ids

Including id in _count/_min/_max and seeding explicit ids ensures deterministic assertions across dialects.

Also applies to: 162-167, 171-179


182-221: LGTM: Having with aggregations is properly exercised

The test verifies combined aggregate predicates (_avg and _sum) against grouped records.

packages/runtime/src/client/query-utils.ts (2)

288-291: Good reuse: switched to common extractFields utility

Consolidating to the shared extractFields improves consistency and testability.


321-333: Aggregate helper is clear and exhaustive

The ts-pattern match with exhaustive() guarantees coverage across AGGREGATE_OPERATORS. This is a clean, type-safe mapping to Kysely functions.

packages/runtime/src/client/crud/dialects/base.ts (2)

122-124: Logical combinator guard reads well

The includes-based check against LOGICAL_COMBINATORS is simple and sufficient for this small set. Good separation via a dedicated type guard.


509-522: Solid: aggregation-aware primitive filtering via match

Routing aggregator keys to aggregate(eb, lhs, op) then reusing buildStandardFilter preserves existing operators/validation without duplication. Nice reuse.

packages/runtime/src/client/crud-types.ts (1)

1065-1068: Nice: GroupByHaving narrows having to aggregation-aware scalar-only where

Good alignment with the validator’s makeHavingSchema and the runtime filter-building logic.

@ymc9 ymc9 added this pull request to the merge queue Aug 12, 2025
Merged via the queue into main with commit 9b36641 Aug 12, 2025
11 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.

3 participants