fix(metadata): publish/discard package drafts in the draft's own org scope (#3115)#3156
Merged
Conversation
…scope (#3115) Studio "Save Draft" goes through REST `PUT /meta/:type/:name?mode=draft`, which never threads the session's `activeOrganizationId` into `saveMetaItem` — so the draft row is written env-wide (`organization_id = NULL`). "Publish" goes through `POST /packages/:id/publish-drafts`, which DOES resolve the active org (non-null once a default org is stamped on the session). PR #1852 taught `listDrafts` to surface those env-wide drafts to a non-null active org via `$or [{org}, {org IS NULL}]` — so the Publish CTA appears — but the publish path (`promoteDraft`) still looked the draft up with a STRICT `organization_id = <org>` equality and 404'd (`[no_draft] No pending draft exists …`) on the env-wide row it could never match. `discardPackageDrafts` had the identical latent gap (delete under the request org silently no-ops on env-wide rows). Fix: `listDrafts` now projects each draft's own `organizationId`, and `publishPackageDrafts` / `discardPackageDrafts` promote / delete each draft in THAT scope (env-wide stays env-wide, per-org stays per-org) — so the pending-changes list and the publish/discard paths agree. Seed-body capture and the ADR-0067 revert-plan pre-state read are scoped the same way. Regression tests reproduce the exact `no_draft` error (env-wide draft + non-null publish org) and assert publish now succeeds env-wide, plus a no-regression case for a genuinely org-scoped draft. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Contributor
📓 Docs Drift CheckThis PR changes 2 package(s): 13 hand-written doc(s) reference the affected code and may need an implementation-accuracy re-verification:
|
…e fix (#3115) Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem — #3115
Saving a new object (with fields) in a package via Studio, then clicking Publish, returns
no_drafteven though the draft was just saved:{ "success": false, "publishedCount": 0, "failedCount": 1, "failed": [{ "type": "object", "name": "…", "error": "[no_draft] No pending draft exists for object/… — nothing to publish.", "code": "no_draft" }] }Root cause — a cross-layer org-scope asymmetry
PUT /meta/:type/:name?mode=draft&package=…(rest-server.ts)activeOrganizationId→ draft written env-wide (organization_id = NULL)POST /packages/:id/publish-drafts(http-dispatcher.ts)session.activeOrganizationId→ non-null once a default org is stamped on the sessionPR #1852 taught
listDraftsto surface env-wide drafts to a non-null active org via$or [{org}, {org IS NULL}]— so the Publish CTA appears — but the publish path was never updated to match:promoteDraftstill looks the draft up with a strictorganization_id = <org>equality and 404s (no_draft) on the env-wide row it can never match.discardPackageDraftshad the identical latent gap (delete under the request org silently no-ops on env-wide rows).Same "orphaned draft" bug as #1852, one layer deeper: the pending-changes list was fixed, the publish/discard action wasn't.
Fix
SysMetadataRepository.listDrafts()now projects each draft's ownorganizationId.publishPackageDrafts/discardPackageDraftspromote / delete each listed draft in the scope it actually lives in (env-wide stays env-wide, per-org stays per-org) instead of forcing the caller's active org. Seed-body capture and the ADR-0067 revert-plan pre-state read are scoped the same way.Package-owned metadata is env-level, so keeping it env-wide on publish is the correct provenance — the bug was purely that publish couldn't reach the env-wide draft.
Tests
protocol-publish-drafts-org-scope.test.ts(new) — reproduces the exact[no_draft] … nothing to publish.error against the reallistDrafts+promoteDraftinteraction (faithful stub engine honouring$or/IS NULL), then asserts publish succeeds env-wide; plus a no-regression case for a genuinely org-scoped draft.sys-metadata-repository-list-drafts.test.ts— asserts the neworganizationIdprojection.metadata-protocol(37) +objectql(905) suites green.Verification
Traced end-to-end: objectui Studio calls
metadataClient.save(type, name, body, { mode: 'draft' })→ env-widePUT /meta?mode=draft; publish viausePublishAllDrafts→POST /packages/:id/publish-drafts. The reported error string is only reachable with an env-wide draft + non-null publish org, which this fix resolves.🤖 Generated with Claude Code