Conversation
…flat schemas Replace z.discriminatedUnion() with flat z.object() + .refine() validation for Claude API compatibility. The Claude API doesn't support oneOf/allOf/anyOf at JSON Schema root level, which discriminated unions generate. Changes: - Convert all CQRS schemas (browse_*, manage_*) to flat schema pattern - Add .refine() validators for required field validation per action - Add .refine() validators to reject fields not valid for specific actions - Update registry handlers with non-null assertions for refine-validated fields - Update all tests to include action field in schema validation Affected entities: files, mrs, pipelines, workitems Closes #29
📊 Test Coverage ReportOverall Coverage: 86.53% Coverage Details
📈 Coverage Report: View detailed coverage report
|
Codecov Report❌ Patch coverage is 📢 Thoughts on this report? Let us know! |
There was a problem hiding this comment.
Pull request overview
This PR refactors all CQRS schemas from z.discriminatedUnion() to flat z.object() with .refine() validations to fix Claude API compatibility issues. The Claude API rejects JSON schemas with oneOf/allOf/anyOf at the root level, which is what Zod generates for discriminated unions.
Changes:
- Converted all CQRS tool schemas (browse/manage for Files, MRs, Pipelines, Work Items) from discriminated unions to flat objects with runtime validation
- Updated registries to use non-null assertions (
!) for fields validated by.refine()at runtime - Replaced
_exhaustive: neverexhaustiveness checking pattern with simpledefault: throw new Error() - Renamed pipeline scope fields (
scope→job_scope,trigger_scope) to avoid ambiguity in flat schema - Updated all integration and unit tests to include
actionfield in test parameters
Reviewed changes
Copilot reviewed 19 out of 19 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
| src/entities/workitems/schema.ts | Converted ManageWorkItemSchema to flat schema with refines for create/update/delete actions |
| src/entities/workitems/schema-readonly.ts | Converted BrowseWorkItemsSchema to flat schema for list/get actions |
| src/entities/workitems/registry.ts | Added non-null assertions for validated fields, simplified exhaustiveness checking |
| src/entities/pipelines/schema.ts | Converted ManagePipelineSchema and ManagePipelineJobSchema to flat schemas |
| src/entities/pipelines/schema-readonly.ts | Converted BrowsePipelinesSchema to flat schema, renamed scope fields to job_scope/trigger_scope |
| src/entities/pipelines/registry.ts | Updated to use non-null assertions and handle renamed scope fields |
| src/entities/mrs/schema.ts | Converted all MR management schemas to flat with extensive refines for action-specific validation |
| src/entities/mrs/schema-readonly.ts | Converted browse schemas to flat with comprehensive field validation per action |
| src/entities/mrs/registry.ts | Added non-null assertions throughout for validated fields |
| src/entities/files/schema.ts | Converted ManageFilesSchema to flat for single/batch/upload actions |
| src/entities/files/schema-readonly.ts | Converted BrowseFilesSchema to flat for tree/content actions |
| src/entities/files/registry.ts | Updated with non-null assertions, fixed Buffer to Uint8Array conversion |
| tests/* | Updated all integration and unit tests to include action field in parameters |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Convert core entity schemas from discriminated unions to flat z.object() with .refine() validation for Claude API compatibility: - BrowseProjectsSchema (search, list, get actions) - BrowseNamespacesSchema (list, get, verify actions) - BrowseCommitsSchema (list, get, diff actions) - BrowseEventsSchema (user, project actions) - ManageRepositorySchema (create, fork actions) - ManageTodosSchema (mark_done, mark_all_done, restore actions) Add assertDefined() utility for type-safe field access after .refine() validation, replacing non-null assertions in all registry handlers: - core/registry.ts - files/registry.ts - mrs/registry.ts - pipelines/registry.ts - workitems/registry.ts Fix switch default cases to properly cast action field to string. Remove unused imports across all refactored files.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 24 out of 24 changed files in this pull request and generated 3 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
- Add 7 tests for pipelines error handling (100% line coverage) - Add 15 tests for assertDefined and requiredId utilities - Fix coverage-pages.yml heredoc to execute shell commands - Fix wrong repo URLs in coverage workflow (project-nexus-mcp -> gitlab-mcp) - Add istanbul ignore for unreachable code in mrs/registry.ts
Buffer is already a Uint8Array subclass in Node.js, no need to wrap it.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 26 out of 26 changed files in this pull request and generated no new comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
- Document why assertDefined only checks undefined (not empty strings) - Clarify trailing ? behavior in URL construction test
Summary
z.discriminatedUnion()to flatz.object()with.refine()validationoneOf/allOf/anyOfat JSON Schema root levelChanges
Schema Pattern Change
Before (discriminated union):
After (flat schema with refines):
Affected Entities
BrowseFilesSchema,ManageFilesSchemaBrowseMergeRequestsSchema,BrowseMrDiscussionsSchema,ManageMergeRequestSchema,ManageMrDiscussionSchema,ManageMrDraftNotesSchemaBrowsePipelinesSchema,ManagePipelineSchema,ManagePipelineJobSchemaBrowseWorkItemsSchema,ManageWorkItemSchemaRegistry Updates
!) for fields validated by.refine()at runtime_exhaustive: neverpattern with simpledefault: throw new Error()Test plan
Closes #29