Skip to content

feat: model /template/update fields as nullable so channels can be patched - #63

Merged
ysyneu merged 2 commits into
mainfrom
feat/template-update-nullable-fields
Aug 24, 2026
Merged

feat: model /template/update fields as nullable so channels can be patched#63
ysyneu merged 2 commits into
mainfrom
feat/template-update-nullable-fields

Conversation

@ysyneu

@ysyneu ysyneu commented Aug 23, 2026

Copy link
Copy Markdown
Collaborator

What

POST /template/update is a partial update: a field absent from the request is left alone, and only an explicit empty string clears a channel. The generated request struct could not express that. TemplateUpdateRequest's 14 channel-content fields, description and team_id were value types with omitempty, so "" encoded identically to "unset" — clearing a channel through the SDK was impossible, and TeamID: 0 could never move a template to account scope.

This marks those properties nullable in the vendored spec and regenerates. They become pointers:

// leave every other channel alone, rewrite one
_, err := c.NotificationTemplates.WriteUpdate(ctx, &flashduty.TemplateUpdateRequest{
    TemplateID:   id,
    TemplateName: name,               // still required on every update
    Feishu:       flashduty.String(src),
})

// clear a channel
Zoom: flashduty.String(""),

Why the spec is edited in place

make sync-spec pulls the whole upstream document, and the vendored copy is a few endpoints behind, so a wholesale resync would bury this schema in unrelated churn. The edit here is byte-identical to the corresponding region of the upstream spec (verified field by field), and the nightly sync job reconciles the rest on its own schedule.

Ordering

Merge flashcatcloud/flashduty-docs#303 first. It carries the same change to the source-of-truth spec; landing this one first means the next nightly sync opens a PR that undoes it.

The pointer fields are correct against the server both before and after the corresponding server-side change ships — a nil field is omitted exactly as omitempty omitted a zero value today — so this can be released ahead of it.

Checks

  • make generate reproduces the committed output (39 services, 336 operations, 707 schemas); the only non-spec diff is models_gen.go + the doc comment on WriteUpdate.
  • go build ./..., go build -tags e2e ./..., go vet ./..., go test ./... — all green.
  • golangci-lint run (v2.11.4, the pinned version) — 0 issues.
  • Both new guards mutation-verified: reverting a channel field to a value type reddens the "clears a channel" case, and dropping an omitempty reddens the "carries only the channel it changes" case.

ysyneu added 2 commits August 23, 2026 00:18
…tched

`POST /template/update` is a partial update: a field absent from the request is
left alone, and only an explicit empty string clears a channel. The generated
request struct could not express that — the 14 channel-content fields,
`description` and `team_id` were value types with `omitempty`, so an empty
string meant the same thing as "unset" and clearing a channel through the SDK
was impossible.

Mark those properties nullable in the vendored spec, matching how
`feishu_app_card_v2_table_enabled` already models "omit keeps the current
setting", and regenerate. They become pointers, so nil omits the field and
`flashduty.String("")` clears the channel. `team_id` likewise: `Int64(0)` now
moves a template to account scope instead of being dropped by the encoder.

The vendored spec is edited in place rather than resynced wholesale so the diff
stays scoped to this schema; the nightly sync job reconciles the rest.

Two guards in flashduty_test.go, on the existing nullable-field tables: an
explicitly cleared channel must reach the wire, and an update that touches one
channel must not carry the others.
Mirrors the upstream wording change so the vendored copy stays byte-identical to
the source spec in that region and the nightly sync has nothing to report. The
generator does not read x-mint.content, so the generated layer is unchanged --
'make generate' reproduces the committed output exactly.
@ysyneu
ysyneu merged commit 4b0d77d into main Aug 24, 2026
4 checks passed
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