From 574b7eb53313db604d2f034951b3cbf0deefff35 Mon Sep 17 00:00:00 2001 From: dqn Date: Fri, 17 Jul 2026 01:53:21 +0900 Subject: [PATCH] fix(cli): stop re-updating unchanged TailorDB types on deploy The platform now returns `optionalOnCreate: false` explicitly on every field config, while locally generated manifests omit the flag. The type diff treated this as a change, so every deploy re-applied every type in the workspace. Normalize `optionalOnCreate: false` to unset at compare time, matching how other known platform defaults are handled. --- .changeset/tailordb-noop-type-updates.md | 5 ++ .../commands/deploy/tailordb/index.test.ts | 64 +++++++++++++++++++ .../src/cli/commands/deploy/tailordb/index.ts | 9 +++ 3 files changed, 78 insertions(+) create mode 100644 .changeset/tailordb-noop-type-updates.md diff --git a/.changeset/tailordb-noop-type-updates.md b/.changeset/tailordb-noop-type-updates.md new file mode 100644 index 0000000000..765da5647e --- /dev/null +++ b/.changeset/tailordb-noop-type-updates.md @@ -0,0 +1,5 @@ +--- +"@tailor-platform/sdk": patch +--- + +Fix deploy re-updating every TailorDB type on each run even when nothing changed diff --git a/packages/sdk/src/cli/commands/deploy/tailordb/index.test.ts b/packages/sdk/src/cli/commands/deploy/tailordb/index.test.ts index 8c630a4083..c7b3f8658a 100644 --- a/packages/sdk/src/cli/commands/deploy/tailordb/index.test.ts +++ b/packages/sdk/src/cli/commands/deploy/tailordb/index.test.ts @@ -543,6 +543,70 @@ describe("planTailorDB (service level)", () => { expect(result.changeSet.type.updates).toHaveLength(0); }); + test("treats remote optionalOnCreate=false as unchanged against a local manifest omitting it", async () => { + const tailordbType: TailorDBType = { + name: "Invoice", + pluralForm: "Invoices", + description: "Invoice type", + fields: { + code: { + name: "code", + config: { + type: "string", + required: true, + }, + }, + }, + forwardRelationships: {}, + backwardRelationships: {}, + settings: {}, + permissions: {}, + files: {}, + }; + + const tailorDBService = createMockTailorDBService("test-tailordb"); + Object.defineProperty(tailorDBService, "types", { + value: { [tailordbType.name]: tailordbType }, + }); + + const client = createRemoteTypeClient("test-tailordb", { + name: "Invoice", + description: "Invoice type", + pluralForm: "invoices", + fields: { + code: { + type: "string", + required: true, + allowedValues: [], + description: "", + validate: [], + array: false, + index: false, + unique: false, + foreignKey: false, + vector: false, + optionalOnCreate: false, + fields: {}, + }, + }, + }); + + const application = createMockApplication([tailorDBService]); + const ctx: PlanContext = { + client, + workspaceId, + application, + forRemoval: false, + config: mockConfig, + noSchemaCheck: true, + }; + + const result = await planTailorDB(ctx); + + expect(result.changeSet.type.unchanged).toEqual([{ name: "Invoice" }]); + expect(result.changeSet.type.updates).toHaveLength(0); + }); + test("updates matching type when forceApplyAll is enabled", async () => { const tailordbType: TailorDBType = { name: "Invoice", diff --git a/packages/sdk/src/cli/commands/deploy/tailordb/index.ts b/packages/sdk/src/cli/commands/deploy/tailordb/index.ts index 3e6399205e..7b04d2715f 100644 --- a/packages/sdk/src/cli/commands/deploy/tailordb/index.ts +++ b/packages/sdk/src/cli/commands/deploy/tailordb/index.ts @@ -1763,6 +1763,15 @@ function normalizeTailorDBCompareValue( return value; } + // Platform returns `optionalOnCreate: false` explicitly, while local + // manifests omit the flag entirely. Treat false as unset so they match. + if (typeof value === "boolean") { + if (path.at(-1) === "optionalOnCreate" && value === false) { + return undefined; + } + return value; + } + if (typeof value === "number" || typeof value === "bigint" || typeof value === "string") { if (matchesNumericStringPath(path) && isNumericLikeValue(value)) { return String(value);