refactor: define mutation backend interfaces#236
refactor: define mutation backend interfaces#236retran wants to merge 16 commits intomendixlabs:mainfrom
Conversation
Phase 1-8: 85 read/write handler tests with mock backend infrastructure Error paths: 49 tests covering backend error propagation for all handler groups Not-connected: 29 tests verifying Connected/ConnectedForWrite guards JSON format: 26 tests validating JSON output for show/list handlers Production code changes: - Added Func fields to MockBackend for 8 agent-editor write methods - Fixed ContainerID parameter semantics in withContainer and all call sites
Create mdl/types/ package with WASM-safe shared types extracted from sdk/mpr: domain model types, ID utilities, EDMX/AsyncAPI parsing, JSON formatting helpers. Migrate all executor handlers to use mdl/types directly, removing type aliases from sdk/mpr/reader_types.go. - Extract 16+ domain types to mdl/types/ (infrastructure, java, navigation, mapping) - Extract GenerateID, BlobToUUID, ValidateID to mdl/types/id.go - Extract ParseEdmx, ParseAsyncAPI to mdl/types/edmx.go, asyncapi.go - Extract PrettyPrintJSON, BuildJsonElementsFromSnippet to json_utils.go - Migrate 30+ executor handler files off sdk/mpr type references - sdk/mpr retains thin delegation wrappers for backward compatibility
AI Code ReviewCritical Issues
Moderate Issues
Minor Issues
What Looks Good
Automated review via OpenRouter (Nemotron Super 120B) — workflow source |
There was a problem hiding this comment.
Pull request overview
This PR advances the “shared-types refactoring” stack by moving several previously sdk/mpr-owned value types into mdl/types, introducing WASM-safe BSON ID helpers, and defining mutation-focused backend interfaces so the executor can mutate pages/workflows through an abstraction layer (rather than manipulating BSON directly).
Changes:
- Add
mdl/typesshared structs + ID/hash utilities and updatesdk/mpr/mdl/callers to use them. - Add
mdl/bsonutil(WASM-safe) for UUID↔BSON Binary conversion and migrate BSON-writing call sites to it. - Define mutation backend contracts (
PageMutator,WorkflowMutator, serialization backends) and extend mock backends + add mock-based executor tests.
Reviewed changes
Copilot reviewed 121 out of 124 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| sdk/mpr/writer_imagecollection_test.go | Update tests to use types.ImageCollection. |
| sdk/mpr/writer_imagecollection.go | Writer now accepts *types.ImageCollection for image collection creation/serialization. |
| sdk/mpr/writer_core.go | Delegate UUID/blob conversion and ID generation to mdl/types. |
| sdk/mpr/utils.go | Delegate ID/UUID/hash helpers to mdl/types; reimplemented IDToBsonBinary. |
| sdk/mpr/reader.go | Delegate blobToUUID to types.BlobToUUID. |
| sdk/mpr/parser_misc.go | Parser returns mdl/types equivalents for Java/JS actions, navigation, image collections, JSON structures. |
| sdk/mpr/asyncapi.go | Replace AsyncAPI structs with type aliases to mdl/types and delegate parsing. |
| mdl/visitor/visitor_agenteditor.go | Remove stray blank line. |
| mdl/types/navigation.go | New navigation document/profile/menu types for backend-agnostic use. |
| mdl/types/mapping.go | New JSON structure + image collection types for backend-agnostic use. |
| mdl/types/java.go | New lightweight Java/JavaScript action descriptors. |
| mdl/types/infrastructure.go | New backend-agnostic infrastructure types (folders, units, raw units, rename hits, etc.). |
| mdl/types/id.go | New shared ID/UUID conversion + hashing utilities. |
| mdl/types/doc.go | Package documentation for mdl/types. |
| mdl/types/asyncapi.go | AsyncAPI document types + parser moved into mdl/types. |
| mdl/linter/rules/page_navigation_security.go | Switch linter navigation menu traversal to types.NavMenuItem. |
| mdl/executor/widget_templates.go | Switch ID generation to types.GenerateID. |
| mdl/executor/widget_operations.go | Switch $ID generation to bsonutil + types.GenerateID. |
| mdl/executor/widget_engine_test.go | Switch BlobToUUID usage to types. |
| mdl/executor/widget_engine.go | Switch template ID generator + widget IDs to types.GenerateID. |
| mdl/executor/helpers.go | Use types.FolderInfo and types.GenerateID in folder helpers. |
| mdl/executor/executor.go | Cache now stores types.UnitInfo / types.FolderInfo. |
| mdl/executor/cmd_workflows_write.go | Switch workflow ID generation to types.GenerateID. |
| mdl/executor/cmd_workflows_mock_test.go | Add mock-based workflow show/describe tests. |
| mdl/executor/cmd_settings_mock_test.go | Add mock-based settings show/describe tests. |
| mdl/executor/cmd_security_write.go | Switch member access/revocation structs to types. |
| mdl/executor/cmd_security_mock_test.go | Add mock-based security show/describe tests. |
| mdl/executor/cmd_rest_clients_mock_test.go | Add mock-based consumed REST client tests. |
| mdl/executor/cmd_rename.go | Switch rename hit types to types.RenameHit. |
| mdl/executor/cmd_published_rest_mock_test.go | Add mock-based published REST tests. |
| mdl/executor/cmd_pages_mock_test.go | Add mock-based pages/snippets/layouts list tests. |
| mdl/executor/cmd_pages_builder_v3_pluggable.go | Use bsonutil.NewIDBsonBinary() for regenerated $IDs; switch ID generator to types. |
| mdl/executor/cmd_pages_builder_v3_layout.go | Switch layout widget IDs to types.GenerateID. |
| mdl/executor/cmd_pages_builder_input_filters.go | Switch widget-template ID generation to types and $ID handling to bsonutil. |
| mdl/executor/cmd_pages_builder_input_cloning_test.go | Update cloning tests to use bsonutil.NewIDBsonBinary(). |
| mdl/executor/cmd_pages_builder_input_cloning.go | Switch regenerated $IDs and binary-ID parsing to bsonutil/types. |
| mdl/executor/cmd_pages_builder_input.go | Switch blob-to-UUID conversion to types and $ID creation to bsonutil. |
| mdl/executor/cmd_pages_builder.go | Switch folder cache element types to types.FolderInfo. |
| mdl/executor/cmd_odata_mock_test.go | Add mock-based OData client/service tests. |
| mdl/executor/cmd_odata.go | Switch ID generation to types and EDMX parsing to types.ParseEdmx. |
| mdl/executor/cmd_notconnected_mock_test.go | Add centralized not-connected guard tests using a disconnected mock backend. |
| mdl/executor/cmd_navigation_mock_test.go | Add mock-based navigation show/describe tests using mdl/types navigation structs. |
| mdl/executor/cmd_navigation.go | Switch navigation spec/document types to mdl/types. |
| mdl/executor/cmd_modules_mock_test.go | Add mock-based module listing test using types.UnitInfo. |
| mdl/executor/cmd_misc_mock_test.go | Add mock-based version output test using types.ProjectVersion. |
| mdl/executor/cmd_microflows_mock_test.go | Add mock-based microflow/nanoflow show/describe tests. |
| mdl/executor/cmd_microflows_create.go | Switch microflow IDs to types.GenerateID. |
| mdl/executor/cmd_microflows_builder_workflow.go | Switch microflow workflow-action builder IDs to types.GenerateID. |
| mdl/executor/cmd_microflows_builder_graph.go | Switch flow graph object IDs to types.GenerateID. |
| mdl/executor/cmd_microflows_builder_flows.go | Switch sequence flow IDs to types.GenerateID. |
| mdl/executor/cmd_microflows_builder_control.go | Switch control-structure IDs to types.GenerateID. |
| mdl/executor/cmd_microflows_builder_annotations.go | Switch annotation IDs/flows to types.GenerateID. |
| mdl/executor/cmd_mermaid_mock_test.go | Add mock-based mermaid domain model describe test. |
| mdl/executor/cmd_jsonstructures_mock_test.go | Add mock-based JSON structure show test using types.JsonStructure. |
| mdl/executor/cmd_jsonstructures.go | Switch JSON structure types + JSON helpers to mdl/types. |
| mdl/executor/cmd_javascript_actions_mock_test.go | Add mock-based JavaScript action show/describe tests using types.JavaScriptAction. |
| mdl/executor/cmd_javaactions_mock_test.go | Add mock-based Java action show/describe tests. |
| mdl/executor/cmd_javaactions.go | Switch Java action ID generation to types.GenerateID. |
| mdl/executor/cmd_import_mappings_mock_test.go | Add mock-based import mapping show test. |
| mdl/executor/cmd_import_mappings.go | Switch JSON-structure element map types to types.JsonElement. |
| mdl/executor/cmd_imagecollections_mock_test.go | Add mock-based image collection show/describe tests using types.ImageCollection. |
| mdl/executor/cmd_imagecollections.go | Switch image collection types to mdl/types. |
| mdl/executor/cmd_fragments_mock_test.go | Add mock-based fragments show tests. |
| mdl/executor/cmd_folders.go | Switch folder list argument type to types.FolderInfo. |
| mdl/executor/cmd_export_mappings_mock_test.go | Add mock-based export mapping show test. |
| mdl/executor/cmd_export_mappings.go | Switch JSON-structure element map types to types.JsonElement. |
| mdl/executor/cmd_enumerations_mock_test.go | Refactor and expand enumeration mock tests to use shared mock helpers. |
| mdl/executor/cmd_entities_mock_test.go | Add mock-based entity list tests. |
| mdl/executor/cmd_entities.go | Switch entity creation IDs (attrs, rules, indexes) to types.GenerateID. |
| mdl/executor/cmd_dbconnection_mock_test.go | Add mock-based DB connection show/describe tests. |
| mdl/executor/cmd_datatransformer_mock_test.go | Add mock-based data transformer list/describe tests. |
| mdl/executor/cmd_constants_mock_test.go | Add mock-based constants show/describe tests. |
| mdl/executor/cmd_businessevents_mock_test.go | Add mock-based business event service tests. |
| mdl/executor/cmd_businessevents.go | Switch generated channel names to use types.GenerateID. |
| mdl/executor/cmd_associations_mock_test.go | Add mock-based associations list tests. |
| mdl/executor/cmd_alter_workflow.go | Switch $ID generation from mpr to bsonutil. |
| mdl/executor/cmd_alter_page.go | Switch blob-to-UUID and $ID generation to types/bsonutil. |
| mdl/executor/cmd_agenteditor_write.go | Formatting/alignment in Agent creation struct literal. |
| mdl/executor/cmd_agenteditor_models.go | Formatting/alignment in Agent Editor model creation struct literal. |
| mdl/catalog/builder_references.go | Switch menu item reference extraction to types.NavMenuItem. |
| mdl/catalog/builder_navigation.go | Switch catalog navigation counting/insertion to types.NavMenuItem. |
| mdl/catalog/builder_contract.go | Switch EDMX/AsyncAPI parsing to mdl/types. |
| mdl/catalog/builder.go | Update CatalogReader interface to use mdl/types value types. |
| mdl/bsonutil/bsonutil.go | New BSON-aware ID utilities (UUID↔BSON Binary + new ID). |
| mdl/backend/workflow.go | Backend interfaces updated to use mdl/types (e.g., image collections). |
| mdl/backend/security.go | Backend security interfaces updated to use mdl/types member access structs. |
| mdl/backend/navigation.go | Backend navigation interfaces updated to use mdl/types navigation structs/specs. |
| mdl/backend/mutation.go | New mutation + serialization backend interfaces (page/workflow mutators). |
| mdl/backend/mock/mock_workflow.go | Mock backend updated for types.ImageCollection. |
| mdl/backend/mock/mock_security.go | Mock backend updated for types.EntityAccessRevocation. |
| mdl/backend/mock/mock_navigation.go | Mock backend updated for types.NavigationDocument/spec. |
| mdl/backend/mock/mock_mutation.go | Add stub/mock implementations for new mutation + serialization interfaces. |
| mdl/backend/mock/mock_module.go | Mock folder listing updated to types.FolderInfo. |
| mdl/backend/mock/mock_mapping.go | Mock mapping/JSON structure APIs updated to types.JsonStructure. |
| mdl/backend/mock/mock_java.go | Mock Java/JS action APIs updated to types.JavaAction/types.JavaScriptAction. |
| mdl/backend/mock/mock_infrastructure.go | Mock infra APIs updated to types (rename hits, raw units, units, widget types) + add agent editor write hooks. |
| mdl/backend/mock/mock_connection.go | Mock connection/version APIs updated to types equivalents. |
| mdl/backend/mock/backend.go | MockBackend fields updated for types-based signatures + new mutation/serialization hooks. |
| mdl/backend/mapping.go | MappingBackend now uses types.JsonStructure. |
| mdl/backend/java.go | JavaBackend now uses types.JavaAction/types.JavaScriptAction. |
| mdl/backend/infrastructure.go | Infrastructure interfaces now use types (rename hits, raw units, units, widget type). |
| mdl/backend/doc.go | Update backend package docs to reflect mdl/types migration. |
| mdl/backend/connection.go | ConnectionBackend now uses types.MPRVersion and types.ProjectVersion; folder listing uses types.FolderInfo. |
| mdl/backend/backend.go | FullBackend now includes mutation + serialization backend interfaces. |
| internal/marketplace/types.go | Minor comment formatting cleanup. |
| cmd/mxcli/project_tree.go | Project tree menu rendering updated to consume types.NavMenuItem. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
- id_test.go: UUID generation, roundtrip, validation, hash - json_utils_test.go: pretty-print, datetime normalization, snippet builder - edmx_test.go: OData4 parsing, enums, capabilities, FindEntityType - asyncapi_test.go: parsing, sorted channels/messages, FindMessage - convert_test.go: prove sdk/mpr type aliases are identical to mdl/types - fix normalizeDateTimeValue matching '-' in date portion (search from idx 19+)
- normalizeDateTimeValue: pad fractional seconds even without timezone suffix - float64→int64: add safe integer range guard (±2^53) - fix reservedExposedNames comment (remove 'Name' not in map) - clarify singularize is intentionally naive (matches Studio Pro)
Add PageMutator, WorkflowMutator, WidgetSerializationBackend interfaces to mdl/backend/mutation.go for BSON-free handler decoupling. Extract BSON ID helpers (IDToBsonBinary, BsonBinaryToID, NewIDBsonBinary) to mdl/bsonutil/ package. Add panic stubs to MprBackend and mock function fields to MockBackend for all new interface methods. - Create mdl/bsonutil/bsonutil.go with BSON ID conversion utilities - Migrate 10 handler files from mpr.IDToBsonBinary to bsonutil.* - Define PageMutationBackend, WorkflowMutationBackend interfaces - Define WidgetSerializationBackend with opaque return types - Add PluggablePropertyContext for domain-typed widget property input
4aa40e9 to
c0decae
Compare
AI Code ReviewReview SummaryThis PR defines mutation backend interfaces to decouple the executor from direct BSON manipulation, preparing for implementation in PR #237. It's part of a shared-types refactoring stack. Critical Issues
Moderate Issues
Minor Issues
What Looks Good
RecommendationApprove the PR. The interface definitions are well-designed and follow project conventions. The placeholder panics are appropriate preparation for PR #237, and any minor issues (like the potentially truncated function in bsonutil.go) are likely display artifacts rather than actual code defects. The PR successfully achieves its goal of defining the mutation contract without blocking current functionality. Automated review via OpenRouter (Nemotron Super 120B) — workflow source |
AI Code ReviewCritical Issues
Moderate IssuesNone identified. Minor Issues
What Looks Good
RecommendationApprove with notes - The PR successfully establishes the mutation contract foundation for the shared-types refactoring. The silent data corruption risk in Automated review via OpenRouter (Nemotron Super 120B) — workflow source |
|
Re: AI Review (comment 1) — conversion function signatures: False positive. |
|
Re: AI Review (comment 2) — truncated function signature and placeholder panics: The truncated |
|
Re: AI Review (comment 3) — IDToBsonBinary silent fallback: The fallback-to-random-ID behavior is inherited from the original The type alias naming suggestion (using |
…ert.go signatures
|
Re: AI Reviews — fixes applied in 26b2478:
|
AI Code ReviewCritical IssuesNone found. Moderate IssuesNone found. Minor Issues
What Looks Good
RecommendationApprove. The PR is a well-scoped, high-quality refactoring that consistently implements the shared-types pattern, prepares cleanly for subsequent implementation work, includes necessary test coverage, and fixes a legitimate bug. No blocking issues were identified. Automated review via OpenRouter (Nemotron Super 120B) — workflow source |
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 123 out of 126 changed files in this pull request and generated 5 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
AI Code ReviewCritical IssuesNone found. Moderate Issues
Minor IssuesNone found. What Looks Good
RecommendationRequest changes until a test file for
Once tests are added, the PR is ready for approval as it cleanly advances the shared-types refactoring goal without modifying MDL syntax or violating design guidelines. The scoped changes align with the PR's stated purpose of preparing for PR #237's implementation. Automated review via OpenRouter (Nemotron Super 120B) — workflow source |
…lePropertyOp; add TODO comments in panic stubs
AI Code ReviewCritical Issues
Moderate Issues
Minor Issues
What Looks Good
RecommendationApprove Automated review via OpenRouter (Nemotron Super 120B) — workflow source |
|
Re: AI Reviews (comments 5 & 6) — fixes applied in 957a1e7 and 741e689:
|
AI Code ReviewWhat Looks Good
Moderate IssuesTest Coverage Gaps
RecommendationApprove with the understanding that test coverage for the new packages and bug fix should be addressed in subsequent work (likely PR #237 where the interfaces are implemented). The refactor is well-scoped, follows the shared-types stack plan, and prepares cleanly for the implementation phase. The missing unit tests are a moderate issue but don't block approval since:
The PR successfully advances the shared-types refactoring goal with minimal risk. Automated review via OpenRouter (Nemotron Super 120B) — workflow source |
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 124 out of 127 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.
AI Code ReviewCritical IssuesNone found. Moderate IssuesNone found. Minor Issues
What Looks Good
RecommendationApprove. This PR is a clean refactor that successfully defines the mutation contract interfaces, prepares the codebase for the upcoming implementation in PR #237, includes appropriate mock implementations for testing, fixes a UUID generation bug, and maintains proper separation of concerns. The minor issue about missing unit tests is acceptable since this is preparation work and tests will likely be added when the implementation arrives in PR #237. Automated review via OpenRouter (Nemotron Super 120B) — workflow source |
|
Re: AI Review (comment 7) — test coverage gaps already addressed:
|
Why
The executor currently manipulates BSON documents directly to alter pages and workflows — constructing widget trees, updating properties, managing workflow activities. This logic is scattered across
cmd_alter_page.go(1721 lines) andcmd_alter_workflow.go(887 lines), tightly coupling the executor tosdk/mprinternals.This PR defines the mutation contract — interfaces that the executor will call through instead of manipulating BSON directly.
What changed (incremental from PR #235)
17 files changed, +485/-146
New files:
mdl/backend/mutation.go(181 lines) — definesPageMutatorandWorkflowMutatorinterfaces covering all mutation operations: widget property ops, widget tree ops (add/drop/move), variable ops, layout ops, pluggable widget ops, activity management, and Savemdl/backend/mock/mock_mutation.go(64 lines) — mock implementations for testingmdl/bsonutil/bsonutil.go(33 lines) — BSON ID conversion utilities (IDToBsonBinary,BsonBinaryToID,NewIDBsonBinary) extracted fromsdk/mpr/utils.gointo a CGO-free packageInterface wiring:
backend.goandmpr/backend.goextended to expose the new mutation interfacescmd_alter_page.go,cmd_alter_workflow.go,cmd_pages_builder_input*.go) updated to call through the new interfaces — preparing for the implementation in PR refactor: implement mutation backends and migrate handlers #237Bug fix:
GenerateDeterministicIDnow sets UUID v4 version and variant bits on hash bytes before formattingDesign:
PageMutatorandWorkflowMutatorare session-scoped — created per mutation operation, accumulate changes, and commit withSave(). This matches the existing pattern of loading a unit, modifying it, and writing it back.Stack
PR 2/5 in the shared-types refactoring stack.
Merge order: #232 → #235 → this → #237 → #238 → #239