Skip to content

[registry] Bridge v1beta3 Connection wire format at model registration boundary#1018

Open
YASHMAHAKAL wants to merge 4 commits into
meshery:masterfrom
YASHMAHAKAL:model-generate-migration
Open

[registry] Bridge v1beta3 Connection wire format at model registration boundary#1018
YASHMAHAKAL wants to merge 4 commits into
meshery:masterfrom
YASHMAHAKAL:model-generate-migration

Conversation

@YASHMAHAKAL

@YASHMAHAKAL YASHMAHAKAL commented Jun 1, 2026

Copy link
Copy Markdown
Contributor

Description

⚠️ Depends on meshery/schemas#914 — CI will pass once that PR is merged.

This is PR 2 of 3 in the model-generate-migration chain:

  • PR 1 — meshery/schemas#914 (schemas) ← merge first
  • PR 2 — this PR (meshkit)
  • PR 3 — meshery/meshery (server + UI) ← pending

What & Why

The companion schemas PR migrates the model Registrant field to the canonical
v1beta3/connection type, fulfilling the camelCase wire-format contract defined
in AGENTS.md.

Because the internal registry persistence interface (RegisterEntity) is intentionally pinned to v1beta1 at the ORM boundary (per AGENTS.md: "the ORM layer is the sole translation boundary"), this PR introduces the required translation layer for writes between the canonical wire format (v1beta3) and the internal storage format (v1beta1) — following the same field-copy bridge pattern already established in the meshery/meshery codebase.

For the read path, the v1beta3 schema is used directly with GORM to prevent data loss.

Changes

  • Registration boundary (Write) — Added a bridge helper (connV3ToV1) to translate the canonical v1beta3 Registrant to the internal v1beta1 storage type at the RegisterEntity call sites. (A direct migration of this signature is deferred until Create() is implemented on v1beta3.Connection).
  • Database hydration (Read) — Fixed a data loss bug by updating the GORM scan struct in component_filter.go to scan connections.* directly into v1beta3.Connection. Because the db: tags are identical across versions, this cleanly bypasses the need for a manual field-copy bridge and ensures fields like description and url are preserved for camelCase wire compliance.
  • Model imports — Updated across the pipeline from v1beta1/model to v1beta2/model to align with the schema upgrade.
  • Relationship schema version — Updated the version constant to v1beta3 to align generated relationships with component and model templates.

Related

Signed-off-by: YASHMAHAKAL <yvsst01@gmail.com>
Switches ModelFilter.Get/GetById to return *v1beta2.ModelDefinition entities,
consistent with the rest of the meshkit model layer after the v1beta1→v1beta2
migration of component.Model (registry/model.go) and registration/register.go.

This ensures type-assertion callers (e.g. component_handler.go) receive the
correct concrete type and avoids a runtime panic at the type-assertion site.

Signed-off-by: YASHMAHAKAL <yvsst01@gmail.com>
Three coordinated changes to align model.Registrant with the updated
v1beta2/model.ModelDefinition.Registrant type (connectionv1beta3.Connection):

registry/model.go:
  createNewRegistrant() now returns connectionv1beta3.Connection. The v1beta3
  Connection struct has full camelCase JSON tags (createdAt, updatedAt,
  deletedAt, userId, credentialId, subType) which are emitted when
  WriteModelDefinition() serializes to disk.

models/registration/register.go:
  Adds connV3ToV1() bridge helper (field-copy v1beta3→v1beta1). All three
  RegisterEntity() call sites use the bridge to satisfy the RegistryManager's
  stable v1beta1.Connection parameter without changing the internal DB API.
  Connection import switched from v1beta1 to v1beta3 for model.Registrant.Status.

models/meshmodel/registry/v1beta1/component_filter.go:
  ConnectionDB (GORM-read v1beta1.Connection) is field-copied to
  connectionv1beta3.Connection when assigned to cd.Model.Registrant.
  DB column tags are identical in both versions — no schema change.

schema/validator.go:
  Adds RelationshipSchemaVersionV1Beta3 constant.

registry/relationship.go:
  Switches from RelationshipSchemaVersionV1Beta2 to V1Beta3 so model generate
  emits relationships.meshery.io/v1beta3 — matching model init templates.

Signed-off-by: YASHMAHAKAL <yvsst01@gmail.com>
…nection

Previously, the GORM scan struct read the connection into v1beta1.Connection
and then manually field-copied 6 fields into v1beta3.Connection, silently
dropping the 'description' and 'url' fields which exist in the DB
(connections table was already AutoMigrated with v1beta3.Connection in
meshery server).

Since db: tags are identical between v1beta1 and v1beta3, GORM can scan
directly into v1beta3.Connection without any data loss. The manual bridge
and the v1beta1/connection import are removed.

The write-path bridge (connV3ToV1 at RegisterEntity call sites) is
unchanged — v1beta3.Connection has no Create() method yet.

Signed-off-by: YASHMAHAKAL <yvsst01@gmail.com>
@welcome

welcome Bot commented Jun 1, 2026

Copy link
Copy Markdown

Yay, your first pull request! 👍 A contributor will be by to give feedback soon. In the meantime, you can find updates in the #github-notifications channel in the community Slack.
Be sure to double-check that you have signed your commits. Here are instructions for making signing an implicit activity while performing a commit.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request updates the imported schema models from v1beta1 to v1beta2 for models and v1beta3 for connections across several generator, model, and registry files, including introducing a v1beta3 relationship schema version. Two critical issues were identified in the review: first, a loop variable capture bug in component_filter.go where taking the address of cm.ModelDB inside a loop causes all component definitions to point to the same model; second, a missing switch case for the new v1beta3 relationship schema version in getEntity within models/registration/utils.go which will cause registration failures.

Comment thread registry/relationship.go

var rel _rel.RelationshipDefinition
rel.SchemaVersion = schema.RelationshipSchemaVersionV1Beta2
rel.SchemaVersion = schema.RelationshipSchemaVersionV1Beta3

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

critical

When updating the relationship schema version to v1beta3, please make sure to also add schema.RelationshipSchemaVersionV1Beta3 to the switch sv.SchemaVersion statement in getEntity within models/registration/utils.go.

Currently, getEntity only handles schema.RelationshipSchemaVersionV1Beta2 and v1alpha3.RelationshipSchemaVersion. If a relationship with v1beta3 is processed, it will fall through to the default case and fail registration with an unrecognized schema version error.

Comment on lines 151 to 152
cd := cm.ComponentDefinitionDB
cd.Model = &cm.ModelDB

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

Taking the address of a field of the loop variable cm (&cm.ModelDB) is a classic Go loop variable capture bug (pre-Go 1.22). Since cm is reused across iterations, all component definitions in defs will end up pointing to the same ModelDB address (the last element's model).

To fix this, copy cm.ModelDB to a local variable inside the loop before taking its address, similar to how it is handled in model_filter.go.

		cd := cm.ComponentDefinitionDB
		modelDB := cm.ModelDB
		cd.Model = &modelDB

@YASHMAHAKAL YASHMAHAKAL marked this pull request as draft June 1, 2026 13:33
@YASHMAHAKAL YASHMAHAKAL marked this pull request as ready for review June 3, 2026 12:26
@YASHMAHAKAL YASHMAHAKAL requested a review from leecalcote June 6, 2026 17:51
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.

[registry] ModelDefinition.Registrant emits snake_case wire format — mismatches v1beta3 canonical contract

1 participant