Skip to content

fix(orm): preserve array mutation shape for optional typed-JSON fields#2557

Merged
ymc9 merged 1 commit into
devfrom
fix/nullable-typed-json-array-mutation-schema
Apr 4, 2026
Merged

fix(orm): preserve array mutation shape for optional typed-JSON fields#2557
ymc9 merged 1 commit into
devfrom
fix/nullable-typed-json-array-mutation-schema

Conversation

@ymc9

@ymc9 ymc9 commented Apr 4, 2026

Copy link
Copy Markdown
Member

Summary

  • makeNullableTypedJsonMutationSchema was calling makeScalarSchema(type, attributes) internally, which discarded the already-built fieldSchema passed by callers — including any array/list mutation shape ({ set } on create, { set, push } on update)
  • Changed the function to accept a fieldSchema: z.ZodTypeAny parameter and use it directly in safeParse instead of reconstructing from scratch
  • Updated both callers (create schema and update schema) to pass the pre-built fieldSchema

Test plan

  • Verify optional typed-JSON array fields accept { set: [...] } on create
  • Verify optional typed-JSON array fields accept { set, push } operators on update
  • Verify null / DbNull / JsonNull sentinels still pass validation for optional typed-JSON fields
  • Run existing regression tests: pnpm test

🤖 Generated with Claude Code

Summary by CodeRabbit

Release Notes

  • Refactor
    • Optimized internal schema validation handling to improve efficiency and consistency in data mutation processing.

makeNullableTypedJsonMutationSchema was rebuilding the schema from type
and attributes via makeScalarSchema, discarding any prior array/list
mutation shape (set, push, etc.) built by the caller. Pass the
already-built fieldSchema so the full shape is preserved.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Apr 4, 2026

Copy link
Copy Markdown
Contributor

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: c80e36d2-29ad-42b8-892e-a6e086af1e70

📥 Commits

Reviewing files that changed from the base of the PR and between e9482fe and faa5166.

📒 Files selected for processing (1)
  • packages/orm/src/client/zod/factory.ts

📝 Walkthrough

Walkthrough

The function makeNullableTypedJsonMutationSchema was refactored to accept a prebuilt Zod schema instead of constructing one internally. The validation logic now delegates to the provided schema while maintaining null/undefined handling. Callers were updated to pass precomputed field schemas.

Changes

Cohort / File(s) Summary
Zod Factory Refactoring
packages/orm/src/client/zod/factory.ts
Changed makeNullableTypedJsonMutationSchema to accept a prebuilt fieldSchema parameter instead of constructing the schema internally. Updated validation to use fieldSchema.safeParse() and modified both create/update data paths to pass precomputed field schemas.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Poem

🐰✨ A schema once built, now passed with care,
No more construction, just reuse we share,
The rabbit hops through mutations with grace,
Each validation finding its proper place! 🎯

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main fix: preserving array mutation shape (set, push operators) for optional typed-JSON fields by changing how the schema is constructed.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/nullable-typed-json-array-mutation-schema

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

claude Bot commented Apr 4, 2026

Copy link
Copy Markdown
Contributor

Claude finished @ymc9's task —— View job


PR Code Review

Review Tasks

  • Read and analyze the modified file
  • Review code quality and implementation
  • Check for potential bugs or issues
  • Assess performance implications
  • Review security considerations
  • Evaluate test coverage needs
  • Provide comprehensive feedback

Summary

This PR fixes a bug in the Zod schema factory where makeNullableTypedJsonMutationSchema was discarding pre-built field schemas that contained array mutation operators ({ set }, { push }). The fix changes the function signature to accept the already-built fieldSchema parameter instead of reconstructing it from scratch.

Code Quality & Implementation ✅

Excellent implementation with clear improvements:

  1. Clear problem identification: The comments in packages/orm/src/client/zod/factory.ts:614-617 perfectly explain the issue and solution
  2. Minimal, focused change: Only touches the specific problematic function and its two call sites
  3. Parameter signature improvement: Changes from (type: string, attributes?: readonly AttributeApplication[]) to (fieldSchema: z.ZodTypeAny) - much cleaner and preserves caller's work
  4. Maintains backward compatibility: Internal function change doesn't affect public API

Potential Issues ✅

No significant issues found:

  1. Type safety: Uses z.ZodTypeAny which is the correct parent type for all Zod schemas
  2. Null handling: Properly preserves existing null value validation logic (packages/orm/src/client/zod/factory.ts:623-628)
  3. Error propagation: Correctly forwards Zod validation errors using ctx.addIssue(issue as any) (packages/orm/src/client/zod/factory.ts:632)

Performance Considerations ✅

Performance neutral or slightly improved:

  1. Eliminates redundant work: No longer calls makeScalarSchema(type, attributes) to rebuild what callers already built
  2. Same validation path: Uses the same safeParse approach, no performance regression
  3. Memory efficiency: Reuses existing schema object instead of creating a new one

Security Considerations ✅

No security concerns:

  1. Input validation preserved: All existing Zod validation rules still apply
  2. No new attack vectors: Changes internal implementation without exposing new inputs
  3. Null sentinel handling intact: Still properly handles DbNull, JsonNull, AnyNull classes

Test Coverage Assessment ⚠️

Test coverage exists but could be more comprehensive:

Existing coverage:

  • Basic typed JSON field tests in /tests/e2e/orm/client-api/typed-json-fields.test.ts
  • General JSON filter tests

Missing coverage for this specific fix:

  • No tests specifically for optional typed-JSON array fields with mutation operators
  • Missing test cases for { set: [...] } on create operations
  • Missing test cases for { set, push } operators on update operations
  • No regression test for the bug this PR fixes

Recommendation: Add test cases to verify:

// Create with array mutation shape
await client.model.create({
  data: {
    optionalTypedJsonArray: { set: [item1, item2] }
  }
})

// Update with array mutation operators  
await client.model.update({
  where: { id: 1 },
  data: {
    optionalTypedJsonArray: { push: newItem }
  }
})

Overall Assessment 🎯

High quality fix with excellent implementation:

  • ✅ Addresses the root cause correctly
  • ✅ Minimal, surgical change
  • ✅ Well-documented with clear comments
  • ✅ No breaking changes
  • ⚠️ Could benefit from more specific test coverage

Recommendation: Approve with suggestion to add regression tests for the specific bug scenario.

@ymc9 ymc9 merged commit da234ea into dev Apr 4, 2026
8 checks passed
@ymc9 ymc9 deleted the fix/nullable-typed-json-array-mutation-schema branch April 4, 2026 17:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant