Skip to content

feat(produce): schema-aware Produce Record backend (UX-1292)#2461

Open
c-julin wants to merge 2 commits into
masterfrom
jc/ux-1292-backend
Open

feat(produce): schema-aware Produce Record backend (UX-1292)#2461
c-julin wants to merge 2 commits into
masterfrom
jc/ux-1292-backend

Conversation

@c-julin
Copy link
Copy Markdown
Contributor

@c-julin c-julin commented May 21, 2026

Summary

Backend half of the schema-aware Produce Record flow. Frontend lands in a stacked PR on top of this branch.

  • proto: new GenerateSchemaSample RPC; extended PublishMessagePayloadOptions with schema_id + index_path so the wire format can address nested Protobuf messages.
  • backend/pkg/schemasample — schema-type-aware sample JSON generator (Avro / Protobuf / JSON Schema), unit-tested.
  • backend/pkg/console:
    • GetSchemaRegistrySubjectDetails embeds per-version MessageTypes for Protobuf entries (descriptor walk via cachedSchemaClient), so the produce UI can render a typed message-type picker without a second RPC.
    • new /schema-registry/schemas endpoint + GetAllSchemas service method.
    • per-version message-type resolution extracted to populateProtoMessageTypes to keep the parent function under the cyclop ceiling.
  • backend/pkg/serde — Protobuf+schemaId payloads now dispatch through the schema-registry serde path so registered subjects resolve correctly.

Test plan

  • task backend:lint — 0 issues locally.
  • task proto:generate regenerates cleanly.
  • Schema-registry CRUD smoke (subjects, details with mixed schema types).
  • Produce flow validated end-to-end in the stacked frontend PR.

Adds schema-introspection + sample-generator infrastructure for the
schema-aware Produce Record flow:

- proto: new GenerateSchemaSample RPC; extended PublishMessagePayloadOptions
  with optional schema_id / index_path so the wire format can address
  nested Protobuf messages.
- backend/pkg/schemasample: schema-type-aware sample JSON generator (Avro /
  Protobuf / JSON Schema), unit-tested.
- backend/pkg/console: GetSchemaRegistrySubjectDetails now embeds
  per-version MessageTypes for Protobuf entries (descriptor walk via
  cachedSchemaClient), so the produce UI can render a typed message-type
  picker without a second RPC. /schema-registry/schemas endpoint + new
  GetAllSchemas service method. Per-version message-type resolution
  extracted to populateProtoMessageTypes helper to keep the parent
  function under the cyclop ceiling.
- backend/pkg/serde: Protobuf+schemaId payloads now dispatch through the
  schema-registry serde path so registered subjects resolve correctly.
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 21, 2026

The latest Buf updates on your PR. Results from workflow Buf CI / validate (pull_request).

BuildFormatLintBreakingUpdated (UTC)
✅ passed✅ passed✅ passed✅ passedMay 21, 2026, 6:22 PM

Addresses adversarial code review findings on PR #2461:

- JSON tags on MessageTypeInfo so the REST subject-details response uses
  fullyQualifiedName/indexPath camelCase. Without tags Go encoded them as
  FullyQualifiedName/IndexPath, breaking the frontend message-type picker.
- avroSamplePrimitiveOrRef no longer double-marks the visited flag. The
  duplicate-flag bug caused the first reference to a non-recursive named
  record to render as null instead of expanding the record's fields.
- walkMessageTypes skips synthetic map-entry descriptors so map<K,V> field
  types don't appear as selectable message types in the produce UI.
- handleGetAllSchemas clamps Limit to 1000 (and defaults to 1000 when
  unset) so an unbounded request can't pull MB-sized payloads.
- Regression test TestAvro_NonRecursiveRecordReference locks the
  visited-flag fix.
Copy link
Copy Markdown
Contributor

@r-vasquez r-vasquez left a comment

Choose a reason for hiding this comment

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

LGTM, just minor nits

if schemas[i].Type != sr.TypeProtobuf {
continue
}
i := i
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.

Do we still need this on the latest go? doesn't go fix ./... removes it?

func walkMessageTypes(msgs protoreflect.MessageDescriptors, prefix []int32, out *[]proto.MessageTypeInfo) {
for i := 0; i < msgs.Len(); i++ {
md := msgs.Get(i)
path := append(append([]int32(nil), prefix...), int32(i))
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.

Suggested change
path := append(append([]int32(nil), prefix...), int32(i))
path := append(slices.Clone(prefix), int32(i))

Nit (I believe) you can use slices.Clone

Comment on lines +28 to +29
// Avro/JSON-Schema literal type names. Extracted as constants so goconst doesn't
// flag the repeated occurrences and to make typos compile-time errors.
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.

Suggested change
// Avro/JSON-Schema literal type names. Extracted as constants so goconst doesn't
// flag the repeated occurrences and to make typos compile-time errors.
// Avro/JSON-Schema literal type names.

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.

2 participants