Status
Deferred from 6.1. Tracking the SalesPlatform polish layer that simplifies updateMediaBuy for adopters.
Today's shape (6.0 / 6.1)
updateMediaBuy(buyId, patch: UpdateMediaBuyRequest, ctx): Promise<UpdateMediaBuySuccess>
Adopter receives the whole wire patch and figures out what changed: which packages were added, which removed, which had targeting overrides changed, whether `active` flipped, etc. Every adopter writes the same diff/dispatch boilerplate.
Proposed 6.2 shape
The SDK pre-reads current state via a required `getMediaBuy(buyId)` primitive, computes the diff against the wire patch, and decomposes into atomic verbs the adopter implements:
// Required new primitive (single-id read):
getMediaBuy(buyId: string, ctx): Promise<NativeMediaBuy>;
// Atomic verbs (replaces the omnibus updateMediaBuy):
addPackage(buyId, productRef, package, ctx): Promise<NativePackage>;
removePackage(buyId, packageId, ctx): Promise<void>;
updatePackage(buyId, packageId, patch, ctx): Promise<NativePackage>;
addCreativeToPackage(buyId, packageId, creative, ctx): Promise<void>;
removeCreativeFromPackage(buyId, packageId, creativeId, ctx): Promise<void>;
pauseMediaBuy(buyId, ctx): Promise<void>;
resumeMediaBuy(buyId, ctx): Promise<void>;
archiveMediaBuy(buyId, ctx): Promise<void>;
SDK does:
- Pre-read `getMediaBuy(buyId)` for current state
- Validate `package_id`s in the patch against current state → throw `PACKAGE_NOT_FOUND` before any platform writes
- Diff patch against current state → decompose into atomic-verb sequence
- Call adopter verbs in sequence
- Post-read `getMediaBuy(buyId)` → project to wire response via StatusMappers
Why this is 6.2 not 6.1
- Requires new `getMediaBuy(id)` primitive — currently optional, becomes required
- Patch-decomposition logic is non-trivial (creative_assignments override-vs-add/remove, targeting_overlay merge semantics, package pricing changes)
- Some platforms have native atomic patches (GAM `lineItem.update`) — needs an opt-out escape hatch where adopter overrides the decomposed shape
- Pre-mutation read adds a round-trip on every update — perf model needs documentation
- Worth validating against Scope3, Prebid, AudioStack adapter implementations before locking
What 6.1 ships instead
`ctx_metadata` round-trip cache (this PR) covers the storage primitive needed for the auto-everything redesign. Adopters can already use `ctx.ctxMetadata.set('package', id, ...)` on `createMediaBuy` to stash per-package state, and the patch decomposition can read it later without an extra DB hop. So 6.2 is purely the request-shape simplification — the storage substrate is there.
Linked
Status
Deferred from 6.1. Tracking the SalesPlatform polish layer that simplifies
updateMediaBuyfor adopters.Today's shape (6.0 / 6.1)
Adopter receives the whole wire patch and figures out what changed: which packages were added, which removed, which had targeting overrides changed, whether `active` flipped, etc. Every adopter writes the same diff/dispatch boilerplate.
Proposed 6.2 shape
The SDK pre-reads current state via a required `getMediaBuy(buyId)` primitive, computes the diff against the wire patch, and decomposes into atomic verbs the adopter implements:
SDK does:
Why this is 6.2 not 6.1
What 6.1 ships instead
`ctx_metadata` round-trip cache (this PR) covers the storage primitive needed for the auto-everything redesign. Adopters can already use `ctx.ctxMetadata.set('package', id, ...)` on `createMediaBuy` to stash per-package state, and the patch decomposition can read it later without an extra DB hop. So 6.2 is purely the request-shape simplification — the storage substrate is there.
Linked
ctx_metadataas adapter-internal round-trip key on resource objects adcp#3640